Name: PPC Support for Non-linear CPU Numbers Patch Author: Rusty Russell Status: Tested on 2.5.15 PPC Depends: Hotcpu/nonlinear-cpus.patch.gz D: This patch fixes up PPC for non-linear CPU numbers. diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/kernel/irq.c working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/irq.c --- working-ppc-2.5-smp/arch/ppc/kernel/irq.c Fri Feb 15 22:21:09 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/irq.c Thu May 23 19:55:01 2002 @@ -370,8 +370,9 @@ struct irqaction * action; seq_puts(p, " "); - for (j=0; j>= 1) - mask |= (cpumask & 1) << smp_hw_index[i]; + for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1) + if (cpu_online(i)) + mask |= (cpumask & 1) << smp_hw_index[i]; return mask; } #else diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/kernel/ppc_ksyms.c working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/ppc_ksyms.c --- working-ppc-2.5-smp/arch/ppc/kernel/ppc_ksyms.c Thu May 9 20:19:54 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/ppc_ksyms.c Thu May 23 15:31:25 2002 @@ -228,7 +228,6 @@ #endif EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_hw_index); -EXPORT_SYMBOL(smp_num_cpus); EXPORT_SYMBOL(synchronize_irq); #endif diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/kernel/setup.c working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/setup.c --- working-ppc-2.5-smp/arch/ppc/kernel/setup.c Thu May 9 20:19:54 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/setup.c Thu May 23 15:33:44 2002 @@ -146,8 +146,8 @@ /* Show summary information */ #ifdef CONFIG_SMP unsigned long bogosum = 0; - for (i = 0; i < smp_num_cpus; ++i) - if (cpu_online_map & (1 << i)) + for (i = 0; i < NR_CPUS; ++i) + if (cpu_online(i)) bogosum += cpu_data[i].loops_per_jiffy; seq_printf(m, "total bogomips\t: %lu.%02lu\n", bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/kernel/smp.c working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/smp.c --- working-ppc-2.5-smp/arch/ppc/kernel/smp.c Wed Apr 10 22:07:21 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/kernel/smp.c Thu May 23 18:23:00 2002 @@ -42,7 +42,6 @@ int smp_threads_ready; volatile int smp_commenced; -int smp_num_cpus = 1; int smp_tb_synchronized; struct cpuinfo_PPC cpu_data[NR_CPUS]; struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; @@ -68,7 +67,6 @@ int start_secondary(void *); extern int cpu_idle(void *unused); void smp_call_function_interrupt(void); -void smp_message_pass(int target, int msg, unsigned long data, int wait); static int __smp_call_function(void (*func) (void *info), void *info, int wait, int target); @@ -174,7 +172,6 @@ void smp_send_stop(void) { smp_call_function(stop_this_cpu, NULL, 1, 0); - smp_num_cpus = 1; } /* @@ -212,7 +209,9 @@ * hardware interrupt handler, you may call it from a bottom half handler. */ { - if (smp_num_cpus <= 1) + /* FIXME: get cpu lock with hotplug cpus, or change this to + bitmask. --RR */ + if (num_online_cpus() <= 1) return 0; return __smp_call_function(func, info, wait, MSG_ALL_BUT_SELF); } @@ -226,9 +225,9 @@ int ncpus = 1; if (target == MSG_ALL_BUT_SELF) - ncpus = smp_num_cpus - 1; + ncpus = num_online_cpus() - 1; else if (target == MSG_ALL) - ncpus = smp_num_cpus; + ncpus = num_online_cpus(); data.func = func; data.info = info; @@ -298,7 +297,6 @@ struct task_struct *p; printk("Entering SMP Mode...\n"); - smp_num_cpus = 1; smp_store_cpu_info(0); cpu_online_map = 1UL; @@ -377,7 +375,6 @@ sprintf(buf, "found cpu %d", i); if (ppc_md.progress) ppc_md.progress(buf, 0x350+i); printk("Processor %d found.\n", i); - smp_num_cpus++; } else { char buf[32]; sprintf(buf, "didn't find cpu %d", i); @@ -389,7 +386,8 @@ /* Setup CPU 0 last (important) */ smp_ops->setup_cpu(0); - if (smp_num_cpus < 2) + /* FIXME: Not with hotplug CPUS --RR */ + if (num_online_cpus() < 2) smp_tb_synchronized = 1; } @@ -415,7 +413,7 @@ for (pass = 2; pass < 2+PASSES; pass++){ if (cpu == 0){ mb(); - for (i = j = 1; i < smp_num_cpus; i++, j++){ + for (i = j = 1; i < NR_CPUS; i++, j++){ /* skip stuck cpus */ while (!cpu_callin_map[j]) ++j; @@ -489,7 +487,8 @@ * * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH */ - if (!smp_tb_synchronized && smp_num_cpus == 2) { + /* FIXME: This doesn't work with hotplug CPUs --RR */ + if (!smp_tb_synchronized && num_online_cpus() == 2) { unsigned long flags; __save_and_cli(flags); smp_software_tb_sync(0); @@ -503,24 +502,18 @@ smp_store_cpu_info(cpu); set_dec(tb_ticks_per_jiffy); + /* Set online before we acknowledge. */ + set_bit(cpu, &cpu_online_map); + wmb(); cpu_callin_map[cpu] = 1; smp_ops->setup_cpu(cpu); - /* - * This cpu is now "online". Only set them online - * before they enter the loop below since write access - * to the below variable is _not_ guaranteed to be - * atomic. - * -- Cort - */ - cpu_online_map |= 1UL << smp_processor_id(); - while (!smp_commenced) barrier(); /* see smp_commence for more info */ - if (!smp_tb_synchronized && smp_num_cpus == 2) { + if (!smp_tb_synchronized && num_online_cpus() == 2) { smp_software_tb_sync(cpu); } __sti(); diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/platforms/chrp_smp.c working-ppc-2.5-pre-hotcpu/arch/ppc/platforms/chrp_smp.c --- working-ppc-2.5-smp/arch/ppc/platforms/chrp_smp.c Sun Feb 10 22:41:24 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/platforms/chrp_smp.c Thu May 23 16:04:30 2002 @@ -63,9 +63,10 @@ static atomic_t ready = ATOMIC_INIT(1); static volatile int frozen = 0; + /* FIXME: Hotplug cpu breaks all this --RR */ if (cpu_nr == 0) { /* wait for all the others */ - while (atomic_read(&ready) < smp_num_cpus) + while (atomic_read(&ready) < num_online_cpus()) barrier(); atomic_set(&ready, 1); /* freeze the timebase */ @@ -75,7 +76,7 @@ /* XXX assumes this is not a 601 */ set_tb(0, 0); last_jiffy_stamp(0) = 0; - while (atomic_read(&ready) < smp_num_cpus) + while (atomic_read(&ready) < num_online_cpus()) barrier(); /* thaw the timebase again */ call_rtas("thaw-time-base", 0, 1, NULL); diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/platforms/iSeries_smp.c working-ppc-2.5-pre-hotcpu/arch/ppc/platforms/iSeries_smp.c --- working-ppc-2.5-smp/arch/ppc/platforms/iSeries_smp.c Sun Feb 10 22:22:35 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/platforms/iSeries_smp.c Thu May 23 16:05:09 2002 @@ -50,7 +50,7 @@ int cpu = smp_processor_id(); int msg; - if ( smp_num_cpus < 2 ) + if ( num_online_cpus() < 2 ) return; for ( msg = 0; msg < 4; ++msg ) @@ -62,7 +62,10 @@ static void smp_iSeries_message_pass(int target, int msg, unsigned long data, int wait) { int i; - for (i = 0; i < smp_num_cpus; ++i) { + for (i = 0; i < NR_CPUS; ++i) { + if (!cpu_online(i)) + continue; + if ( (target == MSG_ALL) || (target == i) || ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) { diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/arch/ppc/platforms/pmac_smp.c working-ppc-2.5-pre-hotcpu/arch/ppc/platforms/pmac_smp.c --- working-ppc-2.5-smp/arch/ppc/platforms/pmac_smp.c Thu May 9 20:19:54 2002 +++ working-ppc-2.5-pre-hotcpu/arch/ppc/platforms/pmac_smp.c Thu May 23 16:06:11 2002 @@ -282,7 +282,7 @@ /* clear interrupt */ psurge_clr_ipi(cpu); - if (smp_num_cpus < 2) + if (num_online_cpus() < 2) return; /* make sure there is a message there */ @@ -302,10 +302,12 @@ { int i; - if (smp_num_cpus < 2) + if (num_online_cpus() < 2) return; - for (i = 0; i < smp_num_cpus; i++) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; if (target == MSG_ALL || (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) || target == i) { @@ -497,7 +499,7 @@ { if (cpu_nr == 0) { - if (smp_num_cpus < 2) + if (num_online_cpus() < 2) return; /* reset the entry point so if we get another intr we won't * try to startup again */ diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/include/asm-ppc/hardirq.h working-ppc-2.5-pre-hotcpu/include/asm-ppc/hardirq.h --- working-ppc-2.5-smp/include/asm-ppc/hardirq.h Thu May 9 20:19:54 2002 +++ working-ppc-2.5-pre-hotcpu/include/asm-ppc/hardirq.h Thu May 23 18:03:30 2002 @@ -56,7 +56,7 @@ { int i; - for (i = 0; i < smp_num_cpus; i++) + for (i = 0; i < NR_CPUS; i++) if (local_irq_count(i)) return 1; return 0; diff -urN -I \$.*\$ --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal working-ppc-2.5-smp/include/asm-ppc/smp.h working-ppc-2.5-pre-hotcpu/include/asm-ppc/smp.h --- working-ppc-2.5-smp/include/asm-ppc/smp.h Fri Feb 15 22:21:09 2002 +++ working-ppc-2.5-pre-hotcpu/include/asm-ppc/smp.h Thu May 23 18:03:18 2002 @@ -15,6 +15,7 @@ #include #include +#include #ifdef CONFIG_SMP @@ -44,11 +45,22 @@ #define NO_PROC_ID 0xFF /* No processor magic marker */ #define PROC_CHANGE_PENALTY 20 -/* 1 to 1 mapping on PPC -- Cort */ -#define cpu_logical_map(cpu) (cpu) -#define cpu_number_map(x) (x) - #define smp_processor_id() (current_thread_info()->cpu) + +#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) + +extern inline unsigned int num_online_cpus(void) +{ + return hweight32(cpu_online_map); +} + +extern inline int any_online_cpu(unsigned int mask) +{ + if (mask & cpu_online_map) + return __ffs(mask & cpu_online_map); + + return -1; +} extern int smp_hw_index[]; #define hard_smp_processor_id() (smp_hw_index[smp_processor_id()])