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
|