Unverified Commit 62ff2622 authored by Samuel Holland's avatar Samuel Holland Committed by Palmer Dabbelt
Browse files

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: default avatarSamuel Holland <samuel.holland@sifive.com>
Reviewed-by: default avatarConor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231121234736.3489608-4-samuel.holland@sifive.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 79093f3e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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 */
+5 −5
Original line number Diff line number Diff line
@@ -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();
}
+5 −7
Original line number Diff line number Diff line
@@ -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
		cpu_ops = &cpu_ops_sbi;
	}
#endif
		cpu_ops[cpuid] = &cpu_ops_spinwait;
}
+1 −1
Original line number Diff line number Diff line
@@ -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(;;)
+5 −8
Original line number Diff line number Diff line
@@ -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;
}