From: Zwane Mwaikambo This patch moves the cpu_online_map cpu clearing to __cpu_disable so that any necessary arch changes can be made before doing the clear. This simplifies a APIC timer interrupt race fix which went in. Signed-off-by: Zwane Mwaikambo Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/smpboot.c | 21 +++++++++------------ 25-akpm/arch/ia64/kernel/smpboot.c | 3 ++- 25-akpm/arch/ppc64/kernel/smp.c | 4 +++- 25-akpm/arch/s390/kernel/smp.c | 4 +++- 25-akpm/kernel/cpu.c | 21 +++++---------------- 5 files changed, 22 insertions(+), 31 deletions(-) diff -puN arch/i386/kernel/smpboot.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable arch/i386/kernel/smpboot.c --- 25/arch/i386/kernel/smpboot.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable 2004-09-11 17:25:54.786427280 -0700 +++ 25-akpm/arch/i386/kernel/smpboot.c 2004-09-11 17:25:54.795425912 -0700 @@ -1132,18 +1132,6 @@ static int __devinit cpu_enable(unsigned return 0; } -void __cpu_prep_disable(void) -{ - /* We enable the timer again on the exit path of the death loop */ - if (smp_processor_id() != 0) { - disable_APIC_timer(); - /* Allow any queued timer interrupts to get serviced */ - local_irq_enable(); - mdelay(1); - local_irq_disable(); - } -} - int __cpu_disable(void) { /* @@ -1157,6 +1145,15 @@ int __cpu_disable(void) if (smp_processor_id() == 0) return -EBUSY; + /* We enable the timer again on the exit path of the death loop */ + disable_APIC_timer(); + /* Allow any queued timer interrupts to get serviced */ + local_irq_enable(); + mdelay(1); + local_irq_disable(); + + /* It's now safe to remove this processor from the online map */ + cpu_clear(smp_processor_id(), cpu_online_map); fixup_irqs(); return 0; } diff -puN arch/ia64/kernel/smpboot.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable arch/ia64/kernel/smpboot.c --- 25/arch/ia64/kernel/smpboot.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable 2004-09-11 17:25:54.787427128 -0700 +++ 25-akpm/arch/ia64/kernel/smpboot.c 2004-09-11 17:25:54.796425760 -0700 @@ -591,9 +591,10 @@ int __cpu_disable(void) if (cpu == 0) return -EBUSY; + cpu_clear(cpu, cpu_online_map); fixup_irqs(); local_flush_tlb_all(); - printk ("Disabled cpu %u\n", smp_processor_id()); + printk("Disabled cpu %u\n", cpu); return 0; } diff -puN arch/ppc64/kernel/smp.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable arch/ppc64/kernel/smp.c --- 25/arch/ppc64/kernel/smp.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable 2004-09-11 17:25:54.789426824 -0700 +++ 25-akpm/arch/ppc64/kernel/smp.c 2004-09-11 17:25:54.797425608 -0700 @@ -255,11 +255,13 @@ int __cpu_disable(void) { /* FIXME: go put this in a header somewhere */ extern void xics_migrate_irqs_away(void); + int cpu = smp_processor_id(); + cpu_clear(cpu, cpu_online_map); systemcfg->processorCount--; /*fix boot_cpuid here*/ - if (smp_processor_id() == boot_cpuid) + if (cpu == boot_cpuid) boot_cpuid = any_online_cpu(cpu_online_map); /* FIXME: abstract this to not be platform specific later on */ diff -puN arch/s390/kernel/smp.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable arch/s390/kernel/smp.c --- 25/arch/s390/kernel/smp.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable 2004-09-11 17:25:54.790426672 -0700 +++ 25-akpm/arch/s390/kernel/smp.c 2004-09-11 17:25:54.798425456 -0700 @@ -688,13 +688,15 @@ __cpu_disable(void) { unsigned long flags; ec_creg_mask_parms cr_parms; + int cpu = smp_processor_id(); spin_lock_irqsave(&smp_reserve_lock, flags); - if (smp_cpu_reserved[smp_processor_id()] != 0) { + if (smp_cpu_reserved[cpu] != 0) { spin_unlock_irqrestore(&smp_reserve_lock, flags); return -EBUSY; } + cpu_clear(cpu, cpu_online_map); /* disable all external interrupts */ cr_parms.start_ctl = 0; diff -puN kernel/cpu.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable kernel/cpu.c --- 25/kernel/cpu.c~hotplug-cpu-move-cpu_online_map-clear-to-__cpu_disable 2004-09-11 17:25:54.792426368 -0700 +++ 25-akpm/kernel/cpu.c 2004-09-11 17:25:54.798425456 -0700 @@ -84,31 +84,20 @@ static int cpu_run_sbin_hotplug(unsigned return call_usermodehelper(argv[0], argv, envp, 0); } -void __attribute__((weak)) __cpu_prep_disable(void) -{ -} - /* Take this CPU down. */ static int take_cpu_down(void *unused) { int err; - /* Prepatory work before clearing the cpu off the online map */ - __cpu_prep_disable(); - - /* Take offline: makes arch_cpu_down somewhat easier. */ - cpu_clear(smp_processor_id(), cpu_online_map); - /* Ensure this CPU doesn't handle any more interrupts. */ err = __cpu_disable(); if (err < 0) - cpu_set(smp_processor_id(), cpu_online_map); - else - /* Force idle task to run as soon as we yield: it should - immediately notice cpu is offline and die quickly. */ - sched_idle_next(); + return err; - return err; + /* Force idle task to run as soon as we yield: it should + immediately notice cpu is offline and die quickly. */ + sched_idle_next(); + return 0; } int cpu_down(unsigned int cpu) _