[PATCH] riscv: Avoid smp_mb__after_spinlock() fences on non-SMP
Davidlohr Bueso
dave at stgolabs.net
Fri Nov 6 06:28:57 PST 2026
ping?
On Sun, 18 Oct 2026, Davidlohr Bueso wrote:
>smp_mb__after_spinlock() is defined in asm/barrier.h, which
>linux/spinlock.h includes unconditionally, so non-SMP kernels get
>RISCV_FENCE(iorw, iorw) as well and emit a full fence.
>
>The other architectures that override it, arm64, csky, powerpc and
>xtensa, define it in asm/spinlock.h, which linux/spinlock.h only
>includes for CONFIG_SMP, so their non-SMP builds get the generic
>kcsan_mb() fallback. Move the riscv definition, the SMP fence is
>unchanged.
>
>Signed-off-by: Davidlohr Bueso <dave at stgolabs.net>
>---
> arch/riscv/include/asm/barrier.h | 27 ---------------------------
> arch/riscv/include/asm/spinlock.h | 27 +++++++++++++++++++++++++++
> 2 files changed, 27 insertions(+), 27 deletions(-)
>
>diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
>index 700ba3f922cb..2284473844d8 100644
>--- a/arch/riscv/include/asm/barrier.h
>+++ b/arch/riscv/include/asm/barrier.h
>@@ -24,33 +24,6 @@
> #define __smp_rmb() RISCV_FENCE(r, r)
> #define __smp_wmb() RISCV_FENCE(w, w)
>
>-/*
>- * This is a very specific barrier: it's currently only used in two places in
>- * the kernel, both in the scheduler. See include/linux/spinlock.h for the two
>- * orderings it guarantees, but the "critical section is RCsc" guarantee
>- * mandates a barrier on RISC-V. The sequence looks like:
>- *
>- * lr.aq lock
>- * sc lock <= LOCKED
>- * smp_mb__after_spinlock()
>- * // critical section
>- * lr lock
>- * sc.rl lock <= UNLOCKED
>- *
>- * The AQ/RL pair provides a RCpc critical section, but there's not really any
>- * way we can take advantage of that here because the ordering is only enforced
>- * on that one lock. Thus, we're just doing a full fence.
>- *
>- * Since we allow writeX to be called from preemptive regions we need at least
>- * an "o" in the predecessor set to ensure device writes are visible before the
>- * task is marked as available for scheduling on a new hart. While I don't see
>- * any concrete reason we need a full IO fence, it seems safer to just upgrade
>- * this in order to avoid any IO crossing a scheduling boundary. In both
>- * instances the scheduler pairs this with an mb(), so nothing is necessary on
>- * the new hart.
>- */
>-#define smp_mb__after_spinlock() RISCV_FENCE(iorw, iorw)
>-
> #define __smp_store_release(p, v) \
> do { \
> compiletime_assert_atomic_type(*p); \
>diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
>index 52f11bfd0079..54bd8db8eb4f 100644
>--- a/arch/riscv/include/asm/spinlock.h
>+++ b/arch/riscv/include/asm/spinlock.h
>@@ -3,6 +3,33 @@
> #ifndef __ASM_RISCV_SPINLOCK_H
> #define __ASM_RISCV_SPINLOCK_H
>
>+#include <asm/fence.h>
>+
>+/*
>+ * This is a very specific barrier. See include/linux/spinlock.h for the two
>+ * orderings it guarantees, but the "critical section is RCsc" guarantee
>+ * mandates a barrier on RISC-V. The sequence looks like:
>+ *
>+ * lr.aq lock
>+ * sc lock <= LOCKED
>+ * smp_mb__after_spinlock()
>+ * // critical section
>+ * lr lock
>+ * sc.rl lock <= UNLOCKED
>+ *
>+ * The AQ/RL pair provides a RCpc critical section, but there's not really any
>+ * way we can take advantage of that here because the ordering is only enforced
>+ * on that one lock. Thus, we're just doing a full fence.
>+ *
>+ * Since we allow writeX to be called from preemptive regions we need at least
>+ * an "o" in the predecessor set to ensure device writes are visible before the
>+ * task is marked as available for scheduling on a new hart. While I don't see
>+ * any concrete reason we need a full IO fence, it seems safer to just upgrade
>+ * this in order to avoid any IO crossing a scheduling boundary. The
>+ * scheduler pairs this with an mb(), so nothing is necessary on the new hart.
>+ */
>+#define smp_mb__after_spinlock() RISCV_FENCE(iorw, iorw)
>+
> #ifdef CONFIG_QUEUED_SPINLOCKS
> #define _Q_PENDING_LOOPS (1 << 9)
> #endif
>--
>2.39.5
>
>
>_______________________________________________
>linux-riscv mailing list
>linux-riscv at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-riscv
More information about the linux-riscv
mailing list