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 <[email protected]> Signed-off-by: Onur Özkan <[email protected]> --- 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
