Unverified Commit 5634d9c2 authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

Merge patch series "riscv: CPU operations cleanup"

Samuel Holland <samuel.holland@sifive.com> says:

This series cleans up some duplicated and dead code around the RISC-V
CPU operations, that was copied from arm64 but is not needed here. The
result is a bit of memory savings and removal of a few SBI calls during
boot, with no functional change.

* b4-shazam-merge:
  riscv: Use the same CPU operations for all CPUs
  riscv: Remove unused members from struct cpu_operations
  riscv: Deduplicate code in setup_smp()

Link: https://lore.kernel.org/r/20231121234736.3489608-1-samuel.holland@sifive.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents b7b4e4d7 62ff2622
Loading
Loading
Loading
Loading
+2 −12
Original line number Diff line number Diff line
@@ -13,33 +13,23 @@
/**
 * struct cpu_operations - Callback operations for hotplugging CPUs.
 *
 * @name:		Name of the boot protocol.
 * @cpu_prepare:	Early one-time preparation step for a cpu. If there
 *			is a mechanism for doing so, tests whether it is
 *			possible to boot the given HART.
 * @cpu_start:		Boots a cpu into the kernel.
 * @cpu_disable:	Prepares a cpu to die. May fail for some
 *			mechanism-specific reason, which will cause the hot
 *			unplug to be aborted. Called from the cpu to be killed.
 * @cpu_stop:		Makes a cpu leave the kernel. Must not fail. Called from
 *			the cpu being stopped.
 * @cpu_is_stopped:	Ensures a cpu has left the kernel. Called from another
 *			cpu.
 */
struct cpu_operations {
	const char	*name;
	int		(*cpu_prepare)(unsigned int cpu);
	int		(*cpu_start)(unsigned int cpu,
				     struct task_struct *tidle);
#ifdef CONFIG_HOTPLUG_CPU
	int		(*cpu_disable)(unsigned int cpu);
	void		(*cpu_stop)(void);
	int		(*cpu_is_stopped)(unsigned int cpu);
#endif
};

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 */
+6 −13
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;
@@ -29,25 +29,18 @@ bool cpu_has_hotplug(unsigned int cpu)
 */
int __cpu_disable(void)
{
	int ret = 0;
	unsigned int cpu = smp_processor_id();

	if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_stop)
	if (!cpu_ops->cpu_stop)
		return -EOPNOTSUPP;

	if (cpu_ops[cpu]->cpu_disable)
		ret = cpu_ops[cpu]->cpu_disable(cpu);

	if (ret)
		return ret;

	remove_cpu_topology(cpu);
	numa_remove_cpu(cpu);
	set_cpu_online(cpu, false);
	riscv_ipi_disable();
	irq_migrate_all_off_this_cpu();

	return ret;
	return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
@@ -62,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);
}
@@ -77,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 −9
Original line number Diff line number Diff line
@@ -13,25 +13,21 @@
#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
const struct cpu_operations cpu_ops_spinwait = {
	.name		= "",
	.cpu_prepare	= NULL,
	.cpu_start	= NULL,
};
#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;
}
+0 −19
Original line number Diff line number Diff line
@@ -79,23 +79,7 @@ static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
	return sbi_hsm_hart_start(hartid, boot_addr, hsm_data);
}

static int sbi_cpu_prepare(unsigned int cpuid)
{
	if (!cpu_ops_sbi.cpu_start) {
		pr_err("cpu start method not defined for CPU [%d]\n", cpuid);
		return -ENODEV;
	}
	return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
static int sbi_cpu_disable(unsigned int cpuid)
{
	if (!cpu_ops_sbi.cpu_stop)
		return -EOPNOTSUPP;
	return 0;
}

static void sbi_cpu_stop(void)
{
	int ret;
@@ -118,11 +102,8 @@ static int sbi_cpu_is_stopped(unsigned int cpuid)
#endif

const struct cpu_operations cpu_ops_sbi = {
	.name		= "sbi",
	.cpu_prepare	= sbi_cpu_prepare,
	.cpu_start	= sbi_cpu_start,
#ifdef CONFIG_HOTPLUG_CPU
	.cpu_disable	= sbi_cpu_disable,
	.cpu_stop	= sbi_cpu_stop,
	.cpu_is_stopped	= sbi_cpu_is_stopped,
#endif
+0 −11
Original line number Diff line number Diff line
@@ -39,15 +39,6 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
	WRITE_ONCE(__cpu_spinwait_task_pointer[hartid], tidle);
}

static int spinwait_cpu_prepare(unsigned int cpuid)
{
	if (!cpu_ops_spinwait.cpu_start) {
		pr_err("cpu start method not defined for CPU [%d]\n", cpuid);
		return -ENODEV;
	}
	return 0;
}

static int spinwait_cpu_start(unsigned int cpuid, struct task_struct *tidle)
{
	/*
@@ -64,7 +55,5 @@ static int spinwait_cpu_start(unsigned int cpuid, struct task_struct *tidle)
}

const struct cpu_operations cpu_ops_spinwait = {
	.name		= "spinwait",
	.cpu_prepare	= spinwait_cpu_prepare,
	.cpu_start	= spinwait_cpu_start,
};
Loading