[PATCH v1 RESEND 2/4] rust: add Work::disable_sync

Onur Özkan posted 4 patches 3 weeks, 4 days ago
[PATCH v1 RESEND 2/4] rust: add Work::disable_sync
Posted by Onur Özkan 3 weeks, 4 days ago
Add Work::disable_sync() as a safe wrapper for disable_work_sync().

Drivers can use this during teardown to stop new queueing and wait for
queued or running work to finish before dropping related resources.

Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
 rust/kernel/workqueue.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
index 706e833e9702..6acc7b5ba31c 100644
--- a/rust/kernel/workqueue.rs
+++ b/rust/kernel/workqueue.rs
@@ -530,6 +530,21 @@ pub unsafe fn raw_get(ptr: *const Self) -> *mut bindings::work_struct {
         // the compiler does not complain that the `work` field is unused.
         unsafe { Opaque::cast_into(core::ptr::addr_of!((*ptr).work)) }
     }
+
+    /// Disables this work item and waits for queued/running executions to finish.
+    ///
+    /// # Safety
+    ///
+    /// Must be called from a sleepable context if the work was last queued on a non-BH
+    /// workqueue.
+    #[inline]
+    pub unsafe fn disable_sync(&self) {
+        let ptr: *const Self = self;
+        // SAFETY: `self` points to a valid initialized work.
+        let raw_work = unsafe { Self::raw_get(ptr) };
+        // SAFETY: `raw_work` is a valid embedded `work_struct`.
+        unsafe { bindings::disable_work_sync(raw_work) };
+    }
 }
 
 /// Declares that a type contains a [`Work<T, ID>`].
-- 
2.51.2

Re: [PATCH v1 RESEND 2/4] rust: add Work::disable_sync
Posted by Alice Ryhl 3 weeks, 4 days ago
On Fri, Mar 13, 2026 at 10:17 AM Onur Özkan <work@onurozkan.dev> wrote:
>
> Add Work::disable_sync() as a safe wrapper for disable_work_sync().
>
> Drivers can use this during teardown to stop new queueing and wait for
> queued or running work to finish before dropping related resources.
>
> Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
> Signed-off-by: Onur Özkan <work@onurozkan.dev>
> ---
>  rust/kernel/workqueue.rs | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> index 706e833e9702..6acc7b5ba31c 100644
> --- a/rust/kernel/workqueue.rs
> +++ b/rust/kernel/workqueue.rs
> @@ -530,6 +530,21 @@ pub unsafe fn raw_get(ptr: *const Self) -> *mut bindings::work_struct {
>          // the compiler does not complain that the `work` field is unused.
>          unsafe { Opaque::cast_into(core::ptr::addr_of!((*ptr).work)) }
>      }
> +
> +    /// Disables this work item and waits for queued/running executions to finish.
> +    ///
> +    /// # Safety
> +    ///
> +    /// Must be called from a sleepable context if the work was last queued on a non-BH
> +    /// workqueue.

We generally do not make functions unsafe just because they might sleep.

Alice
Re: [PATCH v1 RESEND 2/4] rust: add Work::disable_sync
Posted by Onur Özkan 3 weeks, 2 days ago
On Fri, 13 Mar 2026 13:00:13 +0100
Alice Ryhl <aliceryhl@google.com> wrote:

> On Fri, Mar 13, 2026 at 10:17 AM Onur Özkan <work@onurozkan.dev>
> wrote:
> >
> > Add Work::disable_sync() as a safe wrapper for disable_work_sync().
> >
> > Drivers can use this during teardown to stop new queueing and wait
> > for queued or running work to finish before dropping related
> > resources.
> >
> > Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com>
> > Signed-off-by: Onur Özkan <work@onurozkan.dev>
> > ---
> >  rust/kernel/workqueue.rs | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> >
> > diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> > index 706e833e9702..6acc7b5ba31c 100644
> > --- a/rust/kernel/workqueue.rs
> > +++ b/rust/kernel/workqueue.rs
> > @@ -530,6 +530,21 @@ pub unsafe fn raw_get(ptr: *const Self) ->
> > *mut bindings::work_struct { // the compiler does not complain that
> > the `work` field is unused. unsafe {
> > Opaque::cast_into(core::ptr::addr_of!((*ptr).work)) } }
> > +
> > +    /// Disables this work item and waits for queued/running
> > executions to finish.
> > +    ///
> > +    /// # Safety
> > +    ///
> > +    /// Must be called from a sleepable context if the work was
> > last queued on a non-BH
> > +    /// workqueue.
> 
> We generally do not make functions unsafe just because they might
> sleep.
> 
> Alice

I will convert that into a "# Note" in the next version.

Regards,
Onur