Name: ia64 Support for Non-linear CPU Numbers Patch Author: Kimio Suganuma Status: Tested on 2.5.14 Depends: Hotcpu/nonlinear-cpus.patch.gz D: This patch fixes up ia64 for non-linear CPU numbers. diff -Nur linux-2.5.10-base/arch/ia64/kernel/ia64_ksyms.c linux-2.5.10-new/arch/ia64/kernel/ia64_ksyms.c --- linux-2.5.10-base/arch/ia64/kernel/ia64_ksyms.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/ia64_ksyms.c Wed May 8 17:58:55 2002 @@ -85,9 +85,6 @@ EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(ia64_cpu_to_sapicid); -#include -EXPORT_SYMBOL(smp_num_cpus); - #include EXPORT_SYMBOL(kernel_flag); diff -Nur linux-2.5.10-base/arch/ia64/kernel/iosapic.c linux-2.5.10-new/arch/ia64/kernel/iosapic.c --- linux-2.5.10-base/arch/ia64/kernel/iosapic.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/iosapic.c Wed May 8 17:58:55 2002 @@ -254,7 +254,7 @@ char *addr; int redir = (irq & (1<<31)) ? 1 : 0; - mask &= (1UL << smp_num_cpus) - 1; + mask &= cpu_online_map; if (!mask || irq >= IA64_NUM_VECTORS) return; @@ -757,9 +757,8 @@ set_rte(vector, cpu_physical_id(cpu_index) & 0xffff); - cpu_index++; - if (cpu_index >= smp_num_cpus) - cpu_index = 0; + for (cpu_index++; !cpu_online(cpu_index % NR_CPUS); cpu_index++); + cpu_index %= NR_CPUS; } else { /* * Direct the interrupt vector to the current cpu, diff -Nur linux-2.5.10-base/arch/ia64/kernel/irq.c linux-2.5.10-new/arch/ia64/kernel/irq.c --- linux-2.5.10-base/arch/ia64/kernel/irq.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/irq.c Wed May 8 17:58:55 2002 @@ -156,8 +156,9 @@ irq_desc_t *idesc; seq_puts(p, " "); - for (j=0; jhandler->typename); seq_printf(p, " %s", action->name); @@ -181,15 +182,15 @@ seq_putc(p, '\n'); } seq_puts(p, "NMI: "); - for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - nmi_count(cpu_logical_map(j))); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", nmi_count(j)); seq_putc(p, '\n'); #if defined(CONFIG_SMP) && defined(CONFIG_X86) seq_puts(p, "LOC: "); - for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - apic_timer_irqs[cpu_logical_map(j)]); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", apic_timer_irqs[j]); seq_putc(p, '\n'); #endif seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); @@ -218,10 +219,10 @@ printk("\n%s, CPU %d:\n", str, cpu); printk("irq: %d [",irqs_running()); - for(i=0;i < smp_num_cpus;i++) + for(i=0;i < NR_CPUS;i++) printk(" %d",irq_count(i)); printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0); - for(i=0;i < smp_num_cpus;i++) + for(i=0;i < NR_CPUS;i++) printk(" %d",bh_count(i)); printk(" ]\nStack dumps:"); @@ -233,7 +234,7 @@ * idea. */ #elif defined(CONFIG_X86) - for(i=0;i< smp_num_cpus;i++) { + for(i=0;i< NR_CPUS;i++) { unsigned long esp; if(i==cpu) continue; diff -Nur linux-2.5.10-base/arch/ia64/kernel/mca.c linux-2.5.10-new/arch/ia64/kernel/mca.c --- linux-2.5.10-base/arch/ia64/kernel/mca.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/mca.c Wed May 8 17:58:55 2002 @@ -604,9 +604,12 @@ int cpu; /* Clear the Rendez checkin flag for all cpus */ - for(cpu = 0; cpu < smp_num_cpus; cpu++) + for(cpu = 0; cpu < NR_CPUS; cpu++) { + if (!cpu_online(cpu)) + continue; if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE) ia64_mca_wakeup(cpu); + } } diff -Nur linux-2.5.10-base/arch/ia64/kernel/perfmon.c linux-2.5.10-new/arch/ia64/kernel/perfmon.c --- linux-2.5.10-base/arch/ia64/kernel/perfmon.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/perfmon.c Wed May 8 17:58:55 2002 @@ -805,7 +805,7 @@ * and it must be a valid CPU */ cpu = ffs(pfx->ctx_cpu_mask); - if (cpu > smp_num_cpus) { + if (!cpu_online(cpu)) { DBprintk(("CPU%d is not online\n", cpu)); return -EINVAL; } diff -Nur linux-2.5.10-base/arch/ia64/kernel/smp.c linux-2.5.10-new/arch/ia64/kernel/smp.c --- linux-2.5.10-base/arch/ia64/kernel/smp.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/smp.c Wed May 8 17:58:55 2002 @@ -168,8 +168,8 @@ { int i; - for (i = 0; i < smp_num_cpus; i++) { - if (i != smp_processor_id()) + for (i = 0; i < NR_CPUS; i++) { + if (cpu_online(i) && i != smp_processor_id()) send_IPI_single(i, op); } } @@ -179,8 +179,9 @@ { int i; - for (i = 0; i < smp_num_cpus; i++) - send_IPI_single(i, op); + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i)) + send_IPI_single(i, op); } static inline void @@ -205,8 +206,8 @@ { int i; - for (i = 0; i < smp_num_cpus; i++) - if (i != smp_processor_id()) + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i) && i != smp_processor_id()) smp_send_reschedule(i); } @@ -290,7 +291,7 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait) { struct call_data_struct data; - int cpus = smp_num_cpus-1; + int cpus = num_online_cpus()-1; if (!cpus) return 0; @@ -339,7 +340,6 @@ smp_send_stop (void) { send_IPI_allbutself(IPI_CPU_STOP); - smp_num_cpus = 1; } int __init diff -Nur linux-2.5.10-base/arch/ia64/kernel/smpboot.c linux-2.5.10-new/arch/ia64/kernel/smpboot.c --- linux-2.5.10-base/arch/ia64/kernel/smpboot.c Wed May 8 17:51:03 2002 +++ linux-2.5.10-new/arch/ia64/kernel/smpboot.c Wed May 8 17:58:55 2002 @@ -76,9 +76,6 @@ /* Setup configured maximum number of CPUs to activate */ static int max_cpus = -1; -/* Total count of live CPUs */ -int smp_num_cpus = 1; - /* Bitmask of currently online CPUs */ volatile unsigned long cpu_online_map; @@ -508,7 +505,6 @@ if (!max_cpus || (max_cpus < -1)) { printk(KERN_INFO "SMP mode deactivated.\n"); cpu_online_map = 1; - smp_num_cpus = 1; goto smp_done; } if (max_cpus != -1) @@ -538,8 +534,6 @@ printk("phys CPU#%d not responding - cannot use it.\n", cpu); } - smp_num_cpus = cpucount + 1; - /* * Allow the user to impress friends. */ @@ -584,6 +578,5 @@ printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n Forcing UP mode\n", ia64_sal_strerror(sal_ret)); max_cpus = 0; - smp_num_cpus = 1; } } diff -Nur linux-2.5.10-base/arch/ia64/sn/io/sgi_io_init.c linux-2.5.10-new/arch/ia64/sn/io/sgi_io_init.c --- linux-2.5.10-base/arch/ia64/sn/io/sgi_io_init.c Wed May 8 17:51:01 2002 +++ linux-2.5.10-new/arch/ia64/sn/io/sgi_io_init.c Wed May 8 18:00:13 2002 @@ -255,7 +255,7 @@ cnodeid_t cnode; cpuid_t cpu; - for (cpu = 0; cpu < smp_num_cpus; cpu++) { + for (cpu = 0; cpu < NR_CPUS; cpu++) { /* Skip holes in CPU space */ if (cpu_enabled(cpu)) { init_platform_pda(cpu); diff -Nur linux-2.5.10-base/arch/ia64/sn/io/sn1/ml_SN_intr.c linux-2.5.10-new/arch/ia64/sn/io/sn1/ml_SN_intr.c --- linux-2.5.10-base/arch/ia64/sn/io/sn1/ml_SN_intr.c Wed May 8 17:51:01 2002 +++ linux-2.5.10-new/arch/ia64/sn/io/sn1/ml_SN_intr.c Wed May 8 18:01:28 2002 @@ -987,12 +987,13 @@ char subnode_done[NUM_SUBNODES]; // cpu = cnodetocpu(cnode); - for (cpu = 0; cpu < smp_num_cpus; cpu++) { + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (!cpu_online(cpu)) continue; if (cpuid_to_cnodeid(cpu) == cnode) { break; } } - if (cpu == smp_num_cpus) cpu = CPU_NONE; + if (cpu == NR_CPUS) cpu = CPU_NONE; if (cpu == CPU_NONE) { printk("Node %d has no CPUs", cnode); return; @@ -1001,7 +1002,7 @@ for (i=0; iend = end; params->nbits = nbits; params->rid = (unsigned int) ia64_get_rr(start); - atomic_set(¶ms->unfinished_count, smp_num_cpus); + atomic_set(¶ms->unfinished_count, num_online_cpus()); /* The atomic_set above can hit memory *after* the update * to ptcParamsEmpty below, which opens a timing window @@ -425,7 +425,7 @@ { if (!ia64_ptc_domain_info) { printk("SMP: Can't find PTC domain info. Forcing UP mode\n"); - smp_num_cpus = 1; + cpu_online_map = 1; return; } diff -Nur linux-2.5.10-base/include/asm-ia64/hardirq.h linux-2.5.10-new/include/asm-ia64/hardirq.h --- linux-2.5.10-base/include/asm-ia64/hardirq.h Wed May 8 17:50:34 2002 +++ linux-2.5.10-new/include/asm-ia64/hardirq.h Wed May 8 17:58:55 2002 @@ -58,7 +58,7 @@ { int i; - for (i = 0; i < smp_num_cpus; i++) + for (i = 0; i < NR_CPUS; i++) if (irq_count(i)) return 1; return 0; diff -Nur linux-2.5.10-base/include/asm-ia64/smp.h linux-2.5.10-new/include/asm-ia64/smp.h --- linux-2.5.10-base/include/asm-ia64/smp.h Wed May 8 17:50:34 2002 +++ linux-2.5.10-new/include/asm-ia64/smp.h Wed May 8 17:58:55 2002 @@ -39,15 +39,26 @@ extern volatile unsigned long cpu_online_map; extern unsigned long ipi_base_addr; extern unsigned char smp_int_redirect; -extern int smp_num_cpus; extern volatile int ia64_cpu_to_sapicid[]; #define cpu_physical_id(i) ia64_cpu_to_sapicid[i] -#define cpu_number_map(i) (i) -#define cpu_logical_map(i) (i) extern unsigned long ap_wakeup_vector; +#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) +extern inline unsigned int num_online_cpus(void) +{ + return hweight64(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; +} + /* * Function to map hard smp processor id to logical id. Slow, so * don't use this in performance-critical code. @@ -57,7 +68,7 @@ { int i; - for (i = 0; i < smp_num_cpus; ++i) + for (i = 0; i < NR_CPUS; ++i) if (cpu_physical_id(i) == (__u32) cpuid) break; return i; @@ -108,6 +119,11 @@ return lid.f.id << 8 | lid.f.eid; } +/* Upping and downing of CPUs */ +extern int __cpu_disable(void); +extern void __cpu_die(unsigned int cpu); +extern int __cpu_up(unsigned int cpu); + #define NO_PROC_ID 0xffffffff /* no processor magic marker */ extern void __init init_smp_config (void);