[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: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
f455adcff1
commit
85cb185dad
|
@ -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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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);
|
||||||
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);
|
||||||
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)
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue