All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Hindborg <a.hindborg@kernel.org>
To: "Boqun Feng" <boqun.feng@gmail.com>
Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	lkmm@lists.linux.dev, linux-arch@vger.kernel.org,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Will Deacon" <will@kernel.org>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Viresh Kumar" <viresh.kumar@linaro.org>,
	"Lyude Paul" <lyude@redhat.com>, "Ingo Molnar" <mingo@kernel.org>,
	"Mitchell Levy" <levymitchell0@gmail.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Linus Torvalds" <torvalds@linux-foundation.org>,
	"Thomas Gleixner" <tglx@linutronix.de>
Subject: Re: [PATCH v5 06/10] rust: sync: atomic: Add the framework of arithmetic operations
Date: Thu, 26 Jun 2025 14:39:49 +0200	[thread overview]
Message-ID: <87qzz6znfu.fsf@kernel.org> (raw)
In-Reply-To: <20250618164934.19817-7-boqun.feng@gmail.com> (Boqun Feng's message of "Wed, 18 Jun 2025 09:49:30 -0700")

"Boqun Feng" <boqun.feng@gmail.com> writes:

> One important set of atomic operations is the arithmetic operations,
> i.e. add(), sub(), fetch_add(), add_return(), etc. However it may not
> make senses for all the types that `AllowAtomic` to have arithmetic
> operations, for example a `Foo(u32)` may not have a reasonable add() or
> sub(), plus subword types (`u8` and `u16`) currently don't have
> atomic arithmetic operations even on C side and might not have them in
> the future in Rust (because they are usually suboptimal on a few
> architecures). Therefore add a subtrait of `AllowAtomic` describing
> which types have and can do atomic arithemtic operations.
>
> A few things about this `AllowAtomicArithmetic` trait:
>
> * It has an associate type `Delta` instead of using
>   `AllowAllowAtomic::Repr` because, a `Bar(u32)` (whose `Repr` is `i32`)
>   may not wants an `add(&self, i32)`, but an `add(&self, u32)`.
>
> * `AtomicImpl` types already implement an `AtomicHasArithmeticOps`
>   trait, so add blanket implementation for them. In the future, `i8` and
>   `i16` may impl `AtomicImpl` but not `AtomicHasArithmeticOps` if
>   arithemtic operations are not available.
>
> Only add() and fetch_add() are added. The rest will be added in the
> future.
>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> ---
>  rust/kernel/sync/atomic/generic.rs | 101 +++++++++++++++++++++++++++++
>  1 file changed, 101 insertions(+)
>
> diff --git a/rust/kernel/sync/atomic/generic.rs b/rust/kernel/sync/atomic/generic.rs
> index bcdbeea45dd8..8c5bd90b2619 100644
> --- a/rust/kernel/sync/atomic/generic.rs
> +++ b/rust/kernel/sync/atomic/generic.rs
> @@ -57,6 +57,23 @@ fn from_repr(repr: Self::Repr) -> Self {
>      }
>  }
>
> +/// Atomics that allows arithmetic operations with an integer type.
> +pub trait AllowAtomicArithmetic: AllowAtomic {
> +    /// The delta types for arithmetic operations.
> +    type Delta;
> +
> +    /// Converts [`Self::Delta`] into the representation of the atomic type.
> +    fn delta_into_repr(d: Self::Delta) -> Self::Repr;
> +}
> +
> +impl<T: AtomicImpl + AtomicHasArithmeticOps> AllowAtomicArithmetic for T {
> +    type Delta = Self;
> +
> +    fn delta_into_repr(d: Self::Delta) -> Self::Repr {
> +        d
> +    }
> +}
> +
>  impl<T: AllowAtomic> Atomic<T> {
>      /// Creates a new atomic.
>      pub const fn new(v: T) -> Self {
> @@ -410,3 +427,87 @@ fn try_cmpxchg<Ordering: All>(&self, old: &mut T, new: T, _: Ordering) -> bool {
>          }
>      }
>  }
> +
> +impl<T: AllowAtomicArithmetic> Atomic<T>
> +where
> +    T::Repr: AtomicHasArithmeticOps,
> +{
> +    /// Atomic add.
> +    ///
> +    /// The addition is a wrapping addition.
> +    ///
> +    /// # Examples
> +    ///
> +    /// ```rust
> +    /// use kernel::sync::atomic::{Atomic, Relaxed};
> +    ///
> +    /// let x = Atomic::new(42);
> +    ///
> +    /// assert_eq!(42, x.load(Relaxed));
> +    ///
> +    /// x.add(12, Relaxed);
> +    ///
> +    /// assert_eq!(54, x.load(Relaxed));
> +    /// ```
> +    #[inline(always)]
> +    pub fn add<Ordering: RelaxedOnly>(&self, v: T::Delta, _: Ordering) {
> +        let v = T::delta_into_repr(v);
> +        let a = self.as_ptr().cast::<T::Repr>();
> +
> +        // SAFETY:
> +        // - For calling the atomic_add() function:
> +        //   - `self.as_ptr()` is a valid pointer, and per the safety requirement of `AllocAtomic`,

Typo, should be `AllowAtomic`.

> +        //      a `*mut T` is a valid `*mut T::Repr`. Therefore `a` is a valid pointer,
> +        //   - per the type invariants, the following atomic operation won't cause data races.
> +        // - For extra safety requirement of usage on pointers returned by `self.as_ptr():
> +        //   - atomic operations are used here.
> +        unsafe {
> +            T::Repr::atomic_add(a, v);
> +        }
> +    }
> +
> +    /// Atomic fetch and add.
> +    ///
> +    /// The addition is a wrapping addition.
> +    ///
> +    /// # Examples
> +    ///
> +    /// ```rust
> +    /// use kernel::sync::atomic::{Atomic, Acquire, Full, Relaxed};
> +    ///
> +    /// let x = Atomic::new(42);
> +    ///
> +    /// assert_eq!(42, x.load(Relaxed));
> +    ///
> +    /// assert_eq!(54, { x.fetch_add(12, Acquire); x.load(Relaxed) });
> +    ///
> +    /// let x = Atomic::new(42);
> +    ///
> +    /// assert_eq!(42, x.load(Relaxed));
> +    ///
> +    /// assert_eq!(54, { x.fetch_add(12, Full); x.load(Relaxed) } );
> +    /// ```
> +    #[inline(always)]
> +    pub fn fetch_add<Ordering: All>(&self, v: T::Delta, _: Ordering) -> T {
> +        let v = T::delta_into_repr(v);
> +        let a = self.as_ptr().cast::<T::Repr>();
> +
> +        // SAFETY:
> +        // - For calling the atomic_fetch_add*() function:
> +        //   - `self.as_ptr()` is a valid pointer, and per the safety requirement of `AllocAtomic`,

Typo, should be `AllowAtomic`.


Best regards,
Andreas Hindborg



  parent reply	other threads:[~2025-06-26 12:40 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-18 16:49 [PATCH v5 00/10] LKMM generic atomics in Rust Boqun Feng
2025-06-18 16:49 ` [PATCH v5 01/10] rust: Introduce atomic API helpers Boqun Feng
2025-06-26  8:44   ` Andreas Hindborg
2025-06-27 14:00     ` Boqun Feng
2025-06-18 16:49 ` [PATCH v5 02/10] rust: sync: Add basic atomic operation mapping framework Boqun Feng
2025-06-26  8:50   ` Andreas Hindborg
2025-06-26 10:17   ` Andreas Hindborg
2025-06-27 14:30     ` Boqun Feng
2025-06-18 16:49 ` [PATCH v5 03/10] rust: sync: atomic: Add ordering annotation types Boqun Feng
2025-06-19 10:31   ` Peter Zijlstra
2025-06-19 12:19     ` Alice Ryhl
2025-06-19 13:29     ` Boqun Feng
2025-06-19 14:32       ` Peter Zijlstra
2025-06-19 15:00         ` Boqun Feng
2025-06-19 15:10           ` Peter Zijlstra
2025-06-19 15:15             ` Boqun Feng
2025-06-19 18:04           ` Alan Stern
2025-06-21 11:18   ` Gary Guo
2025-06-23  2:48     ` Boqun Feng
2025-06-26 12:36   ` Andreas Hindborg
2025-06-27 14:34     ` Boqun Feng
2025-06-27 14:44       ` Boqun Feng
2025-06-18 16:49 ` [PATCH v5 04/10] rust: sync: atomic: Add generic atomics Boqun Feng
2025-06-21 11:32   ` Gary Guo
2025-06-23  5:19     ` Boqun Feng
2025-06-23 11:54       ` Benno Lossin
2025-06-23 12:58         ` Boqun Feng
2025-06-23 18:30       ` Gary Guo
2025-06-23 19:09         ` Boqun Feng
2025-06-23 23:27           ` Benno Lossin
2025-06-24 16:35             ` Boqun Feng
2025-06-26 13:54               ` Benno Lossin
2025-07-04 21:22                 ` Boqun Feng
2025-07-04 22:05                   ` Benno Lossin
2025-07-04 22:30                     ` Boqun Feng
2025-07-04 22:49                       ` Benno Lossin
2025-07-04 23:21                         ` Boqun Feng
2025-07-04 20:25           ` Boqun Feng
2025-07-04 20:45             ` Benno Lossin
2025-07-04 21:17               ` Boqun Feng
2025-07-04 22:38                 ` Benno Lossin
2025-07-04 23:21                   ` Boqun Feng
2025-07-05  8:04                     ` Benno Lossin
2025-07-05 15:38                       ` Boqun Feng
2025-07-05 21:43                         ` Benno Lossin
2025-06-26 12:15   ` Andreas Hindborg
2025-06-27 15:01     ` Boqun Feng
2025-06-30  9:52       ` Andreas Hindborg
2025-06-30 14:44         ` Alan Stern
2025-07-01  8:54           ` Andreas Hindborg
2025-07-01 14:50             ` Boqun Feng
2025-07-02  8:33               ` Andreas Hindborg
2025-06-18 16:49 ` [PATCH v5 05/10] rust: sync: atomic: Add atomic {cmp,}xchg operations Boqun Feng
2025-06-21 11:37   ` Gary Guo
2025-06-23  5:23     ` Boqun Feng
2025-06-26 13:12   ` Andreas Hindborg
2025-06-28  3:03     ` Boqun Feng
2025-06-30 10:16       ` Andreas Hindborg
2025-06-30 14:51         ` Alan Stern
2025-06-30 15:12           ` Boqun Feng
2025-06-27  8:58   ` Benno Lossin
2025-06-27 13:53     ` Boqun Feng
2025-06-28  6:12       ` Benno Lossin
2025-06-28  7:31         ` Boqun Feng
2025-06-28  8:00           ` Benno Lossin
2025-06-30 15:24             ` Boqun Feng
2025-06-30 15:27               ` Boqun Feng
2025-06-30 15:50               ` Benno Lossin
2025-06-18 16:49 ` [PATCH v5 06/10] rust: sync: atomic: Add the framework of arithmetic operations Boqun Feng
2025-06-21 11:41   ` Gary Guo
2025-06-26 12:39   ` Andreas Hindborg [this message]
2025-06-28  3:04     ` Boqun Feng
2025-06-18 16:49 ` [PATCH v5 07/10] rust: sync: atomic: Add Atomic<u{32,64}> Boqun Feng
2025-06-26 12:47   ` Andreas Hindborg
2025-06-18 16:49 ` [PATCH v5 08/10] rust: sync: atomic: Add Atomic<{usize,isize}> Boqun Feng
2025-06-26 12:49   ` Andreas Hindborg
2025-06-18 16:49 ` [PATCH v5 09/10] rust: sync: atomic: Add Atomic<*mut T> Boqun Feng
2025-06-18 16:49 ` [PATCH v5 10/10] rust: sync: Add memory barriers Boqun Feng
2025-06-26 13:36   ` Andreas Hindborg
2025-06-28  3:42     ` Boqun Feng
2025-06-30  9:54       ` Andreas Hindborg
2025-06-18 20:22 ` [PATCH v5 00/10] LKMM generic atomics in Rust Alice Ryhl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87qzz6znfu.fsf@kernel.org \
    --to=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=levymitchell0@gmail.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lkmm@lists.linux.dev \
    --cc=lossin@kernel.org \
    --cc=lyude@redhat.com \
    --cc=mark.rutland@arm.com \
    --cc=mingo@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tmgross@umich.edu \
    --cc=torvalds@linux-foundation.org \
    --cc=viresh.kumar@linaro.org \
    --cc=wedsonaf@gmail.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.