core kernel fixes
Subsystems (5)
Linus,
Please pull the latest core-fixes-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core-fixes-for-linus
This fixes the percpu related boot crash that i've reported.
Thanks,
Ingo
------------------>
Tejun Heo (2):
lockdep: Move early boot local IRQ enable/disable status to init/main.c
smp: Allow on_each_cpu() to be called while early_boot_irqs_disabled status to init/main.c
arch/x86/xen/enlighten.c | 2 +- include/linux/kernel.h | 2 ++ include/linux/lockdep.h | 8 -------- init/main.c | 13 +++++++++++-- kernel/lockdep.c | 18 +----------------- kernel/smp.c | 11 +++++++---- kernel/trace/trace_irqsoff.c | 8 -------- 7 files changed, 22 insertions(+), 40 deletions(-)
arch/x86/xen/enlighten.c +1 -1
@@ -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 ();
include/linux/kernel.h +2 -0
@@ -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,
include/linux/lockdep.h +0 -8
@@ -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) { }
init/main.c +11 -2
@@ -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);
@@ -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
@@ -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. */
kernel/lockdep.c +1 -17
@@ -2292,22 +2292,6 @@ mark_held_locks(struct task_struct *curr, enum mark_type mark) }/* -* 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: */ void trace_hardirqs_on_caller (unsigned long ip)
@@ -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)) {
kernel/smp.c +7 -4
@@ -430,7 +430,7 @@ void smp_call_function_many(const struct cpumask *mask,* can't happen. */ WARN_ON_ONCE (cpu_online (this_cpu) &&irqs_disabled () - && !oops_in_progress); + && !oops_in_progress && !early_boot_irqs_disabled);/* So, what's a CPU they want? Ignoring this one. */ cpu =cpumask_first_and (mask, cpu_online_mask);
@@ -533,17 +533,20 @@ void ipi_call_unlock_irq(void)#endif /* USE_GENERIC_SMP_HELPERS */ /* -* Call a function on all processors +* Call a function on all processors. May be used during early boot while +* early_boot_irqs_disabled is set. Use local_irq_save/restore() instead +* of local_irq_disable/enable(). */ int on_each_cpu (void (*func) (void *info),void *info,int wait) { +unsigned long flags;int ret =0 ;preempt_disable (); ret =smp_call_function (func, info, wait); -local_irq_disable (); +local_irq_save (flags);func (info); -local_irq_enable (); +local_irq_restore (flags);preempt_enable ();return ret; }
kernel/trace/trace_irqsoff.c +0 -8
@@ -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) { }