From ff2c8252bfbf069dda1e53353a63b560f1369f59 Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Wed, 19 Jul 2017 09:21:03 +0100 Subject: MIPS: SMP: Constify smp ops smp_ops providers do not modify their ops structures, so they should be made const for robustness. Since currently the MIPS kernel is not mapped with memory protection, this does not in itself provide any security benefit, but it still makes sense to make this change. There are also slight code size efficincies from the structure being made read-only, saving 128 bytes of kernel text on a pistachio_defconfig. Before: text data bss dec hex filename 7187239 1772752 470224 9430215 8fe4c7 vmlinux After: text data bss dec hex filename 7187111 1772752 470224 9430087 8fe447 vmlinux Signed-off-by: Matt Redfearn Cc: Sebastian Andrzej Siewior Cc: Arnd Bergmann Cc: Marcin Nowakowski Cc: Bart Van Assche Cc: Masahiro Yamada Cc: Huacai Chen Cc: Paul Gortmaker Cc: Kevin Cernekee Cc: Thomas Gleixner Cc: Doug Ledford Cc: James Hogan Cc: Joe Perches Cc: Florian Fainelli Cc: Ingo Molnar Cc: Paul Burton Cc: Andrew Morton Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/16784/ Signed-off-by: Ralf Baechle --- arch/mips/netlogic/common/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/netlogic') diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index bddf1ef553a4..eac3f2950b14 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -272,7 +272,7 @@ int nlm_wakeup_secondary_cpus(void) return 0; } -struct plat_smp_ops nlm_smp_ops = { +const struct plat_smp_ops nlm_smp_ops = { .send_ipi_single = nlm_send_ipi_single, .send_ipi_mask = nlm_send_ipi_mask, .init_secondary = nlm_init_secondary, -- cgit v1.2.3 From f875a832d2028523f9b53c261b67e05a359bab8b Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sat, 12 Aug 2017 19:49:35 -0700 Subject: MIPS: Abstract CPU core & VP(E) ID access through accessor functions We currently have fields in struct cpuinfo_mips for the core & VP(E) ID of a particular CPU, and various pieces of code directly access those fields. This patch abstracts such access by introducing accessor functions cpu_core(), cpu_set_core(), cpu_vpe_id() & cpu_set_vpe_id() and having code that needs to access these values call those functions rather than directly accessing the struct cpuinfo_mips fields. This prepares us for changes to the way in which those values are stored in later patches. The cpu_vpe_id() function is introduced even though we already had a cpu_vpe_id() macro for a couple of reasons: 1) It's more consistent with the core, and future cluster, accessors. 2) It ensures a sensible return type without explicit casts. 3) It's generally preferable to use functions rather than macros. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/17009/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/cpu-info.h | 27 ++++++++++++++++++++++++--- arch/mips/include/asm/mips-cm.h | 2 +- arch/mips/include/asm/topology.h | 2 +- arch/mips/kernel/cpu-probe.c | 7 +++++-- arch/mips/kernel/mips-cm.c | 4 ++-- arch/mips/kernel/mips-cpc.c | 4 ++-- arch/mips/kernel/pm-cps.c | 6 +++--- arch/mips/kernel/proc.c | 6 +++--- arch/mips/kernel/smp-bmips.c | 2 +- arch/mips/kernel/smp-cps.c | 28 ++++++++++++++-------------- arch/mips/kernel/smp-mt.c | 2 +- arch/mips/kernel/smp.c | 8 ++++---- arch/mips/loongson64/loongson-3/smp.c | 11 ++++++----- arch/mips/netlogic/common/smp.c | 2 +- arch/mips/oprofile/op_model_mipsxx.c | 4 ++-- drivers/cpuidle/cpuidle-cps.c | 2 +- 16 files changed, 71 insertions(+), 46 deletions(-) (limited to 'arch/mips/netlogic') diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index cd6efb07c980..2b2f97023705 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -144,11 +144,32 @@ struct proc_cpuinfo_notifier_args { unsigned long n; }; +static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo) +{ + return cpuinfo->core; +} + +static inline void cpu_set_core(struct cpuinfo_mips *cpuinfo, + unsigned int core) +{ + cpuinfo->core = core; +} + +static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo) +{ #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) -# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) -#else -# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) + return cpuinfo->vpe_id; #endif + return 0; +} + +static inline void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, + unsigned int vpe) +{ +#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) + cpuinfo->vpe_id = vpe; +#endif +} static inline unsigned long cpu_asid_inc(void) { diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 225586bdd81c..6cfc0cc265d7 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -428,7 +428,7 @@ static inline unsigned int mips_cm_max_vp_width(void) */ static inline unsigned int mips_cm_vp_id(unsigned int cpu) { - unsigned int core = cpu_data[cpu].core; + unsigned int core = cpu_core(&cpu_data[cpu]); unsigned int vp = cpu_vpe_id(&cpu_data[cpu]); return (core * mips_cm_max_vp_width()) + vp; diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h index 7afda4150a59..0673d2d0f2e6 100644 --- a/arch/mips/include/asm/topology.h +++ b/arch/mips/include/asm/topology.h @@ -13,7 +13,7 @@ #ifdef CONFIG_SMP #define topology_physical_package_id(cpu) (cpu_data[cpu].package) -#define topology_core_id(cpu) (cpu_data[cpu].core) +#define topology_core_id(cpu) (cpu_core(&cpu_data[cpu])) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu]) #endif diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index c3ebbdefb0ad..b17b819852b8 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -919,9 +919,12 @@ static void decode_configs(struct cpuinfo_mips *c) #ifndef CONFIG_MIPS_CPS if (cpu_has_mips_r2_r6) { - c->core = get_ebase_cpunum(); + unsigned int core; + + core = get_ebase_cpunum(); if (cpu_has_mipsmt) - c->core >>= fls(core_nvpes()) - 1; + core >>= fls(core_nvpes()) - 1; + cpu_set_core(c, core); } #endif } diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 497dbb128438..77ad5468ee93 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -287,7 +287,7 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp) * CM 2.5 & older, so have to ensure other VP(E)s don't * race with us. */ - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); @@ -308,7 +308,7 @@ void mips_cm_unlock_other(void) unsigned int curr_core; if (mips_cm_revision() < CM_REV_CM3) { - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); } else { diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index 0e3ac6d05e75..06952bb34395 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -86,7 +86,7 @@ void mips_cpc_lock_other(unsigned int core) return; preempt_disable(); - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM)); @@ -106,7 +106,7 @@ void mips_cpc_unlock_other(void) /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ return; - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); preempt_enable(); diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index eae363770603..8df320a6b4b9 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -114,7 +114,7 @@ static void coupled_barrier(atomic_t *a, unsigned online) int cps_pm_enter_state(enum cps_pm_state state) { unsigned cpu = smp_processor_id(); - unsigned core = current_cpu_data.core; + unsigned core = cpu_core(¤t_cpu_data); unsigned online, left; cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled); u32 *core_ready_count, *nc_core_ready_count; @@ -486,7 +486,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * defined by the interAptiv & proAptiv SUMs as ensuring that the * operation resulting from the preceding store is complete. */ - uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); + uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu])); uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); @@ -640,7 +640,7 @@ out_err: static int cps_pm_online_cpu(unsigned int cpu) { enum cps_pm_state state; - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); void *entry_fn, *core_rc; for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) { diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 70604c753aa4..bd9bf528f19b 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -134,13 +134,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "kscratch registers\t: %d\n", hweight8(cpu_data[n].kscratch_mask)); seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); - seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); + seq_printf(m, "core\t\t\t: %d\n", cpu_core(&cpu_data[n])); #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) if (cpu_has_mipsmt) - seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); + seq_printf(m, "VPE\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n])); else if (cpu_has_vp) - seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id); + seq_printf(m, "VP\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n])); #endif sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index f86d755e3d75..4ac576c68034 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -245,7 +245,7 @@ static void bmips_init_secondary(void) break; case CPU_BMIPS5000: write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); - current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3; + cpu_set_core(¤t_cpu_data, (read_c0_brcm_config() >> 25) & 3); break; } } diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 5729d2c77461..699459ed293b 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -76,10 +76,8 @@ static void __init cps_smp_setup(void) smp_num_siblings = core_vpes; for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { - cpu_data[nvpes + v].core = c; -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) - cpu_data[nvpes + v].vpe_id = v; -#endif + cpu_set_core(&cpu_data[nvpes + v], c); + cpu_set_vpe_id(&cpu_data[nvpes + v], v); } nvpes += core_vpes; @@ -149,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) cpu_has_dc_aliases ? "dcache aliasing" : ""); for_each_present_cpu(c) { - if (cpu_data[c].core) + if (cpu_core(&cpu_data[c])) set_cpu_present(c, false); } } @@ -189,7 +187,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) } /* Mark this CPU as booted */ - atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask, + atomic_set(&mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)].vpe_mask, 1 << cpu_vpe_id(¤t_cpu_data)); return; @@ -284,7 +282,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id) static void remote_vpe_boot(void *dummy) { - unsigned core = current_cpu_data.core; + unsigned core = cpu_core(¤t_cpu_data); struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); @@ -292,7 +290,7 @@ static void remote_vpe_boot(void *dummy) static void cps_boot_secondary(int cpu, struct task_struct *idle) { - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id]; @@ -321,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) mips_cm_unlock_other(); } - if (core != current_cpu_data.core) { + if (core != cpu_core(¤t_cpu_data)) { /* Boot a VPE on another powered up core */ for (remote = 0; remote < NR_CPUS; remote++) { - if (cpu_data[remote].core != core) + if (cpu_core(&cpu_data[remote]) != core) continue; if (cpu_online(remote)) break; @@ -401,7 +399,7 @@ static int cps_cpu_disable(void) if (!cps_pm_support_state(CPS_PM_POWER_GATED)) return -EINVAL; - core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core]; + core_cfg = &mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)]; atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); smp_mb__after_atomic(); set_cpu_online(cpu, false); @@ -423,15 +421,17 @@ void play_dead(void) local_irq_disable(); idle_task_exit(); cpu = smp_processor_id(); - core = cpu_data[cpu].core; + core = cpu_core(&cpu_data[cpu]); cpu_death = CPU_DEATH_POWER; pr_debug("CPU%d going offline\n", cpu); if (cpu_has_mipsmt || cpu_has_vp) { + core = cpu_core(&cpu_data[cpu]); + /* Look for another online VPE within the core */ for_each_online_cpu(cpu_death_sibling) { - if (cpu_data[cpu_death_sibling].core != core) + if (cpu_core(&cpu_data[cpu_death_sibling]) != core) continue; /* @@ -487,7 +487,7 @@ static void wait_for_sibling_halt(void *ptr_cpu) static void cps_cpu_die(unsigned int cpu) { - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]); ktime_t fail_time; unsigned stat; diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 004ff5e8a820..5a7b5857d083 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -83,7 +83,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0, if (tc != 0) smvp_copy_vpe_config(); - cpu_data[ncpu].vpe_id = tc; + cpu_set_vpe_id(&cpu_data[ncpu], tc); return ncpu; } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 20c1f9ac946a..a54e5857c227 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -97,7 +97,7 @@ static inline void set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu(i, &cpu_sibling_setup_map) { if (cpu_data[cpu].package == cpu_data[i].package && - cpu_data[cpu].core == cpu_data[i].core) { + cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) { cpumask_set_cpu(i, &cpu_sibling_map[cpu]); cpumask_set_cpu(cpu, &cpu_sibling_map[i]); } @@ -135,7 +135,7 @@ void calculate_cpu_foreign_map(void) core_present = 0; for_each_cpu(k, &temp_foreign_map) if (cpu_data[i].package == cpu_data[k].package && - cpu_data[i].core == cpu_data[k].core) + cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k])) core_present = 1; if (!core_present) cpumask_set_cpu(i, &temp_foreign_map); @@ -186,9 +186,9 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action) if (mips_cpc_present()) { for_each_cpu(cpu, mask) { - core = cpu_data[cpu].core; + core = cpu_core(&cpu_data[cpu]); - if (core == current_cpu_data.core) + if (core == cpu_core(¤t_cpu_data)) continue; while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index 5b5a44f50b0b..bde64b0f1e47 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -319,8 +319,8 @@ static void loongson3_init_secondary(void) loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); per_cpu(cpu_state, cpu) = CPU_ONLINE; - cpu_data[cpu].core = - cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_set_core(&cpu_data[cpu], + cpu_logical_map(cpu) % loongson_sysconf.cores_per_package); cpu_data[cpu].package = cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; @@ -386,7 +386,8 @@ static void __init loongson3_smp_setup(void) ipi_status0_regs_init(); ipi_en0_regs_init(); ipi_mailbox_buf_init(); - cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; + cpu_set_core(&cpu_data[0], + cpu_logical_map(0) % loongson_sysconf.cores_per_package); cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; } @@ -697,7 +698,7 @@ void play_dead(void) static int loongson3_disable_clock(unsigned int cpu) { - uint64_t core_id = cpu_data[cpu].core; + uint64_t core_id = cpu_core(&cpu_data[cpu]); uint64_t package_id = cpu_data[cpu].package; if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { @@ -711,7 +712,7 @@ static int loongson3_disable_clock(unsigned int cpu) static int loongson3_enable_clock(unsigned int cpu) { - uint64_t core_id = cpu_data[cpu].core; + uint64_t core_id = cpu_core(&cpu_data[cpu]); uint64_t package_id = cpu_data[cpu].package; if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index eac3f2950b14..615027863f54 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -122,7 +122,7 @@ static void nlm_init_secondary(void) int hwtid; hwtid = hard_smp_processor_id(); - current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; + cpu_set_core(¤t_cpu_data, hwtid / NLM_THREADS_PER_CORE); current_cpu_data.package = nlm_nodeid(); nlm_percpu_init(hwtid); nlm_smp_irq_init(hwtid); diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index c57da6f13929..c3e4c18ef8d4 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -38,9 +38,9 @@ static int perfcount_irq; #ifdef CONFIG_MIPS_MT_SMP static int cpu_has_mipsmt_pertccounters; #define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \ - M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) + M_PERFCTL_VPEID(cpu_vpe_id(¤t_cpu_data))) #define vpe_id() (cpu_has_mipsmt_pertccounters ? \ - 0 : cpu_data[smp_processor_id()].vpe_id) + 0 : cpu_vpe_id(¤t_cpu_data)) /* * The number of bits to shift to convert between counters per core and diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c index 12b9145913de..6041b6104f3d 100644 --- a/drivers/cpuidle/cpuidle-cps.c +++ b/drivers/cpuidle/cpuidle-cps.c @@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev, * TODO: don't treat core 0 specially, just prevent the final core * TODO: remap interrupt affinity temporarily */ - if (!cpu_data[dev->cpu].core && (index > STATE_NC_WAIT)) + if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT)) index = STATE_NC_WAIT; /* Select the appropriate cps_pm_state */ -- cgit v1.2.3 From d595d423d06071bd7a4892c3c2f16bfe1d5b3a85 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sat, 12 Aug 2017 19:49:40 -0700 Subject: MIPS: SMP: Allow boot_secondary SMP op to return errors Allow the boot_secondary SMP op to return an error to __cpu_up(), which will in turn return it to its caller. This will allow SMP implementations to return errors quickly in cases they they know have failed, rather than relying upon __cpu_up() eventually timing out waiting for the cpu_running completion. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/17014/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/smp.c | 8 ++++++-- arch/mips/include/asm/smp-ops.h | 2 +- arch/mips/kernel/smp-bmips.c | 4 +++- arch/mips/kernel/smp-cmp.c | 3 ++- arch/mips/kernel/smp-cps.c | 3 ++- arch/mips/kernel/smp-mt.c | 4 +++- arch/mips/kernel/smp-up.c | 3 ++- arch/mips/kernel/smp.c | 6 +++++- arch/mips/loongson64/loongson-3/smp.c | 3 ++- arch/mips/netlogic/common/smp.c | 4 +++- arch/mips/paravirt/paravirt-smp.c | 3 ++- arch/mips/sgi-ip27/ip27-smp.c | 3 ++- arch/mips/sibyte/bcm1480/smp.c | 3 ++- arch/mips/sibyte/sb1250/smp.c | 3 ++- 14 files changed, 37 insertions(+), 15 deletions(-) (limited to 'arch/mips/netlogic') diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 163663a5363d..75e7c8625659 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -205,7 +205,7 @@ int plat_post_relocation(long offset) * Firmware CPU startup hook * */ -static void octeon_boot_secondary(int cpu, struct task_struct *idle) +static int octeon_boot_secondary(int cpu, struct task_struct *idle) { int count; @@ -223,8 +223,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle) udelay(1); count--; } - if (count == 0) + if (count == 0) { pr_err("Secondary boot timeout\n"); + return -ETIMEDOUT; + } + + return 0; } /** diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h index 38859e7b1f1f..e5f49dd453c7 100644 --- a/arch/mips/include/asm/smp-ops.h +++ b/arch/mips/include/asm/smp-ops.h @@ -26,7 +26,7 @@ struct plat_smp_ops { void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action); void (*init_secondary)(void); void (*smp_finish)(void); - void (*boot_secondary)(int cpu, struct task_struct *idle); + int (*boot_secondary)(int cpu, struct task_struct *idle); void (*smp_setup)(void); void (*prepare_cpus)(unsigned int max_cpus); #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 4ac576c68034..406072e26752 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -179,7 +179,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus) /* * Tell the hardware to boot CPUx - runs on CPU0 */ -static void bmips_boot_secondary(int cpu, struct task_struct *idle) +static int bmips_boot_secondary(int cpu, struct task_struct *idle) { bmips_smp_boot_sp = __KSTK_TOS(idle); bmips_smp_boot_gp = (unsigned long)task_thread_info(idle); @@ -231,6 +231,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) } cpumask_set_cpu(cpu, &bmips_booted_mask); } + + return 0; } /* diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index 1acffdee88f4..04b21deea4f2 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c @@ -78,7 +78,7 @@ static void cmp_smp_finish(void) * __KSTK_TOS(idle) is apparently the stack pointer * (unsigned long)idle->thread_info the gp */ -static void cmp_boot_secondary(int cpu, struct task_struct *idle) +static int cmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); @@ -95,6 +95,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle) #endif amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); + return 0; } /* diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 7aac84ffc2af..4a4a25c722f1 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -288,7 +288,7 @@ static void remote_vpe_boot(void *dummy) mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); } -static void cps_boot_secondary(int cpu, struct task_struct *idle) +static int cps_boot_secondary(int cpu, struct task_struct *idle) { unsigned core = cpu_core(&cpu_data[cpu]); unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); @@ -346,6 +346,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) mips_cps_boot_vpes(core_cfg, vpe_id); out: preempt_enable(); + return 0; } static void cps_init_secondary(void) diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 5a7b5857d083..30415a74f312 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -152,7 +152,7 @@ static void vsmp_smp_finish(void) * (unsigned long)idle->thread_info the gp * assumes a 1:1 mapping of TC => VPE */ -static void vsmp_boot_secondary(int cpu, struct task_struct *idle) +static int vsmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); dvpe(); @@ -184,6 +184,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle) clear_c0_mvpcontrol(MVPCONTROL_VPC); evpe(EVPE_ENABLE); + + return 0; } /* diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c index 4cf015a624d1..525d3196f793 100644 --- a/arch/mips/kernel/smp-up.c +++ b/arch/mips/kernel/smp-up.c @@ -39,8 +39,9 @@ static void up_smp_finish(void) /* * Firmware CPU startup hook */ -static void up_boot_secondary(int cpu, struct task_struct *idle) +static int up_boot_secondary(int cpu, struct task_struct *idle) { + return 0; } static void __init up_smp_setup(void) diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 6248a5a3ec9e..a4a59ed0164c 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -439,7 +439,11 @@ void smp_prepare_boot_cpu(void) int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - mp_ops->boot_secondary(cpu, tidle); + int err; + + err = mp_ops->boot_secondary(cpu, tidle); + if (err) + return err; /* * We must check for timeout here, as the CPU will not be marked diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index bde64b0f1e47..8501109bb0f0 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -400,7 +400,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus) /* * Setup the PC, SP, and GP of a secondary processor and start it runing! */ -static void loongson3_boot_secondary(int cpu, struct task_struct *idle) +static int loongson3_boot_secondary(int cpu, struct task_struct *idle) { unsigned long startargs[4]; @@ -423,6 +423,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); + return 0; } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index 615027863f54..39a300bd6cc2 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -147,7 +147,7 @@ unsigned long nlm_next_gp; unsigned long nlm_next_sp; static cpumask_t phys_cpu_present_mask; -void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) +int nlm_boot_secondary(int logical_cpu, struct task_struct *idle) { uint64_t picbase; int hwtid; @@ -161,6 +161,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) /* barrier for sp/gp store above */ __sync(); nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */ + + return 0; } void __init nlm_smp_setup(void) diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c index b61b26ccf601..107d9f90d668 100644 --- a/arch/mips/paravirt/paravirt-smp.c +++ b/arch/mips/paravirt/paravirt-smp.c @@ -100,11 +100,12 @@ static void paravirt_smp_finish(void) local_irq_enable(); } -static void paravirt_boot_secondary(int cpu, struct task_struct *idle) +static int paravirt_boot_secondary(int cpu, struct task_struct *idle) { paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle); smp_wmb(); paravirt_smp_sp[cpu] = __KSTK_TOS(idle); + return 0; } static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id) diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index 85ee974a1582..545446dfe7fa 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c @@ -195,7 +195,7 @@ static void ip27_smp_finish(void) * set sp to the kernel stack of the newly created idle process, gp to the proc * struct so that current_thread_info() will work. */ -static void ip27_boot_secondary(int cpu, struct task_struct *idle) +static int ip27_boot_secondary(int cpu, struct task_struct *idle) { unsigned long gp = (unsigned long)task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); @@ -203,6 +203,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle) LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), 0, (void *) sp, (void *) gp); + return 0; } static void __init ip27_smp_setup(void) diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index 20091d5fe5a1..90c9d1255ad7 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c @@ -117,7 +117,7 @@ static void bcm1480_smp_finish(void) * Setup the PC, SP, and GP of a secondary processor and start it * running! */ -static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) +static int bcm1480_boot_secondary(int cpu, struct task_struct *idle) { int retval; @@ -126,6 +126,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return retval; } /* diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index 46ce1298c27d..5baabca52f25 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c @@ -106,7 +106,7 @@ static void sb1250_smp_finish(void) * Setup the PC, SP, and GP of a secondary processor and start it * running! */ -static void sb1250_boot_secondary(int cpu, struct task_struct *idle) +static int sb1250_boot_secondary(int cpu, struct task_struct *idle) { int retval; @@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return retval; } /* -- cgit v1.2.3