Skip to content

Commit

Permalink
lockdep: Move early boot local IRQ enable/disable status to init/main.c
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Acked-by: Pekka Enberg <[email protected]>
Cc: Linus Torvalds <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
htejun authored and Ingo Molnar committed Jan 20, 2011
1 parent 12fcdba commit 2ce802f
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 36 deletions.
2 changes: 1 addition & 1 deletion arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ asmlinkage void __init xen_start_kernel(void)
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];

local_irq_disable();
early_boot_irqs_off();
early_boot_irqs_disabled = true;

memblock_init();

Expand Down
2 changes: 2 additions & 0 deletions include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ extern int test_taint(unsigned flag);
extern unsigned long get_taint(void);
extern int root_mountflags;

extern bool early_boot_irqs_disabled;

/* Values used for system_state */
extern enum system_states {
SYSTEM_BOOTING,
Expand Down
8 changes: 0 additions & 8 deletions include/linux/lockdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,16 +436,8 @@ do { \
#endif /* CONFIG_LOCKDEP */

#ifdef CONFIG_TRACE_IRQFLAGS
extern void early_boot_irqs_off(void);
extern void early_boot_irqs_on(void);
extern void print_irqtrace_events(struct task_struct *curr);
#else
static inline void early_boot_irqs_off(void)
{
}
static inline void early_boot_irqs_on(void)
{
}
static inline void print_irqtrace_events(struct task_struct *curr)
{
}
Expand Down
13 changes: 11 additions & 2 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ static inline void mark_rodata_ro(void) { }
extern void tc_init(void);
#endif

/*
* Debug helper: via this flag we know that we are in 'early bootup code'
* where only the boot processor is running with IRQ disabled. This means
* two things - IRQ must not be enabled before the flag is cleared and some
* operations which are not allowed with IRQ disabled are allowed while the
* flag is set.
*/
bool early_boot_irqs_disabled __read_mostly;

enum system_states system_state __read_mostly;
EXPORT_SYMBOL(system_state);

Expand Down Expand Up @@ -554,7 +563,7 @@ asmlinkage void __init start_kernel(void)
cgroup_init_early();

local_irq_disable();
early_boot_irqs_off();
early_boot_irqs_disabled = true;

/*
* Interrupts are still disabled. Do necessary setups, then
Expand Down Expand Up @@ -621,7 +630,7 @@ asmlinkage void __init start_kernel(void)
if (!irqs_disabled())
printk(KERN_CRIT "start_kernel(): bug: interrupts were "
"enabled early\n");
early_boot_irqs_on();
early_boot_irqs_disabled = false;
local_irq_enable();

/* Interrupts are enabled now so all GFP allocations are safe. */
Expand Down
18 changes: 1 addition & 17 deletions kernel/lockdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -2291,22 +2291,6 @@ mark_held_locks(struct task_struct *curr, enum mark_type mark)
return 1;
}

/*
* Debugging helper: via this flag we know that we are in
* 'early bootup code', and will warn about any invalid irqs-on event:
*/
static int early_boot_irqs_enabled;

void early_boot_irqs_off(void)
{
early_boot_irqs_enabled = 0;
}

void early_boot_irqs_on(void)
{
early_boot_irqs_enabled = 1;
}

/*
* Hardirqs will be enabled:
*/
Expand All @@ -2319,7 +2303,7 @@ void trace_hardirqs_on_caller(unsigned long ip)
if (unlikely(!debug_locks || current->lockdep_recursion))
return;

if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled)))
if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled)))
return;

if (unlikely(curr->hardirqs_enabled)) {
Expand Down
8 changes: 0 additions & 8 deletions kernel/trace/trace_irqsoff.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,6 @@ void time_hardirqs_off(unsigned long a0, unsigned long a1)
* Stubs:
*/

void early_boot_irqs_off(void)
{
}

void early_boot_irqs_on(void)
{
}

void trace_softirqs_on(unsigned long ip)
{
}
Expand Down

0 comments on commit 2ce802f

Please sign in to comment.