rust: revocable: use LKMM atomics instead of Rust atomics
PATCH 1/1 rust: revocable: use LKMM atomics instead of Rust atomics
From: Gary Guo <[email protected]>
Kernel code should use LKMM atomics. The existing code is AtomicBool with the need to use xchg, so convert it to AtomicFlag.
--- rust/kernel/revocable.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
rust/kernel/revocable.rs +18 -8
@@ -7,12 +7,22 @@use pin_init::Wrapper ; -use crate ::{bindings, prelude::*, sync::rcu, types::Opaque }; +use crate ::{ + bindings, + prelude::*, + sync::{ + atomic::{ +AtomicFlag , +Relaxed ,// + }, + 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.
@@ -66,7 +76,7 @@/// ``` #[pin_data( PinnedDrop )] pub struct Revocable <T > { - is_available:AtomicBool , + is_available:AtomicFlag ,#[pin] data:Opaque <T >, }
@@ -85,7 +95,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:AtomicFlag ::new (true ), data <-Opaque ::pin_init (data), }?E ) }
@@ -99,7 +109,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))
@@ -117,7 +127,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 <&'aT > { -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 () })
@@ -158,7 +168,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 {
base-commit: b8809969e1d7a591e0f49dd464a5d04b3cf02ab1
Signature · 1 line
2.54.0
Quoted 9 lines · On Thu, 16 Jul 2026 15:55:35 +0100 Gary Guo <[email protected]> wrote:
From: Gary Guo <[email protected]>
Kernel code should use LKMM atomics. The existing code is
AtomicBoolwith the need to usexchg, so convert it toAtomicFlag.Signed-off-by Gary Guo <[email protected]>--- rust/kernel/revocable.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
Quoted 7 lines · Gary Guo
From: Gary Guo <[email protected]>
Kernel code should use LKMM atomics. The existing code is
AtomicBoolwith the need to usexchg, so convert it toAtomicFlag.Signed-off-by Gary Guo <[email protected]>
Quoted 6 lines · Gary Guo
From: Gary Guo <[email protected]>
Kernel code should use LKMM atomics. The existing code is
AtomicBoolwith the need to usexchg, so convert it toAtomicFlag.Signed-off-by Gary Guo <[email protected]>
Queued it in rust-sync, thank you all!
Regards,
Boqun
Quoted 84 lines
--- rust/kernel/revocable.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)rust/kernel/revocable.rs +18
-8@@ -7,12 +7,22 @@use pin_init::Wrapper ; -use crate ::{bindings, prelude::*, sync::rcu, types::Opaque }; +use crate ::{ + bindings, + prelude::*, + sync::{ + atomic::{ +AtomicFlag , +Relaxed ,// + }, + 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. @@ -66,7 +76,7 @@/// ``` #[pin_data( PinnedDrop )] pub struct Revocable <T > { - is_available:AtomicBool , + is_available:AtomicFlag ,#[pin] data:Opaque <T >, }@@ -85,7 +95,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:AtomicFlag ::new (true ), data <-Opaque ::pin_init (data), }?E ) }@@ -99,7 +109,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))@@ -117,7 +127,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 <&'aT > { -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 () })@@ -158,7 +168,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 {base-commit:
b8809969e1d7a591e0f49dd464a5d04b3cf02ab1Signature · 1 line
2.54.0
[tip: locking/core] rust: revocable: Use LKMM atomics instead of Rust atomics
In reply to Gary GuoThe following commit has been merged into the locking/core branch of tip:
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 3f90c16d413b2f68407f1c5bb112a1b16ea35dc4 Gitweb: https://git.kernel.org/tip/3f90c16d413b2f68407f1c5bb112a1b16ea35dc4 Author: Gary Guo <[email protected]> AuthorDate: Thu, 16 Jul 2026 15:55:35 +01:00 Committer: Boqun Feng <[email protected]> CommitterDate: Tue, 04 Aug 2026 05:52:54 -07:00
rust: revocable: Use LKMM atomics instead of Rust atomics
Kernel code should use LKMM atomics. The existing code is AtomicBool with the need to use xchg, so convert it to AtomicFlag.
--- rust/kernel/revocable.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
rust/kernel/revocable.rs +13 -8
@@ -9,14 +9,19 @@ use pin_init::Wrapper;use crate ::{ prelude::*, - sync::rcu, + sync::{ + atomic::{ +AtomicFlag , +Relaxed ,// + }, + 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.
@@ -69,7 +74,7 @@ use core::{/// ``` #[pin_data( PinnedDrop )] pub struct Revocable <T > { - is_available:AtomicBool , + is_available:AtomicFlag ,#[pin] data:Opaque <T >, }
@@ -88,7 +93,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:AtomicFlag ::new (true ), data <-Opaque ::pin_init (data), }?E ) }
@@ -102,7 +107,7 @@ impl<T> Revocable<T> {/// 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))
@@ -120,7 +125,7 @@ impl<T> Revocable<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 <&'aT > { -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 () })
@@ -161,7 +166,7 @@ impl<T> Revocable<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 {