aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/smp.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/kernel/smp.c b/kernel/smp.c
index 4ec30e069987..4b83cd6815e2 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -430,7 +430,7 @@ void smp_call_function_many(const struct cpumask *mask,
430 * can't happen. 430 * can't happen.
431 */ 431 */
432 WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() 432 WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled()
433 && !oops_in_progress); 433 && !oops_in_progress && !early_boot_irqs_disabled);
434 434
435 /* So, what's a CPU they want? Ignoring this one. */ 435 /* So, what's a CPU they want? Ignoring this one. */
436 cpu = cpumask_first_and(mask, cpu_online_mask); 436 cpu = cpumask_first_and(mask, cpu_online_mask);
@@ -533,17 +533,20 @@ void ipi_call_unlock_irq(void)
533#endif /* USE_GENERIC_SMP_HELPERS */ 533#endif /* USE_GENERIC_SMP_HELPERS */
534 534
535/* 535/*
536 * Call a function on all processors 536 * Call a function on all processors. May be used during early boot while
537 * early_boot_irqs_disabled is set. Use local_irq_save/restore() instead
538 * of local_irq_disable/enable().
537 */ 539 */
538int on_each_cpu(void (*func) (void *info), void *info, int wait) 540int on_each_cpu(void (*func) (void *info), void *info, int wait)
539{ 541{
542 unsigned long flags;
540 int ret = 0; 543 int ret = 0;
541 544
542 preempt_disable(); 545 preempt_disable();
543 ret = smp_call_function(func, info, wait); 546 ret = smp_call_function(func, info, wait);
544 local_irq_disable(); 547 local_irq_save(flags);
545 func(info); 548 func(info);
546 local_irq_enable(); 549 local_irq_restore(flags);
547 preempt_enable(); 550 preempt_enable();
548 return ret; 551 return ret;
549} 552}