From: Rusty Russell Andi Kleen reported a problem where a very slow boot caused the timer interrupt on a secondary CPU to go off before the CPU was actually brought up by the core code, so the CPU_PREPARE notifier hadn't been called, so the per-cpu timer code wasn't set up. This was caused by enabling interrupts around calibrate_delay() on secondary CPUs, which is not actually neccessary (interrupts on CPU 0 increments jiffies, which is all that is required). So delay enabling interrupts until the actual __cpu_up() call for that CPU. Signed-off-by: Rusty Russell Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/apic.c | 2 -- 25-akpm/arch/i386/kernel/smpboot.c | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff -puN arch/i386/kernel/apic.c~x86-no-interrupts-from-secondary-cpus-until-officially-online arch/i386/kernel/apic.c --- 25/arch/i386/kernel/apic.c~x86-no-interrupts-from-secondary-cpus-until-officially-online 2005-01-23 14:46:28.214029368 -0800 +++ 25-akpm/arch/i386/kernel/apic.c 2005-01-23 14:46:28.219028608 -0800 @@ -1046,9 +1046,7 @@ void __init setup_boot_APIC_clock(void) void __init setup_secondary_APIC_clock(void) { - local_irq_disable(); /* FIXME: Do we need this? --RR */ setup_APIC_timer(calibration_result); - local_irq_enable(); } void __init disable_APIC_timer(void) diff -puN arch/i386/kernel/smpboot.c~x86-no-interrupts-from-secondary-cpus-until-officially-online arch/i386/kernel/smpboot.c --- 25/arch/i386/kernel/smpboot.c~x86-no-interrupts-from-secondary-cpus-until-officially-online 2005-01-23 14:46:28.215029216 -0800 +++ 25-akpm/arch/i386/kernel/smpboot.c 2005-01-23 14:46:28.220028456 -0800 @@ -383,8 +383,6 @@ void __init smp_callin(void) setup_local_APIC(); map_cpu_to_logical_apicid(); - local_irq_enable(); - /* * Get our bogomips. */ @@ -397,7 +395,7 @@ void __init smp_callin(void) smp_store_cpu_info(cpuid); disable_APIC_timer(); - local_irq_disable(); + /* * Allow the master to continue. */ @@ -439,6 +437,10 @@ static void __init start_secondary(void */ local_flush_tlb(); cpu_set(smp_processor_id(), cpu_online_map); + + /* We can take interrupts now: we're officially "up". */ + local_irq_enable(); + wmb(); cpu_idle(); } _