Commit c79f01b6 authored by Thomas Richter's avatar Thomas Richter Committed by Heiko Carstens

s390/cpumf: disable preemption when accessing per-cpu variable

The following BUG message was triggered repeatedly when complete counter
sets are extracted from the CPUMF:

BUG: using smp_processor_id() in preemptible [00000000]
     code: psvc-readsets/7759
 caller is cf_diag_needspace+0x2c/0x100
 CPU: 7 PID: 7759 Comm: psvc-readsets Not tainted 5.12.0
 Hardware name: IBM 3906 M03 703 (LPAR)
 Call Trace:
  [<00000000c7043f78>] show_stack+0x90/0xf8
  [<00000000c705776a>] dump_stack+0xba/0x108
  [<00000000c705d91c>] check_preemption_disabled+0xec/0xf0
  [<00000000c63eb1c4>] cf_diag_needspace+0x2c/0x100
  [<00000000c63ecbcc>] cf_diag_ioctl_start+0x10c/0x240
  [<00000000c63ece9a>] cf_diag_ioctl+0x19a/0x238
  [<00000000c675f3f4>] __s390x_sys_ioctl+0xc4/0x100
  [<00000000c63ca762>] do_syscall+0x82/0xd0
  [<00000000c705bdd8>] __do_syscall+0xc0/0xd8
  [<00000000c706d532>] system_call+0x72/0x98
 2 locks held by psvc-readsets/7759:
  #0: 00000000c75a57c0 (cpu_hotplug_lock){++++}-{0:0},
      at: cf_diag_ioctl+0x44/0x238
  #1: 00000000c75a3078 (cf_diag_ctrset_mutex){+.+.}-{3:3},
	            at: cf_diag_ioctl+0x54/0x238

This issue is a missing get_cpu_ptr/put_cpu_ptr pair in function
cf_diag_needspace. Add it.

Fixes: cf6acb8b ("s390/cpumf: Add support for complete counter set extraction")
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarThomas Richter <tmricht@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 1e28eed1
...@@ -968,7 +968,7 @@ static int cf_diag_all_start(void) ...@@ -968,7 +968,7 @@ static int cf_diag_all_start(void)
*/ */
static size_t cf_diag_needspace(unsigned int sets) static size_t cf_diag_needspace(unsigned int sets)
{ {
struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); struct cpu_cf_events *cpuhw = get_cpu_ptr(&cpu_cf_events);
size_t bytes = 0; size_t bytes = 0;
int i; int i;
...@@ -984,6 +984,7 @@ static size_t cf_diag_needspace(unsigned int sets) ...@@ -984,6 +984,7 @@ static size_t cf_diag_needspace(unsigned int sets)
sizeof(((struct s390_ctrset_cpudata *)0)->no_sets)); sizeof(((struct s390_ctrset_cpudata *)0)->no_sets));
debug_sprintf_event(cf_diag_dbg, 5, "%s bytes %ld\n", __func__, debug_sprintf_event(cf_diag_dbg, 5, "%s bytes %ld\n", __func__,
bytes); bytes);
put_cpu_ptr(&cpu_cf_events);
return bytes; return bytes;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment