Hello, smp_boot_cpus() in arch/mips/sibyte/sb1250/smp.c does CPU enumeration in an awkward way -- resulting in physical IDs different from what they really are. Additionally the code breaks for more than two processors present -- subsequent CPUs get assigned numbers beyond NR_CPUS. While this may not bite for current SB1250 implementations, it need not necessarily always be the case and the code seems to be intended to handle such configurations. Here's a proposed fix. It requires an API change for prom_boot_secondary() to return a status, but I think it's desirable as it lets the invoker know if the call failed for some reason. Some code elsewhere already defines the function this way. ;-) OK to apply? Maciej -- + Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: macro@ds2.pg.gda.pl, PGP key available + patch-mips-2.4.25-20040322-swarm-smpboot-1 diff -up --recursive --new-file linux-mips-2.4.25-20040322.macro/arch/mips/sibyte/cfe/smp.c linux-mips-2.4.25-20040322/arch/mips/sibyte/cfe/smp.c --- linux-mips-2.4.25-20040322.macro/arch/mips/sibyte/cfe/smp.c 2004-01-06 03:56:57.000000000 +0000 +++ linux-mips-2.4.25-20040322/arch/mips/sibyte/cfe/smp.c 2004-04-02 08:41:08.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation + * Copyright (C) 2004 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,7 +27,7 @@ /* Boot all other cpus in the system, initialize them, and bring them into the boot fn */ -void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) +int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) { int retval; @@ -34,6 +35,8 @@ void prom_boot_secondary(int cpu, unsign if (retval != 0) { printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); } + + return retval; } void prom_init_secondary(void) diff -up --recursive --new-file linux-mips-2.4.25-20040322.macro/arch/mips/sibyte/sb1250/smp.c linux-mips-2.4.25-20040322/arch/mips/sibyte/sb1250/smp.c --- linux-mips-2.4.25-20040322.macro/arch/mips/sibyte/sb1250/smp.c 2004-01-28 03:56:49.000000000 +0000 +++ linux-mips-2.4.25-20040322/arch/mips/sibyte/sb1250/smp.c 2004-04-02 14:27:08.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2004 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -138,7 +139,7 @@ void __init smp_boot_cpus(void) * This loop attempts to compensate for "holes" in the CPU * numbering. It's overkill, but general. */ - for (i = 1; i < smp_num_cpus; ) { + for (i = 1; i < smp_num_cpus && cur_cpu < NR_CPUS; i++) { struct task_struct *p; struct pt_regs regs; printk("Starting CPU %d... ", i); @@ -158,15 +159,20 @@ void __init smp_boot_cpus(void) unhash_process(p); do { + int status; + /* Iterate until we find a CPU that comes up */ cur_cpu++; - prom_boot_secondary(cur_cpu, - (unsigned long)p + KERNEL_STACK_SIZE - 32, - (unsigned long)p); - } while (cur_cpu < smp_num_cpus - 1); - __cpu_number_map[cur_cpu] = i; - __cpu_logical_map[i] = cur_cpu; - i++; + status = prom_boot_secondary(cur_cpu, + (unsigned long)p + + KERNEL_STACK_SIZE - 32, + (unsigned long)p); + if (status == 0) { + __cpu_number_map[cur_cpu] = i; + __cpu_logical_map[i] = cur_cpu; + break; + } + } while (cur_cpu < NR_CPUS); } /* Wait for everyone to come up */ diff -up --recursive --new-file linux-mips-2.4.25-20040322.macro/include/asm-mips/smp.h linux-mips-2.4.25-20040322/include/asm-mips/smp.h --- linux-mips-2.4.25-20040322.macro/include/asm-mips/smp.h 2003-12-31 03:57:06.000000000 +0000 +++ linux-mips-2.4.25-20040322/include/asm-mips/smp.h 2004-04-02 14:27:08.000000000 +0000 @@ -106,7 +106,7 @@ void core_send_ipi(int cpu, unsigned int * Clear all undefined state in the cpu, set up sp and gp to the passed * values, and kick the cpu into smp_bootstrap(); */ -void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); +int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); /* * After we've done initial boot, this function is called to allow the diff -up --recursive --new-file linux-mips-2.4.25-20040322.macro/include/asm-mips64/smp.h linux-mips-2.4.25-20040322/include/asm-mips64/smp.h --- linux-mips-2.4.25-20040322.macro/include/asm-mips64/smp.h 2003-12-31 03:57:06.000000000 +0000 +++ linux-mips-2.4.25-20040322/include/asm-mips64/smp.h 2004-04-02 14:27:08.000000000 +0000 @@ -106,7 +106,7 @@ void core_send_ipi(int cpu, unsigned int * Clear all undefined state in the cpu, set up sp and gp to the passed * values, and kick the cpu into smp_bootstrap(); */ -void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); +int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); /* * After we've done initial boot, this function is called to allow the