[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>

authored by Heiko Carstens and committed by Martin Schwidefsky 85cb185d f455adcf

+8 -8
+8 -8
arch/s390/kernel/smp.c
··· 139 139 if (wait) 140 140 data.finished = CPU_MASK_NONE; 141 141 142 - spin_lock(&call_lock); 143 142 call_data = &data; 144 143 145 144 for_each_cpu_mask(cpu, map) ··· 150 151 if (wait) 151 152 while (!cpus_equal(map, data.finished)) 152 153 cpu_relax(); 153 - spin_unlock(&call_lock); 154 154 out: 155 155 if (local) { 156 156 local_irq_disable(); ··· 175 177 { 176 178 cpumask_t map; 177 179 178 - preempt_disable(); 180 + spin_lock(&call_lock); 179 181 map = cpu_online_map; 180 182 cpu_clear(smp_processor_id(), map); 181 183 __smp_call_function_map(func, info, nonatomic, wait, map); 182 - preempt_enable(); 184 + spin_unlock(&call_lock); 183 185 return 0; 184 186 } 185 187 EXPORT_SYMBOL(smp_call_function); ··· 200 202 int smp_call_function_single(int cpu, void (*func) (void *info), void *info, 201 203 int nonatomic, int wait) 202 204 { 203 - preempt_disable(); 205 + spin_lock(&call_lock); 204 206 __smp_call_function_map(func, info, nonatomic, wait, 205 207 cpumask_of_cpu(cpu)); 206 - preempt_enable(); 208 + spin_unlock(&call_lock); 207 209 return 0; 208 210 } 209 211 EXPORT_SYMBOL(smp_call_function_single); ··· 226 228 int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, 227 229 int wait) 228 230 { 229 - preempt_disable(); 231 + spin_lock(&call_lock); 230 232 cpu_clear(smp_processor_id(), mask); 231 233 __smp_call_function_map(func, info, 0, wait, mask); 232 - preempt_enable(); 234 + spin_unlock(&call_lock); 233 235 return 0; 234 236 } 235 237 EXPORT_SYMBOL(smp_call_function_mask); ··· 590 592 pfault_init(); 591 593 592 594 /* Mark this cpu as online */ 595 + spin_lock(&call_lock); 593 596 cpu_set(smp_processor_id(), cpu_online_map); 597 + spin_unlock(&call_lock); 594 598 /* Switch on interrupts */ 595 599 local_irq_enable(); 596 600 /* Print info about this processor */