All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Hubbard <jhubbard@nvidia.com>
To: Danilo Krummrich <dakr@kernel.org>,
	tj@kernel.org, jiangshanlai@gmail.com, aliceryhl@google.com,
	ojeda@kernel.org, boqun@kernel.org, gary@garyguo.net,
	bjorn3_gh@protonmail.com, lossin@kernel.org,
	a.hindborg@kernel.org, tmgross@umich.edu,
	daniel.almeida@collabora.com, tamird@kernel.org,
	acourbot@nvidia.com, work@onurozkan.dev
Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	driver-core@lists.linux.dev
Subject: Re: [PATCH 6/7] rust: workqueue: add Work::cancel_work_sync()
Date: Thu, 6 Aug 2026 18:37:56 -0700	[thread overview]
Message-ID: <c5fae595-2407-42cf-8040-384699df537d@nvidia.com> (raw)
In-Reply-To: <20260804195248.665636-7-dakr@kernel.org>

On 8/4/26 12:52 PM, Danilo Krummrich wrote:
> Add a method to cancel a work item and wait for it to finish if it is
> currently running.
> 
> This will also be used by ScopedWork's destructor to synchronously
> cancel work before dropping borrowed data.
> 
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> ---
>  rust/kernel/workqueue/mod.rs | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/rust/kernel/workqueue/mod.rs b/rust/kernel/workqueue/mod.rs
> index 5de88c59b2e5..2b87f935712a 100644
> --- a/rust/kernel/workqueue/mod.rs
> +++ b/rust/kernel/workqueue/mod.rs
> @@ -585,6 +585,14 @@ 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)) }
>      }
> +
> +    /// Cancels the work item and waits for it to finish if it is running.
> +    ///
> +    /// Returns `true` if the work was pending, `false` otherwise.
> +    pub fn cancel_work_sync(&self) -> bool {
> +        // SAFETY: We have a reference to a valid, initialized Work, so the pointer is valid.
> +        unsafe { bindings::cancel_work_sync(Self::raw_get(self)) }
> +    }

This seems to expose a way for driver writers to leak work items,
doesn't it?

Previously, work items were either run, or failed to enqueue, and
both of those paths restored the Arc via Arc::from_raw().

But now with this new cancel_work_sync(), Arc::from_raw() never gets
called. So for example:

#[pin_data]
struct MyStruct {
    #[pin]
    work: Work<MyStruct>,
}

impl_has_work! {
    impl HasWork<Self> for MyStruct { self.work }
}

impl WorkItem for MyStruct {
    type Pointer = Arc<MyStruct>;

    fn run(_this: Arc<MyStruct>) {}
}

let obj = Arc::pin_init(
    pin_init!(MyStruct {
        work <- new_work!("MyStruct::work"),
    }),
    GFP_KERNEL,
)?;

// refcount 1 -> 2, and the workqueue owns the second one
let _ = workqueue::system_dfl().enqueue(obj.clone());

// takes it off the worklist, so run() never reclaims that reference
obj.work.cancel_work_sync();

// refcount 2 -> 1. MyStruct is never dropped.
drop(obj);

thanks,
-- 
John Hubbard


  reply	other threads:[~2026-08-07  1:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-04 19:52 [PATCH 0/7] workqueue OwnedQueue, ScopedQueue and ScopedWork Danilo Krummrich
2026-08-04 19:52 ` [PATCH 1/7] rust: workqueue: replace deprecated system_wq with system_{percpu,dfl}_wq Danilo Krummrich
2026-08-04 19:52 ` [PATCH 2/7] rust: workqueue: restrict delayed work to global wqs Danilo Krummrich
2026-08-04 19:52 ` [PATCH 3/7] rust: workqueue: create workqueue subdirectory Danilo Krummrich
2026-08-04 19:52 ` [PATCH 4/7] rust: workqueue: add creation of workqueues Danilo Krummrich
2026-08-04 19:52 ` [PATCH 5/7] rust: workqueue: add ScopedQueue for lifetime bound items Danilo Krummrich
2026-08-04 19:52 ` [PATCH 6/7] rust: workqueue: add Work::cancel_work_sync() Danilo Krummrich
2026-08-07  1:37   ` John Hubbard [this message]
2026-08-07 11:49     ` Danilo Krummrich
2026-08-07 19:31       ` John Hubbard
2026-08-07  7:51   ` Onur Özkan
2026-08-07 11:51     ` Danilo Krummrich
2026-08-04 19:52 ` [PATCH 7/7] rust: workqueue: add ScopedWork for non-'static work items Danilo Krummrich

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=c5fae595-2407-42cf-8040-384699df537d@nvidia.com \
    --to=jhubbard@nvidia.com \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=driver-core@lists.linux.dev \
    --cc=gary@garyguo.net \
    --cc=jiangshanlai@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tamird@kernel.org \
    --cc=tj@kernel.org \
    --cc=tmgross@umich.edu \
    --cc=work@onurozkan.dev \
    /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.