All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Hindborg <nmi@metaspace.dk>
To: Alice Ryhl <aliceryhl@google.com>
Cc: rust-for-linux@vger.kernel.org, "Miguel Ojeda" <ojeda@kernel.org>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Tejun Heo" <tj@kernel.org>,
	"Lai Jiangshan" <jiangshanlai@gmail.com>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	linux-kernel@vger.kernel.org, patches@lists.linux.dev
Subject: Re: [PATCH v1 1/7] rust: workqueue: add low-level workqueue bindings
Date: Tue, 30 May 2023 10:26:02 +0200	[thread overview]
Message-ID: <87ttvu9q4o.fsf@metaspace.dk> (raw)
In-Reply-To: <20230517203119.3160435-2-aliceryhl@google.com>


Alice Ryhl <aliceryhl@google.com> writes:

> Define basic low-level bindings to a kernel workqueue. The API defined
> here can only be used unsafely. Later commits will provide safe
> wrappers.
>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> ---
>  rust/kernel/lib.rs       |  1 +
>  rust/kernel/workqueue.rs | 99 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 100 insertions(+)
>  create mode 100644 rust/kernel/workqueue.rs
>
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index 676995d4e460..c718524056a6 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -47,6 +47,7 @@ pub mod str;
>  pub mod sync;
>  pub mod task;
>  pub mod types;
> +pub mod workqueue;
>  
>  #[doc(hidden)]
>  pub use bindings;
> diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs
> new file mode 100644
> index 000000000000..e66b6b50dfae
> --- /dev/null
> +++ b/rust/kernel/workqueue.rs
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Work queues.
> +//!
> +//! C header: [`include/linux/workqueue.h`](../../../../include/linux/workqueue.h)

I think we need to add workqueue.h to rust/bindings/bindings_helper.h
with this commit. It is probably transitively included as is, but it
would be the right thing to explicitly include it.

BR Andreas

> +
> +use crate::{bindings, types::Opaque};
> +
> +/// A kernel work queue.
> +///
> +/// Wraps the kernel's C `struct workqueue_struct`.
> +///
> +/// It allows work items to be queued to run on thread pools managed by the kernel. Several are
> +/// always available, for example, `system`, `system_highpri`, `system_long`, etc.
> +#[repr(transparent)]
> +pub struct Queue(Opaque<bindings::workqueue_struct>);
> +
> +// SAFETY: Kernel workqueues are usable from any thread.
> +unsafe impl Send for Queue {}
> +unsafe impl Sync for Queue {}
> +
> +impl Queue {
> +    /// Use the provided `struct workqueue_struct` with Rust.
> +    ///
> +    /// # Safety
> +    ///
> +    /// The caller must ensure that the provided raw pointer is not dangling, that it points at a
> +    /// valid workqueue, and that it remains valid until the end of 'a.
> +    pub unsafe fn from_raw<'a>(ptr: *const bindings::workqueue_struct) -> &'a Queue {
> +        // SAFETY: The `Queue` type is `#[repr(transparent)]`, so the pointer cast is valid. The
> +        // caller promises that the pointer is not dangling.
> +        unsafe { &*(ptr as *const Queue) }
> +    }
> +
> +    /// Enqueues a work item.
> +    ///
> +    /// This may fail if the work item is already enqueued in a workqueue.
> +    pub fn enqueue<T: WorkItem + Send + 'static>(&self, w: T) -> T::EnqueueOutput {
> +        let queue_ptr = self.0.get();
> +
> +        // SAFETY: There are two cases.
> +        //
> +        //  1. If `queue_work_on` returns false, then we failed to push the work item to the queue.
> +        //     In this case, we don't touch the work item again.
> +        //
> +        //  2. If `queue_work_on` returns true, then we pushed the work item to the queue. The work
> +        //     queue will call the function pointer in the `work_struct` at some point in the
> +        //     future. We require `T` to be static, so the type has no lifetimes annotated on it.
> +        //     We require `T` to be send, so there are no thread-safety issues to take care of.
> +        //
> +        // In either case we follow the safety requirements of `__enqueue`.
> +        unsafe {
> +            w.__enqueue(move |work_ptr| {
> +                bindings::queue_work_on(bindings::WORK_CPU_UNBOUND as _, queue_ptr, work_ptr)
> +            })
> +        }
> +    }
> +}
> +
> +/// A work item.
> +///
> +/// This is the low-level trait that is designed for being as general as possible.
> +///
> +/// # Safety
> +///
> +/// Implementers must ensure that `__enqueue` behaves as documented.
> +pub unsafe trait WorkItem {
> +    /// The return type of [`Queue::enqueue`].
> +    type EnqueueOutput;
> +
> +    /// Enqueues this work item on a queue using the provided `queue_work_on` method.
> +    ///
> +    /// # Safety
> +    ///
> +    /// Calling this method guarantees that the provided closure will be called with a raw pointer
> +    /// to a `struct work_struct`. The closure should behave in the following way:
> +    ///
> +    ///  1. If the `struct work_struct` cannot be pushed to a workqueue because its already in one,
> +    ///     then the closure should return `false`. It may not access the pointer after returning
> +    ///     `false`.
> +    ///  2. If the `struct work_struct` is successfully added to a workqueue, then the closure
> +    ///     should return `true`. When the workqueue executes the work item, it will do so by
> +    ///     calling the function pointer stored in the `struct work_struct`. The work item ensures
> +    ///     that the raw pointer remains valid until that happens.
> +    ///
> +    /// This method may not have any other failure cases than the closure returning `false`. The
> +    /// output type should reflect this, but it may also be an infallible type if the work item
> +    /// statically ensures that pushing the `struct work_struct` will succeed.
> +    ///
> +    /// If the work item type is annotated with any lifetimes, then the workqueue must call the
> +    /// function pointer before any such lifetime expires. (Or it may forget the work item and
> +    /// never call the function pointer at all.)
> +    ///
> +    /// If the work item type is not [`Send`], then the work item must be executed on the same
> +    /// thread as the call to `__enqueue`.
> +    unsafe fn __enqueue<F>(self, queue_work_on: F) -> Self::EnqueueOutput
> +    where
> +        F: FnOnce(*mut bindings::work_struct) -> bool;
> +}


  parent reply	other threads:[~2023-05-30  8:31 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-17 20:31 [PATCH v1 0/7] Bindings for the workqueue Alice Ryhl
2023-05-17 20:31 ` [PATCH v1 1/7] rust: workqueue: add low-level workqueue bindings Alice Ryhl
2023-05-18 14:51   ` Martin Rodriguez Reboredo
2023-05-19  9:40     ` Alice Ryhl
2023-05-19 12:04       ` Martin Rodriguez Reboredo
2023-05-23 10:03         ` Alice Ryhl
2023-05-30  8:26   ` Andreas Hindborg [this message]
2023-05-17 20:31 ` [PATCH v1 2/7] rust: add offset_of! macro Alice Ryhl
2023-05-18 14:51   ` Martin Rodriguez Reboredo
2023-05-23 15:48   ` Gary Guo
2023-05-24 12:26     ` Alice Ryhl
2023-05-30  8:40     ` Andreas Hindborg
2023-05-17 20:31 ` [PATCH v1 3/7] rust: sync: add `Arc::{from_raw, into_raw}` Alice Ryhl
2023-05-18 14:51   ` Martin Rodriguez Reboredo
2023-05-23 15:43   ` Gary Guo
2023-05-24 11:19     ` Alice Ryhl
2023-05-24 10:20   ` Andreas Hindborg
2023-05-24 11:11     ` Alice Ryhl
2023-05-25  7:45       ` Andreas Hindborg
2023-05-25 16:32         ` Gary Guo
2023-05-30  7:23           ` Andreas Hindborg
2023-05-17 20:31 ` [PATCH v1 4/7] rust: workqueue: define built-in queues Alice Ryhl
2023-05-18 14:52   ` Martin Rodriguez Reboredo
2023-05-25 11:40   ` Andreas Hindborg
2023-05-31 14:02     ` Alice Ryhl
2023-06-02 10:23       ` Andreas Hindborg (Samsung)
2023-05-17 20:31 ` [PATCH v1 5/7] rust: workqueue: add helper for defining work_struct fields Alice Ryhl
2023-05-18 23:18   ` Martin Rodriguez Reboredo
2023-05-24 14:50   ` Benno Lossin
2023-05-30  8:44   ` Andreas Hindborg
2023-05-31  9:00     ` Alice Ryhl
2023-05-31 10:18       ` Andreas Hindborg
2023-05-17 20:31 ` [PATCH v1 6/7] rust: workqueue: add safe API to workqueue Alice Ryhl
2023-05-19  0:17   ` Martin Rodriguez Reboredo
2023-05-23 11:07     ` Alice Ryhl
2023-05-30  7:19       ` Andreas Hindborg
2023-05-30 13:23         ` Martin Rodriguez Reboredo
2023-05-30 14:13       ` Miguel Ojeda
2023-05-24 14:51   ` Benno Lossin
2023-05-31  9:07     ` Alice Ryhl
2023-05-30  8:51   ` Andreas Hindborg
2023-05-31 14:07     ` Alice Ryhl
2023-05-17 20:31 ` [PATCH v1 7/7] rust: workqueue: add `try_spawn` helper method Alice Ryhl
2023-05-18  6:15   ` kernel test robot
2023-05-19  0:22   ` Martin Rodriguez Reboredo
2023-05-22  9:39   ` kernel test robot
2023-05-24 14:52   ` Benno Lossin
2023-05-31 14:03     ` Alice Ryhl
2023-05-17 21:48 ` [PATCH v1 0/7] Bindings for the workqueue Tejun Heo
2023-05-17 22:22   ` Alice Ryhl
2023-05-23 14:08     ` Andreas Hindborg
2023-05-23 14:14 ` Andreas Hindborg
2023-05-24 12:33   ` Alice Ryhl

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=87ttvu9q4o.fsf@metaspace.dk \
    --to=nmi@metaspace.dk \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=jiangshanlai@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=wedsonaf@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 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.