From nobody Tue Sep 29 13:20:16 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F2B238F65C; Fri, 7 Aug 2026 16:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786118746; cv=none; b=cyeaLCLjFHaSJvkwowrt3NkLie7ru9+Q+1OK6jLRMYCe1EMs1LKNHXxuXujPJVA04Y9pzEXYtXZ0Z1XEzJ+n9RUDEoycS7UOxfU8eDbrAKNcPdAqJCLEVbJNc3u1p/Q/As8V4suEQH440BC1cjXl0aKOAT6TDganMu2oYjcWu2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786118746; c=relaxed/simple; bh=lDxGYo9JptexjN4qdBgYT+hnyxgOqfTKKQ4Lpel4ltk=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=cVaa32k6Dw/FvRn+p2Ujzxob8+Z6Dk/Q6Vx87SH1K2YMY3kuncPdhfgVOSHV0zEIhYaIR4A/qkay9xjcnYTamg1QKXaWSASP1IXe5n7kxzH0hIFRIJT3f/w74INgJpCz87AcfYGfAPAeO7G27+jTxXaLsy+V/Z+yjNBQ9d2WqA0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=UCBVbYPf; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=yjTU3a78; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="UCBVbYPf"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="yjTU3a78" Date: Fri, 07 Aug 2026 16:05:40 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1786118741; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J2zIlBbtV0QCfgAnjrI4eLowFvVZh99dC3sfusHkRwA=; b=UCBVbYPfQvyUfvJaqt3Bv1nwYsTKu6VVL3vTHPK6Mpbf6uPR3zwB31yeZV9dPf3/aRVFsP LidWGZyTFducLqT0m+e7bxN97KBep/OQjNoVeScXZkyfgWzThn+SBWnXd6qgcjOLniYk65 PXE5oyjhOqEqyKh1cEKqJiYqE+WTGmSVFq6gNYS1umeN/0scdsGITT2kUS7ySh4/WazJmP 3G7KVW84pbsek5m4UlWKlB5d6Y8j/wzGJvdXSFj2oQo06TMpa0nbXhxwuPCj4d6sxqqY5g u9pwIVcVC84Fk/lHy0tiaWuGNPxI3/MMXgqyCXzugDPiv8ipphZGf2Sk0KfcPw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1786118741; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J2zIlBbtV0QCfgAnjrI4eLowFvVZh99dC3sfusHkRwA=; b=yjTU3a78AUkLgzTfZ2w4NBikfLfpjhSNeZ02nnuOy4PbVBCf8HiOimzcvWU0acYdcpoqBf KtBgfaMQb8Ac9aAw== From: "tip-bot2 for Gary Guo" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/core] rust: sync: Add generic memory barriers Cc: Gary Guo , Boqun Feng , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20260609-rust-barrier-v2-2-30fcc48e1cd0@garyguo.net> References: <20260609-rust-barrier-v2-2-30fcc48e1cd0@garyguo.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178611874012.708.17644517940419950258.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the locking/core branch of tip: Commit-ID: 72856afd33f2fa166c06f1536003e300e51ecf09 Gitweb: https://git.kernel.org/tip/72856afd33f2fa166c06f1536003e300e= 51ecf09 Author: Gary Guo AuthorDate: Tue, 09 Jun 2026 16:38:38 +01:00 Committer: Boqun Feng CommitterDate: Tue, 04 Aug 2026 05:52:54 -07:00 rust: sync: Add generic memory barriers Implement a generic interface for memory barriers (full system/DMA/SMP). The interface uses a parameter to force user to specify their intent with barriers. Provide `Read`, `Write`, `Full` orderings which map to the existing `rmb()`, `wmb()` and `mb()`. Generic is used here instead of providing individual standalone functions to reduce code duplication; for example, the `CONFIG_SMP` check in `smp_mb` is uniformly implemented for all SMP barriers. This could extend to `virt_mb`'s if they're introduced in the future. It would also make it easier if new ordering types are introduced in the future (e.g. `Acquire`, `Release`). Signed-off-by: Gary Guo Signed-off-by: Boqun Feng Link: https://patch.msgid.link/20260609-rust-barrier-v2-2-30fcc48e1cd0@gary= guo.net --- rust/kernel/sync/atomic/ordering.rs | 2 +- rust/kernel/sync/barrier.rs | 127 +++++++++++++++++++++------ 2 files changed, 100 insertions(+), 29 deletions(-) diff --git a/rust/kernel/sync/atomic/ordering.rs b/rust/kernel/sync/atomic/= ordering.rs index 3f103aa..c4e732e 100644 --- a/rust/kernel/sync/atomic/ordering.rs +++ b/rust/kernel/sync/atomic/ordering.rs @@ -15,7 +15,7 @@ //! - It provides ordering between the annotated operation and all the f= ollowing memory accesses. //! - It provides ordering between all the preceding memory accesses and= all the following memory //! accesses. -//! - All the orderings are the same strength as a full memory barrier (= i.e. `smp_mb()`). +//! - All the orderings are the same strength as a full memory barrier (= i.e. `smp_mb(Full)`). //! - [`Relaxed`] provides no ordering except the dependency orderings. De= pendency orderings are //! described in "DEPENDENCY RELATIONS" in [`LKMM`]'s [`explanation`]. //! diff --git a/rust/kernel/sync/barrier.rs b/rust/kernel/sync/barrier.rs index 8f2d435..1180695 100644 --- a/rust/kernel/sync/barrier.rs +++ b/rust/kernel/sync/barrier.rs @@ -7,6 +7,38 @@ //! //! [`LKMM`]: srctree/tools/memory-model/ =20 +#![expect(private_bounds, reason =3D "sealed implementation")] + +/// Memory barrier orderings. +/// +/// The semantics of these orderings follows the [`LKMM`] definitions and = rules. +/// +/// - [`Read`] provides ordering between preceding load operations and suc= ceeding load operations. +/// - [`Write`] provides ordering between preceding store operations and s= ucceeding store +/// operations. +/// - [`Full`] provides ordering between all the preceding memory accesses= and succeeding memory +/// accesses. +/// +/// [`LKMM`]: srctree/tools/memory-model/ +pub mod ordering { + pub use crate::sync::atomic::ordering::Full; + + /// The annotation type for read-read barrier ordering. + pub struct Read; + + /// The annotation type for write-write barrier ordering. + pub struct Write; +} + +pub use ordering::{ + Full, + Read, + Write, // +}; + +struct Smp; +struct Dma; + /// A compiler barrier. /// /// A barrier that prevents compiler from reordering memory accesses acros= s the barrier. @@ -19,43 +51,82 @@ pub(crate) fn barrier() { unsafe { core::arch::asm!("") }; } =20 -/// A full memory barrier. +trait MemoryBarrier { + fn run(); +} + +macro_rules! define_barrier { + ($([$flavour:ident])? $ordering:ident, $binding:ident) =3D> { + impl MemoryBarrier$(<$flavour>)? for $ordering { + #[inline] + fn run() { + // SAFETY: barrier methods are safe to call. + unsafe { bindings::$binding() }; + } + } + }; +} + +define_barrier!(Full, mb); +define_barrier!(Read, rmb); +define_barrier!(Write, wmb); +define_barrier!([Dma] Full, dma_mb); +define_barrier!([Dma] Read, dma_rmb); +define_barrier!([Dma] Write, dma_wmb); +define_barrier!([Smp] Full, smp_mb); +define_barrier!([Smp] Read, smp_rmb); +define_barrier!([Smp] Write, smp_wmb); + +/// Memory barrier. /// /// A barrier that prevents compiler and CPU from reordering memory access= es across the barrier. -#[inline(always)] -pub fn smp_mb() { - if cfg!(CONFIG_SMP) { - // SAFETY: `smp_mb()` is safe to call. - unsafe { bindings::smp_mb() }; - } else { - barrier(); - } +/// +/// The specific forms of reordering can be specified using the parameter. +/// - `mb(Read)` provides a read-read barrier. +/// - `mb(Write)` provides a write-write barrier. +/// - `mb(Full)` provides a full barrier. +/// +/// # Examples +/// +/// ``` +/// # use kernel::sync::barrier::*; +/// mb(Read); +/// mb(Write); +/// mb(Full); +/// ``` +#[inline] +#[doc(alias =3D "rmb")] +#[doc(alias =3D "wmb")] +pub fn mb(_: T) { + T::run() } =20 -/// A write-write memory barrier. +/// Memory barrier between CPUs. /// -/// A barrier that prevents compiler and CPU from reordering memory write = accesses across the -/// barrier. -#[inline(always)] -pub fn smp_wmb() { +/// A barrier that prevents compiler and CPU from reordering memory access= es across the barrier. +/// Does not prevent re-ordering with respect to other bus-mastering devic= es. +/// +/// See [`mb`] for usage. +#[inline] +#[doc(alias =3D "smp_rmb")] +#[doc(alias =3D "smp_wmb")] +pub fn smp_mb>(_: T) { if cfg!(CONFIG_SMP) { - // SAFETY: `smp_wmb()` is safe to call. - unsafe { bindings::smp_wmb() }; + T::run() } else { - barrier(); + barrier() } } =20 -/// A read-read memory barrier. +/// Memory barrier between local CPU and bus-mastering devices. /// -/// A barrier that prevents compiler and CPU from reordering memory read a= ccesses across the -/// barrier. -#[inline(always)] -pub fn smp_rmb() { - if cfg!(CONFIG_SMP) { - // SAFETY: `smp_rmb()` is safe to call. - unsafe { bindings::smp_rmb() }; - } else { - barrier(); - } +/// A barrier that prevents compiler and CPU from reordering memory access= es across the barrier. +/// Does not prevent re-ordering with respect to other CPUs. +/// +/// See [`mb`] for usage. +#[inline] +#[doc(alias =3D "dma_rmb")] +#[doc(alias =3D "dma_wmb")] +pub fn dma_mb>(_: T) { + T::run() }