[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.