Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lockdep: Move early boot local IRQ enable/disable status to init/main.c

During early boot, local IRQ is disabled until IRQ subsystem is
properly initialized. During this time, no one should enable
local IRQ and some operations which usually are not allowed with
IRQ disabled, e.g. operations which might sleep or require
communications with other processors, are allowed.

lockdep tracked this with early_boot_irqs_off/on() callbacks.
As other subsystems need this information too, move it to
init/main.c and make it generally available. While at it,
toggle the boolean to early_boot_irqs_disabled instead of
enabled so that it can be initialized with %false and %true
indicates the exceptional condition.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Pekka Enberg <penberg@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
LKML-Reference: <20110120110635.GB6036@htj.dyndns.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by

Tejun Heo and committed by
Ingo Molnar
2ce802f6 12fcdba1

+15 -36
+1 -1
arch/x86/xen/enlighten.c
··· 1194 1194 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; 1195 1195 1196 1196 local_irq_disable(); 1197 - early_boot_irqs_off(); 1197 + early_boot_irqs_disabled = true; 1198 1198 1199 1199 memblock_init(); 1200 1200
+2
include/linux/kernel.h
··· 243 243 extern unsigned long get_taint(void); 244 244 extern int root_mountflags; 245 245 246 + extern bool early_boot_irqs_disabled; 247 + 246 248 /* Values used for system_state */ 247 249 extern enum system_states { 248 250 SYSTEM_BOOTING,
-8
include/linux/lockdep.h
··· 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 }
+11 -2
init/main.c
··· 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 ··· 563 554 cgroup_init_early(); 564 555 565 556 local_irq_disable(); 566 - early_boot_irqs_off(); 557 + early_boot_irqs_disabled = true; 567 558 568 559 /* 569 560 * Interrupts are still disabled. Do necessary setups, then ··· 630 621 if (!irqs_disabled()) 631 622 printk(KERN_CRIT "start_kernel(): bug: interrupts were " 632 623 "enabled early\n"); 633 - early_boot_irqs_on(); 624 + early_boot_irqs_disabled = false; 634 625 local_irq_enable(); 635 626 636 627 /* Interrupts are enabled now so all GFP allocations are safe. */
+1 -17
kernel/lockdep.c
··· 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) ··· 2303 2319 if (unlikely(!debug_locks || current->lockdep_recursion)) 2304 2320 return; 2305 2321 2306 - if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled))) 2322 + if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled))) 2307 2323 return; 2308 2324 2309 2325 if (unlikely(curr->hardirqs_enabled)) {
-8
kernel/trace/trace_irqsoff.c
··· 453 453 * Stubs: 454 454 */ 455 455 456 - void early_boot_irqs_off(void) 457 - { 458 - } 459 - 460 - void early_boot_irqs_on(void) 461 - { 462 - } 463 - 464 456 void trace_softirqs_on(unsigned long ip) 465 457 { 466 458 }