From beb0cd177f10a6bdafd73aac19059fecf6a07a91 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 15 Mar 2024 19:55:23 +0530 Subject: lib: sbi: Simplify wait_for_coldboot() implementation On QEMU virt machine with large number of HARTs, some of the HARTs randomly fail to come out of wait_for_coldboot() due to one of the following race-conditions: 1) Failing HARTs are not able to acquire the coldboot_lock and update the coldboot_hartmask in wait_for_coldboot() before the coldboot HART acquires the coldboot_lock and sends IPI in wake_coldboot_harts() hence the failing HARTs never receive IPI from the coldboot HART. 2) Failing HARTs acquire the coldbood_lock and update the coldboot_hartmask before coldboot HART does sbi_scratch_init() so the sbi_hartmask_set_hartid() does not update the coldboot_hartmask on the failing HARTs hence they never receive IPI from the coldboot HART. To address this, use a simple busy-loop in wait_for_coldboot() for polling on coldboot_done flag. Signed-off-by: Anup Patel --- include/sbi/riscv_barrier.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/sbi/riscv_barrier.h b/include/sbi/riscv_barrier.h index 1fba8b82..3d4a038c 100644 --- a/include/sbi/riscv_barrier.h +++ b/include/sbi/riscv_barrier.h @@ -40,7 +40,11 @@ #define smp_wmb() RISCV_FENCE(w,w) /* CPU relax for busy loop */ -#define cpu_relax() asm volatile ("" : : : "memory") +#define cpu_relax() \ +do { \ + unsigned long __t; \ + __asm__ __volatile__ ("div %0, %0, zero" : "=r" (__t)); \ +} while (0) /* clang-format on */ -- cgit v1.2.3