Commit 85cb185dad54be308c3f3a6068dd7d418b8b53e4

Authored by Heiko Carstens
Committed by Martin Schwidefsky
1 parent f455adcff1

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

Showing 1 changed file with 8 additions and 8 deletions Side-by-side Diff

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