diff options
author | Anup Patel <apatel@ventanamicro.com> | 2024-03-15 19:55:23 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2024-04-05 17:48:23 +0530 |
commit | beb0cd177f10a6bdafd73aac19059fecf6a07a91 (patch) | |
tree | b54f4bd17bd293cb3e27c62ffdf3338571758937 /include | |
parent | f5375bc15e9f3e577dfc24f9095a3e37246a3fa3 (diff) | |
download | opensbi-beb0cd177f10a6bdafd73aac19059fecf6a07a91.zip opensbi-beb0cd177f10a6bdafd73aac19059fecf6a07a91.tar.gz opensbi-beb0cd177f10a6bdafd73aac19059fecf6a07a91.tar.bz2 |
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 <apatel@ventanamicro.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/sbi/riscv_barrier.h | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/include/sbi/riscv_barrier.h b/include/sbi/riscv_barrier.h index 1fba8b8..3d4a038 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 */ |