diff options
| author | Anton Blanchard <anton@samba.org> | 2002-06-22 05:29:18 +1000 |
|---|---|---|
| committer | Anton Blanchard <anton@samba.org> | 2002-06-22 05:29:18 +1000 |
| commit | a9d1ed0d1a2fdf6cbfb38cd3e0f702bdbc5fa037 (patch) | |
| tree | 565479005a508d96b42c709cabd22d216088e3c9 | |
| parent | e7c3270d63468121a6f5e4f3a242fa76e6821228 (diff) | |
ppc64: non linear cpu support
| -rw-r--r-- | arch/ppc64/kernel/irq.c | 31 | ||||
| -rw-r--r-- | arch/ppc64/kernel/open_pic.c | 31 | ||||
| -rw-r--r-- | arch/ppc64/kernel/pSeries_lpar.c | 2 | ||||
| -rw-r--r-- | arch/ppc64/kernel/pmc.c | 4 | ||||
| -rw-r--r-- | arch/ppc64/kernel/ppc_ksyms.c | 1 | ||||
| -rw-r--r-- | arch/ppc64/kernel/proc_pmc.c | 28 | ||||
| -rw-r--r-- | arch/ppc64/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/ppc64/kernel/prom.c | 60 | ||||
| -rw-r--r-- | arch/ppc64/kernel/rtasd.c | 41 | ||||
| -rw-r--r-- | arch/ppc64/kernel/setup.c | 4 | ||||
| -rw-r--r-- | arch/ppc64/kernel/smp.c | 136 | ||||
| -rw-r--r-- | arch/ppc64/kernel/xics.c | 38 | ||||
| -rw-r--r-- | include/asm-ppc64/hardirq.h | 6 | ||||
| -rw-r--r-- | include/asm-ppc64/machdep.h | 2 | ||||
| -rw-r--r-- | include/asm-ppc64/naca.h | 1 | ||||
| -rw-r--r-- | include/asm-ppc64/paca.h | 2 | ||||
| -rw-r--r-- | include/asm-ppc64/smp.h | 23 |
17 files changed, 199 insertions, 219 deletions
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index e2e199855acc..51447d58869b 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -346,8 +346,10 @@ int show_interrupts(struct seq_file *p, void *v) struct irqaction * action; seq_printf(p, " "); - for (j=0; j<smp_num_cpus; j++) - seq_printf(p, "CPU%d ",j); + for (j=0; j<NR_CPUS; j++) { + if (cpu_online(j)) + seq_printf(p, "CPU%d ",j); + } seq_putc(p, '\n'); for (i = 0 ; i < NR_IRQS ; i++) { @@ -356,9 +358,10 @@ int show_interrupts(struct seq_file *p, void *v) continue; seq_printf(p, "%3d: ", i); #ifdef CONFIG_SMP - for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); + for (j = 0; j < NR_CPUS; j++) { + if (cpu_online(j)) + seq_printf(p, "%10u ", kstat.irqs[j][i]); + } #else seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ @@ -425,14 +428,14 @@ static unsigned long move(unsigned long curr_cpu, unsigned long allowed_mask, inside: if (direction == 1) { cpu++; - if (cpu >= smp_num_cpus) + if (cpu >= NR_CPUS) cpu = 0; } else { cpu--; if (cpu == -1) - cpu = smp_num_cpus-1; + cpu = NR_CPUS-1; } - } while (!IRQ_ALLOWED(cpu,allowed_mask) || + } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) || (search_idle && !IDLE_ENOUGH(cpu,now))); return cpu; @@ -653,12 +656,16 @@ static void show(char * str) printk("\n%s, CPU %d:\n", str, cpu); printk("irq: %d [ ", irqs_running()); - for (i = 0; i < smp_num_cpus; i++) - printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]); + for (i = 0; i < NR_CPUS; i++) { + if (cpu_online(i)) + printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]); + } printk("]\nbh: %d [ ", (spin_is_locked(&global_bh_lock) ? 1 : 0)); - for (i = 0; i < smp_num_cpus; i++) - printk("%u ", local_bh_count(i)); + for (i = 0; i < NR_CPUS; i++) { + if (cpu_online(i)) + printk("%u ", local_bh_count(i)); + } printk("]\n"); } diff --git a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c index c1d52e0cc785..969e533f8e84 100644 --- a/arch/ppc64/kernel/open_pic.c +++ b/arch/ppc64/kernel/open_pic.c @@ -85,10 +85,10 @@ unsigned int openpic_vec_spurious; */ #ifdef CONFIG_SMP #define THIS_CPU Processor[cpu] -#define DECL_THIS_CPU int cpu = hard_smp_processor_id() +#define DECL_THIS_CPU int cpu = smp_processor_id() #define CHECK_THIS_CPU check_arg_cpu(cpu) #else -#define THIS_CPU Processor[hard_smp_processor_id()] +#define THIS_CPU Processor[smp_processor_id()] #define DECL_THIS_CPU #define CHECK_THIS_CPU #endif /* CONFIG_SMP */ @@ -356,7 +356,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, /* SIOint (8259 cascade) is special */ if (offset) { openpic_initirq(0, 8, offset, 1, 1); - openpic_mapirq(0, 1<<get_hard_smp_processor_id(0)); + openpic_mapirq(0, 1 << boot_cpuid); } /* Init all external sources */ @@ -374,7 +374,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, /* Enabled, Priority 8 or 9 */ openpic_initirq(i, pri, i+offset, !sense, sense); /* Processor 0 */ - openpic_mapirq(i, 1<<get_hard_smp_processor_id(0)); + openpic_mapirq(i, 1 << boot_cpuid); } /* Init descriptors */ @@ -503,23 +503,10 @@ static void openpic_set_spurious(u_int vec) vec); } -/* - * Convert a cpu mask from logical to physical cpu numbers. - */ -static inline u32 physmask(u32 cpumask) -{ - int i; - u32 mask = 0; - - for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1) - mask |= (cpumask & 1) << get_hard_smp_processor_id(i); - return mask; -} - void openpic_init_processor(u_int cpumask) { openpic_write(&OpenPIC->Global.Processor_Initialization, - physmask(cpumask)); + cpumask & cpu_online_map); } #ifdef CONFIG_SMP @@ -553,7 +540,7 @@ void openpic_cause_IPI(u_int ipi, u_int cpumask) CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), - physmask(cpumask)); + cpumask & cpu_online_map); } void openpic_request_IPIs(void) @@ -593,7 +580,7 @@ void __init do_openpic_setup_cpu(void) { #ifdef CONFIG_IRQ_ALL_CPUS int i; - u32 msk = 1 << hard_smp_processor_id(); + u32 msk = 1 << smp_processor_id(); #endif spin_lock(&openpic_setup_lock); @@ -638,7 +625,7 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask) { check_arg_timer(timer); openpic_write(&OpenPIC->Global.Timer[timer].Destination, - physmask(cpumask)); + cpumask & cpu_online_map); } @@ -761,7 +748,7 @@ static void openpic_end_irq(unsigned int irq_nr) static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) { - openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask)); + openpic_mapirq(irq_nr - open_pic_irq_offset, cpumask & cpu_online_map); } #ifdef CONFIG_SMP diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c index 372b5fbf12b6..ea528fe1dd33 100644 --- a/arch/ppc64/kernel/pSeries_lpar.c +++ b/arch/ppc64/kernel/pSeries_lpar.c @@ -309,7 +309,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value) { unsigned long lpar_rc; - lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu),value); + lpar_rc = plpar_ipi(n_cpu, value); if (lpar_rc != H_Success) { panic(" bad return code qirr -ipi - rc = %lx \n", lpar_rc); } diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c index 5a920ef2662b..44d866a66b26 100644 --- a/arch/ppc64/kernel/pmc.c +++ b/arch/ppc64/kernel/pmc.c @@ -59,7 +59,9 @@ ppc64_pmc_stab(int file) stab_faults = stab_capacity_castouts = stab_invalidations = n = 0; if (file == -1) { - for (i = 0; i < smp_num_cpus; i++) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; stab_faults += pmc_sw_cpu[i].stab_faults; stab_capacity_castouts += pmc_sw_cpu[i].stab_capacity_castouts; stab_invalidations += pmc_sw_cpu[i].stab_invalidations; diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c index f9995267a769..08bceea9626e 100644 --- a/arch/ppc64/kernel/ppc_ksyms.c +++ b/arch/ppc64/kernel/ppc_ksyms.c @@ -87,7 +87,6 @@ EXPORT_SYMBOL(disable_irq_nosync); #ifdef CONFIG_SMP EXPORT_SYMBOL(kernel_flag); EXPORT_SYMBOL(synchronize_irq); -EXPORT_SYMBOL(smp_num_cpus); #endif /* CONFIG_SMP */ EXPORT_SYMBOL(register_ioctl32_conversion); diff --git a/arch/ppc64/kernel/proc_pmc.c b/arch/ppc64/kernel/proc_pmc.c index 08039aad6da3..f46196055894 100644 --- a/arch/ppc64/kernel/proc_pmc.c +++ b/arch/ppc64/kernel/proc_pmc.c @@ -109,14 +109,19 @@ void proc_ppc64_init(void) proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64_root); proc_ppc64_pmc_system_root = proc_mkdir("system", proc_ppc64_pmc_root); - for (i = 0; i < naca->processorCount; i++) { - sprintf(buf, "cpu%ld", i); - proc_ppc64_pmc_cpu_root[i] = proc_mkdir(buf, proc_ppc64_pmc_root); + for (i = 0; i < NR_CPUS; i++) { + if (cpu_online(i)) { + sprintf(buf, "cpu%ld", i); + proc_ppc64_pmc_cpu_root[i] = + proc_mkdir(buf, proc_ppc64_pmc_root); + } } /* Create directories for the software counters. */ - for (i = 0; i < naca->processorCount; i++) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; ent = create_proc_entry("stab", S_IRUGO | S_IWUSR, proc_ppc64_pmc_cpu_root[i]); if (ent) { @@ -155,7 +160,9 @@ void proc_ppc64_init(void) } /* Create directories for the hardware counters. */ - for (i = 0; i < naca->processorCount; i++) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; ent = create_proc_entry("hardware", S_IRUGO | S_IWUSR, proc_ppc64_pmc_cpu_root[i]); if (ent) { @@ -191,7 +198,9 @@ int proc_ppc64_pmc_find_file(void *data) (unsigned long) proc_ppc64_pmc_system_root) { return(-1); } else { - for (i = 0; i < naca->processorCount; i++) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; if ((unsigned long)data == (unsigned long)proc_ppc64_pmc_cpu_root[i]) { return(i); @@ -383,9 +392,10 @@ int proc_get_lpevents (unsigned long)xItLpQueue.xLpIntCountByType[i] ); } len += sprintf( page+len, "\n events processed by processor:\n" ); - for (i=0; i<naca->processorCount; ++i) { - len += sprintf( page+len, " CPU%02d %10u\n", - i, paca[i].lpEvent_count ); + for (i = 0; i < NR_CPUS; ++i) { + if (cpu_online(i)) + len += sprintf( page+len, " CPU%02d %10u\n", + i, paca[i].lpEvent_count ); } return pmc_calc_metrics( page, start, off, count, eof, len ); diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index b794c8585d58..6b8d9d5ff65f 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -304,7 +304,9 @@ void initialize_paca_hardware_interrupt_stack(void) unsigned long stack; unsigned long end_of_stack =0; - for (i=1; i < naca->processorCount; i++) { + for (i=1; i < NR_CPUS; i++) { + if (!cpu_possible(i)) + continue; /* Carve out storage for the hardware interrupt stack */ stack = __get_free_pages(GFP_KERNEL, get_order(8*PAGE_SIZE)); @@ -327,7 +329,9 @@ void initialize_paca_hardware_interrupt_stack(void) if (__is_processor(PV_POWER4)) return; - for (i=0; i < naca->processorCount; i++) { + for (i=0; i < NR_CPUS; i++) { + if (!cpu_possible(i)) + continue; /* set page at the top of stack to be protected - prevent overflow */ end_of_stack = paca[i].xHrdIntStack - (8*PAGE_SIZE - STACK_FRAME_OVERHEAD); ppc_md.hpte_updateboltedpp(PP_RXRX,end_of_stack); diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index a7d5e7cc6e5b..eff84aa12fe6 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -445,9 +445,12 @@ prom_initialize_naca(unsigned long mem) } /* We gotta have at least 1 cpu... */ - if ( (_naca->processorCount = num_cpus) < 1 ) + if (num_cpus < 1) PROM_BUG(); + if (num_cpus > 1) + RELOC(ppc64_is_smp) = 1; + _naca->physicalMemorySize = lmb_phys_mem_size(); if (_naca->platform == PLATFORM_PSERIES) { @@ -477,10 +480,6 @@ prom_initialize_naca(unsigned long mem) _naca->slb_size = 64; #ifdef DEBUG_PROM - prom_print(RELOC("naca->processorCount = 0x")); - prom_print_hex(_naca->processorCount); - prom_print_nl(); - prom_print(RELOC("naca->physicalMemorySize = 0x")); prom_print_hex(_naca->physicalMemorySize); prom_print_nl(); @@ -1044,20 +1043,15 @@ prom_hold_cpus(unsigned long mem) phandle node; unsigned long offset = reloc_offset(); char type[64], *path; - int cpuid = 0; extern void __secondary_hold(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; unsigned long *spinloop = __v2a(&__secondary_hold_spinloop); unsigned long *acknowledge = __v2a(&__secondary_hold_acknowledge); unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold)); - struct naca_struct *_naca = RELOC(naca); struct paca_struct *_xPaca = PTRRELOC(&paca[0]); struct prom_t *_prom = PTRRELOC(&prom); - /* Initially, we must have one active CPU. */ - _naca->processorCount = 1; - #ifdef DEBUG_PROM prom_print(RELOC("prom_hold_cpus: start...\n")); prom_print(RELOC(" 1) spinloop = 0x")); @@ -1117,19 +1111,12 @@ prom_hold_cpus(unsigned long mem) node, path, 255) < 0) continue; - cpuid++; - #ifdef DEBUG_PROM prom_print_nl(); - prom_print(RELOC("cpuid = 0x")); - prom_print_hex(cpuid); - prom_print_nl(); prom_print(RELOC("cpu hw idx = 0x")); prom_print_hex(reg); prom_print_nl(); #endif - _xPaca[cpuid].xHwProcNum = reg; - prom_print(RELOC("starting cpu ")); prom_print(path); @@ -1155,11 +1142,9 @@ prom_hold_cpus(unsigned long mem) prom_print(RELOC(" 3) secondary_hold = 0x")); prom_print_hex(secondary_hold); prom_print_nl(); - prom_print(RELOC(" 3) cpuid = 0x")); - prom_print_hex(cpuid); prom_print_nl(); #endif - call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid); + call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, reg); prom_print(RELOC("...")); for ( i = 0 ; (i < 100000000) && (*acknowledge == ((unsigned long)-1)); i++ ) ; @@ -1171,10 +1156,10 @@ prom_hold_cpus(unsigned long mem) prom_print_nl(); } #endif - if (*acknowledge == cpuid) { + if (*acknowledge == reg) { prom_print(RELOC("ok\n")); /* Set the number of active processors. */ - _naca->processorCount++; + _xPaca[reg].active = 1; } else { prom_print(RELOC("failed: ")); prom_print_hex(*acknowledge); @@ -1188,10 +1173,11 @@ prom_hold_cpus(unsigned long mem) __is_processor(PV_SSTAR)) { prom_print(RELOC(" starting secondary threads\n")); - for (i=0; i < _naca->processorCount ;i++) { - unsigned long threadid = _naca->processorCount*2-1-i; - - if (i == 0) { + for (i = 0; i < NR_CPUS; i += 2) { + if (!_xPaca[i].active) + continue; + + if (i == boot_cpuid) { unsigned long pir = _get_PIR(); if (__is_processor(PV_PULSAR)) { RELOC(hmt_thread_data)[i].pir = @@ -1201,21 +1187,9 @@ prom_hold_cpus(unsigned long mem) pir & 0x3ff; } } - - RELOC(hmt_thread_data)[i].threadid = threadid; -#ifdef DEBUG_PROM - prom_print(RELOC(" cpuid 0x")); - prom_print_hex(i); - prom_print(RELOC(" maps to threadid 0x")); - prom_print_hex(threadid); - prom_print_nl(); - prom_print(RELOC(" pir 0x")); - prom_print_hex(RELOC(hmt_thread_data)[i].pir); - prom_print_nl(); -#endif - _xPaca[threadid].xHwProcNum = _xPaca[i].xHwProcNum+1; + _xPaca[i+1].active = 1; + RELOC(hmt_thread_data)[i].threadid = i+1; } - _naca->processorCount *= 2; } else { prom_print(RELOC("Processor is not HMT capable\n")); } @@ -1372,7 +1346,9 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, cpu_pkg, RELOC("reg"), &getprop_rval, sizeof(getprop_rval)); _prom->cpu = (int)(unsigned long)getprop_rval; - _xPaca[0].xHwProcNum = _prom->cpu; + _xPaca[_prom->cpu].active = 1; + RELOC(cpu_online_map) = 1 << _prom->cpu; + RELOC(boot_cpuid) = _prom->cpu; #ifdef DEBUG_PROM prom_print(RELOC("Booting CPU hw index = 0x")); @@ -1408,7 +1384,7 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, * following, regardless of whether we have an SMP * kernel or not. */ - if ( _naca->processorCount > 1 ) + if (RELOC(ppc64_is_smp)) prom_hold_cpus(mem); mem = check_display(mem); diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c index 673d40c97bb8..ca1cc0ec810e 100644 --- a/arch/ppc64/kernel/rtasd.c +++ b/arch/ppc64/kernel/rtasd.c @@ -220,10 +220,15 @@ static int rtasd(void *unused) current->nice = sys_sched_get_priority_max(SCHED_FIFO) + 1; #endif - cpu = 0; - set_cpus_allowed(current, 1UL << cpu_logical_map(cpu)); +repeat: + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (!cpu_online(cpu)) + continue; + + DEBUG("scheduling on %d\n", cpu); + set_cpus_allowed(current, 1UL << cpu); + DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id()); - while(1) { do { memset(logdata, 0, rtas_error_log_max); error = rtas_call(event_scan, 4, 1, NULL, @@ -239,25 +244,6 @@ static int rtasd(void *unused) } while(error == 0); - DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id()); - - cpu++; - if (cpu >= smp_num_cpus) { - - if (first_pass && surveillance_requested) { - DEBUG("enabling surveillance\n"); - if (enable_surveillance()) - goto error_vfree; - DEBUG("surveillance enabled\n"); - } - - first_pass = 0; - cpu = 0; - } - - set_cpus_allowed(current, 1UL << cpu_logical_map(cpu)); - - /* Check all cpus for pending events before sleeping*/ if (!first_pass) { set_current_state(TASK_INTERRUPTIBLE); @@ -265,6 +251,17 @@ static int rtasd(void *unused) } } + if (first_pass && surveillance_requested) { + DEBUG("enabling surveillance\n"); + if (enable_surveillance()) + goto error_vfree; + DEBUG("surveillance enabled\n"); + } else { + first_pass = 0; + } + + goto repeat; + error_vfree: vfree(rtas_log_buf); error: diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index a7b69496f6cb..5dae36c8cba2 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -168,10 +168,6 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, udbg_puthex((unsigned long)naca); udbg_putc('\n'); - udbg_puts("naca->processorCount = 0x"); - udbg_puthex(naca->processorCount); - udbg_putc('\n'); - udbg_puts("naca->physicalMemorySize = 0x"); udbg_puthex(naca->physicalMemorySize); udbg_putc('\n'); diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index ffba3e7ea509..10d0100bea86 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -54,13 +54,15 @@ int smp_threads_ready = 0; volatile int smp_commenced = 0; -int smp_num_cpus = 1; int smp_tb_synchronized = 0; spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED; unsigned long cache_decay_ticks; static int max_cpus __initdata = NR_CPUS; -unsigned long cpu_online_map; +/* initialised so it doesnt end up in bss */ +unsigned long cpu_online_map = 0; +int boot_cpuid = 0; +int ppc64_is_smp = 0; volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; @@ -98,7 +100,7 @@ void iSeries_smp_message_recv( struct pt_regs * regs ) int cpu = smp_processor_id(); int msg; - if ( smp_num_cpus < 2 ) + if ( num_online_cpus() < 2 ) return; for ( msg = 0; msg < 4; ++msg ) @@ -110,11 +112,16 @@ void iSeries_smp_message_recv( struct pt_regs * regs ) 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) { - if ( (target == MSG_ALL) || - (target == i) || - ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) { - set_bit( msg, &iSeries_smp_message[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())) ) { + set_bit(msg, &iSeries_smp_message[i]); HvCall_sendIPI(&(paca[i])); } } @@ -135,7 +142,7 @@ static int smp_iSeries_numProcs(void) return np; } -static int smp_iSeries_probe(void) +static void smp_iSeries_probe(void) { unsigned i; unsigned np; @@ -149,9 +156,8 @@ static int smp_iSeries_probe(void) paca[i].next_jiffy_update_tb = paca[0].next_jiffy_update_tb; } } - + smp_tb_synchronized = 1; - return np; } static void smp_iSeries_kick_cpu(int nr) @@ -191,8 +197,10 @@ void smp_init_iSeries(void) ppc_md.smp_probe = smp_iSeries_probe; ppc_md.smp_kick_cpu = smp_iSeries_kick_cpu; ppc_md.smp_setup_cpu = smp_iSeries_setup_cpu; - +#ifdef CONFIG_PPC_ISERIES +#warning fix for iseries naca->processorCount = smp_iSeries_numProcs(); +#endif } @@ -220,13 +228,10 @@ smp_openpic_message_pass(int target, int msg, unsigned long data, int wait) } } -static int -smp_chrp_probe(void) +static void smp_chrp_probe(void) { - if (naca->processorCount > 1) + if (ppc64_is_smp) openpic_request_IPIs(); - - return naca->processorCount; } static void @@ -253,14 +258,14 @@ smp_kick_cpu(int nr) extern struct gettimeofday_struct do_gtod; -static void smp_space_timers( unsigned nr ) +static void smp_space_timers() { - unsigned long offset, i; - - offset = tb_ticks_per_jiffy / nr; - for ( i=1; i<nr; ++i ) { - paca[i].next_jiffy_update_tb = paca[i-1].next_jiffy_update_tb + offset; - } + int i; + unsigned long offset = tb_ticks_per_jiffy / NR_CPUS; + + for (i = 1; i < NR_CPUS; ++i) + paca[i].next_jiffy_update_tb = + paca[i-1].next_jiffy_update_tb + offset; } static void @@ -272,7 +277,7 @@ smp_chrp_setup_cpu(int cpu_nr) if (naca->platform == PLATFORM_PSERIES_LPAR) { /* timebases already synced under the hypervisor. */ paca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb(); - if (cpu_nr == 0) { + if (cpu_nr == boot_cpuid) { do_gtod.tb_orig_stamp = tb_last_stamp; /* Should update do_gtod.stamp_xsec. * For now we leave it which means the time can be some @@ -281,9 +286,9 @@ smp_chrp_setup_cpu(int cpu_nr) } smp_tb_synchronized = 1; } else { - if (cpu_nr == 0) { + if (cpu_nr == boot_cpuid) { /* 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 */ @@ -291,9 +296,9 @@ smp_chrp_setup_cpu(int cpu_nr) mb(); frozen = 1; set_tb(0, 0); - paca[0].next_jiffy_update_tb = 0; - smp_space_timers(smp_num_cpus); - while (atomic_read(&ready) < smp_num_cpus) + paca[boot_cpuid].next_jiffy_update_tb = 0; + smp_space_timers(); + while (atomic_read(&ready) < num_online_cpus()) barrier(); /* thaw the timebase again */ rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); @@ -317,8 +322,8 @@ smp_chrp_setup_cpu(int cpu_nr) if (OpenPIC_Addr) { do_openpic_setup_cpu(); } else { - if (cpu_nr > 0) - xics_setup_cpu(); + if (cpu_nr != boot_cpuid) + xics_setup_cpu(); } } @@ -327,7 +332,10 @@ smp_xics_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())) { @@ -338,10 +346,8 @@ smp_xics_message_pass(int target, int msg, unsigned long data, int wait) } } -static int -smp_xics_probe(void) +static void smp_xics_probe(void) { - return naca->processorCount; } /* This is called very early */ @@ -429,7 +435,6 @@ static void stop_this_cpu(void *dummy) void smp_send_stop(void) { smp_call_function(stop_this_cpu, NULL, 1, 0); - smp_num_cpus = 1; } /* @@ -467,7 +472,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, { struct call_data_struct data; - int ret = -1, cpus = smp_num_cpus-1; + int ret = -1, cpus = num_online_cpus()-1; int timeout; if (!cpus) @@ -554,29 +559,23 @@ struct thread_struct *current_set[NR_CPUS] = {&init_thread_union, 0}; void __init smp_boot_cpus(void) { - int i, cpu_nr; + int i, cpu_nr = 0; struct task_struct *p; printk("Entering SMP Mode...\n"); - smp_num_cpus = 1; - smp_store_cpu_info(0); - cpu_online_map = 1UL; + smp_store_cpu_info(boot_cpuid); + cpu_callin_map[boot_cpuid] = 1; - /* - * assume for now that the first cpu booted is - * cpu 0, the master -- Cort - */ - cpu_callin_map[0] = 1; /* XXX buggy - Anton */ current_thread_info()->cpu = 0; for (i = 0; i < NR_CPUS; i++) { paca[i].prof_counter = 1; paca[i].prof_multiplier = 1; - if(i != 0) { + if (i != boot_cpuid) { /* - * Processor 0's segment table is statically + * the boot cpu segment table is statically * initialized to real address 0x5000. The * Other processor's tables are created and * initialized here. @@ -593,28 +592,33 @@ void __init smp_boot_cpus(void) */ cache_decay_ticks = HZ/100; - /* Probe arch for CPUs */ - cpu_nr = ppc_md.smp_probe(); + ppc_md.smp_probe(); + for (i = 0; i < NR_CPUS; i++) { + if (paca[i].active) + cpu_nr++; + } printk("Probe found %d CPUs\n", cpu_nr); - /* - * only check for cpus we know exist. We keep the callin map - * with cpus at the bottom -- Cort - */ - if (cpu_nr > max_cpus) - cpu_nr = max_cpus; - #ifdef CONFIG_ISERIES - smp_space_timers( cpu_nr ); + smp_space_timers(); #endif printk("Waiting for %d CPUs\n", cpu_nr-1); - for ( i = 1 ; i < cpu_nr; i++ ) { + for (i = 1 ; i < NR_CPUS; i++) { int c; struct pt_regs regs; + if (!paca[i].active) + continue; + + if (i == boot_cpuid) + continue; + + if (num_online_cpus() >= max_cpus) + break; + /* create a process for the processor */ /* we don't care about the values in regs since we'll never reschedule the forked task. */ @@ -658,16 +662,15 @@ void __init smp_boot_cpus(void) { printk("Processor %d found.\n", i); /* this sync's the decr's -- Cort */ - smp_num_cpus++; } else { printk("Processor %d is stuck.\n", i); } } - /* Setup CPU 0 last (important) */ - ppc_md.smp_setup_cpu(0); - - if (smp_num_cpus < 2) { + /* Setup boot cpu last (important) */ + ppc_md.smp_setup_cpu(boot_cpuid); + + if (num_online_cpus() < 2) { tb_last_stamp = get_tb(); smp_tb_synchronized = 1; } @@ -689,8 +692,9 @@ void __init smp_callin(void) smp_store_cpu_info(cpu); set_dec(paca[cpu].default_decr); - cpu_callin_map[cpu] = 1; set_bit(smp_processor_id(), &cpu_online_map); + smp_mb(); + cpu_callin_map[cpu] = 1; ppc_md.smp_setup_cpu(cpu); diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index be8a9772e6d4..d7962c12288f 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -340,7 +340,7 @@ nextnode: /* Find the server numbers for the boot cpu. */ for (np = find_type_devices("cpu"); np; np = np->next) { ireg = (uint *)get_property(np, "reg", &ilen); - if (ireg && ireg[0] == hard_smp_processor_id()) { + if (ireg && ireg[0] == smp_processor_id()) { ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); i = ilen / sizeof(int); if (ireg && i > 0) { @@ -371,10 +371,12 @@ nextnode: if (naca->platform == PLATFORM_PSERIES) { #ifdef CONFIG_SMP - for (i = 0; i < naca->processorCount; ++i) { + for (i = 0; i < NR_CPUS; ++i) { + if (!paca[i].active) + continue; xics_info.per_cpu[i] = - __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr, - (ulong)inodes[get_hard_smp_processor_id(i)].size, _PAGE_NO_CACHE); + __ioremap((ulong)inodes[i].addr, + (ulong)inodes[i].size, _PAGE_NO_CACHE); } #else xics_info.per_cpu[0] = __ioremap((ulong)intr_base, intr_size, _PAGE_NO_CACHE); @@ -395,7 +397,7 @@ nextnode: for (; i < NR_IRQS; ++i) irq_desc[i].handler = &xics_pic; - ops->cppr_info(0, 0xff); + ops->cppr_info(boot_cpuid, 0xff); iosync(); if (xics_irq_8259_cascade != -1) { if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, @@ -420,23 +422,6 @@ void xics_isa_init(void) i8259_init(); } -/* - * Find first logical cpu and return its physical cpu number - */ -static inline u32 physmask(u32 cpumask) -{ - int i; - - for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1) { - if (cpumask & 1) - return get_hard_smp_processor_id(i); - } - - printk(KERN_ERR "xics_set_affinity: invalid irq mask\n"); - - return default_distrib_server; -} - void xics_set_affinity(unsigned int virq, unsigned long cpumask) { irq_desc_t *desc = irq_desc + virq; @@ -462,10 +447,13 @@ void xics_set_affinity(unsigned int virq, unsigned long cpumask) } /* For the moment only implement delivery to all cpus or one cpu */ - if (cpumask == 0xffffffff) + if (cpumask == 0xffffffff) { newmask = default_distrib_server; - else - newmask = physmask(cpumask); + } else { + if (!(cpumask & cpu_online_map)) + goto out; + newmask = find_first_bit(&cpumask, 32); + } status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, newmask, xics_status[1]); diff --git a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h index 29b07a4f69c2..2fcde4ad0df9 100644 --- a/include/asm-ppc64/hardirq.h +++ b/include/asm-ppc64/hardirq.h @@ -15,7 +15,7 @@ #include <linux/config.h> #include <linux/brlock.h> #include <linux/spinlock.h> - +#include <asm/smp.h> typedef struct { unsigned long __softirq_pending; @@ -67,8 +67,8 @@ static __inline__ int irqs_running(void) { int i; - for (i = 0; i < smp_num_cpus; i++) - if (local_irq_count(cpu_logical_map(i))) + for (i = 0; i < NR_CPUS; i++) + if (local_irq_count(i)) return 1; return 0; } diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index f076955d5d60..5b78e41bff20 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h @@ -62,7 +62,7 @@ struct machdep_calls { int msg, unsigned long data, int wait); - int (*smp_probe)(void); + void (*smp_probe)(void); void (*smp_kick_cpu)(int nr); void (*smp_setup_cpu)(int nr); diff --git a/include/asm-ppc64/naca.h b/include/asm-ppc64/naca.h index ed28065ae2a7..082d5bfa15fe 100644 --- a/include/asm-ppc64/naca.h +++ b/include/asm-ppc64/naca.h @@ -18,7 +18,6 @@ struct naca_struct { u64 xRamDiskSize; /* In pages */ struct paca_struct *paca; /* Ptr to an array of pacas */ u64 debug_switch; /* Bits to control debug printing */ - u16 processorCount; /* # of physical processors */ u16 dCacheL1LineSize; /* Line size of L1 DCache in bytes */ u16 dCacheL1LogLineSize; /* Log-2 of DCache line size */ u16 dCacheL1LinesPerPage; /* DCache lines per page */ diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h index 32e7ba98d1f7..e569f4b461cb 100644 --- a/include/asm-ppc64/paca.h +++ b/include/asm-ppc64/paca.h @@ -71,7 +71,7 @@ struct paca_struct { struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC 0x08 */ u64 xCurrent; /* Pointer to current 0x10 */ u16 xPacaIndex; /* Logical processor number 0x18 */ - u16 xHwProcNum; /* Actual Hardware Processor Number 0x1a */ + u16 active; /* Is this cpu active? 0x1a */ u32 default_decr; /* Default decrementer value 0x1c */ u64 xHrdIntStack; /* Stack for hardware interrupts 0x20 */ u64 xKsave; /* Saved Kernel stack addr or zero 0x28 */ diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h index 305b69fa3c82..d2ca9cc9cf1c 100644 --- a/include/asm-ppc64/smp.h +++ b/include/asm-ppc64/smp.h @@ -39,16 +39,27 @@ extern void smp_send_reschedule_all(void); #define NO_PROC_ID 0xFF /* No processor magic marker */ -/* 1 to 1 mapping on PPC -- Cort */ -#define cpu_logical_map(cpu) (cpu) -#define cpu_number_map(x) (x) +#define cpu_online(cpu) test_bit((cpu), &cpu_online_map) + +#define cpu_possible(cpu) paca[cpu].active + +static inline int num_online_cpus(void) +{ + int i, nr = 0; + + for (i = 0; i < NR_CPUS; i++) + nr += test_bit(i, &cpu_online_map); + + return nr; +} + extern volatile unsigned long cpu_callin_map[NR_CPUS]; #define smp_processor_id() (get_paca()->xPacaIndex) -#define hard_smp_processor_id() (get_paca()->xHwProcNum) -#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum) - +/* remove when the boot sequence gets rewritten to use hotplug interface */ +extern int boot_cpuid; +extern int ppc64_is_smp; /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. * |
