mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 09:34:12 +08:00
acpi-cpufreq: fix 'smp_call_function_many()' confusion
It turns out that 'smp_call_function_many()' doesn't work at all like 'smp_call_function_single()', and my change to Andrew's patch to use it rather than a loop over all CPU's acpi-cpufreq doesn't work. My bad. 'smp_call_function_many()' has two "features" (aka "documented bugs"): (a) it needs to be called with preemption disabled, because it uses smp_processor_id() without guarding the CPU lookup with 'get_cpu()' and 'put_cpu()' like the 'single' variant does. (b) even if the current CPU is part of the CPU mask, it won't do the call on that CPU. Still, we're better off trying to use 'smp_call_function_many()' than looping over CPU's, since it at least in theory allows us to use a broadcast IPI and do it all in parallel. So let's just work around the silly semantic bugs in that function. Reported-and-tested-by: Ali Gholami Rudi <ali@rudi.ir> Cc: Ingo Molnar <mingo@elte.hu> Cc: Andrew Morton <akpm@linux-foundation.org>, Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Dave Jones <davej@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
0882e8dd3a
commit
ea34f43a07
@ -204,7 +204,13 @@ static void drv_read(struct drv_cmd *cmd)
|
||||
|
||||
static void drv_write(struct drv_cmd *cmd)
|
||||
{
|
||||
int this_cpu;
|
||||
|
||||
this_cpu = get_cpu();
|
||||
if (cpumask_test_cpu(this_cpu, cmd->mask))
|
||||
do_drv_write(cmd);
|
||||
smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
static u32 get_cur_val(const struct cpumask *mask)
|
||||
|
Loading…
Reference in New Issue
Block a user