Commit 2b1caf6ed7b888c95a1909d343799672731651a5
Exists in
master
and in
4 other branches
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
…/git/tip/linux-2.6-tip * 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: smp: Allow on_each_cpu() to be called while early_boot_irqs_disabled status to init/main.c lockdep: Move early boot local IRQ enable/disable status to init/main.c
Showing 7 changed files Side-by-side Diff
arch/x86/xen/enlighten.c
include/linux/kernel.h
include/linux/lockdep.h
... | ... | @@ -436,16 +436,8 @@ |
436 | 436 | #endif /* CONFIG_LOCKDEP */ |
437 | 437 | |
438 | 438 | #ifdef CONFIG_TRACE_IRQFLAGS |
439 | -extern void early_boot_irqs_off(void); | |
440 | -extern void early_boot_irqs_on(void); | |
441 | 439 | extern void print_irqtrace_events(struct task_struct *curr); |
442 | 440 | #else |
443 | -static inline void early_boot_irqs_off(void) | |
444 | -{ | |
445 | -} | |
446 | -static inline void early_boot_irqs_on(void) | |
447 | -{ | |
448 | -} | |
449 | 441 | static inline void print_irqtrace_events(struct task_struct *curr) |
450 | 442 | { |
451 | 443 | } |
init/main.c
... | ... | @@ -96,6 +96,15 @@ |
96 | 96 | extern void tc_init(void); |
97 | 97 | #endif |
98 | 98 | |
99 | +/* | |
100 | + * Debug helper: via this flag we know that we are in 'early bootup code' | |
101 | + * where only the boot processor is running with IRQ disabled. This means | |
102 | + * two things - IRQ must not be enabled before the flag is cleared and some | |
103 | + * operations which are not allowed with IRQ disabled are allowed while the | |
104 | + * flag is set. | |
105 | + */ | |
106 | +bool early_boot_irqs_disabled __read_mostly; | |
107 | + | |
99 | 108 | enum system_states system_state __read_mostly; |
100 | 109 | EXPORT_SYMBOL(system_state); |
101 | 110 | |
... | ... | @@ -554,7 +563,7 @@ |
554 | 563 | cgroup_init_early(); |
555 | 564 | |
556 | 565 | local_irq_disable(); |
557 | - early_boot_irqs_off(); | |
566 | + early_boot_irqs_disabled = true; | |
558 | 567 | |
559 | 568 | /* |
560 | 569 | * Interrupts are still disabled. Do necessary setups, then |
... | ... | @@ -621,7 +630,7 @@ |
621 | 630 | if (!irqs_disabled()) |
622 | 631 | printk(KERN_CRIT "start_kernel(): bug: interrupts were " |
623 | 632 | "enabled early\n"); |
624 | - early_boot_irqs_on(); | |
633 | + early_boot_irqs_disabled = false; | |
625 | 634 | local_irq_enable(); |
626 | 635 | |
627 | 636 | /* Interrupts are enabled now so all GFP allocations are safe. */ |
kernel/lockdep.c
... | ... | @@ -2292,22 +2292,6 @@ |
2292 | 2292 | } |
2293 | 2293 | |
2294 | 2294 | /* |
2295 | - * Debugging helper: via this flag we know that we are in | |
2296 | - * 'early bootup code', and will warn about any invalid irqs-on event: | |
2297 | - */ | |
2298 | -static int early_boot_irqs_enabled; | |
2299 | - | |
2300 | -void early_boot_irqs_off(void) | |
2301 | -{ | |
2302 | - early_boot_irqs_enabled = 0; | |
2303 | -} | |
2304 | - | |
2305 | -void early_boot_irqs_on(void) | |
2306 | -{ | |
2307 | - early_boot_irqs_enabled = 1; | |
2308 | -} | |
2309 | - | |
2310 | -/* | |
2311 | 2295 | * Hardirqs will be enabled: |
2312 | 2296 | */ |
2313 | 2297 | void trace_hardirqs_on_caller(unsigned long ip) |
... | ... | @@ -2319,7 +2303,7 @@ |
2319 | 2303 | if (unlikely(!debug_locks || current->lockdep_recursion)) |
2320 | 2304 | return; |
2321 | 2305 | |
2322 | - if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled))) | |
2306 | + if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled))) | |
2323 | 2307 | return; |
2324 | 2308 | |
2325 | 2309 | if (unlikely(curr->hardirqs_enabled)) { |
kernel/smp.c
... | ... | @@ -459,7 +459,7 @@ |
459 | 459 | * can't happen. |
460 | 460 | */ |
461 | 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 | 464 | /* So, what's a CPU they want? Ignoring this one. */ |
465 | 465 | cpu = cpumask_first_and(mask, cpu_online_mask); |
466 | 466 | |
467 | 467 | |
468 | 468 | |
... | ... | @@ -572,17 +572,20 @@ |
572 | 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 | */ |
577 | 579 | int on_each_cpu(void (*func) (void *info), void *info, int wait) |
578 | 580 | { |
581 | + unsigned long flags; | |
579 | 582 | int ret = 0; |
580 | 583 | |
581 | 584 | preempt_disable(); |
582 | 585 | ret = smp_call_function(func, info, wait); |
583 | - local_irq_disable(); | |
586 | + local_irq_save(flags); | |
584 | 587 | func(info); |
585 | - local_irq_enable(); | |
588 | + local_irq_restore(flags); | |
586 | 589 | preempt_enable(); |
587 | 590 | return ret; |
588 | 591 | } |
kernel/trace/trace_irqsoff.c