diff options
author | Alice Ryhl <aliceryhl@google.com> | 2023-08-28 13:48:04 +0300 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2023-09-25 22:46:42 +0300 |
commit | 7324b88975c525a013ae0db747df97924ce80675 (patch) | |
tree | afa7347e3fa89aa37ba897a53b42bf7ff2bc79f6 /scripts/Makefile.build | |
parent | 033941307471787ef8ee65bfc411dcbb6a81ea18 (diff) | |
download | linux-7324b88975c525a013ae0db747df97924ce80675.tar.xz |
rust: workqueue: add helper for defining work_struct fields
The main challenge with defining `work_struct` fields is making sure
that the function pointer stored in the `work_struct` is appropriate for
the work item type it is embedded in. It needs to know the offset of the
`work_struct` field being used (even if there are several!) so that it
can do a `container_of`, and it needs to know the type of the work item
so that it can call into the right user-provided code. All of this needs
to happen in a way that provides a safe API to the user, so that users
of the workqueue cannot mix up the function pointers.
There are three important pieces that are relevant when doing this:
* The pointer type.
* The work item struct. This is what the pointer points at.
* The `work_struct` field. This is a field of the work item struct.
This patch introduces a separate trait for each piece. The pointer type
is given a `WorkItemPointer` trait, which pointer types need to
implement to be usable with the workqueue. This trait will be
implemented for `Arc` and `Box` in a later patch in this patchset.
Implementing this trait is unsafe because this is where the
`container_of` operation happens, but user-code will not need to
implement it themselves.
The work item struct should then implement the `WorkItem` trait. This
trait is where user-code specifies what they want to happen when a work
item is executed. It also specifies what the correct pointer type is.
Finally, to make the work item struct know the offset of its
`work_struct` field, we use a trait called `HasWork<T, ID>`. If a type
implements this trait, then the type declares that, at the given offset,
there is a field of type `Work<T, ID>`. The trait is marked unsafe
because the OFFSET constant must be correct, but we provide an
`impl_has_work!` macro that can safely implement `HasWork<T>` on a type.
The macro expands to something that only compiles if the specified field
really has the type `Work<T>`. It is used like this:
```
struct MyWorkItem {
work_field: Work<MyWorkItem, 1>,
}
impl_has_work! {
impl HasWork<MyWorkItem, 1> for MyWorkItem { self.work_field }
}
```
Note that since the `Work` type is annotated with an id, you can have
several `work_struct` fields by using a different id for each one.
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'scripts/Makefile.build')
-rw-r--r-- | scripts/Makefile.build | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 82e3fb19fdaf..da37bfa97211 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -262,7 +262,7 @@ $(obj)/%.lst: $(src)/%.c FORCE # Compile Rust sources (.rs) # --------------------------------------------------------------------------- -rust_allowed_features := new_uninit +rust_allowed_features := new_uninit,offset_of # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree |