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-16 23:22:01.400045728 -0800 +++ 25-akpm/arch/i386/kernel/apic.c 2005-01-16 23:22:01.407044664 -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-16 23:22:01.401045576 -0800 +++ 25-akpm/arch/i386/kernel/smpboot.c 2005-01-16 23:22:01.406044816 -0800 @@ -384,8 +384,6 @@ void __init smp_callin(void) setup_local_APIC(); map_cpu_to_logical_apicid(); - local_irq_enable(); - /* * Get our bogomips. */ @@ -398,7 +396,7 @@ void __init smp_callin(void) smp_store_cpu_info(cpuid); disable_APIC_timer(); - local_irq_disable(); + /* * Allow the master to continue. */ @@ -440,6 +438,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(); } _