From: "Onur Özkan" <work@onurozkan.dev>
To: linux-kernel@vger.kernel.org
Cc: dakr@kernel.org, aliceryhl@google.com,
daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch,
dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
"Onur Özkan" <work@onurozkan.dev>,
"Deborah Brouwer" <deborah.brouwer@collabora.com>
Subject: [PATCH v1 RESEND 3/4] rust: add ordered workqueue wrapper
Date: Fri, 13 Mar 2026 12:16:43 +0300 [thread overview]
Message-ID: <20260313091646.16938-4-work@onurozkan.dev> (raw)
In-Reply-To: <20260313091646.16938-1-work@onurozkan.dev>
Add an owned OrderedQueue wrapper for alloc_ordered_workqueue() and
destroy_workqueue().
This gives Rust drivers a simple way to create and own an ordered
workqueue with automatic cleanup in Drop.
Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
rust/helpers/workqueue.c | 6 +++++
rust/kernel/workqueue.rs | 47 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/rust/helpers/workqueue.c b/rust/helpers/workqueue.c
index ce1c3a5b2150..7cd3b000a5b6 100644
--- a/rust/helpers/workqueue.c
+++ b/rust/helpers/workqueue.c
@@ -14,3 +14,9 @@ __rust_helper void rust_helper_init_work_with_key(struct work_struct *work,
INIT_LIST_HEAD(&work->entry);
work->func = func;
}
+
+__rust_helper struct workqueue_struct *
+rust_helper_alloc_ordered_workqueue(const char *name, unsigned int flags)
+{
+ return alloc_ordered_workqueue("%s", flags, name);
+}
diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
index 6acc7b5ba31c..d5aa61a5ef93 100644
--- a/rust/kernel/workqueue.rs
+++ b/rust/kernel/workqueue.rs
@@ -195,6 +195,7 @@
types::Opaque,
};
use core::marker::PhantomData;
+use core::ptr::NonNull;
/// Creates a [`Work`] initialiser with the given name and a newly-created lock class.
#[macro_export]
@@ -346,6 +347,52 @@ pub fn try_spawn<T: 'static + Send + FnOnce()>(
}
}
+/// A kernel work queue that allocates and owns an ordered `workqueue_struct`.
+///
+/// Unlike [`Queue`], [`OrderedQueue`] takes ownership of the underlying C
+/// workqueue and automatically destroys it when dropped.
+pub struct OrderedQueue(NonNull<bindings::workqueue_struct>);
+
+// SAFETY: Workqueue objects are thread-safe to share and use concurrently.
+unsafe impl Send for OrderedQueue {}
+// SAFETY: Workqueue objects are thread-safe to share and use concurrently.
+unsafe impl Sync for OrderedQueue {}
+
+impl OrderedQueue {
+ /// Allocates an ordered workqueue.
+ ///
+ /// It is equivalent to C's `alloc_ordered_workqueue()`.
+ pub fn new(name: &'static CStr, flags: u32) -> Result<Self> {
+ // SAFETY: `name` is a `&'static CStr`, guaranteeing a valid, null-terminated C
+ // string pointer for the duration of this call.
+ let ptr = unsafe { bindings::alloc_ordered_workqueue(name.as_char_ptr(), flags) };
+ let ptr = NonNull::new(ptr).ok_or(ENOMEM)?;
+ Ok(Self(ptr))
+ }
+
+ /// Enqueues a work item.
+ ///
+ /// This may fail if the work item is already enqueued in a workqueue.
+ ///
+ /// The work item will be submitted using `WORK_CPU_UNBOUND`.
+ pub fn enqueue<W, const ID: u64>(&self, w: W) -> W::EnqueueOutput
+ where
+ W: RawWorkItem<ID> + Send + 'static,
+ {
+ // SAFETY: `self.0` is valid while `self` is alive.
+ unsafe { Queue::from_raw(self.0.as_ptr()) }.enqueue(w)
+ }
+}
+
+impl Drop for OrderedQueue {
+ fn drop(&mut self) {
+ // SAFETY:
+ // - Pointer comes from `alloc_ordered_workqueue()` and is owned by `self`.
+ // - `OrderedQueue` does not expose delayed scheduling API.
+ unsafe { bindings::destroy_workqueue(self.0.as_ptr()) };
+ }
+}
+
/// A helper type used in [`try_spawn`].
///
/// [`try_spawn`]: Queue::try_spawn
--
2.51.2
next prev parent reply other threads:[~2026-03-13 9:24 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-13 9:16 [PATCH v1 RESEND 0/4] drm/tyr: implement GPU reset API Onur Özkan
2026-03-13 9:16 ` [PATCH v1 RESEND 1/4] drm/tyr: clear reset IRQ before soft reset Onur Özkan
2026-03-19 10:47 ` Boris Brezillon
2026-03-13 9:16 ` [PATCH v1 RESEND 2/4] rust: add Work::disable_sync Onur Özkan
2026-03-13 12:00 ` Alice Ryhl
2026-03-15 10:45 ` Onur Özkan
2026-03-13 9:16 ` Onur Özkan [this message]
2026-03-13 9:16 ` [PATCH v1 RESEND 4/4] drm/tyr: add GPU reset handling Onur Özkan
2026-03-13 14:56 ` Daniel Almeida
2026-03-15 10:44 ` Onur Özkan
2026-03-19 11:08 ` Boris Brezillon
2026-03-19 12:51 ` Onur Özkan
2026-03-13 9:52 ` [PATCH v1 RESEND 0/4] drm/tyr: implement GPU reset API Alice Ryhl
2026-03-13 11:12 ` Onur Özkan
2026-03-13 11:26 ` 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=20260313091646.16938-4-work@onurozkan.dev \
--to=work@onurozkan.dev \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=deborah.brouwer@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox