aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/smp.c')
-rw-r--r--kernel/smp.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/kernel/smp.c b/kernel/smp.c
index 2fe66f7c617a..9910744f0856 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -459,7 +459,7 @@ void smp_call_function_many(const struct cpumask *mask,
459 * can't happen. 459 * can't happen.
460 */ 460 */
461 WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() 461 WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled()
462 && !oops_in_progress); 462 && !oops_in_progress && !early_boot_irqs_disabled);
463 463
464 /* So, what's a CPU they want? Ignoring this one. */ 464 /* So, what's a CPU they want? Ignoring this one. */
465 cpu = cpumask_first_and(mask, cpu_online_mask); 465 cpu = cpumask_first_and(mask, cpu_online_mask);
@@ -572,17 +572,20 @@ void ipi_call_unlock_irq(void)
572#endif /* USE_GENERIC_SMP_HELPERS */ 572#endif /* USE_GENERIC_SMP_HELPERS */
573 573
574/* 574/*
575 * Call a function on all processors 575 * Call a function on all processors. May be used during early boot while
576 * early_boot_irqs_disabled is set. Use local_irq_save/restore() instead
577 * of local_irq_disable/enable().
576 */ 578 */
577int on_each_cpu(void (*func) (void *info), void *info, int wait) 579int on_each_cpu(void (*func) (void *info), void *info, int wait)
578{ 580{
581 unsigned long flags;
579 int ret = 0; 582 int ret = 0;
580 583
581 preempt_disable(); 584 preempt_disable();
582 ret = smp_call_function(func, info, wait); 585 ret = smp_call_function(func, info, wait);
583 local_irq_disable(); 586 local_irq_save(flags);
584 func(info); 587 func(info);
585 local_irq_enable(); 588 local_irq_restore(flags);
586 preempt_enable(); 589 preempt_enable();
587 return ret; 590 return ret;
588} 591}