Commit de300974 authored by Michael Ellerman's avatar Michael Ellerman Committed by Benjamin Herrenschmidt

powerpc/smp: smp_ops->kick_cpu() should be able to fail

When we start a cpu we use smp_ops->kick_cpu(), which currently
returns void, it should be able to fail. Convert it to return
int, and update all uses.

Convert all the current error cases to return -ENOENT, which is
what would eventually be returned by __cpu_up() currently when
it doesn't detect the cpu as coming up in time.
Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 6c5b59b9
...@@ -33,7 +33,7 @@ struct kimage; ...@@ -33,7 +33,7 @@ struct kimage;
struct smp_ops_t { struct smp_ops_t {
void (*message_pass)(int target, int msg); void (*message_pass)(int target, int msg);
int (*probe)(void); int (*probe)(void);
void (*kick_cpu)(int nr); int (*kick_cpu)(int nr);
void (*setup_cpu)(int nr); void (*setup_cpu)(int nr);
void (*bringup_done)(void); void (*bringup_done)(void);
void (*take_timebase)(void); void (*take_timebase)(void);
......
...@@ -150,7 +150,7 @@ extern int smt_enabled_at_boot; ...@@ -150,7 +150,7 @@ extern int smt_enabled_at_boot;
extern int smp_mpic_probe(void); extern int smp_mpic_probe(void);
extern void smp_mpic_setup_cpu(int cpu); extern void smp_mpic_setup_cpu(int cpu);
extern void smp_generic_kick_cpu(int nr); extern int smp_generic_kick_cpu(int nr);
extern void smp_generic_give_timebase(void); extern void smp_generic_give_timebase(void);
extern void smp_generic_take_timebase(void); extern void smp_generic_take_timebase(void);
......
...@@ -95,7 +95,7 @@ int smt_enabled_at_boot = 1; ...@@ -95,7 +95,7 @@ int smt_enabled_at_boot = 1;
static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
void __devinit smp_generic_kick_cpu(int nr) int __devinit smp_generic_kick_cpu(int nr)
{ {
BUG_ON(nr < 0 || nr >= NR_CPUS); BUG_ON(nr < 0 || nr >= NR_CPUS);
...@@ -106,6 +106,8 @@ void __devinit smp_generic_kick_cpu(int nr) ...@@ -106,6 +106,8 @@ void __devinit smp_generic_kick_cpu(int nr)
*/ */
paca[nr].cpu_start = 1; paca[nr].cpu_start = 1;
smp_mb(); smp_mb();
return 0;
} }
#endif #endif
...@@ -434,7 +436,11 @@ int __cpuinit __cpu_up(unsigned int cpu) ...@@ -434,7 +436,11 @@ int __cpuinit __cpu_up(unsigned int cpu)
/* wake up cpus */ /* wake up cpus */
DBG("smp: kicking cpu %d\n", cpu); DBG("smp: kicking cpu %d\n", cpu);
smp_ops->kick_cpu(cpu); rc = smp_ops->kick_cpu(cpu);
if (rc) {
pr_err("smp: failed starting cpu %d (rc %d)\n", cpu, rc);
return rc;
}
/* /*
* wait to see if the cpu made a callin (is actually up). * wait to see if the cpu made a callin (is actually up).
......
...@@ -87,7 +87,7 @@ static void __cpuinit smp_iss4xx_setup_cpu(int cpu) ...@@ -87,7 +87,7 @@ static void __cpuinit smp_iss4xx_setup_cpu(int cpu)
mpic_setup_this_cpu(); mpic_setup_this_cpu();
} }
static void __cpuinit smp_iss4xx_kick_cpu(int cpu) static int __cpuinit smp_iss4xx_kick_cpu(int cpu)
{ {
struct device_node *cpunode = of_get_cpu_node(cpu, NULL); struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
const u64 *spin_table_addr_prop; const u64 *spin_table_addr_prop;
...@@ -104,7 +104,7 @@ static void __cpuinit smp_iss4xx_kick_cpu(int cpu) ...@@ -104,7 +104,7 @@ static void __cpuinit smp_iss4xx_kick_cpu(int cpu)
NULL); NULL);
if (spin_table_addr_prop == NULL) { if (spin_table_addr_prop == NULL) {
pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu); pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu);
return; return -ENOENT;
} }
/* Assume it's mapped as part of the linear mapping. This is a bit /* Assume it's mapped as part of the linear mapping. This is a bit
...@@ -117,6 +117,8 @@ static void __cpuinit smp_iss4xx_kick_cpu(int cpu) ...@@ -117,6 +117,8 @@ static void __cpuinit smp_iss4xx_kick_cpu(int cpu)
smp_wmb(); smp_wmb();
spin_table[1] = __pa(start_secondary_47x); spin_table[1] = __pa(start_secondary_47x);
mb(); mb();
return 0;
} }
static struct smp_ops_t iss_smp_ops = { static struct smp_ops_t iss_smp_ops = {
......
...@@ -41,7 +41,7 @@ extern void __early_start(void); ...@@ -41,7 +41,7 @@ extern void __early_start(void);
#define NUM_BOOT_ENTRY 8 #define NUM_BOOT_ENTRY 8
#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32)) #define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32))
static void __init static int __init
smp_85xx_kick_cpu(int nr) smp_85xx_kick_cpu(int nr)
{ {
unsigned long flags; unsigned long flags;
...@@ -60,7 +60,7 @@ smp_85xx_kick_cpu(int nr) ...@@ -60,7 +60,7 @@ smp_85xx_kick_cpu(int nr)
if (cpu_rel_addr == NULL) { if (cpu_rel_addr == NULL) {
printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
return; return -ENOENT;
} }
/* /*
...@@ -107,6 +107,8 @@ smp_85xx_kick_cpu(int nr) ...@@ -107,6 +107,8 @@ smp_85xx_kick_cpu(int nr)
iounmap(bptr_vaddr); iounmap(bptr_vaddr);
pr_debug("waited %d msecs for CPU #%d.\n", n, nr); pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
return 0;
} }
static void __init static void __init
......
...@@ -56,7 +56,7 @@ smp_86xx_release_core(int nr) ...@@ -56,7 +56,7 @@ smp_86xx_release_core(int nr)
} }
static void __init static int __init
smp_86xx_kick_cpu(int nr) smp_86xx_kick_cpu(int nr)
{ {
unsigned int save_vector; unsigned int save_vector;
...@@ -65,7 +65,7 @@ smp_86xx_kick_cpu(int nr) ...@@ -65,7 +65,7 @@ smp_86xx_kick_cpu(int nr)
unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100); unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100);
if (nr < 0 || nr >= NR_CPUS) if (nr < 0 || nr >= NR_CPUS)
return; return -ENOENT;
pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr); pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr);
...@@ -92,6 +92,8 @@ smp_86xx_kick_cpu(int nr) ...@@ -92,6 +92,8 @@ smp_86xx_kick_cpu(int nr)
local_irq_restore(flags); local_irq_restore(flags);
pr_debug("wait CPU #%d for %d msecs.\n", nr, n); pr_debug("wait CPU #%d for %d msecs.\n", nr, n);
return 0;
} }
......
...@@ -93,12 +93,11 @@ static void __devinit smp_beatic_setup_cpu(int cpu) ...@@ -93,12 +93,11 @@ static void __devinit smp_beatic_setup_cpu(int cpu)
beatic_setup_cpu(cpu); beatic_setup_cpu(cpu);
} }
static void __devinit smp_celleb_kick_cpu(int nr) static int __devinit smp_celleb_kick_cpu(int nr)
{ {
BUG_ON(nr < 0 || nr >= NR_CPUS); BUG_ON(nr < 0 || nr >= NR_CPUS);
if (!smp_startup_cpu(nr)) return smp_startup_cpu(nr);
return;
} }
static int smp_celleb_cpu_bootable(unsigned int nr) static int smp_celleb_cpu_bootable(unsigned int nr)
......
...@@ -137,12 +137,12 @@ static void __devinit smp_cell_setup_cpu(int cpu) ...@@ -137,12 +137,12 @@ static void __devinit smp_cell_setup_cpu(int cpu)
mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
} }
static void __devinit smp_cell_kick_cpu(int nr) static int __devinit smp_cell_kick_cpu(int nr)
{ {
BUG_ON(nr < 0 || nr >= NR_CPUS); BUG_ON(nr < 0 || nr >= NR_CPUS);
if (!smp_startup_cpu(nr)) if (!smp_startup_cpu(nr))
return; return -ENOENT;
/* /*
* The processor is currently spinning, waiting for the * The processor is currently spinning, waiting for the
...@@ -150,6 +150,8 @@ static void __devinit smp_cell_kick_cpu(int nr) ...@@ -150,6 +150,8 @@ static void __devinit smp_cell_kick_cpu(int nr)
* the processor will continue on to secondary_start * the processor will continue on to secondary_start
*/ */
paca[nr].cpu_start = 1; paca[nr].cpu_start = 1;
return 0;
} }
static int smp_cell_cpu_bootable(unsigned int nr) static int smp_cell_cpu_bootable(unsigned int nr)
......
...@@ -30,10 +30,12 @@ ...@@ -30,10 +30,12 @@
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/rtas.h> #include <asm/rtas.h>
static void __devinit smp_chrp_kick_cpu(int nr) static int __devinit smp_chrp_kick_cpu(int nr)
{ {
*(unsigned long *)KERNELBASE = nr; *(unsigned long *)KERNELBASE = nr;
asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
return 0;
} }
static void __devinit smp_chrp_setup_cpu(int cpu_nr) static void __devinit smp_chrp_setup_cpu(int cpu_nr)
......
...@@ -86,13 +86,13 @@ static int smp_iSeries_probe(void) ...@@ -86,13 +86,13 @@ static int smp_iSeries_probe(void)
return cpumask_weight(cpu_possible_mask); return cpumask_weight(cpu_possible_mask);
} }
static void smp_iSeries_kick_cpu(int nr) static int smp_iSeries_kick_cpu(int nr)
{ {
BUG_ON((nr < 0) || (nr >= NR_CPUS)); BUG_ON((nr < 0) || (nr >= NR_CPUS));
/* Verify that our partition has a processor nr */ /* Verify that our partition has a processor nr */
if (lppaca_of(nr).dyn_proc_status >= 2) if (lppaca_of(nr).dyn_proc_status >= 2)
return; return -ENOENT;
/* The processor is currently spinning, waiting /* The processor is currently spinning, waiting
* for the cpu_start field to become non-zero * for the cpu_start field to become non-zero
...@@ -100,6 +100,8 @@ static void smp_iSeries_kick_cpu(int nr) ...@@ -100,6 +100,8 @@ static void smp_iSeries_kick_cpu(int nr)
* continue on to secondary_start in iSeries_head.S * continue on to secondary_start in iSeries_head.S
*/ */
paca[nr].cpu_start = 1; paca[nr].cpu_start = 1;
return 0;
} }
static void __devinit smp_iSeries_setup_cpu(int nr) static void __devinit smp_iSeries_setup_cpu(int nr)
......
...@@ -329,7 +329,7 @@ static int __init smp_psurge_probe(void) ...@@ -329,7 +329,7 @@ static int __init smp_psurge_probe(void)
return ncpus; return ncpus;
} }
static void __init smp_psurge_kick_cpu(int nr) static int __init smp_psurge_kick_cpu(int nr)
{ {
unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
unsigned long a, flags; unsigned long a, flags;
...@@ -394,6 +394,8 @@ static void __init smp_psurge_kick_cpu(int nr) ...@@ -394,6 +394,8 @@ static void __init smp_psurge_kick_cpu(int nr)
psurge_set_ipi(1); psurge_set_ipi(1);
if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
return 0;
} }
static struct irqaction psurge_irqaction = { static struct irqaction psurge_irqaction = {
...@@ -791,14 +793,14 @@ static int __init smp_core99_probe(void) ...@@ -791,14 +793,14 @@ static int __init smp_core99_probe(void)
return ncpus; return ncpus;
} }
static void __devinit smp_core99_kick_cpu(int nr) static int __devinit smp_core99_kick_cpu(int nr)
{ {
unsigned int save_vector; unsigned int save_vector;
unsigned long target, flags; unsigned long target, flags;
unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100); unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
if (nr < 0 || nr > 3) if (nr < 0 || nr > 3)
return; return -ENOENT;
if (ppc_md.progress) if (ppc_md.progress)
ppc_md.progress("smp_core99_kick_cpu", 0x346); ppc_md.progress("smp_core99_kick_cpu", 0x346);
...@@ -830,6 +832,8 @@ static void __devinit smp_core99_kick_cpu(int nr) ...@@ -830,6 +832,8 @@ static void __devinit smp_core99_kick_cpu(int nr)
local_irq_restore(flags); local_irq_restore(flags);
if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
return 0;
} }
static void __devinit smp_core99_setup_cpu(int cpu_nr) static void __devinit smp_core99_setup_cpu(int cpu_nr)
......
...@@ -152,12 +152,12 @@ static void __devinit smp_xics_setup_cpu(int cpu) ...@@ -152,12 +152,12 @@ static void __devinit smp_xics_setup_cpu(int cpu)
#endif #endif
} }
static void __devinit smp_pSeries_kick_cpu(int nr) static int __devinit smp_pSeries_kick_cpu(int nr)
{ {
BUG_ON(nr < 0 || nr >= NR_CPUS); BUG_ON(nr < 0 || nr >= NR_CPUS);
if (!smp_startup_cpu(nr)) if (!smp_startup_cpu(nr))
return; return -ENOENT;
/* /*
* The processor is currently spinning, waiting for the * The processor is currently spinning, waiting for the
...@@ -179,6 +179,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr) ...@@ -179,6 +179,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
"Ret= %ld\n", nr, rc); "Ret= %ld\n", nr, rc);
} }
#endif #endif
return 0;
} }
static int smp_pSeries_cpu_bootable(unsigned int nr) static int smp_pSeries_cpu_bootable(unsigned int nr)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment