mirror of
https://github.com/torvalds/linux
synced 2026-07-22 10:10:47 +09:00
In the original sbi_cpu_is_stopped(), if rc doesn't equal to the
SBI_HSM_STATE_STOPPED, it will return rc to the caller directly. But
there is a hidden problem, the rc could be SBI_HSM_STATE_STARTED, if
so, this function will report cpu stopped while the cpu isn't really
stopped.
Furthermore, from the name of cpu_is_stopped(), it gives a sense the
return value is a bool type, true means the cpu is stopped, conversely
false means the cpu is not stopped.
Here change the return value type to bool and change the callers
accordingly. This could fix the above two issues.
Fixes: f1e58583b9 ("RISC-V: Support cpu hotplug")
Signed-off-by: Hui Wang <hui.wang@canonical.com>
Link: https://patch.msgid.link/20260413123515.48423-1-hui.wang@canonical.com
[pjw@kernel.org: cleaned up some of the pr_warn() messages]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
77 lines
1.5 KiB
C
77 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2020 Western Digital Corporation or its affiliates.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/err.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/cpuhotplug.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/sched/hotplug.h>
|
|
#include <asm/irq.h>
|
|
#include <asm/cpu_ops.h>
|
|
#include <asm/numa.h>
|
|
#include <asm/smp.h>
|
|
|
|
bool cpu_has_hotplug(unsigned int cpu)
|
|
{
|
|
if (cpu_ops->cpu_stop)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* __cpu_disable runs on the processor to be shutdown.
|
|
*/
|
|
int __cpu_disable(void)
|
|
{
|
|
unsigned int cpu = smp_processor_id();
|
|
|
|
if (!cpu_ops->cpu_stop)
|
|
return -EOPNOTSUPP;
|
|
|
|
remove_cpu_topology(cpu);
|
|
numa_remove_cpu(cpu);
|
|
set_cpu_online(cpu, false);
|
|
riscv_ipi_disable();
|
|
irq_migrate_all_off_this_cpu();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Called on the thread which is asking for a CPU to be shutdown, if the
|
|
* CPU reported dead to the hotplug core.
|
|
*/
|
|
void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu)
|
|
{
|
|
int ret = 0;
|
|
|
|
pr_notice("CPU%u: off\n", cpu);
|
|
|
|
clear_tasks_mm_cpumask(cpu);
|
|
/* Verify from the firmware if the cpu is really stopped*/
|
|
if (cpu_ops->cpu_is_stopped)
|
|
ret = cpu_ops->cpu_is_stopped(cpu);
|
|
if (!ret)
|
|
pr_warn("CPU%u may not have stopped\n", cpu);
|
|
}
|
|
|
|
/*
|
|
* Called from the idle thread for the CPU which has been shutdown.
|
|
*/
|
|
void __noreturn arch_cpu_idle_dead(void)
|
|
{
|
|
idle_task_exit();
|
|
|
|
cpuhp_ap_report_dead();
|
|
|
|
cpu_ops->cpu_stop();
|
|
/* It should never reach here */
|
|
BUG();
|
|
}
|