public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives
@ 2025-12-30  9:37 FUJITA Tomonori
  2025-12-30  9:37 ` [PATCH v1 1/3] rust: revocable: " FUJITA Tomonori
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: FUJITA Tomonori @ 2025-12-30  9:37 UTC (permalink / raw)
  To: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	boqun.feng
  Cc: a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

Convert uses of core::sync::atomic to Rust LKMM atomics.

Each patch can be applied independently, but all of them depend on the
atomic bool series.

https://lore.kernel.org/all/20251230045028.1773445-1-fujita.tomonori@gmail.com/


FUJITA Tomonori (3):
  rust: revocable: Switch to kernel::sync atomic primitives
  rust: list: Switch to kernel::sync atomic primitives
  rust_binder: Switch to kernel::sync atomic primitives

 drivers/android/binder/rust_binder_main.rs | 20 ++++++++----------
 drivers/android/binder/stats.rs            |  8 ++++----
 drivers/android/binder/thread.rs           | 24 ++++++++++------------
 drivers/android/binder/transaction.rs      | 16 +++++++--------
 rust/kernel/list/arc.rs                    | 14 ++++++-------
 rust/kernel/revocable.rs                   | 24 ++++++++++++++--------
 6 files changed, 54 insertions(+), 52 deletions(-)


base-commit: d4cd35bacb06d53acf39ff248ea2b3eef50573f6
-- 
2.43.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives FUJITA Tomonori
@ 2025-12-30  9:37 ` FUJITA Tomonori
  2025-12-30 23:29   ` Boqun Feng
  2025-12-31 10:54   ` Alice Ryhl
  2025-12-30  9:37 ` [PATCH v1 2/3] rust: list: " FUJITA Tomonori
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 14+ messages in thread
From: FUJITA Tomonori @ 2025-12-30  9:37 UTC (permalink / raw)
  To: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	boqun.feng
  Cc: a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

Convert uses of `AtomicBool` to `Atomic<bool>`.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/revocable.rs | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs
index 0f4ae673256d..47cd2b45eada 100644
--- a/rust/kernel/revocable.rs
+++ b/rust/kernel/revocable.rs
@@ -7,12 +7,20 @@
 
 use pin_init::Wrapper;
 
-use crate::{bindings, prelude::*, sync::rcu, types::Opaque};
+use crate::{
+    bindings,
+    prelude::*,
+    sync::atomic::{
+        ordering::Relaxed,
+        Atomic, //
+    },
+    sync::rcu,
+    types::Opaque, //
+};
 use core::{
     marker::PhantomData,
     ops::Deref,
-    ptr::drop_in_place,
-    sync::atomic::{AtomicBool, Ordering},
+    ptr::drop_in_place, //
 };
 
 /// An object that can become inaccessible at runtime.
@@ -65,7 +73,7 @@
 /// ```
 #[pin_data(PinnedDrop)]
 pub struct Revocable<T> {
-    is_available: AtomicBool,
+    is_available: Atomic<bool>,
     #[pin]
     data: Opaque<T>,
 }
@@ -84,7 +92,7 @@ impl<T> Revocable<T> {
     /// Creates a new revocable instance of the given data.
     pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, E> {
         try_pin_init!(Self {
-            is_available: AtomicBool::new(true),
+            is_available: Atomic::new(true),
             data <- Opaque::pin_init(data),
         }? E)
     }
@@ -98,7 +106,7 @@ pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, E> {
     /// because another CPU may be waiting to complete the revocation of this object.
     pub fn try_access(&self) -> Option<RevocableGuard<'_, T>> {
         let guard = rcu::read_lock();
-        if self.is_available.load(Ordering::Relaxed) {
+        if self.is_available.load(Relaxed) {
             // Since `self.is_available` is true, data is initialised and has to remain valid
             // because the RCU read side lock prevents it from being dropped.
             Some(RevocableGuard::new(self.data.get(), guard))
@@ -116,7 +124,7 @@ pub fn try_access(&self) -> Option<RevocableGuard<'_, T>> {
     /// allowed to sleep because another CPU may be waiting to complete the revocation of this
     /// object.
     pub fn try_access_with_guard<'a>(&'a self, _guard: &'a rcu::Guard) -> Option<&'a T> {
-        if self.is_available.load(Ordering::Relaxed) {
+        if self.is_available.load(Relaxed) {
             // SAFETY: Since `self.is_available` is true, data is initialised and has to remain
             // valid because the RCU read side lock prevents it from being dropped.
             Some(unsafe { &*self.data.get() })
@@ -157,7 +165,7 @@ pub unsafe fn access(&self) -> &T {
     ///
     /// Callers must ensure that there are no more concurrent users of the revocable object.
     unsafe fn revoke_internal<const SYNC: bool>(&self) -> bool {
-        let revoke = self.is_available.swap(false, Ordering::Relaxed);
+        let revoke = self.is_available.xchg(false, Relaxed);
 
         if revoke {
             if SYNC {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v1 2/3] rust: list: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives FUJITA Tomonori
  2025-12-30  9:37 ` [PATCH v1 1/3] rust: revocable: " FUJITA Tomonori
@ 2025-12-30  9:37 ` FUJITA Tomonori
  2025-12-31 10:53   ` Alice Ryhl
  2025-12-30  9:37 ` [PATCH v1 3/3] rust_binder: " FUJITA Tomonori
  2026-01-05 13:34 ` [PATCH v1 0/3] rust: " Boqun Feng
  3 siblings, 1 reply; 14+ messages in thread
From: FUJITA Tomonori @ 2025-12-30  9:37 UTC (permalink / raw)
  To: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	boqun.feng
  Cc: a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

Convert uses of `AtomicBool` to `Atomic<bool>`.

Note that the compare_exchange migration simplifies to
`try_cmpxchg()`, since `try_cmpxchg()` provides relaxed ordering on
failure, making the explicit failure ordering unnecessary.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/kernel/list/arc.rs | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/rust/kernel/list/arc.rs b/rust/kernel/list/arc.rs
index d92bcf665c89..2282f33913ee 100644
--- a/rust/kernel/list/arc.rs
+++ b/rust/kernel/list/arc.rs
@@ -6,11 +6,11 @@
 
 use crate::alloc::{AllocError, Flags};
 use crate::prelude::*;
+use crate::sync::atomic::{ordering, Atomic};
 use crate::sync::{Arc, ArcBorrow, UniqueArc};
 use core::marker::PhantomPinned;
 use core::ops::Deref;
 use core::pin::Pin;
-use core::sync::atomic::{AtomicBool, Ordering};
 
 /// Declares that this type has some way to ensure that there is exactly one `ListArc` instance for
 /// this id.
@@ -469,7 +469,7 @@ impl<T, U, const ID: u64> core::ops::DispatchFromDyn<ListArc<U, ID>> for ListArc
 /// If the boolean is `false`, then there is no [`ListArc`] for this value.
 #[repr(transparent)]
 pub struct AtomicTracker<const ID: u64 = 0> {
-    inner: AtomicBool,
+    inner: Atomic<bool>,
     // This value needs to be pinned to justify the INVARIANT: comment in `AtomicTracker::new`.
     _pin: PhantomPinned,
 }
@@ -480,12 +480,12 @@ pub fn new() -> impl PinInit<Self> {
         // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will
         // not be constructed in an `Arc` that already has a `ListArc`.
         Self {
-            inner: AtomicBool::new(false),
+            inner: Atomic::new(false),
             _pin: PhantomPinned,
         }
     }
 
-    fn project_inner(self: Pin<&mut Self>) -> &mut AtomicBool {
+    fn project_inner(self: Pin<&mut Self>) -> &mut Atomic<bool> {
         // SAFETY: The `inner` field is not structurally pinned, so we may obtain a mutable
         // reference to it even if we only have a pinned reference to `self`.
         unsafe { &mut Pin::into_inner_unchecked(self).inner }
@@ -500,7 +500,7 @@ unsafe fn on_create_list_arc_from_unique(self: Pin<&mut Self>) {
 
     unsafe fn on_drop_list_arc(&self) {
         // INVARIANT: We just dropped a ListArc, so the boolean should be false.
-        self.inner.store(false, Ordering::Release);
+        self.inner.store(false, ordering::Release);
     }
 }
 
@@ -514,8 +514,6 @@ unsafe impl<const ID: u64> TryNewListArc<ID> for AtomicTracker<ID> {
     fn try_new_list_arc(&self) -> bool {
         // INVARIANT: If this method returns true, then the boolean used to be false, and is no
         // longer false, so it is okay for the caller to create a new [`ListArc`].
-        self.inner
-            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
-            .is_ok()
+        self.inner.cmpxchg(false, true, ordering::Acquire).is_ok()
     }
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v1 3/3] rust_binder: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives FUJITA Tomonori
  2025-12-30  9:37 ` [PATCH v1 1/3] rust: revocable: " FUJITA Tomonori
  2025-12-30  9:37 ` [PATCH v1 2/3] rust: list: " FUJITA Tomonori
@ 2025-12-30  9:37 ` FUJITA Tomonori
  2025-12-31 10:52   ` Alice Ryhl
  2026-01-05 13:34 ` [PATCH v1 0/3] rust: " Boqun Feng
  3 siblings, 1 reply; 14+ messages in thread
From: FUJITA Tomonori @ 2025-12-30  9:37 UTC (permalink / raw)
  To: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	boqun.feng
  Cc: a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

Convert uses of AtomicBool, AtomicUsize, and AtomicU32.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 drivers/android/binder/rust_binder_main.rs | 20 ++++++++----------
 drivers/android/binder/stats.rs            |  8 ++++----
 drivers/android/binder/thread.rs           | 24 ++++++++++------------
 drivers/android/binder/transaction.rs      | 16 +++++++--------
 4 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index c79a9e742240..47bfb114cabb 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -18,6 +18,7 @@
     prelude::*,
     seq_file::SeqFile,
     seq_print,
+    sync::atomic::{ordering::Relaxed, Atomic},
     sync::poll::PollTable,
     sync::Arc,
     task::Pid,
@@ -28,10 +29,7 @@
 
 use crate::{context::Context, page_range::Shrinker, process::Process, thread::Thread};
 
-use core::{
-    ptr::NonNull,
-    sync::atomic::{AtomicBool, AtomicUsize, Ordering},
-};
+use core::ptr::NonNull;
 
 mod allocation;
 mod context;
@@ -90,9 +88,9 @@ fn default() -> Self {
 }
 
 fn next_debug_id() -> usize {
-    static NEXT_DEBUG_ID: AtomicUsize = AtomicUsize::new(0);
+    static NEXT_DEBUG_ID: Atomic<usize> = Atomic::new(0);
 
-    NEXT_DEBUG_ID.fetch_add(1, Ordering::Relaxed)
+    NEXT_DEBUG_ID.fetch_add(1, Relaxed)
 }
 
 /// Provides a single place to write Binder return values via the
@@ -215,7 +213,7 @@ fn arc_pin_init(init: impl PinInit<T>) -> Result<DLArc<T>, kernel::error::Error>
 
 struct DeliverCode {
     code: u32,
-    skip: AtomicBool,
+    skip: Atomic<bool>,
 }
 
 kernel::list::impl_list_arc_safe! {
@@ -226,7 +224,7 @@ impl DeliverCode {
     fn new(code: u32) -> Self {
         Self {
             code,
-            skip: AtomicBool::new(false),
+            skip: Atomic::new(false),
         }
     }
 
@@ -235,7 +233,7 @@ fn new(code: u32) -> Self {
     /// This is used instead of removing it from the work list, since `LinkedList::remove` is
     /// unsafe, whereas this method is not.
     fn skip(&self) {
-        self.skip.store(true, Ordering::Relaxed);
+        self.skip.store(true, Relaxed);
     }
 }
 
@@ -245,7 +243,7 @@ fn do_work(
         _thread: &Thread,
         writer: &mut BinderReturnWriter<'_>,
     ) -> Result<bool> {
-        if !self.skip.load(Ordering::Relaxed) {
+        if !self.skip.load(Relaxed) {
             writer.write_code(self.code)?;
         }
         Ok(true)
@@ -259,7 +257,7 @@ fn should_sync_wakeup(&self) -> bool {
 
     fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
         seq_print!(m, "{}", prefix);
-        if self.skip.load(Ordering::Relaxed) {
+        if self.skip.load(Relaxed) {
             seq_print!(m, "(skipped) ");
         }
         if self.code == defs::BR_TRANSACTION_COMPLETE {
diff --git a/drivers/android/binder/stats.rs b/drivers/android/binder/stats.rs
index 037002651941..ab75e9561cbf 100644
--- a/drivers/android/binder/stats.rs
+++ b/drivers/android/binder/stats.rs
@@ -5,7 +5,7 @@
 //! Keep track of statistics for binder_logs.
 
 use crate::defs::*;
-use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
+use kernel::sync::atomic::{ordering::Relaxed, Atomic};
 use kernel::{ioctl::_IOC_NR, seq_file::SeqFile, seq_print};
 
 const BC_COUNT: usize = _IOC_NR(BC_REPLY_SG) as usize + 1;
@@ -14,14 +14,14 @@
 pub(crate) static GLOBAL_STATS: BinderStats = BinderStats::new();
 
 pub(crate) struct BinderStats {
-    bc: [AtomicU32; BC_COUNT],
-    br: [AtomicU32; BR_COUNT],
+    bc: [Atomic<u32>; BC_COUNT],
+    br: [Atomic<u32>; BR_COUNT],
 }
 
 impl BinderStats {
     pub(crate) const fn new() -> Self {
         #[expect(clippy::declare_interior_mutable_const)]
-        const ZERO: AtomicU32 = AtomicU32::new(0);
+        const ZERO: Atomic<u32> = Atomic::new(0);
 
         Self {
             bc: [ZERO; BC_COUNT],
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 1a8e6fdc0dc4..82264db06507 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -15,6 +15,7 @@
     security,
     seq_file::SeqFile,
     seq_print,
+    sync::atomic::{ordering::Relaxed, Atomic},
     sync::poll::{PollCondVar, PollTable},
     sync::{Arc, SpinLock},
     task::Task,
@@ -34,10 +35,7 @@
     BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverCode, DeliverToRead,
 };
 
-use core::{
-    mem::size_of,
-    sync::atomic::{AtomicU32, Ordering},
-};
+use core::mem::size_of;
 
 /// Stores the layout of the scatter-gather entries. This is used during the `translate_objects`
 /// call and is discarded when it returns.
@@ -273,8 +271,8 @@ struct InnerThread {
 impl InnerThread {
     fn new() -> Result<Self> {
         fn next_err_id() -> u32 {
-            static EE_ID: AtomicU32 = AtomicU32::new(0);
-            EE_ID.fetch_add(1, Ordering::Relaxed)
+            static EE_ID: Atomic<u32> = Atomic::new(0);
+            EE_ID.fetch_add(1, Relaxed)
         }
 
         Ok(Self {
@@ -1537,7 +1535,7 @@ pub(crate) fn release(self: &Arc<Self>) {
 
 #[pin_data]
 struct ThreadError {
-    error_code: AtomicU32,
+    error_code: Atomic<u32>,
     #[pin]
     links_track: AtomicTracker,
 }
@@ -1545,18 +1543,18 @@ struct ThreadError {
 impl ThreadError {
     fn try_new() -> Result<DArc<Self>> {
         DTRWrap::arc_pin_init(pin_init!(Self {
-            error_code: AtomicU32::new(BR_OK),
+            error_code: Atomic::new(BR_OK),
             links_track <- AtomicTracker::new(),
         }))
         .map(ListArc::into_arc)
     }
 
     fn set_error_code(&self, code: u32) {
-        self.error_code.store(code, Ordering::Relaxed);
+        self.error_code.store(code, Relaxed);
     }
 
     fn is_unused(&self) -> bool {
-        self.error_code.load(Ordering::Relaxed) == BR_OK
+        self.error_code.load(Relaxed) == BR_OK
     }
 }
 
@@ -1566,8 +1564,8 @@ fn do_work(
         _thread: &Thread,
         writer: &mut BinderReturnWriter<'_>,
     ) -> Result<bool> {
-        let code = self.error_code.load(Ordering::Relaxed);
-        self.error_code.store(BR_OK, Ordering::Relaxed);
+        let code = self.error_code.load(Relaxed);
+        self.error_code.store(BR_OK, Relaxed);
         writer.write_code(code)?;
         Ok(true)
     }
@@ -1583,7 +1581,7 @@ fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
             m,
             "{}transaction error: {}\n",
             prefix,
-            self.error_code.load(Ordering::Relaxed)
+            self.error_code.load(Relaxed)
         );
         Ok(())
     }
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index 4bd3c0e417eb..2273a8e9d01c 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -2,11 +2,11 @@
 
 // Copyright (C) 2025 Google LLC.
 
-use core::sync::atomic::{AtomicBool, Ordering};
 use kernel::{
     prelude::*,
     seq_file::SeqFile,
     seq_print,
+    sync::atomic::{ordering::Relaxed, Atomic},
     sync::{Arc, SpinLock},
     task::Kuid,
     time::{Instant, Monotonic},
@@ -33,7 +33,7 @@ pub(crate) struct Transaction {
     pub(crate) to: Arc<Process>,
     #[pin]
     allocation: SpinLock<Option<Allocation>>,
-    is_outstanding: AtomicBool,
+    is_outstanding: Atomic<bool>,
     code: u32,
     pub(crate) flags: u32,
     data_size: usize,
@@ -105,7 +105,7 @@ pub(crate) fn new(
             offsets_size: trd.offsets_size as _,
             data_address,
             allocation <- kernel::new_spinlock!(Some(alloc.success()), "Transaction::new"),
-            is_outstanding: AtomicBool::new(false),
+            is_outstanding: Atomic::new(false),
             txn_security_ctx_off,
             oneway_spam_detected,
             start_time: Instant::now(),
@@ -145,7 +145,7 @@ pub(crate) fn new_reply(
             offsets_size: trd.offsets_size as _,
             data_address: alloc.ptr,
             allocation <- kernel::new_spinlock!(Some(alloc.success()), "Transaction::new"),
-            is_outstanding: AtomicBool::new(false),
+            is_outstanding: Atomic::new(false),
             txn_security_ctx_off: None,
             oneway_spam_detected,
             start_time: Instant::now(),
@@ -215,8 +215,8 @@ pub(crate) fn find_from(&self, thread: &Thread) -> Option<&DArc<Transaction>> {
 
     pub(crate) fn set_outstanding(&self, to_process: &mut ProcessInner) {
         // No race because this method is only called once.
-        if !self.is_outstanding.load(Ordering::Relaxed) {
-            self.is_outstanding.store(true, Ordering::Relaxed);
+        if !self.is_outstanding.load(Relaxed) {
+            self.is_outstanding.store(true, Relaxed);
             to_process.add_outstanding_txn();
         }
     }
@@ -227,8 +227,8 @@ fn drop_outstanding_txn(&self) {
         // destructor, which is guaranteed to not race with any other operations on the
         // transaction. It also cannot race with `set_outstanding`, since submission happens
         // before delivery.
-        if self.is_outstanding.load(Ordering::Relaxed) {
-            self.is_outstanding.store(false, Ordering::Relaxed);
+        if self.is_outstanding.load(Relaxed) {
+            self.is_outstanding.store(false, Relaxed);
             self.to.drop_outstanding_txn();
         }
     }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 ` [PATCH v1 1/3] rust: revocable: " FUJITA Tomonori
@ 2025-12-30 23:29   ` Boqun Feng
  2025-12-31  9:35     ` FUJITA Tomonori
  2025-12-31 10:12     ` Alice Ryhl
  2025-12-31 10:54   ` Alice Ryhl
  1 sibling, 2 replies; 14+ messages in thread
From: Boqun Feng @ 2025-12-30 23:29 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Tue, Dec 30, 2025 at 06:37:16PM +0900, FUJITA Tomonori wrote:
> Convert uses of `AtomicBool` to `Atomic<bool>`.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
>  rust/kernel/revocable.rs | 24 ++++++++++++++++--------
>  1 file changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs
> index 0f4ae673256d..47cd2b45eada 100644
> --- a/rust/kernel/revocable.rs
> +++ b/rust/kernel/revocable.rs
> @@ -7,12 +7,20 @@
>  
>  use pin_init::Wrapper;
>  
> -use crate::{bindings, prelude::*, sync::rcu, types::Opaque};
> +use crate::{
> +    bindings,
> +    prelude::*,
> +    sync::atomic::{
> +        ordering::Relaxed,
> +        Atomic, //
> +    },
> +    sync::rcu,
> +    types::Opaque, //
> +};
>  use core::{
>      marker::PhantomData,
>      ops::Deref,
> -    ptr::drop_in_place,
> -    sync::atomic::{AtomicBool, Ordering},
> +    ptr::drop_in_place, //
>  };
>  
>  /// An object that can become inaccessible at runtime.
> @@ -65,7 +73,7 @@
>  /// ```
>  #[pin_data(PinnedDrop)]
>  pub struct Revocable<T> {
> -    is_available: AtomicBool,
> +    is_available: Atomic<bool>,
>      #[pin]
>      data: Opaque<T>,

I actually think we should use Atomic<i32> instead of Atomic<bool> here,
because in most of the cases `T` is a aligned to at least 4-bytes (e.g.
Devres uses a Revocable<IoMem>) And in that case, using Atomic<bool>
doesn't save extra memory but makes the xchg() operation slower on
architectures that don't support byte-wise RmW instructions (e.g.
riscv).

My rule of thumb for using Atomic<bool> is: when you really care about
the memory usage, and you can guarantee using Atomic<bool> is saving
memory. For a general "flag" usage, Atomic<bool> is not strictly better
than Atomic<i32> in most cases imo.

Regards,
Boqun

>  }
> @@ -84,7 +92,7 @@ impl<T> Revocable<T> {
>      /// Creates a new revocable instance of the given data.
>      pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, E> {
>          try_pin_init!(Self {
> -            is_available: AtomicBool::new(true),
> +            is_available: Atomic::new(true),
>              data <- Opaque::pin_init(data),
>          }? E)
>      }
> @@ -98,7 +106,7 @@ pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, E> {
>      /// because another CPU may be waiting to complete the revocation of this object.
>      pub fn try_access(&self) -> Option<RevocableGuard<'_, T>> {
>          let guard = rcu::read_lock();
> -        if self.is_available.load(Ordering::Relaxed) {
> +        if self.is_available.load(Relaxed) {
>              // Since `self.is_available` is true, data is initialised and has to remain valid
>              // because the RCU read side lock prevents it from being dropped.
>              Some(RevocableGuard::new(self.data.get(), guard))
> @@ -116,7 +124,7 @@ pub fn try_access(&self) -> Option<RevocableGuard<'_, T>> {
>      /// allowed to sleep because another CPU may be waiting to complete the revocation of this
>      /// object.
>      pub fn try_access_with_guard<'a>(&'a self, _guard: &'a rcu::Guard) -> Option<&'a T> {
> -        if self.is_available.load(Ordering::Relaxed) {
> +        if self.is_available.load(Relaxed) {
>              // SAFETY: Since `self.is_available` is true, data is initialised and has to remain
>              // valid because the RCU read side lock prevents it from being dropped.
>              Some(unsafe { &*self.data.get() })
> @@ -157,7 +165,7 @@ pub unsafe fn access(&self) -> &T {
>      ///
>      /// Callers must ensure that there are no more concurrent users of the revocable object.
>      unsafe fn revoke_internal<const SYNC: bool>(&self) -> bool {
> -        let revoke = self.is_available.swap(false, Ordering::Relaxed);
> +        let revoke = self.is_available.xchg(false, Relaxed);
>  
>          if revoke {
>              if SYNC {
> -- 
> 2.43.0
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-30 23:29   ` Boqun Feng
@ 2025-12-31  9:35     ` FUJITA Tomonori
  2025-12-31 23:41       ` Boqun Feng
  2026-01-01  4:34       ` Gary Guo
  2025-12-31 10:12     ` Alice Ryhl
  1 sibling, 2 replies; 14+ messages in thread
From: FUJITA Tomonori @ 2025-12-31  9:35 UTC (permalink / raw)
  To: boqun.feng
  Cc: fujita.tomonori, aliceryhl, arve, brauner, cmllamas, gregkh,
	ojeda, tkjos, a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Wed, 31 Dec 2025 07:29:17 +0800
Boqun Feng <boqun.feng@gmail.com> wrote:

>>  /// An object that can become inaccessible at runtime.
>> @@ -65,7 +73,7 @@
>>  /// ```
>>  #[pin_data(PinnedDrop)]
>>  pub struct Revocable<T> {
>> -    is_available: AtomicBool,
>> +    is_available: Atomic<bool>,
>>      #[pin]
>>      data: Opaque<T>,
> 
> I actually think we should use Atomic<i32> instead of Atomic<bool> here,
> because in most of the cases `T` is a aligned to at least 4-bytes (e.g.
> Devres uses a Revocable<IoMem>) And in that case, using Atomic<bool>
> doesn't save extra memory but makes the xchg() operation slower on
> architectures that don't support byte-wise RmW instructions (e.g.
> riscv).

I agree. Recent RISC-V support byte-wise swap instructions so this may
not appliy to them. Among the architectures currently supporting Rust,
perhaps only loongarch could have this issue.


> My rule of thumb for using Atomic<bool> is: when you really care about
> the memory usage, and you can guarantee using Atomic<bool> is saving
> memory. For a general "flag" usage, Atomic<bool> is not strictly better
> than Atomic<i32> in most cases imo.

I agree again.

Maybe we should provide an enum type with i32 representation to
express boolean values like Atomic<Flag>? That way, users could avoid
writing unsafe code:

unsafe impl AtomicType for Flag {
    type Repr = i32;
}


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-30 23:29   ` Boqun Feng
  2025-12-31  9:35     ` FUJITA Tomonori
@ 2025-12-31 10:12     ` Alice Ryhl
  2025-12-31 10:33       ` FUJITA Tomonori
  1 sibling, 1 reply; 14+ messages in thread
From: Alice Ryhl @ 2025-12-31 10:12 UTC (permalink / raw)
  To: Boqun Feng
  Cc: FUJITA Tomonori, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Wed, Dec 31, 2025 at 07:29:17AM +0800, Boqun Feng wrote:
> On Tue, Dec 30, 2025 at 06:37:16PM +0900, FUJITA Tomonori wrote:
> > Convert uses of `AtomicBool` to `Atomic<bool>`.
> > 
> > Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> > ---
> >  rust/kernel/revocable.rs | 24 ++++++++++++++++--------
> >  1 file changed, 16 insertions(+), 8 deletions(-)
> > 
> > diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs
> > index 0f4ae673256d..47cd2b45eada 100644
> > --- a/rust/kernel/revocable.rs
> > +++ b/rust/kernel/revocable.rs
> > @@ -7,12 +7,20 @@
> >  
> >  use pin_init::Wrapper;
> >  
> > -use crate::{bindings, prelude::*, sync::rcu, types::Opaque};
> > +use crate::{
> > +    bindings,
> > +    prelude::*,
> > +    sync::atomic::{
> > +        ordering::Relaxed,
> > +        Atomic, //
> > +    },
> > +    sync::rcu,
> > +    types::Opaque, //
> > +};
> >  use core::{
> >      marker::PhantomData,
> >      ops::Deref,
> > -    ptr::drop_in_place,
> > -    sync::atomic::{AtomicBool, Ordering},
> > +    ptr::drop_in_place, //
> >  };
> >  
> >  /// An object that can become inaccessible at runtime.
> > @@ -65,7 +73,7 @@
> >  /// ```
> >  #[pin_data(PinnedDrop)]
> >  pub struct Revocable<T> {
> > -    is_available: AtomicBool,
> > +    is_available: Atomic<bool>,
> >      #[pin]
> >      data: Opaque<T>,
> 
> I actually think we should use Atomic<i32> instead of Atomic<bool> here,
> because in most of the cases `T` is a aligned to at least 4-bytes (e.g.
> Devres uses a Revocable<IoMem>) And in that case, using Atomic<bool>
> doesn't save extra memory but makes the xchg() operation slower on
> architectures that don't support byte-wise RmW instructions (e.g.
> riscv).
> 
> My rule of thumb for using Atomic<bool> is: when you really care about
> the memory usage, and you can guarantee using Atomic<bool> is saving
> memory. For a general "flag" usage, Atomic<bool> is not strictly better
> than Atomic<i32> in most cases imo.

In Binder I believe we only use load/store with Atomic<bool>. Does it
matter in that case?

Alice

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-31 10:12     ` Alice Ryhl
@ 2025-12-31 10:33       ` FUJITA Tomonori
  0 siblings, 0 replies; 14+ messages in thread
From: FUJITA Tomonori @ 2025-12-31 10:33 UTC (permalink / raw)
  To: aliceryhl
  Cc: boqun.feng, fujita.tomonori, arve, brauner, cmllamas, gregkh,
	ojeda, tkjos, a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Wed, 31 Dec 2025 10:12:07 +0000
Alice Ryhl <aliceryhl@google.com> wrote:

> On Wed, Dec 31, 2025 at 07:29:17AM +0800, Boqun Feng wrote:
>> On Tue, Dec 30, 2025 at 06:37:16PM +0900, FUJITA Tomonori wrote:
>> > Convert uses of `AtomicBool` to `Atomic<bool>`.
>> > 
>> > Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
>> > ---
>> >  rust/kernel/revocable.rs | 24 ++++++++++++++++--------
>> >  1 file changed, 16 insertions(+), 8 deletions(-)
>> > 
>> > diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs
>> > index 0f4ae673256d..47cd2b45eada 100644
>> > --- a/rust/kernel/revocable.rs
>> > +++ b/rust/kernel/revocable.rs
>> > @@ -7,12 +7,20 @@
>> >  
>> >  use pin_init::Wrapper;
>> >  
>> > -use crate::{bindings, prelude::*, sync::rcu, types::Opaque};
>> > +use crate::{
>> > +    bindings,
>> > +    prelude::*,
>> > +    sync::atomic::{
>> > +        ordering::Relaxed,
>> > +        Atomic, //
>> > +    },
>> > +    sync::rcu,
>> > +    types::Opaque, //
>> > +};
>> >  use core::{
>> >      marker::PhantomData,
>> >      ops::Deref,
>> > -    ptr::drop_in_place,
>> > -    sync::atomic::{AtomicBool, Ordering},
>> > +    ptr::drop_in_place, //
>> >  };
>> >  
>> >  /// An object that can become inaccessible at runtime.
>> > @@ -65,7 +73,7 @@
>> >  /// ```
>> >  #[pin_data(PinnedDrop)]
>> >  pub struct Revocable<T> {
>> > -    is_available: AtomicBool,
>> > +    is_available: Atomic<bool>,
>> >      #[pin]
>> >      data: Opaque<T>,
>> 
>> I actually think we should use Atomic<i32> instead of Atomic<bool> here,
>> because in most of the cases `T` is a aligned to at least 4-bytes (e.g.
>> Devres uses a Revocable<IoMem>) And in that case, using Atomic<bool>
>> doesn't save extra memory but makes the xchg() operation slower on
>> architectures that don't support byte-wise RmW instructions (e.g.
>> riscv).
>> 
>> My rule of thumb for using Atomic<bool> is: when you really care about
>> the memory usage, and you can guarantee using Atomic<bool> is saving
>> memory. For a general "flag" usage, Atomic<bool> is not strictly better
>> than Atomic<i32> in most cases imo.
> 
> In Binder I believe we only use load/store with Atomic<bool>. Does it
> matter in that case?

In the case of Binder, since it only use load and store with
Atomic<bool>, the performance issue with xchg doesn't apply.

The concern is specifically about atomic read-modify-write operations
like xchg and cmpxchg, not simple atomic loads or stores.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] rust_binder: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 ` [PATCH v1 3/3] rust_binder: " FUJITA Tomonori
@ 2025-12-31 10:52   ` Alice Ryhl
  0 siblings, 0 replies; 14+ messages in thread
From: Alice Ryhl @ 2025-12-31 10:52 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: arve, brauner, cmllamas, gregkh, ojeda, tkjos, boqun.feng,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Tue, Dec 30, 2025 at 06:37:18PM +0900, FUJITA Tomonori wrote:
> Convert uses of AtomicBool, AtomicUsize, and AtomicU32.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>

Thanks

Acked-by: Alice Ryhl <aliceryhl@google.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 2/3] rust: list: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 ` [PATCH v1 2/3] rust: list: " FUJITA Tomonori
@ 2025-12-31 10:53   ` Alice Ryhl
  0 siblings, 0 replies; 14+ messages in thread
From: Alice Ryhl @ 2025-12-31 10:53 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: arve, brauner, cmllamas, gregkh, ojeda, tkjos, boqun.feng,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Tue, Dec 30, 2025 at 06:37:17PM +0900, FUJITA Tomonori wrote:
> Convert uses of `AtomicBool` to `Atomic<bool>`.
> 
> Note that the compare_exchange migration simplifies to
> `try_cmpxchg()`, since `try_cmpxchg()` provides relaxed ordering on
> failure, making the explicit failure ordering unnecessary.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>

Thanks.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 ` [PATCH v1 1/3] rust: revocable: " FUJITA Tomonori
  2025-12-30 23:29   ` Boqun Feng
@ 2025-12-31 10:54   ` Alice Ryhl
  1 sibling, 0 replies; 14+ messages in thread
From: Alice Ryhl @ 2025-12-31 10:54 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: arve, brauner, cmllamas, gregkh, ojeda, tkjos, boqun.feng,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Tue, Dec 30, 2025 at 06:37:16PM +0900, FUJITA Tomonori wrote:
> Convert uses of `AtomicBool` to `Atomic<bool>`.
> 
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>

With the comment about i32 vs bool addressed:
Reviewed-by: Alice Ryhl <aliceryhl@google.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-31  9:35     ` FUJITA Tomonori
@ 2025-12-31 23:41       ` Boqun Feng
  2026-01-01  4:34       ` Gary Guo
  1 sibling, 0 replies; 14+ messages in thread
From: Boqun Feng @ 2025-12-31 23:41 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Wed, Dec 31, 2025 at 06:35:02PM +0900, FUJITA Tomonori wrote:
> On Wed, 31 Dec 2025 07:29:17 +0800
> Boqun Feng <boqun.feng@gmail.com> wrote:
> 
> >>  /// An object that can become inaccessible at runtime.
> >> @@ -65,7 +73,7 @@
> >>  /// ```
> >>  #[pin_data(PinnedDrop)]
> >>  pub struct Revocable<T> {
> >> -    is_available: AtomicBool,
> >> +    is_available: Atomic<bool>,
> >>      #[pin]
> >>      data: Opaque<T>,
> > 
> > I actually think we should use Atomic<i32> instead of Atomic<bool> here,
> > because in most of the cases `T` is a aligned to at least 4-bytes (e.g.
> > Devres uses a Revocable<IoMem>) And in that case, using Atomic<bool>
> > doesn't save extra memory but makes the xchg() operation slower on
> > architectures that don't support byte-wise RmW instructions (e.g.
> > riscv).
> 
> I agree. Recent RISC-V support byte-wise swap instructions so this may
> not appliy to them. Among the architectures currently supporting Rust,
> perhaps only loongarch could have this issue.
> 
> 
> > My rule of thumb for using Atomic<bool> is: when you really care about
> > the memory usage, and you can guarantee using Atomic<bool> is saving
> > memory. For a general "flag" usage, Atomic<bool> is not strictly better
> > than Atomic<i32> in most cases imo.
> 
> I agree again.
> 
> Maybe we should provide an enum type with i32 representation to
> express boolean values like Atomic<Flag>? That way, users could avoid

Yes, that sounds good to me.

Regards,
Boqun

> writing unsafe code:
> 
> unsafe impl AtomicType for Flag {
>     type Repr = i32;
> }
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 1/3] rust: revocable: Switch to kernel::sync atomic primitives
  2025-12-31  9:35     ` FUJITA Tomonori
  2025-12-31 23:41       ` Boqun Feng
@ 2026-01-01  4:34       ` Gary Guo
  1 sibling, 0 replies; 14+ messages in thread
From: Gary Guo @ 2026-01-01  4:34 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: boqun.feng, aliceryhl, arve, brauner, cmllamas, gregkh, ojeda,
	tkjos, a.hindborg, bjorn3_gh, dakr, lossin, tmgross,
	rust-for-linux

On Wed, 31 Dec 2025 18:35:02 +0900 (JST)
FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:

> On Wed, 31 Dec 2025 07:29:17 +0800
> Boqun Feng <boqun.feng@gmail.com> wrote:
> 
> >>  /// An object that can become inaccessible at runtime.
> >> @@ -65,7 +73,7 @@
> >>  /// ```
> >>  #[pin_data(PinnedDrop)]
> >>  pub struct Revocable<T> {
> >> -    is_available: AtomicBool,
> >> +    is_available: Atomic<bool>,
> >>      #[pin]
> >>      data: Opaque<T>,  
> > 
> > I actually think we should use Atomic<i32> instead of Atomic<bool> here,
> > because in most of the cases `T` is a aligned to at least 4-bytes (e.g.
> > Devres uses a Revocable<IoMem>) And in that case, using Atomic<bool>
> > doesn't save extra memory but makes the xchg() operation slower on
> > architectures that don't support byte-wise RmW instructions (e.g.
> > riscv).  
> 
> I agree. Recent RISC-V support byte-wise swap instructions so this may
> not appliy to them. Among the architectures currently supporting Rust,
> perhaps only loongarch could have this issue.

The narrower atomic instructions are extensions and not part of the base
ISA. RISC-V arch use alternative mechanisms for this, but using the
mechanism has an overhead, let alone the hardwares that do not have the
extensions.

Best,
Gary

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives
  2025-12-30  9:37 [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives FUJITA Tomonori
                   ` (2 preceding siblings ...)
  2025-12-30  9:37 ` [PATCH v1 3/3] rust_binder: " FUJITA Tomonori
@ 2026-01-05 13:34 ` Boqun Feng
  3 siblings, 0 replies; 14+ messages in thread
From: Boqun Feng @ 2026-01-05 13:34 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: aliceryhl, arve, brauner, cmllamas, gregkh, ojeda, tkjos,
	a.hindborg, bjorn3_gh, dakr, gary, lossin, tmgross,
	rust-for-linux

On Tue, Dec 30, 2025 at 06:37:15PM +0900, FUJITA Tomonori wrote:
> Convert uses of core::sync::atomic to Rust LKMM atomics.
> 
> Each patch can be applied independently, but all of them depend on the
> atomic bool series.
> 
> https://lore.kernel.org/all/20251230045028.1773445-1-fujita.tomonori@gmail.com/
> 
> 
> FUJITA Tomonori (3):
>   rust: revocable: Switch to kernel::sync atomic primitives
>   rust: list: Switch to kernel::sync atomic primitives
>   rust_binder: Switch to kernel::sync atomic primitives
> 

I queued patch #2 and #3 with tags from Alice, thanks!

Regards,
Boqun

>  drivers/android/binder/rust_binder_main.rs | 20 ++++++++----------
>  drivers/android/binder/stats.rs            |  8 ++++----
>  drivers/android/binder/thread.rs           | 24 ++++++++++------------
>  drivers/android/binder/transaction.rs      | 16 +++++++--------
>  rust/kernel/list/arc.rs                    | 14 ++++++-------
>  rust/kernel/revocable.rs                   | 24 ++++++++++++++--------
>  6 files changed, 54 insertions(+), 52 deletions(-)
> 
> 
> base-commit: d4cd35bacb06d53acf39ff248ea2b3eef50573f6
> -- 
> 2.43.0
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-01-05 13:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-30  9:37 [PATCH v1 0/3] rust: Switch to kernel::sync atomic primitives FUJITA Tomonori
2025-12-30  9:37 ` [PATCH v1 1/3] rust: revocable: " FUJITA Tomonori
2025-12-30 23:29   ` Boqun Feng
2025-12-31  9:35     ` FUJITA Tomonori
2025-12-31 23:41       ` Boqun Feng
2026-01-01  4:34       ` Gary Guo
2025-12-31 10:12     ` Alice Ryhl
2025-12-31 10:33       ` FUJITA Tomonori
2025-12-31 10:54   ` Alice Ryhl
2025-12-30  9:37 ` [PATCH v1 2/3] rust: list: " FUJITA Tomonori
2025-12-31 10:53   ` Alice Ryhl
2025-12-30  9:37 ` [PATCH v1 3/3] rust_binder: " FUJITA Tomonori
2025-12-31 10:52   ` Alice Ryhl
2026-01-05 13:34 ` [PATCH v1 0/3] rust: " Boqun Feng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox