* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 16:34 [RFC PATCH] rust: workqueue: Add an example for try_spawn() Boqun Feng
@ 2025-07-30 16:38 ` Miguel Ojeda
2025-07-30 18:48 ` Boqun Feng
2025-07-30 17:40 ` Joel Fernandes
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Miguel Ojeda @ 2025-07-30 16:38 UTC (permalink / raw)
To: Boqun Feng
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Tejun Heo, Tamir Duberstein,
Hamza Mahfooz, Alban Kurti, Joel Fernandes, Paul E. McKenney
On Wed, Jul 30, 2025 at 6:34 PM Boqun Feng <boqun.feng@gmail.com> wrote:
>
> Miguel, Alice and Tejun, while I'm at it, should we also rename the
> function to `spawn()` because of the motivation mentioned here [1]?
Sounds good to me.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 16:38 ` Miguel Ojeda
@ 2025-07-30 18:48 ` Boqun Feng
0 siblings, 0 replies; 10+ messages in thread
From: Boqun Feng @ 2025-07-30 18:48 UTC (permalink / raw)
To: Miguel Ojeda
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Tejun Heo, Tamir Duberstein,
Hamza Mahfooz, Alban Kurti, Joel Fernandes, Paul E. McKenney
On Wed, Jul 30, 2025 at 06:38:46PM +0200, Miguel Ojeda wrote:
> On Wed, Jul 30, 2025 at 6:34 PM Boqun Feng <boqun.feng@gmail.com> wrote:
> >
> > Miguel, Alice and Tejun, while I'm at it, should we also rename the
> > function to `spawn()` because of the motivation mentioned here [1]?
>
> Sounds good to me.
>
Thanks, I will add it in v2 (probably as a separate patch) if no one
shows any objection.
Regards,
Boqun
> Cheers,
> Miguel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 16:34 [RFC PATCH] rust: workqueue: Add an example for try_spawn() Boqun Feng
2025-07-30 16:38 ` Miguel Ojeda
@ 2025-07-30 17:40 ` Joel Fernandes
2025-07-30 19:28 ` Benno Lossin
2025-08-01 9:05 ` Alice Ryhl
3 siblings, 0 replies; 10+ messages in thread
From: Joel Fernandes @ 2025-07-30 17:40 UTC (permalink / raw)
To: Boqun Feng, rust-for-linux, linux-kernel
Cc: Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Tejun Heo, Tamir Duberstein, Hamza Mahfooz,
Alban Kurti, Paul E. McKenney
On 7/30/2025 12:34 PM, Boqun Feng wrote:
> `try_spawn()` could use an example to demonstrate the usage, and
> arguably it's the most simple usage of workqueue in case someone needs a
> deferred work, so add it.
>
> Cc: Joel Fernandes <joelagnelf@nvidia.com>
> Cc: "Paul E. McKenney" <paulmck@kernel.org>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Makes sense, LGTM.
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
thanks,
- Joel
> ---
> Miguel, Alice and Tejun, while I'm at it, should we also rename the
> function to `spawn()` because of the motivation mentioned here [1]?
>
> [1]: https://rust-for-linux.zulipchat.com/#narrow/channel/291566-Library/topic/.60new.60.20or.20.60try_new.60.3F/near/529533317
>
> Also I find the `{ <clone> || { } }` is really good if I only need to
> clone the Arc for passing to a callback closure, but I'm not sure how
> people feel about it, so criticism is welcome ;-)
>
> rust/kernel/workqueue.rs | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> index b9343d5bc00f..59c1a5e14d12 100644
> --- a/rust/kernel/workqueue.rs
> +++ b/rust/kernel/workqueue.rs
> @@ -331,6 +331,33 @@ pub fn enqueue_delayed<W, const ID: u64>(&self, w: W, delay: Jiffies) -> W::Enqu
> /// Tries to spawn the given function or closure as a work item.
> ///
> /// This method can fail because it allocates memory to store the work item.
> + ///
> + /// # Examples
> + ///
> + /// ```
> + /// use kernel::{alloc::flags, sync::{Arc, Completion, new_spinlock}, workqueue};
> + ///
> + /// let work_done = Arc::pin_init(Completion::new(), flags::GFP_KERNEL)?;
> + /// let data = Arc::pin_init(new_spinlock!(0), flags::GFP_KERNEL)?;
> + ///
> + /// workqueue::system().try_spawn(
> + /// flags::GFP_KERNEL,
> + /// {
> + /// let work_done = work_done.clone();
> + /// let data = data.clone();
> + /// move || {
> + /// *data.lock() = 42;
> + /// work_done.complete_all();
> + /// }
> + /// }
> + /// )?;
> + ///
> + /// work_done.wait_for_completion();
> + ///
> + /// // `work_done` being completed implies the observation of the write of `data` in the work.
> + /// assert_eq!(*data.lock(), 42);
> + /// # Ok::<(), Error>(())
> + /// ```
> pub fn try_spawn<T: 'static + Send + FnOnce()>(
> &self,
> flags: Flags,
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 16:34 [RFC PATCH] rust: workqueue: Add an example for try_spawn() Boqun Feng
2025-07-30 16:38 ` Miguel Ojeda
2025-07-30 17:40 ` Joel Fernandes
@ 2025-07-30 19:28 ` Benno Lossin
2025-07-30 19:38 ` Boqun Feng
2025-08-01 9:05 ` Alice Ryhl
3 siblings, 1 reply; 10+ messages in thread
From: Benno Lossin @ 2025-07-30 19:28 UTC (permalink / raw)
To: Boqun Feng, rust-for-linux, linux-kernel
Cc: Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
Tejun Heo, Tamir Duberstein, Hamza Mahfooz, Alban Kurti,
Joel Fernandes, Paul E. McKenney
On Wed Jul 30, 2025 at 6:34 PM CEST, Boqun Feng wrote:
> `try_spawn()` could use an example to demonstrate the usage, and
> arguably it's the most simple usage of workqueue in case someone needs a
> deferred work, so add it.
>
> Cc: Joel Fernandes <joelagnelf@nvidia.com>
> Cc: "Paul E. McKenney" <paulmck@kernel.org>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> ---
> Miguel, Alice and Tejun, while I'm at it, should we also rename the
> function to `spawn()` because of the motivation mentioned here [1]?
>
> [1]: https://rust-for-linux.zulipchat.com/#narrow/channel/291566-Library/topic/.60new.60.20or.20.60try_new.60.3F/near/529533317
>
> Also I find the `{ <clone> || { } }` is really good if I only need to
> clone the Arc for passing to a callback closure, but I'm not sure how
> people feel about it, so criticism is welcome ;-)
I'm not so sure, see below :)
> rust/kernel/workqueue.rs | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> index b9343d5bc00f..59c1a5e14d12 100644
> --- a/rust/kernel/workqueue.rs
> +++ b/rust/kernel/workqueue.rs
> @@ -331,6 +331,33 @@ pub fn enqueue_delayed<W, const ID: u64>(&self, w: W, delay: Jiffies) -> W::Enqu
> /// Tries to spawn the given function or closure as a work item.
> ///
> /// This method can fail because it allocates memory to store the work item.
> + ///
> + /// # Examples
> + ///
> + /// ```
> + /// use kernel::{alloc::flags, sync::{Arc, Completion, new_spinlock}, workqueue};
> + ///
> + /// let work_done = Arc::pin_init(Completion::new(), flags::GFP_KERNEL)?;
> + /// let data = Arc::pin_init(new_spinlock!(0), flags::GFP_KERNEL)?;
> + ///
> + /// workqueue::system().try_spawn(
> + /// flags::GFP_KERNEL,
> + /// {
> + /// let work_done = work_done.clone();
> + /// let data = data.clone();
> + /// move || {
> + /// *data.lock() = 42;
> + /// work_done.complete_all();
> + /// }
> + /// }
> + /// )?;
Not doing your pattern and instead adding a `2` postfix we get:
let work_done2 = work_done.clone();
let data2 = data.clone();
workqueue::system().try_spawn(flags::GFP_KERNEL, move || {
*data2.lock() = 42;
work_done2.complete_all();
})?;
There are some discussions of introducing some better syntax for (cheap)
cloning, so maybe we can use that in the future.
---
Cheers,
Benno
> + ///
> + /// work_done.wait_for_completion();
> + ///
> + /// // `work_done` being completed implies the observation of the write of `data` in the work.
> + /// assert_eq!(*data.lock(), 42);
> + /// # Ok::<(), Error>(())
> + /// ```
> pub fn try_spawn<T: 'static + Send + FnOnce()>(
> &self,
> flags: Flags,
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 19:28 ` Benno Lossin
@ 2025-07-30 19:38 ` Boqun Feng
2025-07-31 9:30 ` Benno Lossin
0 siblings, 1 reply; 10+ messages in thread
From: Boqun Feng @ 2025-07-30 19:38 UTC (permalink / raw)
To: Benno Lossin
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Tejun Heo, Tamir Duberstein, Hamza Mahfooz,
Alban Kurti, Joel Fernandes, Paul E. McKenney
On Wed, Jul 30, 2025 at 09:28:05PM +0200, Benno Lossin wrote:
> On Wed Jul 30, 2025 at 6:34 PM CEST, Boqun Feng wrote:
> > `try_spawn()` could use an example to demonstrate the usage, and
> > arguably it's the most simple usage of workqueue in case someone needs a
> > deferred work, so add it.
> >
> > Cc: Joel Fernandes <joelagnelf@nvidia.com>
> > Cc: "Paul E. McKenney" <paulmck@kernel.org>
> > Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> > ---
> > Miguel, Alice and Tejun, while I'm at it, should we also rename the
> > function to `spawn()` because of the motivation mentioned here [1]?
> >
> > [1]: https://rust-for-linux.zulipchat.com/#narrow/channel/291566-Library/topic/.60new.60.20or.20.60try_new.60.3F/near/529533317
> >
> > Also I find the `{ <clone> || { } }` is really good if I only need to
> > clone the Arc for passing to a callback closure, but I'm not sure how
> > people feel about it, so criticism is welcome ;-)
>
> I'm not so sure, see below :)
>
> > rust/kernel/workqueue.rs | 27 +++++++++++++++++++++++++++
> > 1 file changed, 27 insertions(+)
> >
> > diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> > index b9343d5bc00f..59c1a5e14d12 100644
> > --- a/rust/kernel/workqueue.rs
> > +++ b/rust/kernel/workqueue.rs
> > @@ -331,6 +331,33 @@ pub fn enqueue_delayed<W, const ID: u64>(&self, w: W, delay: Jiffies) -> W::Enqu
> > /// Tries to spawn the given function or closure as a work item.
> > ///
> > /// This method can fail because it allocates memory to store the work item.
> > + ///
> > + /// # Examples
> > + ///
> > + /// ```
> > + /// use kernel::{alloc::flags, sync::{Arc, Completion, new_spinlock}, workqueue};
> > + ///
> > + /// let work_done = Arc::pin_init(Completion::new(), flags::GFP_KERNEL)?;
> > + /// let data = Arc::pin_init(new_spinlock!(0), flags::GFP_KERNEL)?;
> > + ///
> > + /// workqueue::system().try_spawn(
> > + /// flags::GFP_KERNEL,
> > + /// {
> > + /// let work_done = work_done.clone();
> > + /// let data = data.clone();
> > + /// move || {
> > + /// *data.lock() = 42;
> > + /// work_done.complete_all();
> > + /// }
> > + /// }
> > + /// )?;
>
> Not doing your pattern and instead adding a `2` postfix we get:
>
> let work_done2 = work_done.clone();
> let data2 = data.clone();
>
Yeah, the thing I want to achieve with my pattern is: make it clear that
the work and the task that queues the work are sharing the same
`work_done` and `data` (well, no the same `Arc` exactly, but the `Arc`s
that are pointing to the same object). This pattern here doesn't show
that clearly imo.
That said, I'm not really against using `work_done2` and `data2`, just
I'm afraid that may be more confusing.
> workqueue::system().try_spawn(flags::GFP_KERNEL, move || {
> *data2.lock() = 42;
> work_done2.complete_all();
> })?;
>
> There are some discussions of introducing some better syntax for (cheap)
> cloning, so maybe we can use that in the future.
Do you have links to these discussions.
Regards,
Boqun
>
> ---
> Cheers,
> Benno
>
> > + ///
> > + /// work_done.wait_for_completion();
> > + ///
> > + /// // `work_done` being completed implies the observation of the write of `data` in the work.
> > + /// assert_eq!(*data.lock(), 42);
> > + /// # Ok::<(), Error>(())
> > + /// ```
> > pub fn try_spawn<T: 'static + Send + FnOnce()>(
> > &self,
> > flags: Flags,
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 19:38 ` Boqun Feng
@ 2025-07-31 9:30 ` Benno Lossin
2025-08-01 1:15 ` Boqun Feng
0 siblings, 1 reply; 10+ messages in thread
From: Benno Lossin @ 2025-07-31 9:30 UTC (permalink / raw)
To: Boqun Feng
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Tejun Heo, Tamir Duberstein, Hamza Mahfooz,
Alban Kurti, Joel Fernandes, Paul E. McKenney
On Wed Jul 30, 2025 at 9:38 PM CEST, Boqun Feng wrote:
> On Wed, Jul 30, 2025 at 09:28:05PM +0200, Benno Lossin wrote:
>> On Wed Jul 30, 2025 at 6:34 PM CEST, Boqun Feng wrote:
>> > + /// workqueue::system().try_spawn(
>> > + /// flags::GFP_KERNEL,
>> > + /// {
>> > + /// let work_done = work_done.clone();
>> > + /// let data = data.clone();
>> > + /// move || {
>> > + /// *data.lock() = 42;
>> > + /// work_done.complete_all();
>> > + /// }
>> > + /// }
>> > + /// )?;
>>
>> Not doing your pattern and instead adding a `2` postfix we get:
>>
>> let work_done2 = work_done.clone();
>> let data2 = data.clone();
>>
>
> Yeah, the thing I want to achieve with my pattern is: make it clear that
> the work and the task that queues the work are sharing the same
> `work_done` and `data` (well, no the same `Arc` exactly, but the `Arc`s
> that are pointing to the same object). This pattern here doesn't show
> that clearly imo.
I think it's fine, that pattern is often used for that. Not heavily
opposed to doing it your way, but I feel like the code looks a bit weird
& my instinct is to move the let bindings out (which would produce code
that doesn't compile).
> That said, I'm not really against using `work_done2` and `data2`, just
> I'm afraid that may be more confusing.
I don't think that's a problem.
>> workqueue::system().try_spawn(flags::GFP_KERNEL, move || {
>> *data2.lock() = 42;
>> work_done2.complete_all();
>> })?;
>>
>> There are some discussions of introducing some better syntax for (cheap)
>> cloning, so maybe we can use that in the future.
>
> Do you have links to these discussions.
It's an RFC:
https://github.com/rust-lang/rfcs/pull/368
There probably are more discussions on zulip, but I haven't read those.
The RFC also has a project goal:
https://rust-lang.github.io/rust-project-goals/2025h2/ergonomic-rc.html
---
Cheers,
Benno
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-31 9:30 ` Benno Lossin
@ 2025-08-01 1:15 ` Boqun Feng
2025-08-01 8:54 ` Benno Lossin
0 siblings, 1 reply; 10+ messages in thread
From: Boqun Feng @ 2025-08-01 1:15 UTC (permalink / raw)
To: Benno Lossin
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Tejun Heo, Tamir Duberstein, Hamza Mahfooz,
Alban Kurti, Joel Fernandes, Paul E. McKenney
On Thu, Jul 31, 2025 at 11:30:10AM +0200, Benno Lossin wrote:
> On Wed Jul 30, 2025 at 9:38 PM CEST, Boqun Feng wrote:
> > On Wed, Jul 30, 2025 at 09:28:05PM +0200, Benno Lossin wrote:
> >> On Wed Jul 30, 2025 at 6:34 PM CEST, Boqun Feng wrote:
> >> > + /// workqueue::system().try_spawn(
> >> > + /// flags::GFP_KERNEL,
> >> > + /// {
> >> > + /// let work_done = work_done.clone();
> >> > + /// let data = data.clone();
> >> > + /// move || {
> >> > + /// *data.lock() = 42;
> >> > + /// work_done.complete_all();
> >> > + /// }
> >> > + /// }
> >> > + /// )?;
> >>
> >> Not doing your pattern and instead adding a `2` postfix we get:
> >>
> >> let work_done2 = work_done.clone();
> >> let data2 = data.clone();
> >>
> >
> > Yeah, the thing I want to achieve with my pattern is: make it clear that
> > the work and the task that queues the work are sharing the same
> > `work_done` and `data` (well, no the same `Arc` exactly, but the `Arc`s
> > that are pointing to the same object). This pattern here doesn't show
> > that clearly imo.
>
> I think it's fine, that pattern is often used for that. Not heavily
> opposed to doing it your way, but I feel like the code looks a bit weird
Ok, I will drop my style and use work_done2 and data2, because it'll be
at the general documentation, but I might keep using my pattern in other
code because it looks reasonable to me ;-)
> & my instinct is to move the let bindings out (which would produce code
> that doesn't compile).
>
> > That said, I'm not really against using `work_done2` and `data2`, just
> > I'm afraid that may be more confusing.
>
> I don't think that's a problem.
>
> >> workqueue::system().try_spawn(flags::GFP_KERNEL, move || {
> >> *data2.lock() = 42;
> >> work_done2.complete_all();
> >> })?;
> >>
> >> There are some discussions of introducing some better syntax for (cheap)
> >> cloning, so maybe we can use that in the future.
> >
> > Do you have links to these discussions.
>
> It's an RFC:
>
> https://github.com/rust-lang/rfcs/pull/368
>
> There probably are more discussions on zulip, but I haven't read those.
> The RFC also has a project goal:
>
> https://rust-lang.github.io/rust-project-goals/2025h2/ergonomic-rc.html
Thanks for the pointer.
Regards,
Boqun
>
> ---
> Cheers,
> Benno
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-08-01 1:15 ` Boqun Feng
@ 2025-08-01 8:54 ` Benno Lossin
0 siblings, 0 replies; 10+ messages in thread
From: Benno Lossin @ 2025-08-01 8:54 UTC (permalink / raw)
To: Boqun Feng
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Tejun Heo, Tamir Duberstein, Hamza Mahfooz,
Alban Kurti, Joel Fernandes, Paul E. McKenney
On Fri Aug 1, 2025 at 3:15 AM CEST, Boqun Feng wrote:
> On Thu, Jul 31, 2025 at 11:30:10AM +0200, Benno Lossin wrote:
>> On Wed Jul 30, 2025 at 9:38 PM CEST, Boqun Feng wrote:
>> > On Wed, Jul 30, 2025 at 09:28:05PM +0200, Benno Lossin wrote:
>> >> On Wed Jul 30, 2025 at 6:34 PM CEST, Boqun Feng wrote:
>> >> > + /// workqueue::system().try_spawn(
>> >> > + /// flags::GFP_KERNEL,
>> >> > + /// {
>> >> > + /// let work_done = work_done.clone();
>> >> > + /// let data = data.clone();
>> >> > + /// move || {
>> >> > + /// *data.lock() = 42;
>> >> > + /// work_done.complete_all();
>> >> > + /// }
>> >> > + /// }
>> >> > + /// )?;
>> >>
>> >> Not doing your pattern and instead adding a `2` postfix we get:
>> >>
>> >> let work_done2 = work_done.clone();
>> >> let data2 = data.clone();
>> >>
>> >
>> > Yeah, the thing I want to achieve with my pattern is: make it clear that
>> > the work and the task that queues the work are sharing the same
>> > `work_done` and `data` (well, no the same `Arc` exactly, but the `Arc`s
>> > that are pointing to the same object). This pattern here doesn't show
>> > that clearly imo.
>>
>> I think it's fine, that pattern is often used for that. Not heavily
>> opposed to doing it your way, but I feel like the code looks a bit weird
>
> Ok, I will drop my style and use work_done2 and data2, because it'll be
> at the general documentation, but I might keep using my pattern in other
> code because it looks reasonable to me ;-)
It is reasonable :) If you do want to use the same name for them, then I
personally think this looks better than moving the let bindings inside
of the expression:
{
let work_done = work_done.clone();
let data = data.clone();
workqueue::system().try_spawn(flags::GFP_KERNEL, move || {
*data.lock() = 42;
work_done.complete_all();
})?;
}
But that gives the `try_spawn` call extra indentation which also isn't
ideal... I'd be best for the language feature to exist :)
---
Cheers,
Benno
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH] rust: workqueue: Add an example for try_spawn()
2025-07-30 16:34 [RFC PATCH] rust: workqueue: Add an example for try_spawn() Boqun Feng
` (2 preceding siblings ...)
2025-07-30 19:28 ` Benno Lossin
@ 2025-08-01 9:05 ` Alice Ryhl
3 siblings, 0 replies; 10+ messages in thread
From: Alice Ryhl @ 2025-08-01 9:05 UTC (permalink / raw)
To: Boqun Feng
Cc: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Tejun Heo, Tamir Duberstein,
Hamza Mahfooz, Alban Kurti, Joel Fernandes, Paul E. McKenney
On Wed, Jul 30, 2025 at 09:34:39AM -0700, Boqun Feng wrote:
> `try_spawn()` could use an example to demonstrate the usage, and
> arguably it's the most simple usage of workqueue in case someone needs a
> deferred work, so add it.
>
> Cc: Joel Fernandes <joelagnelf@nvidia.com>
> Cc: "Paul E. McKenney" <paulmck@kernel.org>
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> ---
> Miguel, Alice and Tejun, while I'm at it, should we also rename the
> function to `spawn()` because of the motivation mentioned here [1]?
>
> [1]: https://rust-for-linux.zulipchat.com/#narrow/channel/291566-Library/topic/.60new.60.20or.20.60try_new.60.3F/near/529533317
Renaming sounds good to me.
> Also I find the `{ <clone> || { } }` is really good if I only need to
> clone the Arc for passing to a callback closure, but I'm not sure how
> people feel about it, so criticism is welcome ;-)
It's a neat trick, but I think it risks confusing people. I would
probably not include it in an example like this one.
> rust/kernel/workqueue.rs | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> index b9343d5bc00f..59c1a5e14d12 100644
> --- a/rust/kernel/workqueue.rs
> +++ b/rust/kernel/workqueue.rs
> @@ -331,6 +331,33 @@ pub fn enqueue_delayed<W, const ID: u64>(&self, w: W, delay: Jiffies) -> W::Enqu
> /// Tries to spawn the given function or closure as a work item.
> ///
> /// This method can fail because it allocates memory to store the work item.
> + ///
> + /// # Examples
> + ///
> + /// ```
> + /// use kernel::{alloc::flags, sync::{Arc, Completion, new_spinlock}, workqueue};
> + ///
> + /// let work_done = Arc::pin_init(Completion::new(), flags::GFP_KERNEL)?;
> + /// let data = Arc::pin_init(new_spinlock!(0), flags::GFP_KERNEL)?;
> + ///
> + /// workqueue::system().try_spawn(
> + /// flags::GFP_KERNEL,
> + /// {
> + /// let work_done = work_done.clone();
> + /// let data = data.clone();
> + /// move || {
> + /// *data.lock() = 42;
> + /// work_done.complete_all();
> + /// }
> + /// }
> + /// )?;
> + ///
> + /// work_done.wait_for_completion();
> + ///
> + /// // `work_done` being completed implies the observation of the write of `data` in the work.
> + /// assert_eq!(*data.lock(), 42);
> + /// # Ok::<(), Error>(())
> + /// ```
> pub fn try_spawn<T: 'static + Send + FnOnce()>(
> &self,
> flags: Flags,
> --
> 2.39.5 (Apple Git-154)
>
^ permalink raw reply [flat|nested] 10+ messages in thread