[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260128215330.58410-8-boqun.feng@gmail.com>
Date: Wed, 28 Jan 2026 13:53:30 -0800
From: Boqun Feng <boqun.feng@...il.com>
To: linux-kernel@...r.kernel.org,
rust-for-linux@...r.kernel.org,
rcu@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Arve Hjønnevåg <arve@...roid.com>,
Todd Kjos <tkjos@...roid.com>, Christian Brauner <brauner@...nel.org>,
Carlos Llamas <cmllamas@...gle.com>, Alice Ryhl <aliceryhl@...gle.com>,
Miguel Ojeda <ojeda@...nel.org>, Boqun Feng <boqun.feng@...il.com>,
Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>,
Andreas Hindborg <a.hindborg@...nel.org>,
Trevor Gross <tmgross@...ch.edu>, Danilo Krummrich <dakr@...nel.org>,
"Paul E. McKenney" <paulmck@...nel.org>,
Frederic Weisbecker <frederic@...nel.org>,
Neeraj Upadhyay <neeraj.upadhyay@...nel.org>,
Joel Fernandes <joelagnelf@...dia.com>,
Josh Triplett <josh@...htriplett.org>,
Uladzislau Rezki <urezki@...il.com>,
Steven Rostedt <rostedt@...dmis.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Lai Jiangshan <jiangshanlai@...il.com>, Zqiang <qiang.zhang@...ux.dev>,
FUJITA Tomonori <fujita.tomonori@...il.com>,
Lyude Paul <lyude@...hat.com>, Thomas Gleixner <tglx@...nel.org>,
Anna-Maria Behnsen <anna-maria@...utronix.de>,
John Stultz <jstultz@...gle.com>, Stephen Boyd <sboyd@...nel.org>,
"Yury Norov (NVIDIA)" <yury.norov@...il.com>,
Vitaly Wool <vitaly.wool@...sulko.se>,
Tamir Duberstein <tamird@...nel.org>,
Viresh Kumar <viresh.kumar@...aro.org>,
Daniel Almeida <daniel.almeida@...labora.com>,
Mitchell Levy <levymitchell0@...il.com>, David Gow <davidgow@...gle.com>,
Peter Novak <seimun018r@...il.com>,
José Expósito <jose.exposito89@...il.com>
Subject: [RFC PATCH 7/7] rust: sync: rcu: Introduce RcuHead
In order to support RCU delay free (call_rcu() and kfree_rcu()), the
abstraction of the `rcu_head` is introduced. Types that want to support
RCU delay free can specify a `RcuHead<T>` in it, e.g.
#[derive(HasField)]
struct Foo {
a: i32,
b: i32,
#[field]
rcu_head: RcuHead,
}
A wrapper `WithRcuHead<T>` is also provided for users that want to
specify a generic `T` with a rcu_head.
Signed-off-by: Boqun Feng <boqun.feng@...il.com>
---
rust/kernel/sync/rcu.rs | 69 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/sync/rcu.rs b/rust/kernel/sync/rcu.rs
index a32bef6e490b..694ca2f54953 100644
--- a/rust/kernel/sync/rcu.rs
+++ b/rust/kernel/sync/rcu.rs
@@ -4,7 +4,14 @@
//!
//! C header: [`include/linux/rcupdate.h`](srctree/include/linux/rcupdate.h)
-use crate::{bindings, types::NotThreadSafe};
+use crate::{
+ bindings,
+ field::{Field, HasField},
+ macros::HasField,
+ types::{NotThreadSafe, Opaque},
+};
+
+use core::ops::Deref;
/// Evidence that the RCU read side lock is held on the current thread/CPU.
///
@@ -50,3 +57,63 @@ fn drop(&mut self) {
pub fn read_lock() -> Guard {
Guard::new()
}
+
+/// RCU head for call backs.
+///
+/// # Examples
+///
+/// Use `#[derive(HasField)]` macro to specify a struct has a RCU head.
+///
+/// ```
+/// use kernel::sync::rcu::RcuHead;
+///
+/// #[derive(HasField)]
+/// struct Foo {
+/// a: i32,
+/// #[field]
+/// rcu_head: RcuHead,
+/// b: i32,
+/// }
+///
+/// const _: () = {
+/// const fn assert_has_field<T: HasField<T, RcuHead>>() { }
+/// assert_has_field::<Foo>();
+/// };
+/// ```
+#[repr(transparent)]
+pub struct RcuHead(Opaque<bindings::callback_head>);
+
+impl<T> Field<T> for RcuHead {}
+
+// SAFETY: `callback_head` doesn't hold anything local to the current execution context, so it's
+// safe to transfer to another execution context.
+unsafe impl Send for RcuHead {}
+// SAFETY: `callback_head` should only be used when it's in the destructor, and accesses to it are
+// already unsafe, hence make it `Sync`.
+unsafe impl Sync for RcuHead {}
+
+/// A wrapper that adds an `RcuHead` on `T`.
+#[derive(HasField)]
+pub struct WithRcuHead<T> {
+ #[field]
+ head: RcuHead,
+ data: T,
+}
+
+impl<T> WithRcuHead<T> {
+ /// Creates a new wrapper on `T` with `RcuHead`.
+ pub fn new(data: T) -> Self {
+ Self {
+ head: RcuHead(Opaque::zeroed()),
+ data,
+ }
+ }
+}
+
+impl<T> Deref for WithRcuHead<T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.data
+ }
+}
--
2.50.1 (Apple Git-155)
Powered by blists - more mailing lists