aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/smp.c')
-rw-r--r--kernel/smp.c192
1 files changed, 40 insertions, 152 deletions
diff --git a/kernel/smp.c b/kernel/smp.c
index 29dd40a9f2f4..8e451f3ff51b 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -16,23 +16,14 @@
16#include "smpboot.h" 16#include "smpboot.h"
17 17
18#ifdef CONFIG_USE_GENERIC_SMP_HELPERS 18#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
19static struct {
20 struct list_head queue;
21 raw_spinlock_t lock;
22} call_function __cacheline_aligned_in_smp =
23 {
24 .queue = LIST_HEAD_INIT(call_function.queue),
25 .lock = __RAW_SPIN_LOCK_UNLOCKED(call_function.lock),
26 };
27
28enum { 19enum {
29 CSD_FLAG_LOCK = 0x01, 20 CSD_FLAG_LOCK = 0x01,
30}; 21};
31 22
32struct call_function_data { 23struct call_function_data {
33 struct call_single_data csd; 24 struct call_single_data __percpu *csd;
34 atomic_t refs;
35 cpumask_var_t cpumask; 25 cpumask_var_t cpumask;
26 cpumask_var_t cpumask_ipi;
36}; 27};
37 28
38static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data); 29static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data);
@@ -56,6 +47,14 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
56 if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL, 47 if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
57 cpu_to_node(cpu))) 48 cpu_to_node(cpu)))
58 return notifier_from_errno(-ENOMEM); 49 return notifier_from_errno(-ENOMEM);
50 if (!zalloc_cpumask_var_node(&cfd->cpumask_ipi, GFP_KERNEL,
51 cpu_to_node(cpu)))
52 return notifier_from_errno(-ENOMEM);
53 cfd->csd = alloc_percpu(struct call_single_data);
54 if (!cfd->csd) {
55 free_cpumask_var(cfd->cpumask);
56 return notifier_from_errno(-ENOMEM);
57 }
59 break; 58 break;
60 59
61#ifdef CONFIG_HOTPLUG_CPU 60#ifdef CONFIG_HOTPLUG_CPU
@@ -65,6 +64,8 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
65 case CPU_DEAD: 64 case CPU_DEAD:
66 case CPU_DEAD_FROZEN: 65 case CPU_DEAD_FROZEN:
67 free_cpumask_var(cfd->cpumask); 66 free_cpumask_var(cfd->cpumask);
67 free_cpumask_var(cfd->cpumask_ipi);
68 free_percpu(cfd->csd);
68 break; 69 break;
69#endif 70#endif
70 }; 71 };
@@ -166,85 +167,6 @@ void generic_exec_single(int cpu, struct call_single_data *data, int wait)
166} 167}
167 168
168/* 169/*
169 * Invoked by arch to handle an IPI for call function. Must be called with
170 * interrupts disabled.
171 */
172void generic_smp_call_function_interrupt(void)
173{
174 struct call_function_data *data;
175 int cpu = smp_processor_id();
176
177 /*
178 * Shouldn't receive this interrupt on a cpu that is not yet online.
179 */
180 WARN_ON_ONCE(!cpu_online(cpu));
181
182 /*
183 * Ensure entry is visible on call_function_queue after we have
184 * entered the IPI. See comment in smp_call_function_many.
185 * If we don't have this, then we may miss an entry on the list
186 * and never get another IPI to process it.
187 */
188 smp_mb();
189
190 /*
191 * It's ok to use list_for_each_rcu() here even though we may
192 * delete 'pos', since list_del_rcu() doesn't clear ->next
193 */
194 list_for_each_entry_rcu(data, &call_function.queue, csd.list) {
195 int refs;
196 smp_call_func_t func;
197
198 /*
199 * Since we walk the list without any locks, we might
200 * see an entry that was completed, removed from the
201 * list and is in the process of being reused.
202 *
203 * We must check that the cpu is in the cpumask before
204 * checking the refs, and both must be set before
205 * executing the callback on this cpu.
206 */
207
208 if (!cpumask_test_cpu(cpu, data->cpumask))
209 continue;
210
211 smp_rmb();
212
213 if (atomic_read(&data->refs) == 0)
214 continue;
215
216 func = data->csd.func; /* save for later warn */
217 func(data->csd.info);
218
219 /*
220 * If the cpu mask is not still set then func enabled
221 * interrupts (BUG), and this cpu took another smp call
222 * function interrupt and executed func(info) twice
223 * on this cpu. That nested execution decremented refs.
224 */
225 if (!cpumask_test_and_clear_cpu(cpu, data->cpumask)) {
226 WARN(1, "%pf enabled interrupts and double executed\n", func);
227 continue;
228 }
229
230 refs = atomic_dec_return(&data->refs);
231 WARN_ON(refs < 0);
232
233 if (refs)
234 continue;
235
236 WARN_ON(!cpumask_empty(data->cpumask));
237
238 raw_spin_lock(&call_function.lock);
239 list_del_rcu(&data->csd.list);
240 raw_spin_unlock(&call_function.lock);
241
242 csd_unlock(&data->csd);
243 }
244
245}
246
247/*
248 * Invoked by arch to handle an IPI for call function single. Must be 170 * Invoked by arch to handle an IPI for call function single. Must be
249 * called from the arch with interrupts disabled. 171 * called from the arch with interrupts disabled.
250 */ 172 */
@@ -448,8 +370,7 @@ void smp_call_function_many(const struct cpumask *mask,
448 smp_call_func_t func, void *info, bool wait) 370 smp_call_func_t func, void *info, bool wait)
449{ 371{
450 struct call_function_data *data; 372 struct call_function_data *data;
451 unsigned long flags; 373 int cpu, next_cpu, this_cpu = smp_processor_id();
452 int refs, cpu, next_cpu, this_cpu = smp_processor_id();
453 374
454 /* 375 /*
455 * Can deadlock when called with interrupts disabled. 376 * Can deadlock when called with interrupts disabled.
@@ -481,79 +402,46 @@ void smp_call_function_many(const struct cpumask *mask,
481 } 402 }
482 403
483 data = &__get_cpu_var(cfd_data); 404 data = &__get_cpu_var(cfd_data);
484 csd_lock(&data->csd);
485
486 /* This BUG_ON verifies our reuse assertions and can be removed */
487 BUG_ON(atomic_read(&data->refs) || !cpumask_empty(data->cpumask));
488 405
489 /*
490 * The global call function queue list add and delete are protected
491 * by a lock, but the list is traversed without any lock, relying
492 * on the rcu list add and delete to allow safe concurrent traversal.
493 * We reuse the call function data without waiting for any grace
494 * period after some other cpu removes it from the global queue.
495 * This means a cpu might find our data block as it is being
496 * filled out.
497 *
498 * We hold off the interrupt handler on the other cpu by
499 * ordering our writes to the cpu mask vs our setting of the
500 * refs counter. We assert only the cpu owning the data block
501 * will set a bit in cpumask, and each bit will only be cleared
502 * by the subject cpu. Each cpu must first find its bit is
503 * set and then check that refs is set indicating the element is
504 * ready to be processed, otherwise it must skip the entry.
505 *
506 * On the previous iteration refs was set to 0 by another cpu.
507 * To avoid the use of transitivity, set the counter to 0 here
508 * so the wmb will pair with the rmb in the interrupt handler.
509 */
510 atomic_set(&data->refs, 0); /* convert 3rd to 1st party write */
511
512 data->csd.func = func;
513 data->csd.info = info;
514
515 /* Ensure 0 refs is visible before mask. Also orders func and info */
516 smp_wmb();
517
518 /* We rely on the "and" being processed before the store */
519 cpumask_and(data->cpumask, mask, cpu_online_mask); 406 cpumask_and(data->cpumask, mask, cpu_online_mask);
520 cpumask_clear_cpu(this_cpu, data->cpumask); 407 cpumask_clear_cpu(this_cpu, data->cpumask);
521 refs = cpumask_weight(data->cpumask);
522 408
523 /* Some callers race with other cpus changing the passed mask */ 409 /* Some callers race with other cpus changing the passed mask */
524 if (unlikely(!refs)) { 410 if (unlikely(!cpumask_weight(data->cpumask)))
525 csd_unlock(&data->csd);
526 return; 411 return;
527 }
528 412
529 raw_spin_lock_irqsave(&call_function.lock, flags);
530 /* 413 /*
531 * Place entry at the _HEAD_ of the list, so that any cpu still 414 * After we put an entry into the list, data->cpumask
532 * observing the entry in generic_smp_call_function_interrupt() 415 * may be cleared again when another CPU sends another IPI for
533 * will not miss any other list entries: 416 * a SMP function call, so data->cpumask will be zero.
534 */ 417 */
535 list_add_rcu(&data->csd.list, &call_function.queue); 418 cpumask_copy(data->cpumask_ipi, data->cpumask);
536 /*
537 * We rely on the wmb() in list_add_rcu to complete our writes
538 * to the cpumask before this write to refs, which indicates
539 * data is on the list and is ready to be processed.
540 */
541 atomic_set(&data->refs, refs);
542 raw_spin_unlock_irqrestore(&call_function.lock, flags);
543 419
544 /* 420 for_each_cpu(cpu, data->cpumask) {
545 * Make the list addition visible before sending the ipi. 421 struct call_single_data *csd = per_cpu_ptr(data->csd, cpu);
546 * (IPIs must obey or appear to obey normal Linux cache 422 struct call_single_queue *dst =
547 * coherency rules -- see comment in generic_exec_single). 423 &per_cpu(call_single_queue, cpu);
548 */ 424 unsigned long flags;
549 smp_mb(); 425
426 csd_lock(csd);
427 csd->func = func;
428 csd->info = info;
429
430 raw_spin_lock_irqsave(&dst->lock, flags);
431 list_add_tail(&csd->list, &dst->list);
432 raw_spin_unlock_irqrestore(&dst->lock, flags);
433 }
550 434
551 /* Send a message to all CPUs in the map */ 435 /* Send a message to all CPUs in the map */
552 arch_send_call_function_ipi_mask(data->cpumask); 436 arch_send_call_function_ipi_mask(data->cpumask_ipi);
553 437
554 /* Optionally wait for the CPUs to complete */ 438 if (wait) {
555 if (wait) 439 for_each_cpu(cpu, data->cpumask) {
556 csd_lock_wait(&data->csd); 440 struct call_single_data *csd =
441 per_cpu_ptr(data->csd, cpu);
442 csd_lock_wait(csd);
443 }
444 }
557} 445}
558EXPORT_SYMBOL(smp_call_function_many); 446EXPORT_SYMBOL(smp_call_function_many);
559 447