Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpufreq: powernv: Hot-plug safe the kworker thread

In the kworker_thread powernv_cpufreq_work_fn(), we can end up
sending an IPI to a cpu going offline. This is a rare corner case
which is fixed using {get/put}_online_cpus(). Along with this fix,
this patch adds changes to do oneshot cpumask_{clear/and} operation.

Suggested-by: Shreyas B Prabhu <shreyas@linux.vnet.ibm.com>
Suggested-by: Gautham R Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Shilpasri G Bhat and committed by
Rafael J. Wysocki
6d167a44 86622cb8

+11 -8
+11 -8
drivers/cpufreq/powernv-cpufreq.c
··· 28 28 #include <linux/of.h> 29 29 #include <linux/reboot.h> 30 30 #include <linux/slab.h> 31 + #include <linux/cpu.h> 31 32 32 33 #include <asm/cputhreads.h> 33 34 #include <asm/firmware.h> ··· 424 423 { 425 424 struct chip *chip = container_of(work, struct chip, throttle); 426 425 unsigned int cpu; 427 - cpumask_var_t mask; 426 + cpumask_t mask; 428 427 429 - smp_call_function_any(&chip->mask, 428 + get_online_cpus(); 429 + cpumask_and(&mask, &chip->mask, cpu_online_mask); 430 + smp_call_function_any(&mask, 430 431 powernv_cpufreq_throttle_check, NULL, 0); 431 432 432 433 if (!chip->restore) 433 - return; 434 + goto out; 434 435 435 436 chip->restore = false; 436 - cpumask_copy(mask, &chip->mask); 437 - for_each_cpu_and(cpu, mask, cpu_online_mask) { 438 - int index, tcpu; 437 + for_each_cpu(cpu, &mask) { 438 + int index; 439 439 struct cpufreq_policy policy; 440 440 441 441 cpufreq_get_policy(&policy, cpu); ··· 444 442 policy.cur, 445 443 CPUFREQ_RELATION_C, &index); 446 444 powernv_cpufreq_target_index(&policy, index); 447 - for_each_cpu(tcpu, policy.cpus) 448 - cpumask_clear_cpu(tcpu, mask); 445 + cpumask_andnot(&mask, &mask, policy.cpus); 449 446 } 447 + out: 448 + put_online_cpus(); 450 449 } 451 450 452 451 static char throttle_reason[][30] = {