Re: [PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores
On Thu, Aug 27, 2015 at 4:55 AM, Scott Wood wrote: On Wed, Aug 26, 2015 at 08:09:47PM +0800, Chenhui Zhao wrote: +int check_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} I'm not sure this needs to be a function versus open-coded, but if you do want to make it a function, make it more obvious from the caller side by changing it to: bool is_cpu_dead(unsigned int cpu); Otherwise if I see "if (check_cpu_dead(cpu))" I don't know if the if-block is executed if the CPU is dead or if it isn't. OK. diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h index 0b20ae3..8ee19a3 100644 --- a/arch/powerpc/platforms/85xx/smp.h +++ b/arch/powerpc/platforms/85xx/smp.h @@ -6,6 +6,7 @@ #ifdef CONFIG_SMP void __init mpc85xx_smp_init(void); int __init mpc85xx_setup_pmc(void); +int __init fsl_rcpm_init(void); #else Why wasn't this added in the patch that added fsl_rcpm_init()? -Scott Will move it to there. Thanks, -Chenhui -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores
On Thu, Aug 27, 2015 at 4:55 AM, Scott Wood scottw...@freescale.com wrote: On Wed, Aug 26, 2015 at 08:09:47PM +0800, Chenhui Zhao wrote: +int check_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} I'm not sure this needs to be a function versus open-coded, but if you do want to make it a function, make it more obvious from the caller side by changing it to: bool is_cpu_dead(unsigned int cpu); Otherwise if I see if (check_cpu_dead(cpu)) I don't know if the if-block is executed if the CPU is dead or if it isn't. OK. diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h index 0b20ae3..8ee19a3 100644 --- a/arch/powerpc/platforms/85xx/smp.h +++ b/arch/powerpc/platforms/85xx/smp.h @@ -6,6 +6,7 @@ #ifdef CONFIG_SMP void __init mpc85xx_smp_init(void); int __init mpc85xx_setup_pmc(void); +int __init fsl_rcpm_init(void); #else Why wasn't this added in the patch that added fsl_rcpm_init()? -Scott Will move it to there. Thanks, -Chenhui -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores
On Wed, Aug 26, 2015 at 08:09:47PM +0800, Chenhui Zhao wrote: > +int check_cpu_dead(unsigned int cpu) > +{ > + return per_cpu(cpu_state, cpu) == CPU_DEAD; > +} I'm not sure this needs to be a function versus open-coded, but if you do want to make it a function, make it more obvious from the caller side by changing it to: bool is_cpu_dead(unsigned int cpu); Otherwise if I see "if (check_cpu_dead(cpu))" I don't know if the if-block is executed if the CPU is dead or if it isn't. > diff --git a/arch/powerpc/platforms/85xx/smp.h > b/arch/powerpc/platforms/85xx/smp.h > index 0b20ae3..8ee19a3 100644 > --- a/arch/powerpc/platforms/85xx/smp.h > +++ b/arch/powerpc/platforms/85xx/smp.h > @@ -6,6 +6,7 @@ > #ifdef CONFIG_SMP > void __init mpc85xx_smp_init(void); > int __init mpc85xx_setup_pmc(void); > +int __init fsl_rcpm_init(void); > #else Why wasn't this added in the patch that added fsl_rcpm_init()? -Scott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores
Freescale E500MC and E5500 core-based platforms, like P4080, T1040, support disabling/enabling CPU dynamically. This patch adds this feature on those platforms. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- major changes for v2: * factor out smp_85xx_start_cpu() * move fsl_rcpm_init() into mpc85xx_smp_init() due to the init sequence * add hard_irq_disable() after local_irq_save(). for platforms that implement lazy enabling/disabling of interrupts, call hard_irq_disable() to ensure interrupts are disabled physically. arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/smp.h| 3 + arch/powerpc/kernel/smp.c | 7 +- arch/powerpc/platforms/85xx/smp.c | 193 ++ arch/powerpc/platforms/85xx/smp.h | 1 + 5 files changed, 122 insertions(+), 84 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5ef2711..dd9e252 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -386,7 +386,7 @@ config SWIOTLB config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" depends on SMP && (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC)) + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 825663c..4ff5b71 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu); void generic_set_cpu_dead(unsigned int cpu); void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); +int check_cpu_dead(unsigned int cpu); +#else +#define generic_set_cpu_up(i) do { } while (0) #endif #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ec9ec20..95111f2 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -427,7 +427,7 @@ void generic_cpu_die(unsigned int cpu) for (i = 0; i < 100; i++) { smp_rmb(); - if (per_cpu(cpu_state, cpu) == CPU_DEAD) + if (check_cpu_dead(cpu)) return; msleep(100); } @@ -454,6 +454,11 @@ int generic_check_cpu_restart(unsigned int cpu) return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; } +int check_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} + static bool secondaries_inhibited(void) { return kvm_hv_mode_active(); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index f9552b8..73eb994 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -10,6 +10,8 @@ * option) any later version. */ +#define pr_fmt(fmt) "smp: %s: " fmt, __func__ + #include #include #include @@ -52,6 +54,7 @@ static void mpc85xx_give_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); while (!tb_req) barrier(); @@ -100,6 +103,7 @@ static void mpc85xx_take_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); tb_req = 1; while (!tb_valid) @@ -135,8 +139,31 @@ static void smp_85xx_mach_cpu_die(void) while (1) ; } + +static void qoriq_cpu_kill(unsigned int cpu) +{ + int i; + + for (i = 0; i < 500; i++) { + if (check_cpu_dead(cpu)) { +#ifdef CONFIG_PPC64 + paca[cpu].cpu_start = 0; +#endif + return; + } + msleep(20); + } + pr_err("CPU%d didn't die...\n", cpu); +} #endif +/* + * To keep it compatible with old boot program which uses + * cache-inhibit spin table, we need to flush the cache + * before accessing spin table to invalidate any staled data. + * We also need to flush the cache after writing to spin + * table to push data out. + */ static inline void flush_spin_table(void *spin_table) { flush_dcache_range((ulong)spin_table, @@ -168,51 +195,20 @@ static void wake_hw_thread(void *info) } #endif -static int smp_85xx_kick_cpu(int nr) +static int smp_85xx_start_cpu(int cpu) { - unsigned long flags; - const u64 *cpu_rel_addr; - __iomem struct epapr_spin_table *spin_table; + int ret = 0; struct device_node *np; - int hw_cpu = get_hard_smp_processor_id(nr); + const u64 *cpu_rel_addr; + unsigned long flags; int ioremappable; - int ret = 0; - - WARN_ON(nr < 0 || nr >= NR_CPUS); - WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS); - - pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); - -#ifdef CONFIG_PPC64 - /* Threads don't use the spin table */ - if (cpu_thread_in_core(nr) != 0) { -
Re: [PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores
On Wed, Aug 26, 2015 at 08:09:47PM +0800, Chenhui Zhao wrote: +int check_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} I'm not sure this needs to be a function versus open-coded, but if you do want to make it a function, make it more obvious from the caller side by changing it to: bool is_cpu_dead(unsigned int cpu); Otherwise if I see if (check_cpu_dead(cpu)) I don't know if the if-block is executed if the CPU is dead or if it isn't. diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h index 0b20ae3..8ee19a3 100644 --- a/arch/powerpc/platforms/85xx/smp.h +++ b/arch/powerpc/platforms/85xx/smp.h @@ -6,6 +6,7 @@ #ifdef CONFIG_SMP void __init mpc85xx_smp_init(void); int __init mpc85xx_setup_pmc(void); +int __init fsl_rcpm_init(void); #else Why wasn't this added in the patch that added fsl_rcpm_init()? -Scott -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2,4/5] PowerPC/mpc85xx: Add hotplug support on E5500 and E500MC cores
Freescale E500MC and E5500 core-based platforms, like P4080, T1040, support disabling/enabling CPU dynamically. This patch adds this feature on those platforms. Signed-off-by: Chenhui Zhao chenhui.z...@freescale.com Signed-off-by: Tang Yuantian yuantian.t...@feescale.com --- major changes for v2: * factor out smp_85xx_start_cpu() * move fsl_rcpm_init() into mpc85xx_smp_init() due to the init sequence * add hard_irq_disable() after local_irq_save(). for platforms that implement lazy enabling/disabling of interrupts, call hard_irq_disable() to ensure interrupts are disabled physically. arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/smp.h| 3 + arch/powerpc/kernel/smp.c | 7 +- arch/powerpc/platforms/85xx/smp.c | 193 ++ arch/powerpc/platforms/85xx/smp.h | 1 + 5 files changed, 122 insertions(+), 84 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5ef2711..dd9e252 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -386,7 +386,7 @@ config SWIOTLB config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx !PPC_E500MC)) + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 825663c..4ff5b71 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu); void generic_set_cpu_dead(unsigned int cpu); void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); +int check_cpu_dead(unsigned int cpu); +#else +#define generic_set_cpu_up(i) do { } while (0) #endif #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ec9ec20..95111f2 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -427,7 +427,7 @@ void generic_cpu_die(unsigned int cpu) for (i = 0; i 100; i++) { smp_rmb(); - if (per_cpu(cpu_state, cpu) == CPU_DEAD) + if (check_cpu_dead(cpu)) return; msleep(100); } @@ -454,6 +454,11 @@ int generic_check_cpu_restart(unsigned int cpu) return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; } +int check_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} + static bool secondaries_inhibited(void) { return kvm_hv_mode_active(); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index f9552b8..73eb994 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -10,6 +10,8 @@ * option) any later version. */ +#define pr_fmt(fmt) smp: %s: fmt, __func__ + #include linux/stddef.h #include linux/kernel.h #include linux/init.h @@ -52,6 +54,7 @@ static void mpc85xx_give_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); while (!tb_req) barrier(); @@ -100,6 +103,7 @@ static void mpc85xx_take_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); tb_req = 1; while (!tb_valid) @@ -135,8 +139,31 @@ static void smp_85xx_mach_cpu_die(void) while (1) ; } + +static void qoriq_cpu_kill(unsigned int cpu) +{ + int i; + + for (i = 0; i 500; i++) { + if (check_cpu_dead(cpu)) { +#ifdef CONFIG_PPC64 + paca[cpu].cpu_start = 0; +#endif + return; + } + msleep(20); + } + pr_err(CPU%d didn't die...\n, cpu); +} #endif +/* + * To keep it compatible with old boot program which uses + * cache-inhibit spin table, we need to flush the cache + * before accessing spin table to invalidate any staled data. + * We also need to flush the cache after writing to spin + * table to push data out. + */ static inline void flush_spin_table(void *spin_table) { flush_dcache_range((ulong)spin_table, @@ -168,51 +195,20 @@ static void wake_hw_thread(void *info) } #endif -static int smp_85xx_kick_cpu(int nr) +static int smp_85xx_start_cpu(int cpu) { - unsigned long flags; - const u64 *cpu_rel_addr; - __iomem struct epapr_spin_table *spin_table; + int ret = 0; struct device_node *np; - int hw_cpu = get_hard_smp_processor_id(nr); + const u64 *cpu_rel_addr; + unsigned long flags; int ioremappable; - int ret = 0; - - WARN_ON(nr 0 || nr = NR_CPUS); - WARN_ON(hw_cpu 0 || hw_cpu = NR_CPUS); - - pr_debug(smp_85xx_kick_cpu: kick CPU #%d\n, nr); - -#ifdef CONFIG_PPC64 - /* Threads don't