All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	rcu@vger.kernel.org
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Arve Hjønnevåg" <arve@android.com>,
	"Todd Kjos" <tkjos@android.com>,
	"Christian Brauner" <brauner@kernel.org>,
	"Carlos Llamas" <cmllamas@google.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	"Frederic Weisbecker" <frederic@kernel.org>,
	"Neeraj Upadhyay" <neeraj.upadhyay@kernel.org>,
	"Joel Fernandes" <joelagnelf@nvidia.com>,
	"Josh Triplett" <josh@joshtriplett.org>,
	"Uladzislau Rezki" <urezki@gmail.com>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>,
	"Lai Jiangshan" <jiangshanlai@gmail.com>,
	Zqiang <qiang.zhang@linux.dev>,
	"FUJITA Tomonori" <fujita.tomonori@gmail.com>,
	"Lyude Paul" <lyude@redhat.com>,
	"Thomas Gleixner" <tglx@kernel.org>,
	"Anna-Maria Behnsen" <anna-maria@linutronix.de>,
	"John Stultz" <jstultz@google.com>,
	"Stephen Boyd" <sboyd@kernel.org>,
	"Yury Norov (NVIDIA)" <yury.norov@gmail.com>,
	"Vitaly Wool" <vitaly.wool@konsulko.se>,
	"Tamir Duberstein" <tamird@kernel.org>,
	"Viresh Kumar" <viresh.kumar@linaro.org>,
	"Daniel Almeida" <daniel.almeida@collabora.com>,
	"Mitchell Levy" <levymitchell0@gmail.com>,
	"David Gow" <davidgow@google.com>,
	"Peter Novak" <seimun018r@gmail.com>,
	"José Expósito" <jose.exposito89@gmail.com>
Subject: [RFC PATCH 3/7] rust: workqueue: Add HasField support for Work
Date: Wed, 28 Jan 2026 13:53:26 -0800	[thread overview]
Message-ID: <20260128215330.58410-4-boqun.feng@gmail.com> (raw)
In-Reply-To: <20260128215330.58410-1-boqun.feng@gmail.com>

Implement `HasWork` via `HasField` so that manually impl_has_work!() is
no longer needed.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
---
 rust/kernel/workqueue.rs | 60 +++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 22 deletions(-)

diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
index 706e833e9702..2dcfd3eace39 100644
--- a/rust/kernel/workqueue.rs
+++ b/rust/kernel/workqueue.rs
@@ -34,19 +34,17 @@
 //!
 //! ```
 //! use kernel::sync::Arc;
-//! use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem};
+//! use kernel::workqueue::{self, new_work, Work, WorkItem};
 //!
+//! #[derive(HasField)]
 //! #[pin_data]
 //! struct MyStruct {
 //!     value: i32,
 //!     #[pin]
+//!     #[field]
 //!     work: Work<MyStruct>,
 //! }
 //!
-//! impl_has_work! {
-//!     impl HasWork<Self> for MyStruct { self.work }
-//! }
-//!
 //! impl MyStruct {
 //!     fn new(value: i32) -> Result<Arc<Self>> {
 //!         Arc::pin_init(pin_init!(MyStruct {
@@ -76,23 +74,21 @@
 //!
 //! ```
 //! use kernel::sync::Arc;
-//! use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem};
+//! use kernel::workqueue::{self, new_work, Work, WorkItem};
 //!
+//! #[derive(HasField)]
 //! #[pin_data]
 //! struct MyStruct {
 //!     value_1: i32,
 //!     value_2: i32,
 //!     #[pin]
+//!     #[field]
 //!     work_1: Work<MyStruct, 1>,
 //!     #[pin]
+//!     #[field]
 //!     work_2: Work<MyStruct, 2>,
 //! }
 //!
-//! impl_has_work! {
-//!     impl HasWork<Self, 1> for MyStruct { self.work_1 }
-//!     impl HasWork<Self, 2> for MyStruct { self.work_2 }
-//! }
-//!
 //! impl MyStruct {
 //!     fn new(value_1: i32, value_2: i32) -> Result<Arc<Self>> {
 //!         Arc::pin_init(pin_init!(MyStruct {
@@ -188,6 +184,11 @@
 use crate::{
     alloc::{AllocError, Flags},
     container_of,
+    field::{
+        Field,
+        HasField, //
+    },
+    macros::HasField,
     prelude::*,
     sync::Arc,
     sync::LockClassKey,
@@ -349,9 +350,11 @@ pub fn try_spawn<T: 'static + Send + FnOnce()>(
 /// A helper type used in [`try_spawn`].
 ///
 /// [`try_spawn`]: Queue::try_spawn
+#[derive(HasField)]
 #[pin_data]
 struct ClosureWork<T> {
     #[pin]
+    #[field]
     work: Work<ClosureWork<T>>,
     func: Option<T>,
 }
@@ -534,19 +537,17 @@ pub unsafe fn raw_get(ptr: *const Self) -> *mut bindings::work_struct {
 
 /// Declares that a type contains a [`Work<T, ID>`].
 ///
-/// The intended way of using this trait is via the [`impl_has_work!`] macro. You can use the macro
-/// like this:
+/// The intended way of using this trait is via the `#[derive(HasField)]` macro. You can use the
+/// macro like this:
 ///
-/// ```no_run
-/// use kernel::workqueue::{impl_has_work, Work};
+/// ```
+/// use kernel::workqueue::Work;
 ///
+/// #[derive(HasField)]
 /// struct MyWorkItem {
+///     #[field]
 ///     work_field: Work<MyWorkItem, 1>,
 /// }
-///
-/// impl_has_work! {
-///     impl HasWork<MyWorkItem, 1> for MyWorkItem { self.work_field }
-/// }
 /// ```
 ///
 /// Note that since the [`Work`] type is annotated with an id, you can have several `work_struct`
@@ -559,7 +560,6 @@ pub unsafe fn raw_get(ptr: *const Self) -> *mut bindings::work_struct {
 /// - `work_container_of(raw_get_work(ptr)) == ptr` for any `ptr: *mut Self`.
 /// - `raw_get_work(work_container_of(ptr)) == ptr` for any `ptr: *mut Work<T, ID>`.
 ///
-/// [`impl_has_work!`]: crate::impl_has_work
 /// [`raw_get_work`]: HasWork::raw_get_work
 /// [`work_container_of`]: HasWork::work_container_of
 pub unsafe trait HasWork<T, const ID: u64 = 0> {
@@ -627,8 +627,24 @@ unsafe fn work_container_of(
 }
 pub use impl_has_work;
 
-impl_has_work! {
-    impl{T} HasWork<Self> for ClosureWork<T> { self.work }
+impl<T, const ID: u64> Field<T> for Work<T, ID> {}
+
+/// SAFETY: Per the safety requirement of `HasField`, `raw_get_field()` and `field_container_of()`
+/// return valid pointers and are true inverses of each other, hence the implementation below
+/// fulfills `HasWork`'s safety requirement as well.
+unsafe impl<T: HasField<T, Work<T, ID>>, const ID: u64> HasWork<T, ID> for T {
+    #[inline]
+    unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID> {
+        // SAFETY: Per the function safety requirement, `ptr` is a valid pointer.
+        unsafe { <T as HasField<T, Work<T, ID>>>::raw_get_field(ptr) }
+    }
+
+    #[inline]
+    unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self {
+        // SAFETY: Per the function safety requirement, `ptr` is a valid pointer, and it points to
+        // a work field in struct `T`.
+        unsafe { <T as HasField<T, Work<T, ID>>>::field_container_of(ptr) }
+    }
 }
 
 /// Links for a delayed work item.
-- 
2.50.1 (Apple Git-155)


  parent reply	other threads:[~2026-01-28 23:24 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-28 21:53 [RFC PATCH 0/7] Introduce HasField infrastructure Boqun Feng
2026-01-28 21:53 ` [RFC PATCH 1/7] rust: types: Introduce HasField trait and derive macro Boqun Feng
2026-01-28 21:53 ` [RFC PATCH 2/7] rust: time: hrtimer: Make `HasField` a super-trait of `HasHrTimer` Boqun Feng
2026-01-28 21:53 ` Boqun Feng [this message]
2026-01-28 21:53 ` [RFC PATCH 4/7] drivers: android: binder: Replace `impl_has_work!` with `#[derive(HasField)]` Boqun Feng
2026-01-28 21:53 ` [RFC PATCH 5/7] rust: sync: Completion: " Boqun Feng
2026-01-28 21:53 ` [RFC PATCH 6/7] rust: work: Remove `impl_has_work!` Boqun Feng
2026-01-28 21:53 ` [RFC PATCH 7/7] rust: sync: rcu: Introduce RcuHead Boqun Feng
2026-02-04 14:20 ` [RFC PATCH 0/7] Introduce HasField infrastructure Gary Guo
2026-02-05 20:47   ` Boqun Feng
2026-02-17  1:21 ` Joel Fernandes
2026-02-27 15:00   ` Gary Guo

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=20260128215330.58410-4-boqun.feng@gmail.com \
    --to=boqun.feng@gmail.com \
    --cc=a.hindborg@kernel.org \
    --cc=aliceryhl@google.com \
    --cc=anna-maria@linutronix.de \
    --cc=arve@android.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=brauner@kernel.org \
    --cc=cmllamas@google.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=davidgow@google.com \
    --cc=frederic@kernel.org \
    --cc=fujita.tomonori@gmail.com \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jiangshanlai@gmail.com \
    --cc=joelagnelf@nvidia.com \
    --cc=jose.exposito89@gmail.com \
    --cc=josh@joshtriplett.org \
    --cc=jstultz@google.com \
    --cc=levymitchell0@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=lyude@redhat.com \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=neeraj.upadhyay@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=qiang.zhang@linux.dev \
    --cc=rcu@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=sboyd@kernel.org \
    --cc=seimun018r@gmail.com \
    --cc=tamird@kernel.org \
    --cc=tglx@kernel.org \
    --cc=tkjos@android.com \
    --cc=tmgross@umich.edu \
    --cc=urezki@gmail.com \
    --cc=viresh.kumar@linaro.org \
    --cc=vitaly.wool@konsulko.se \
    --cc=yury.norov@gmail.com \
    /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.