Commit Graph
59 Commits
Author SHA1 Message Date
Benno Lossin 42415d163e rust: pin-init: add references to previously initialized fields
After initializing a field in an initializer macro, create a variable
holding a reference that points at that field. The type is either
`Pin<&mut T>` or `&mut T` depending on the field's structural pinning
kind.

[ Applied fixes to devres and rust_driver_pci sample - Benno]
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-09-11 23:30:02 +02:00
Benno Lossin 1fa516794f rust: pin-init: add code blocks to [try_][pin_]init! macros
Allow writing `_: { /* any number of statements */ }` in initializers to
run arbitrary code during initialization.

    try_init!(MyStruct {
        _: {
            if check_something() {
                return Err(MyError);
            }
        },
        foo: Foo::new(val),
        _: {
            println!("successfully initialized `MyStruct`");
        },
    })

Tested-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Tested-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-09-11 23:26:44 +02:00
Benno Lossin 619db96daf rust: pin-init: add pin projections to #[pin_data]
Make the `#[pin_data]` macro generate a `*Projection` struct that holds
either `Pin<&mut Field>` or `&mut Field` for every field of the original
struct. Which version is chosen depends on weather there is a `#[pin]`
or not respectively. Access to this projected version is enabled through
generating `fn project(self: Pin<&mut Self>) -> SelfProjection<'_>`.

[ Adapt workqueue to use the new projection instead of its own, custom
  one - Benno ]

Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-09-11 23:26:20 +02:00
Benno Lossin d49c56368c rust: pin-init: rename project -> project_this in doctest
The next commit makes the `#[pin_data]` attribute generate a `project`
function that would collide with any existing ones.

Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-09-11 23:26:11 +02:00
Benno Lossin 62a9c70961 rust: pin-init: README: add information banner on the rename to pin-init
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-09-11 23:26:03 +02:00
Benno Lossin 3d53627744 rust: pin-init: examples: error: use Error in fn main()
When running this example with no cargo features enabled, the compiler
warns on 1.89:

  error: struct `Error` is never constructed
    --> examples/error.rs:11:12
     |
  11 | pub struct Error;
     |            ^^^^^
     |
     = note: `-D dead-code` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(dead_code)]`

Thus use the error in the main function to avoid this warning.

Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-09-11 23:25:54 +02:00
Miguel Ojeda e8fa0481ea Merge tag 'pin-init-v6.17' of https://github.com/Rust-for-Linux/linux into rust-next
Pull pin-init updates from Benno Lossin:
 "Added:

   - 'impl<T, E> [Pin]Init<T, E> for Result<T, E>', so results are now
     (pin-)initializers.

   - 'Zeroable::init_zeroed()' delegating to 'init_zeroed()'.

   - New 'zeroed()', a safe version of 'mem::zeroed()' and also provide
     it via 'Zeroable::zeroed()'.

   - Implement 'Zeroable' for 'Option<&T>' and 'Option<&mut T>'.

   - Implement 'Zeroable' for 'Option<[unsafe] [extern "abi"]
     fn(...args...) -> ret>' for '"Rust"' and '"C"' ABIs and up to 20
     arguments.

  Changed:

   - Blanket impls of 'Init' and 'PinInit' from 'impl<T, E>
     [Pin]Init<T, E> for T' to 'impl<T> [Pin]Init<T> for T'.

   - Renamed 'zeroed()' to 'init_zeroed()'.

  Upstream dev news:

   - More CI improvements to deny warnings, use '--all-targets'. Also
     check the synchronization status of the two '-next' branches in
     upstream and the kernel."

Acked-by: Andreas Hindborg <a.hindborg@kernel.org>

* tag 'pin-init-v6.17' of https://github.com/Rust-for-Linux/linux:
  rust: pin-init: examples, tests: use `ignore` instead of conditionally compiling tests
  rust: init: remove doctest's `Error::from_errno` workaround
  rust: init: re-enable doctests
  rust: pin-init: implement `ZeroableOption` for function pointers with up to 20 arguments
  rust: pin-init: change `impl Zeroable for Option<NonNull<T>>` to `ZeroableOption for NonNull<T>`
  rust: pin-init: implement `ZeroableOption` for `&T` and `&mut T`
  rust: pin-init: add `zeroed()` & `Zeroable::zeroed()` functions
  rust: pin-init: add `Zeroable::init_zeroed`
  rust: pin-init: rename `zeroed` to `init_zeroed`
  rust: pin-init: feature-gate the `stack_init_reuse` test on the `std` feature
  rust: pin-init: examples: pthread_mutex: disable the main test for miri
  rust: pin-init: examples, tests: add conditional compilation in order to compile under any feature combination
  rust: pin-init: change blanket impls for `[Pin]Init` and add one for `Result<T, E>`
  rust: pin-init: improve safety documentation for `impl<T> [Pin]Init<T> for T`
2025-07-13 23:05:14 +02:00
Viresh Kumar b6985083be rust: Use consistent "# Examples" heading style in rustdoc
Use a consistent `# Examples` heading in rustdoc across the codebase.

Some modules previously used `## Examples` (even when they should be
available as top-level headers), while others used `# Example`, which
deviates from the preferred `# Examples` style.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://lore.kernel.org/r/ddd5ce0ac20c99a72a4f1e4322d3de3911056922.1749545815.git.viresh.kumar@linaro.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-06-24 01:02:30 +02:00
Benno Lossin fc3870dc5c rust: pin-init: examples, tests: use ignore instead of conditionally compiling tests
Change `#[cfg(cond)]` to `#[cfg_attr(not(cond), ignore)]` on tests.

Ignoring tests instead of disabling them still makes them appear in the
test list, but with `ignored`. It also still compiles the code in those
cases.

Some tests still need to be ignore, because they use types that are not
present when the condition is false. For example the condition is
`feature = std` and then it uses `std::thread::Thread`.

Suggested-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/all/aDC9y829vZZBzZ2p@google.com
Link: https://github.com/Rust-for-Linux/pin-init/pull/58/commits/b004dd8e64d4cbe219a4eff0d25f0a5f5bc750ca
Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Link: https://lore.kernel.org/all/20250605155258.573391-1-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:57 +02:00
Benno Lossin ec87ec35ca rust: pin-init: implement ZeroableOption for function pointers with up to 20 arguments
`Option<[unsafe] [extern "abi"] fn(...args...) -> ret>` is documented
[1] to also have the `None` variant equal all zeroes.

Link: https://doc.rust-lang.org/stable/std/option/index.html#representation [1]
Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/b6c1ab4fb3699765f81ae512ecac5a2f032d8d51
Link: https://lore.kernel.org/all/20250523145125.523275-7-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:57 +02:00
Benno Lossin 9f47353870 rust: pin-init: change impl Zeroable for Option<NonNull<T>> to ZeroableOption for NonNull<T>
This brings it in line with references. It too is listed in [1].

Link: https://doc.rust-lang.org/stable/std/option/index.html#representation
Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/8e52bf56ddc2190ce901d2f7c008ab8a64f653a9
Link: https://lore.kernel.org/all/20250523145125.523275-6-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin e93a238605 rust: pin-init: implement ZeroableOption for &T and &mut T
`Option<&T>` and `Option<&mut T>` are documented [1] to have the `None`
variant be all zeroes.

Link: https://doc.rust-lang.org/stable/std/option/index.html#representation [1]
Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/5ef1638c79e019d3dc0c62db5905601644c2e60a
Link: https://lore.kernel.org/all/20250523145125.523275-5-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin d67b370120 rust: pin-init: add zeroed() & Zeroable::zeroed() functions
`zeroed()` returns a zeroed out value of a sized type implementing
`Zeroable`.

The function is added as a free standing function, in addition to an
associated function on `Zeroable`, because then it can be marked `const`
(functions in traits can't be const at the moment).

Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/809e4ec160579c1601dce5d78b432a5b6c8e4e40
Link: https://lore.kernel.org/all/20250523145125.523275-4-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin c47024ba19 rust: pin-init: add Zeroable::init_zeroed
The trait function delegates to the already existing `init_zeroed`
function that returns a zeroing initializer for `Self`.

The syntax `..Zeroable::init_zeroed()` is already used by the
initialization macros to initialize all fields that are not mentioned in
the initializer with zero. Therefore it is expected that the function
also exists on the trait.

Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/a424a6c9af5a4418a8e5e986a3db26a4432e2f1a
Link: https://lore.kernel.org/all/20250523145125.523275-3-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin 101b7cf006 rust: pin-init: rename zeroed to init_zeroed
The name `zeroed` is a much better fit for a function that returns the
type by-value.

Link: https://github.com/Rust-for-Linux/pin-init/pull/56/commits/7dbe38682c9725405bab91dcabe9c4d8893d2f5e
[ also rename uses in `rust/kernel/init.rs` - Benno]
Link: https://lore.kernel.org/all/20250523145125.523275-2-lossin@kernel.org
[ Fix wrong replacement of `mem::zeroed` in the definition of `trait
  Zeroable`. - Benno ]
[ Also change occurrences of `zeroed` in `configfs.rs` - Benno ]
Acked-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin b3b4f760cc rust: pin-init: feature-gate the stack_init_reuse test on the std feature
When trying to run `cargo check --all-targets --no-default-features`, an
error is reported by the test, as it cannot find the `std` crate. This
is to be expected, since the `--no-default-features` flag enables the
`no-std` behavior of the crate. Thus exclude the test in that scenario.

Link: https://github.com/Rust-for-Linux/pin-init/pull/50/commits/2813729ccacdedee9dbfcab1ed285b8721a0391b
Link: https://lore.kernel.org/all/20250523125424.192843-4-lossin@kernel.org
[ Changed my author email address to @kernel.org. - Benno ]
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin 2408678d70 rust: pin-init: examples: pthread_mutex: disable the main test for miri
`miri` takes a long time to execute the test, so disable it.

Link: https://github.com/Rust-for-Linux/pin-init/pull/50/commits/e717a9eec85024c11e79e8bd9dcb664ad0de8f94
Link: https://lore.kernel.org/all/20250523125424.192843-3-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin 58cebd6888 rust: pin-init: examples, tests: add conditional compilation in order to compile under any feature combination
In the CI, all examples & tests should be run under all feature
combinations. Currently several examples & tests use `std` without
conditionally enabling it. Thus make them all compile under any feature
combination by conditionally disabling the code that uses e.g. `std`.

Link: https://github.com/Rust-for-Linux/pin-init/pull/50/commits/fdfb70efddbc711b4543c850ee38a2f5a8d17cb6
Link: https://lore.kernel.org/all/20250523125424.192843-2-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin e832374cca rust: pin-init: change blanket impls for [Pin]Init and add one for Result<T, E>
Remove the error from the blanket implementations `impl<T, E> Init<T, E>
for T` (and also for `PinInit`). Add implementations for `Result<T, E>`.

This allows one to easily construct (un)conditional failing
initializers. It also improves the compatibility with APIs that do not
use pin-init, because users can supply a `Result<T, E>` to a  function
taking an `impl PinInit<T, E>`.

Suggested-by: Alice Ryhl <aliceryhl@google.com>
Link: https://github.com/Rust-for-Linux/pin-init/pull/62/commits/58612514b256c6f4a4a0718be25298410e67387a
[ Also fix a compile error in block. - Benno ]
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/all/20250529081027.297648-2-lossin@kernel.org
[ Add title prefix `rust: pin-init`. - Benno ]
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Benno Lossin 8b3d955f72 rust: pin-init: improve safety documentation for impl<T> [Pin]Init<T> for T
The inner SAFETY comments were missing since commit 5cfe7bef6751 ("rust:
enable `clippy::undocumented_unsafe_blocks` lint").

Also rework the implementation of `__pinned_init` to better justify the
SAFETY comment.

Link: https://github.com/Rust-for-Linux/pin-init/pull/62/commits/df925b2e27d499b7144df7e62b01acb00d4b94b8
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/all/20250529081027.297648-1-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-11 21:13:56 +02:00
Miguel Ojeda b04d170621 Merge tag 'pin-init-v6.16' of https://github.com/Rust-for-Linux/linux into rust-next
Pull pin-init updates from Benno Lossin:
 "Added:

   - 'Wrapper<T>' trait for creating pin-initializers for wrapper
     structs with a structurally pinned value such as 'UnsafeCell<T>' or
     'MaybeUninit<T>'.

   - 'MaybeZeroable' derive macro to try to derive 'Zeroable', but not
     error if not all fields implement it. This is needed to derive
     'Zeroable' for all bindgen-generated structs.

   - 'unsafe fn cast_[pin_]init()' functions to unsafely change the
     initialized type of an initializer. These are utilized by the
     'Wrapper<T>' implementations.

  Changed:

   - Added support for visibility in 'Zeroable' derive macro.

   - Added support for 'union's in 'Zeroable' derive macro.

  Upstream dev news:

   - The CI has been streamlined & some bugs with it have been fixed. I
     also added new workflows to check if the user-space version and the
     one in the kernel tree have diverged.

   - I also started to use the issues [1] tab to keep track of any
     problems or unexpected/unwanted things. This should help folks
     report and diagnose issues w.r.t. 'pin-init' better.

      [1] https://github.com/rust-for-linux/pin-init/issues"

* tag 'pin-init-v6.16' of https://github.com/Rust-for-Linux/linux:
  rust: pin-init: improve documentation for `Zeroable` derive macros
  rust: pin-init: fix typos
  rust: pin-init: add `MaybeZeroable` derive macro
  rust: pin-init: allow `Zeroable` derive macro to also be applied to unions
  rust: pin-init: allow `pub` fields in `derive(Zeroable)`
  rust: pin-init: Update the structural pinning link in readme.
  rust: pin-init: Update Changelog and Readme
  rust: pin-init: Implement `Wrapper` for `UnsafePinned` behind feature flag.
  rust: pin-init: Add the `Wrapper` trait.
  rust: pin-init: add `cast_[pin_]init` functions to change the initialized type
  rust: pin-init: examples: use `allow` instead of `expect`
  rust: pin-init: examples: conditionally enable `feature(lint_reasons)`
  rust: pin-init: internal: skip rustfmt formatting of kernel-only module
  rust: pin-init: synchronize README.md
2025-05-18 20:42:49 +02:00
Miguel Ojeda 211dcf7785 rust: clean Rust 1.88.0's clippy::uninlined_format_args lint
Starting with Rust 1.88.0 (expected 2025-06-26) [1], `rustc` may move
back the `uninlined_format_args` to `style` from `pedantic` (it was
there waiting for rust-analyzer suppotr), and thus we will start to see
lints like:

    warning: variables can be used directly in the `format!` string
       --> rust/macros/kunit.rs:105:37
        |
    105 |         let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{}", test);
        |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    105 -         let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{}", test);
    105 +         let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}");

There is even a case that is a pure removal:

    warning: variables can be used directly in the `format!` string
      --> rust/macros/module.rs:51:13
       |
    51 |             format!("{field}={content}\0", field = field, content = content)
       |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
       |
    51 -             format!("{field}={content}\0", field = field, content = content)
    51 +             format!("{field}={content}\0")

The lints all seem like nice cleanups, thus just apply them.

We may want to disable `allow-mixed-uninlined-format-args` in the future.

Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust-clippy/pull/14160 [1]
Acked-by: Benno Lossin <lossin@kernel.org>
Reviewed-by: Tamir Duberstein <tamird@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250502140237.1659624-6-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-07 00:11:47 +02:00
Benno Lossin 9de1a293c8 rust: pin-init: improve documentation for Zeroable derive macros
Specify that both `MaybeZeroable` and `Zeroable` work on `union`s. Add a
doc example for a union. Also include an example with visibility on the
field.

Link: https://github.com/Rust-for-Linux/pin-init/pull/48/commits/ab0985a0e08df06c60a32ca5888f74adcc2c1cf3
Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
2025-05-01 18:16:22 +02:00
Benno Lossin a919ba2159 rust: pin-init: fix typos
Correct two typos in the `Wrapper::pin_init` documentation.

Link: https://github.com/Rust-for-Linux/pin-init/pull/48/commits/fd0bf5e244b685188dc642fc4a0bd3f042468fdb
Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
2025-05-01 18:15:37 +02:00
Benno Lossin 00fccd3ecc rust: pin-init: add MaybeZeroable derive macro
This derive macro implements `Zeroable` for structs & unions precisely
if all fields also implement `Zeroable` and does nothing otherwise. The
plain `Zeroable` derive macro instead errors when it cannot derive
`Zeroable` safely. The `MaybeZeroable` derive macro is useful in cases
where manual checking is infeasible such as with the bindings crate.

Move the zeroable generics parsing into a standalone function in order
to avoid code duplication between the two derive macros.

Link: https://github.com/Rust-for-Linux/pin-init/pull/42/commits/1165cdad1a391b923efaf30cf76bc61e38da022e
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
2025-05-01 18:15:26 +02:00