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
This commit is contained in:
Linus Torvalds 2011-01-20 18:30:37 -08:00
commit 2b1caf6ed7
7 changed files with 22 additions and 40 deletions

View File

@ -1194,7 +1194,7 @@ asmlinkage void __init xen_start_kernel(void)
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
local_irq_disable(); local_irq_disable();
early_boot_irqs_off(); early_boot_irqs_disabled = true;
memblock_init(); memblock_init();

View File

@ -243,6 +243,8 @@ extern int test_taint(unsigned flag);
extern unsigned long get_taint(void); extern unsigned long get_taint(void);
extern int root_mountflags; extern int root_mountflags;
extern bool early_boot_irqs_disabled;
/* Values used for system_state */ /* Values used for system_state */
extern enum system_states { extern enum system_states {
SYSTEM_BOOTING, SYSTEM_BOOTING,

View File

@ -436,16 +436,8 @@ do { \
#endif /* CONFIG_LOCKDEP */ #endif /* CONFIG_LOCKDEP */
#ifdef CONFIG_TRACE_IRQFLAGS #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); extern void print_irqtrace_events(struct task_struct *curr);
#else #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) static inline void print_irqtrace_events(struct task_struct *curr)
{ {
} }

View File

@ -96,6 +96,15 @@ static inline void mark_rodata_ro(void) { }
extern void tc_init(void); extern void tc_init(void);
#endif #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; enum system_states system_state __read_mostly;
EXPORT_SYMBOL(system_state); EXPORT_SYMBOL(system_state);
@ -554,7 +563,7 @@ asmlinkage void __init start_kernel(void)
cgroup_init_early(); cgroup_init_early();
local_irq_disable(); local_irq_disable();
early_boot_irqs_off(); early_boot_irqs_disabled = true;
/* /*
* Interrupts are still disabled. Do necessary setups, then * Interrupts are still disabled. Do necessary setups, then
@ -621,7 +630,7 @@ asmlinkage void __init start_kernel(void)
if (!irqs_disabled()) if (!irqs_disabled())
printk(KERN_CRIT "start_kernel(): bug: interrupts were " printk(KERN_CRIT "start_kernel(): bug: interrupts were "
"enabled early\n"); "enabled early\n");
early_boot_irqs_on(); early_boot_irqs_disabled = false;
local_irq_enable(); local_irq_enable();
/* Interrupts are enabled now so all GFP allocations are safe. */ /* Interrupts are enabled now so all GFP allocations are safe. */

View File

@ -2291,22 +2291,6 @@ mark_held_locks(struct task_struct *curr, enum mark_type mark)
return 1; 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: * Hardirqs will be enabled:
*/ */
@ -2319,7 +2303,7 @@ void trace_hardirqs_on_caller(unsigned long ip)
if (unlikely(!debug_locks || current->lockdep_recursion)) if (unlikely(!debug_locks || current->lockdep_recursion))
return; return;
if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled))) if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled)))
return; return;
if (unlikely(curr->hardirqs_enabled)) { if (unlikely(curr->hardirqs_enabled)) {

View File

@ -459,7 +459,7 @@ void smp_call_function_many(const struct cpumask *mask,
* can't happen. * can't happen.
*/ */
WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() 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. */ /* So, what's a CPU they want? Ignoring this one. */
cpu = cpumask_first_and(mask, cpu_online_mask); cpu = cpumask_first_and(mask, cpu_online_mask);
@ -572,17 +572,20 @@ void ipi_call_unlock_irq(void)
#endif /* USE_GENERIC_SMP_HELPERS */ #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) int on_each_cpu(void (*func) (void *info), void *info, int wait)
{ {
unsigned long flags;
int ret = 0; int ret = 0;
preempt_disable(); preempt_disable();
ret = smp_call_function(func, info, wait); ret = smp_call_function(func, info, wait);
local_irq_disable(); local_irq_save(flags);
func(info); func(info);
local_irq_enable(); local_irq_restore(flags);
preempt_enable(); preempt_enable();
return ret; return ret;
} }

View File

@ -453,14 +453,6 @@ void time_hardirqs_off(unsigned long a0, unsigned long a1)
* Stubs: * Stubs:
*/ */
void early_boot_irqs_off(void)
{
}
void early_boot_irqs_on(void)
{
}
void trace_softirqs_on(unsigned long ip) void trace_softirqs_on(unsigned long ip)
{ {
} }