aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/enlighten.c2
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/lockdep.h8
-rw-r--r--init/main.c13
-rw-r--r--kernel/lockdep.c18
-rw-r--r--kernel/smp.c11
-rw-r--r--kernel/trace/trace_irqsoff.c8
7 files changed, 22 insertions, 40 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 7e8d3bc80af6..50542efe45fb 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1194,7 +1194,7 @@ asmlinkage void __init xen_start_kernel(void)
1194 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; 1194 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
1195 1195
1196 local_irq_disable(); 1196 local_irq_disable();
1197 early_boot_irqs_off(); 1197 early_boot_irqs_disabled = true;
1198 1198
1199 memblock_init(); 1199 memblock_init();
1200 1200
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5a9d9059520b..d07d8057e440 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -243,6 +243,8 @@ extern int test_taint(unsigned flag);
243extern unsigned long get_taint(void); 243extern unsigned long get_taint(void);
244extern int root_mountflags; 244extern int root_mountflags;
245 245
246extern bool early_boot_irqs_disabled;
247
246/* Values used for system_state */ 248/* Values used for system_state */
247extern enum system_states { 249extern enum system_states {
248 SYSTEM_BOOTING, 250 SYSTEM_BOOTING,
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 71c09b26c759..f638fd78d106 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -436,16 +436,8 @@ do { \
436#endif /* CONFIG_LOCKDEP */ 436#endif /* CONFIG_LOCKDEP */
437 437
438#ifdef CONFIG_TRACE_IRQFLAGS 438#ifdef CONFIG_TRACE_IRQFLAGS
439extern void early_boot_irqs_off(void);
440extern void early_boot_irqs_on(void);
441extern void print_irqtrace_events(struct task_struct *curr); 439extern void print_irqtrace_events(struct task_struct *curr);
442#else 440#else
443static inline void early_boot_irqs_off(void)
444{
445}
446static inline void early_boot_irqs_on(void)
447{
448}
449static inline void print_irqtrace_events(struct task_struct *curr) 441static inline void print_irqtrace_events(struct task_struct *curr)
450{ 442{
451} 443}
diff --git a/init/main.c b/init/main.c
index 00799c1d4628..33c37c379e96 100644
--- a/init/main.c
+++ b/init/main.c
@@ -96,6 +96,15 @@ static inline void mark_rodata_ro(void) { }
96extern void tc_init(void); 96extern void tc_init(void);
97#endif 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 */
106bool early_boot_irqs_disabled __read_mostly;
107
99enum system_states system_state __read_mostly; 108enum system_states system_state __read_mostly;
100EXPORT_SYMBOL(system_state); 109EXPORT_SYMBOL(system_state);
101 110
@@ -554,7 +563,7 @@ asmlinkage void __init start_kernel(void)
554 cgroup_init_early(); 563 cgroup_init_early();
555 564
556 local_irq_disable(); 565 local_irq_disable();
557 early_boot_irqs_off(); 566 early_boot_irqs_disabled = true;
558 567
559/* 568/*
560 * Interrupts are still disabled. Do necessary setups, then 569 * Interrupts are still disabled. Do necessary setups, then
@@ -621,7 +630,7 @@ asmlinkage void __init start_kernel(void)
621 if (!irqs_disabled()) 630 if (!irqs_disabled())
622 printk(KERN_CRIT "start_kernel(): bug: interrupts were " 631 printk(KERN_CRIT "start_kernel(): bug: interrupts were "
623 "enabled early\n"); 632 "enabled early\n");
624 early_boot_irqs_on(); 633 early_boot_irqs_disabled = false;
625 local_irq_enable(); 634 local_irq_enable();
626 635
627 /* Interrupts are enabled now so all GFP allocations are safe. */ 636 /* Interrupts are enabled now so all GFP allocations are safe. */
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 42ba65dff7d9..0d2058da80f5 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -2292,22 +2292,6 @@ mark_held_locks(struct task_struct *curr, enum mark_type mark)
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 */
2298static int early_boot_irqs_enabled;
2299
2300void early_boot_irqs_off(void)
2301{
2302 early_boot_irqs_enabled = 0;
2303}
2304
2305void early_boot_irqs_on(void)
2306{
2307 early_boot_irqs_enabled = 1;
2308}
2309
2310/*
2311 * Hardirqs will be enabled: 2295 * Hardirqs will be enabled:
2312 */ 2296 */
2313void trace_hardirqs_on_caller(unsigned long ip) 2297void trace_hardirqs_on_caller(unsigned long ip)
@@ -2319,7 +2303,7 @@ void trace_hardirqs_on_caller(unsigned long ip)
2319 if (unlikely(!debug_locks || current->lockdep_recursion)) 2303 if (unlikely(!debug_locks || current->lockdep_recursion))
2320 return; 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 return; 2307 return;
2324 2308
2325 if (unlikely(curr->hardirqs_enabled)) { 2309 if (unlikely(curr->hardirqs_enabled)) {
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}
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 5cf8c602b880..92b6e1e12d98 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -453,14 +453,6 @@ void time_hardirqs_off(unsigned long a0, unsigned long a1)
453 * Stubs: 453 * Stubs:
454 */ 454 */
455 455
456void early_boot_irqs_off(void)
457{
458}
459
460void early_boot_irqs_on(void)
461{
462}
463
464void trace_softirqs_on(unsigned long ip) 456void trace_softirqs_on(unsigned long ip)
465{ 457{
466} 458}