From: Boqun Feng <boqun.feng@gmail.com>
To: Konstantin Shelekhin <k.shelekhin@ftml.net>
Cc: Alice Ryhl <aliceryhl@google.com>,
alex.gaynor@gmail.com, benno.lossin@proton.me,
bjorn3_gh@protonmail.com, gary@garyguo.net,
jiangshanlai@gmail.com, linux-kernel@vger.kernel.org,
nmi@metaspace.dk, ojeda@kernel.org, patches@lists.linux.dev,
rust-for-linux@vger.kernel.org, tj@kernel.org,
wedsonaf@gmail.com, yakoyoku@gmail.com
Subject: Re: [PATCH v4 7/7] rust: workqueue: add examples
Date: Wed, 4 Oct 2023 07:38:26 -0700 [thread overview]
Message-ID: <ZR144pugIJQRAFjj@boqun-archlinux> (raw)
In-Reply-To: <CVZLU74VWMKA.GQXYH7WUNPS4@pogg>
On Wed, Oct 04, 2023 at 02:06:05PM +0300, Konstantin Shelekhin wrote:
> On Wed Oct 4, 2023 at 1:29 AM MSK, Alice Ryhl wrote:
> > On Tue, Oct 3, 2023 at 10:13PM Konstantin Shelekhin <k.shelekhin@ftml.net> wrote:
> > > +//! #[pin_data]
> > > +//! struct MyStruct {
> > > +//! value: i32,
> > > +//! #[pin]
> > > +//! work: Work<MyStruct>,
> > > +//! }
> > > +//!
> > > +//! impl_has_work! {
> > > +//! impl HasWork<Self> for MyStruct { self.work }
> > > +//! }
> > > +//!
> > > +//! impl MyStruct {
> > > +//! fn new(value: i32) -> Result<Arc<Self>> {
> > > +//! Arc::pin_init(pin_init!(MyStruct {
> > > +//! value,
> > > +//! work <- new_work!("MyStruct::work"),
> > > +//! }))
> > > +//! }
> > > +//! }
> > > +//!
> > > +//! impl WorkItem for MyStruct {
> > > +//! type Pointer = Arc<MyStruct>;
> > > +//!
> > > +//! fn run(this: Arc<MyStruct>) {
> > > +//! pr_info!("The value is: {}", this.value);
> > > +//! }
> > > +//! }
> > > +//!
> > > +//! /// This method will enqueue the struct for execution on the system workqueue, where its value
> > > +//! /// will be printed.
> > > +//! fn print_later(val: Arc<MyStruct>) {
> > > +//! let _ = workqueue::system().enqueue(val);
> > > +//! }
> > >
> > > I understand that this is highly opionated, but is it possible to make
> > > the initialization less verbose?
> >
> > The short answer is yes. There are safe alternatives that are much less
> > verbose. Unfortunately, those alternatives give up some of the features
> > that this design has. Specifically, they give up the feature that allows
> > you to embed the work_struct inside custom structs. I need to be able to
> > embed the work_struct inside of custom structs, so I did not go that
> > route.
>
> My concern with the approach of using traits instead of calling an
> initialization function is that a some of existing code uses the
> following pattern:
>
> static void nvmet_file_submit_buffered_io(struct nvmet_req *req)
> {
> INIT_WORK(&req->f.work, nvmet_file_buffered_io_work);
> queue_work(buffered_io_wq, &req->f.work);
> }
>
> static void nvmet_file_execute_flush(struct nvmet_req *req)
> {
> if (!nvmet_check_transfer_len(req, 0))
> return;
> INIT_WORK(&req->f.work, nvmet_file_flush_work);
> queue_work(nvmet_wq, &req->f.work);
> }
>
> static void nvmet_file_execute_dsm(struct nvmet_req *req)
> {
> if (!nvmet_check_data_len_lte(req, nvmet_dsm_len(req)))
> return;
> INIT_WORK(&req->f.work, nvmet_file_dsm_work);
> queue_work(nvmet_wq, &req->f.work);
> }
>
> As you can see a single work struct is used here, and dispatching
> happens beforehands. While it's possible to do the dispatching later in
> run(), it's IMO cleaner to do this earlier.
This is not a problem until nvmet actually uses/switches to Rust, right?
;-) We can certainly improve the API when a real user needs something.
Or you know someone is already working on this?
[...]
>
> I get where all this coming from, I just really dislike the idea to
> write all this code every time I need to pass something down the
> workqueue. Maybe it's possible to hide most of the boilerplate behind a
> derive.
>
> Something like this, for example:
>
> #[pin_data, derive(WorkContainer)]
> struct MyStruct {
> value: i32,
> #[pin, work(fn = log_value)]
> work: Work,
> }
>
> fn log_value(s: Arc<MyStruct>) {
> pr_info!("The value is: {}", s.value);
> }
>
> fn print_later(s: Arc<MyStruct>) {
> workqueue::system().enqueue(s);
> }
All of your suggestions make senses to me, but because we don't have
many users right now, it's actually hard to determine a "best" API. I
like what we have right now because it's explicit: people won't need to
learn much about procedure macros to understand how it works, and it
also provides better opportunities for people who's yet not familiar
with Rust to give some reviews. So starting with something relatively
simple and verbose may not be a bad idea ;-)
Again, I like your idea, we need to explore that direction, but one
dragon at a time ;-)
Regards,
Boqun
next prev parent reply other threads:[~2023-10-04 14:39 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-28 10:48 [PATCH v4 0/7] rust: workqueue: add bindings for the workqueue Alice Ryhl
2023-08-28 10:48 ` [PATCH v4 1/7] rust: sync: add `Arc::{from_raw, into_raw}` Alice Ryhl
2023-08-28 10:48 ` [PATCH v4 2/7] rust: workqueue: add low-level workqueue bindings Alice Ryhl
2023-08-28 10:48 ` [PATCH v4 3/7] rust: workqueue: define built-in queues Alice Ryhl
2023-08-28 10:48 ` [PATCH v4 4/7] rust: workqueue: add helper for defining work_struct fields Alice Ryhl
[not found] ` <CGME20230828112151eucas1p2371f4cf778e6265e8ac5baf8ea91be4d@eucas1p2.samsung.com>
2023-08-28 11:21 ` Andreas Hindborg
2023-09-04 0:29 ` Martin Rodriguez Reboredo
2023-09-05 10:07 ` Benno Lossin
2023-09-06 9:56 ` Alice Ryhl
2023-09-26 10:01 ` Alice Ryhl
2023-09-23 2:56 ` Gary Guo
2023-08-28 10:48 ` [PATCH v4 5/7] rust: workqueue: implement `WorkItemPointer` for pointer types Alice Ryhl
2023-08-28 10:48 ` [PATCH v4 6/7] rust: workqueue: add `try_spawn` helper method Alice Ryhl
2023-08-28 10:48 ` [PATCH v4 7/7] rust: workqueue: add examples Alice Ryhl
2023-10-03 20:13 ` Konstantin Shelekhin
2023-10-03 22:29 ` Alice Ryhl
2023-10-04 11:06 ` Konstantin Shelekhin
2023-10-04 14:38 ` Boqun Feng [this message]
2023-10-04 14:56 ` Konstantin Shelekhin
2023-10-04 15:49 ` Andreas Hindborg (Samsung)
2023-10-05 6:32 ` Trevor Gross
2023-09-12 5:14 ` [PATCH v4 0/7] rust: workqueue: add bindings for the workqueue Boqun Feng
2023-09-25 19:49 ` Tejun Heo
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=ZR144pugIJQRAFjj@boqun-archlinux \
--to=boqun.feng@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=gary@garyguo.net \
--cc=jiangshanlai@gmail.com \
--cc=k.shelekhin@ftml.net \
--cc=linux-kernel@vger.kernel.org \
--cc=nmi@metaspace.dk \
--cc=ojeda@kernel.org \
--cc=patches@lists.linux.dev \
--cc=rust-for-linux@vger.kernel.org \
--cc=tj@kernel.org \
--cc=wedsonaf@gmail.com \
--cc=yakoyoku@gmail.com \
/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;
as well as URLs for NNTP newsgroup(s).