[PATCH] riscv: cpu_ops_sbi: retry checking if CPU is stopped
Jimmy Ho <[email protected]>
| Newsgroups | org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Introduce a retry loop with a timeout to wait for the HSM state of the core being hotplugged down to properly transition to HSM_STATE_STOPPED. Suggested-by: Samuel Holland <[email protected]> Signed-off-by: Jimmy Ho <[email protected]> --- arch/riscv/kernel/cpu_ops_sbi.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c index ee6e4b5cc39e..41e577400591 100644 --- a/arch/riscv/kernel/cpu_ops_sbi.c +++ b/arch/riscv/kernel/cpu_ops_sbi.c @@ -5,6 +5,7 @@ * Copyright (c) 2020 Western Digital Corporation or its affiliates. */ +#include <linux/delay.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/sched/task_stack.h> @@ -87,8 +88,23 @@ static bool sbi_cpu_is_stopped(unsigned int cpuid) { int rc; unsigned long hartid = cpuid_to_hartid_map(cpuid); - - rc = sbi_hsm_hart_get_status(hartid); + unsigned long start, end; + + /* + * The core that is being hotplugged down might still + * be processing SBI ecall hotplug down. + * So, try again a few times. + */ + + start = jiffies; + end = start + msecs_to_jiffies(100); + do { + rc = sbi_hsm_hart_get_status(hartid); + if (rc == SBI_HSM_STATE_STOPPED) + break; + + usleep_range(100, 1000); + } while (time_before(jiffies, end)); if (rc != SBI_HSM_STATE_STOPPED) { pr_warn("HART%lu isn't stopped; status %d\n", hartid, rc); -- 2.43.7 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv