riscv: Use the same CPU operations for all CPUs

RISC-V provides no binding (ACPI or DT) to describe per-cpu start/stop
operations, so cpu_set_ops() will always detect the same operations for
every CPU. Replace the cpu_ops array with a single pointer to save space
and reduce boot time.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231121234736.3489608-4-samuel.holland@sifive.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
Samuel Holland 2023-11-21 15:47:26 -08:00 committed by Palmer Dabbelt
parent 79093f3ec3
commit 62ff262227
No known key found for this signature in database
GPG Key ID: 2E1319F35FBB1889
5 changed files with 18 additions and 23 deletions

View File

@ -29,7 +29,7 @@ struct cpu_operations {
};
extern const struct cpu_operations cpu_ops_spinwait;
extern const struct cpu_operations *cpu_ops[NR_CPUS];
void __init cpu_set_ops(int cpu);
extern const struct cpu_operations *cpu_ops;
void __init cpu_set_ops(void);
#endif /* ifndef __ASM_CPU_OPS_H */

View File

@ -18,7 +18,7 @@
bool cpu_has_hotplug(unsigned int cpu)
{
if (cpu_ops[cpu]->cpu_stop)
if (cpu_ops->cpu_stop)
return true;
return false;
@ -31,7 +31,7 @@ int __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_stop)
if (!cpu_ops->cpu_stop)
return -EOPNOTSUPP;
remove_cpu_topology(cpu);
@ -55,8 +55,8 @@ void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu)
pr_notice("CPU%u: off\n", cpu);
/* Verify from the firmware if the cpu is really stopped*/
if (cpu_ops[cpu]->cpu_is_stopped)
ret = cpu_ops[cpu]->cpu_is_stopped(cpu);
if (cpu_ops->cpu_is_stopped)
ret = cpu_ops->cpu_is_stopped(cpu);
if (ret)
pr_warn("CPU%d may not have stopped: %d\n", cpu, ret);
}
@ -70,7 +70,7 @@ void __noreturn arch_cpu_idle_dead(void)
cpuhp_ap_report_dead();
cpu_ops[smp_processor_id()]->cpu_stop();
cpu_ops->cpu_stop();
/* It should never reach here */
BUG();
}

View File

@ -13,7 +13,7 @@
#include <asm/sbi.h>
#include <asm/smp.h>
const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init;
const struct cpu_operations *cpu_ops __ro_after_init = &cpu_ops_spinwait;
extern const struct cpu_operations cpu_ops_sbi;
#ifndef CONFIG_RISCV_BOOT_SPINWAIT
@ -22,14 +22,12 @@ const struct cpu_operations cpu_ops_spinwait = {
};
#endif
void __init cpu_set_ops(int cpuid)
void __init cpu_set_ops(void)
{
#if IS_ENABLED(CONFIG_RISCV_SBI)
if (sbi_probe_extension(SBI_EXT_HSM)) {
if (!cpuid)
pr_info("SBI HSM extension detected\n");
cpu_ops[cpuid] = &cpu_ops_sbi;
} else
pr_info("SBI HSM extension detected\n");
cpu_ops = &cpu_ops_sbi;
}
#endif
cpu_ops[cpuid] = &cpu_ops_spinwait;
}

View File

@ -81,7 +81,7 @@ static inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_has_hotplug(cpu))
cpu_ops[cpu]->cpu_stop();
cpu_ops->cpu_stop();
#endif
for(;;)

View File

@ -166,25 +166,22 @@ void __init setup_smp(void)
{
int cpuid;
cpu_set_ops(0);
cpu_set_ops();
if (acpi_disabled)
of_parse_and_init_cpus();
else
acpi_parse_and_init_cpus();
for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) {
if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) {
cpu_set_ops(cpuid);
for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++)
if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID)
set_cpu_possible(cpuid, true);
}
}
}
static int start_secondary_cpu(int cpu, struct task_struct *tidle)
{
if (cpu_ops[cpu]->cpu_start)
return cpu_ops[cpu]->cpu_start(cpu, tidle);
if (cpu_ops->cpu_start)
return cpu_ops->cpu_start(cpu, tidle);
return -EOPNOTSUPP;
}