提交 85cb185d 编写于 作者: H Heiko Carstens 提交者: Martin Schwidefsky

[S390] smp: __smp_call_function_map vs cpu_online_map fix.

Both smp_call_function() and __smp_call_function_map() access
cpu_online_map. Both functions run with preemption disabled which
protects for cpus going offline. However new cpus can be added and
therefore the cpu_online_map can change unexpectedly.
So use the call_lock to protect against changes to the cpu_online_map
in start_secondary() and all smp_call_* functions.
Signed-off-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 f455adcf
...@@ -139,7 +139,6 @@ static void __smp_call_function_map(void (*func) (void *info), void *info, ...@@ -139,7 +139,6 @@ static void __smp_call_function_map(void (*func) (void *info), void *info,
if (wait) if (wait)
data.finished = CPU_MASK_NONE; data.finished = CPU_MASK_NONE;
spin_lock(&call_lock);
call_data = &data; call_data = &data;
for_each_cpu_mask(cpu, map) for_each_cpu_mask(cpu, map)
...@@ -151,7 +150,6 @@ static void __smp_call_function_map(void (*func) (void *info), void *info, ...@@ -151,7 +150,6 @@ static void __smp_call_function_map(void (*func) (void *info), void *info,
if (wait) if (wait)
while (!cpus_equal(map, data.finished)) while (!cpus_equal(map, data.finished))
cpu_relax(); cpu_relax();
spin_unlock(&call_lock);
out: out:
if (local) { if (local) {
local_irq_disable(); local_irq_disable();
...@@ -177,11 +175,11 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic, ...@@ -177,11 +175,11 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
{ {
cpumask_t map; cpumask_t map;
preempt_disable(); spin_lock(&call_lock);
map = cpu_online_map; map = cpu_online_map;
cpu_clear(smp_processor_id(), map); cpu_clear(smp_processor_id(), map);
__smp_call_function_map(func, info, nonatomic, wait, map); __smp_call_function_map(func, info, nonatomic, wait, map);
preempt_enable(); spin_unlock(&call_lock);
return 0; return 0;
} }
EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_call_function);
...@@ -202,10 +200,10 @@ EXPORT_SYMBOL(smp_call_function); ...@@ -202,10 +200,10 @@ EXPORT_SYMBOL(smp_call_function);
int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait) int nonatomic, int wait)
{ {
preempt_disable(); spin_lock(&call_lock);
__smp_call_function_map(func, info, nonatomic, wait, __smp_call_function_map(func, info, nonatomic, wait,
cpumask_of_cpu(cpu)); cpumask_of_cpu(cpu));
preempt_enable(); spin_unlock(&call_lock);
return 0; return 0;
} }
EXPORT_SYMBOL(smp_call_function_single); EXPORT_SYMBOL(smp_call_function_single);
...@@ -228,10 +226,10 @@ EXPORT_SYMBOL(smp_call_function_single); ...@@ -228,10 +226,10 @@ EXPORT_SYMBOL(smp_call_function_single);
int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info,
int wait) int wait)
{ {
preempt_disable(); spin_lock(&call_lock);
cpu_clear(smp_processor_id(), mask); cpu_clear(smp_processor_id(), mask);
__smp_call_function_map(func, info, 0, wait, mask); __smp_call_function_map(func, info, 0, wait, mask);
preempt_enable(); spin_unlock(&call_lock);
return 0; return 0;
} }
EXPORT_SYMBOL(smp_call_function_mask); EXPORT_SYMBOL(smp_call_function_mask);
...@@ -592,7 +590,9 @@ int __cpuinit start_secondary(void *cpuvoid) ...@@ -592,7 +590,9 @@ int __cpuinit start_secondary(void *cpuvoid)
pfault_init(); pfault_init();
/* Mark this cpu as online */ /* Mark this cpu as online */
spin_lock(&call_lock);
cpu_set(smp_processor_id(), cpu_online_map); cpu_set(smp_processor_id(), cpu_online_map);
spin_unlock(&call_lock);
/* Switch on interrupts */ /* Switch on interrupts */
local_irq_enable(); local_irq_enable();
/* Print info about this processor */ /* Print info about this processor */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册