1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
Commit graph

39 commits

Author SHA1 Message Date
Gary Guo
d072acda48 rust: use custom FFI integer types
Currently FFI integer types are defined in libcore. This commit creates
the `ffi` crate and asks bindgen to use that crate for FFI integer types
instead of `core::ffi`.

This commit is preparatory and no type changes are made in this commit
yet.

Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240913213041.395655-4-gary@garyguo.net
[ Added `rustdoc`, `rusttest` and KUnit tests support. Rebased on top of
  `rust-next` (e.g. migrated more `core::ffi` cases). Reworded crate
  docs slightly and formatted. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-11-10 23:58:00 +01:00
Danilo Krummrich
e8c6ccdbca rust: alloc: remove extension of std's Box
Now that all existing `Box` users were moved to the kernel `Box` type,
remove the `BoxExt` extension and all other related extensions.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241004154149.93856-14-dakr@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-10-15 22:56:59 +02:00
Danilo Krummrich
8373147ce4 rust: treewide: switch to our kernel Box type
Now that we got the kernel `Box` type in place, convert all existing
`Box` users to make use of it.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241004154149.93856-13-dakr@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-10-15 22:56:59 +02:00
Miguel Ojeda
1f9ed17254 rust: start using the #[expect(...)] attribute
In Rust, it is possible to `allow` particular warnings (diagnostics,
lints) locally, making the compiler ignore instances of a given warning
within a given function, module, block, etc.

It is similar to `#pragma GCC diagnostic push` + `ignored` + `pop` in C:

    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wunused-function"
    static void f(void) {}
    #pragma GCC diagnostic pop

But way less verbose:

    #[allow(dead_code)]
    fn f() {}

By that virtue, it makes it possible to comfortably enable more
diagnostics by default (i.e. outside `W=` levels) that may have some
false positives but that are otherwise quite useful to keep enabled to
catch potential mistakes.

The `#[expect(...)]` attribute [1] takes this further, and makes the
compiler warn if the diagnostic was _not_ produced. For instance, the
following will ensure that, when `f()` is called somewhere, we will have
to remove the attribute:

    #[expect(dead_code)]
    fn f() {}

If we do not, we get a warning from the compiler:

    warning: this lint expectation is unfulfilled
     --> x.rs:3:10
      |
    3 | #[expect(dead_code)]
      |          ^^^^^^^^^
      |
      = note: `#[warn(unfulfilled_lint_expectations)]` on by default

This means that `expect`s do not get forgotten when they are not needed.

See the next commit for more details, nuances on its usage and
documentation on the feature.

The attribute requires the `lint_reasons` [2] unstable feature, but it
is becoming stable in 1.81.0 (to be released on 2024-09-05) and it has
already been useful to clean things up in this patch series, finding
cases where the `allow`s should not have been there.

Thus, enable `lint_reasons` and convert some of our `allow`s to `expect`s
where possible.

This feature was also an example of the ongoing collaboration between
Rust and the kernel -- we tested it in the kernel early on and found an
issue that was quickly resolved [3].

Cc: Fridtjof Stoldt <xfrednet@gmail.com>
Cc: Urgau <urgau@numericable.fr>
Link: https://rust-lang.github.io/rfcs/2383-lint-reasons.html#expect-lint-attribute [1]
Link: https://github.com/rust-lang/rust/issues/54503 [2]
Link: https://github.com/rust-lang/rust/issues/114557 [3]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Tested-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240904204347.168520-18-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-10-07 21:39:57 +02:00
Miguel Ojeda
624063b9ac rust: enable Clippy's check-private-items
In Rust 1.76.0, Clippy added the `check-private-items` lint configuration
option. When turned on (the default is off), it makes several lints
check private items as well.

In our case, it affects two lints we have enabled [1]:
`missing_safety_doc` and `unnecessary_safety_doc`.

It also seems to affect the new `too_long_first_doc_paragraph` lint [2],
even though the documentation does not mention it.

Thus allow the few instances remaining we currently hit and enable
the lint.

Link: https://doc.rust-lang.org/nightly/clippy/lint_configuration.html#check-private-items [1]
Link: https://rust-lang.github.io/rust-clippy/master/index.html#/too_long_first_doc_paragraph [2]
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Tested-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240904204347.168520-16-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-10-07 21:39:57 +02:00
Miguel Ojeda
d5cc7ab0a0 rust: init: remove unneeded #[allow(clippy::disallowed_names)]
These few cases, unlike others in the same file, did not need the `allow`.

Thus clean them up.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Tested-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240904204347.168520-10-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-10-07 21:39:05 +02:00
Miguel Ojeda
db4f72c904 rust: enable clippy::undocumented_unsafe_blocks lint
Checking that we are not missing any `// SAFETY` comments in our `unsafe`
blocks is something we have wanted to do for a long time, as well as
cleaning up the remaining cases that were not documented [1].

Back when Rust for Linux started, this was something that could have
been done via a script, like Rust's `tidy`. Soon after, in Rust 1.58.0,
Clippy implemented the `undocumented_unsafe_blocks` lint [2].

Even though the lint has a few false positives, e.g. in some cases where
attributes appear between the comment and the `unsafe` block [3], there
are workarounds and the lint seems quite usable already.

Thus enable the lint now.

We still have a few cases to clean up, so just allow those for the moment
by writing a `TODO` comment -- some of those may be good candidates for
new contributors.

Link: https://github.com/Rust-for-Linux/linux/issues/351 [1]
Link: https://rust-lang.github.io/rust-clippy/master/#/undocumented_unsafe_blocks [2]
Link: https://github.com/rust-lang/rust-clippy/issues/13189 [3]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Tested-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240904204347.168520-5-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-10-07 21:39:05 +02:00
Benno Lossin
0528ca0a4f rust: init: add assert_pinned macro
Add a macro to statically check if a field of a struct is marked with
`#[pin]` ie that it is structurally pinned. This can be used when
`unsafe` code needs to rely on fields being structurally pinned.

The macro has a special "inline" mode for the case where the type
depends on generic parameters from the surrounding scope.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Co-developed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20240814-linked-list-v5-1-f5f5e8075da0@google.com
[ Replaced `compile_fail` with `ignore` and a TODO note. Removed
  `pub` from example to clean `unreachable_pub` lint. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-08-23 06:25:59 +02:00
Benno Lossin
6d1c22d0ac rust: init: add write_[pin_]init functions
Sometimes it is necessary to split allocation and initialization into
two steps. One such situation is when reusing existing allocations
obtained via `Box::drop_contents`. See [1] for an example.

In order to support this use case add `write_[pin_]init` functions to the
pin-init API. These functions operate on already allocated smart
pointers that wrap `MaybeUninit<T>`.

Link: https://lore.kernel.org/rust-for-linux/f026532f-8594-4f18-9aa5-57ad3f5bc592@proton.me/ [1]
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240819112415.99810-2-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-08-22 00:16:16 +02:00
Alex Mantel
08f983a55c rust: Implement the smart pointer InPlaceInit for Arc
For pinned and unpinned initialization of structs, a trait named
`InPlaceInit` exists for uniform access. `Arc` did not implement
`InPlaceInit` yet, although the functions already existed. The main
reason for that, was that the trait itself returned a `Pin<Self>`. The
`Arc` implementation of the kernel is already implicitly pinned.

To enable `Arc` to implement `InPlaceInit` and to have uniform access,
for in-place and pinned in-place initialization, an associated type is
introduced for `InPlaceInit`. The new implementation of `InPlaceInit`
for `Arc` sets `Arc` as the associated type. Older implementations use
an explicit `Pin<T>` as the associated type. The implemented methods for
`Arc` are mostly moved from a direct implementation on `Arc`. There
should be no user impact. The implementation for `ListArc` is omitted,
because it is not merged yet.

Link: https://github.com/Rust-for-Linux/linux/issues/1079
Signed-off-by: Alex Mantel <alexmantel93@mailbox.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20240727042442.682109-1-alexmantel93@mailbox.org
[ Removed "Rusts" (Benno). - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-08-18 23:10:53 +02:00
Miguel Ojeda
dee1396a48 rust: init: simplify from map_err to inspect_err
A new complexity lint, `manual_inspect` [1], has been introduced in
the upcoming Rust 1.81 (currently in nightly), which checks for uses of
`map*` which return the original item:

    error:
    --> rust/kernel/init.rs:846:23
        |
    846 |         (self.1)(val).map_err(|e| {
        |                       ^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect
        = note: `-D clippy::manual-inspect` implied by `-D warnings`
        = help: to override `-D warnings` add `#[allow(clippy::manual_inspect)]`
    help: try
        |
    846 ~         (self.1)(val).inspect_err(|e| {
    847 |             // SAFETY: `slot` was initialized above.
    848 ~             unsafe { core::ptr::drop_in_place(slot) };
        |

Thus clean them up.

Link: https://rust-lang.github.io/rust-clippy/master/index.html#/manual_inspect [1]
Tested-by: Benno Lossin <benno.lossin@proton.me>
Tested-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20240709160615.998336-3-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-07-10 10:28:51 +02:00
Linus Torvalds
8f5b5f7811 Rust changes for v6.10
The most notable change is the drop of the 'alloc' in-tree fork. This
 is nicely reflected in the diffstat as a ~10k lines drop. In turn, this
 makes the version upgrades way simpler and smaller in the future, e.g.
 the latest one in commit 56f64b3706 ("rust: upgrade to Rust 1.78.0").
 
 More importantly, this increases the chances that a newer compiler
 version just works, which in turn means supporting several compiler
 versions is easier now. Thus we will look into finally setting a minimum
 version in the near future.
 
 Toolchain and infrastructure:
 
  - Upgrade to Rust 1.78.0.
 
    This time around, due to how the kernel and Rust schedules have
    aligned, there are two upgrades in fact. These allow us to remove one
    more unstable feature ('offset_of') from the list, among other
    improvements.
 
  - Drop 'alloc' in-tree fork of the standard library crate, which means
    all the unstable features used by 'alloc' (~30 language ones, ~60
    library ones) are not a concern anymore.
 
  - Support DWARFv5 via the '-Zdwarf-version' flag.
 
  - Support zlib and zstd debuginfo compression via the
    '-Zdebuginfo-compression' flag.
 
 'kernel' crate:
 
  - Support allocation flags ('GFP_*'), particularly in 'Box' (via
    'BoxExt'), 'Vec' (via 'VecExt'), 'Arc' and 'UniqueArc', as well as in
    the 'init' module APIs.
 
  - Remove usage of the 'allocator_api' unstable feature.
 
  - Remove 'try_' prefix in allocation APIs' names.
 
  - Add 'VecExt' (an extension trait) to be able to drop the 'alloc'
    fork.
 
  - Add the '{make,to}_{upper,lower}case()' methods to 'CStr'/'CString'.
 
  - Add the 'as_ptr' method to 'ThisModule'.
 
  - Add the 'from_raw' method to 'ArcBorrow'.
 
  - Add the 'into_unique_or_drop' method to 'Arc'.
 
  - Display column number in the 'dbg!' macro output by applying the
    equivalent change done to the standard library one.
 
  - Migrate 'Work' to '#[pin_data]' thanks to the changes in the 'macros'
    crate, which allows to remove an unsafe call in its 'new' associated
    function.
 
  - Prevent namespacing issues when using the '[try_][pin_]init!' macros
    by changing the generated name of guard variables.
 
  - Make the 'get' method in 'Opaque' const.
 
  - Implement the 'Default' trait for 'LockClassKey'.
 
  - Remove unneeded 'kernel::prelude' imports from doctests.
 
  - Remove redundant imports.
 
 'macros' crate:
 
  - Add 'decl_generics' to 'parse_generics()' to support default values,
    and use that to allow them in '#[pin_data]'.
 
 Helpers:
 
  - Trivial English grammar fix.
 
 Documentation:
 
  - Add section on Rust Kselftests to the "Testing" document.
 
  - Expand the "Abstractions vs. bindings" section of the "General
    Information" document.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmZBIzoACgkQGXyLc2ht
 IW2/7hAAz5fRsx1M1b/JU3P3lc3XKUaFCmAWJX6F+sNHp8vNeFYNzVZ3ylk6Z4zB
 idkTq0Y5Rlc8ejryHiEMaY3X7Zrh0yt3G/AzKZqZx54IAPUp59BRSvG3+SJanQ7p
 Gjy+cCXweLtYjF79Au5Ejt52gV+JAwPtGLkbl1skNs0jPr4rqm+Zg4bPhE5Sr0Eh
 mh2VxcHf3rbIVhBYJTYGNpsnQYZNwfPDJ+bRudYp1BymLYOG8A328ocvU19BM63+
 6FFQBLgB3N8OS+Mw0c8AeFVNkeCw4NesmIkBMco8wm8QXyLz1zjg948LT9ogPCgB
 5eC41yAxa83uPdt8L034YNfJa+IgFleZp339QKW2+vXHks43M8IMLq9WP7GU84M1
 Axu5ekl5sR6awOk0265Zc1ghkOTQREIi0kiqtNBh9wc/qILAD2DyYoy1td9ch1Qi
 BBNxyKYaMx9z+7mhK4ksTbRb+VrdDmFPDhXOIJD5zg4yrLZOM6Mb/O+BnSD2pxa3
 6cUGwfQTv0hbBTeY4ZgdNgFu2YJ/9rqACKtULoaT0AID/d8I3fxc7J35AWnqeC/x
 nALHTa2JMkBvN03Afn0wCVuXbdLW0/9DCGnuuhYMn0DhFC/uuKicsvwfjcGSKnPN
 iaRJoRCYKjlc0AJSYHhavgyp2R9HnVM0E53PC3ubjiKz5DsaRDU=
 =j6/D
 -----END PGP SIGNATURE-----

Merge tag 'rust-6.10' of https://github.com/Rust-for-Linux/linux

Pull Rust updates from Miguel Ojeda:
 "The most notable change is the drop of the 'alloc' in-tree fork. This
  is nicely reflected in the diffstat as a ~10k lines drop. In turn,
  this makes the version upgrades way simpler and smaller in the future,
  e.g. the latest one in commit 56f64b3706 ("rust: upgrade to Rust
  1.78.0").

  More importantly, this increases the chances that a newer compiler
  version just works, which in turn means supporting several compiler
  versions is easier now. Thus we will look into finally setting a
  minimum version in the near future.

  Toolchain and infrastructure:

   - Upgrade to Rust 1.78.0

     This time around, due to how the kernel and Rust schedules have
     aligned, there are two upgrades in fact. These allow us to remove
     one more unstable feature ('offset_of') from the list, among other
     improvements

   - Drop 'alloc' in-tree fork of the standard library crate, which
     means all the unstable features used by 'alloc' (~30 language ones,
     ~60 library ones) are not a concern anymore

   - Support DWARFv5 via the '-Zdwarf-version' flag

   - Support zlib and zstd debuginfo compression via the
     '-Zdebuginfo-compression' flag

  'kernel' crate:

   - Support allocation flags ('GFP_*'), particularly in 'Box' (via
     'BoxExt'), 'Vec' (via 'VecExt'), 'Arc' and 'UniqueArc', as well as
     in the 'init' module APIs

   - Remove usage of the 'allocator_api' unstable feature

   - Remove 'try_' prefix in allocation APIs' names

   - Add 'VecExt' (an extension trait) to be able to drop the 'alloc'
     fork

   - Add the '{make,to}_{upper,lower}case()' methods to 'CStr'/'CString'

   - Add the 'as_ptr' method to 'ThisModule'

   - Add the 'from_raw' method to 'ArcBorrow'

   - Add the 'into_unique_or_drop' method to 'Arc'

   - Display column number in the 'dbg!' macro output by applying the
     equivalent change done to the standard library one

   - Migrate 'Work' to '#[pin_data]' thanks to the changes in the
     'macros' crate, which allows to remove an unsafe call in its 'new'
     associated function

   - Prevent namespacing issues when using the '[try_][pin_]init!'
     macros by changing the generated name of guard variables

   - Make the 'get' method in 'Opaque' const

   - Implement the 'Default' trait for 'LockClassKey'

   - Remove unneeded 'kernel::prelude' imports from doctests

   - Remove redundant imports

  'macros' crate:

   - Add 'decl_generics' to 'parse_generics()' to support default
     values, and use that to allow them in '#[pin_data]'

  Helpers:

   - Trivial English grammar fix

  Documentation:

   - Add section on Rust Kselftests to the 'Testing' document

   - Expand the 'Abstractions vs. bindings' section of the 'General
     Information' document"

* tag 'rust-6.10' of https://github.com/Rust-for-Linux/linux: (31 commits)
  rust: alloc: fix dangling pointer in VecExt<T>::reserve()
  rust: upgrade to Rust 1.78.0
  rust: kernel: remove redundant imports
  rust: sync: implement `Default` for `LockClassKey`
  docs: rust: extend abstraction and binding documentation
  docs: rust: Add instructions for the Rust kselftest
  rust: remove unneeded `kernel::prelude` imports from doctests
  rust: update `dbg!()` to format column number
  rust: helpers: Fix grammar in comment
  rust: init: change the generated name of guard variables
  rust: sync: add `Arc::into_unique_or_drop`
  rust: sync: add `ArcBorrow::from_raw`
  rust: types: Make Opaque::get const
  rust: kernel: remove usage of `allocator_api` unstable feature
  rust: init: update `init` module to take allocation flags
  rust: sync: update `Arc` and `UniqueArc` to take allocation flags
  rust: alloc: update `VecExt` to take allocation flags
  rust: alloc: introduce the `BoxExt` trait
  rust: alloc: introduce allocation flags
  rust: alloc: remove our fork of the `alloc` crate
  ...
2024-05-13 15:13:54 -07:00
Nell Shamrell-Harrington
4a2ae88051 rust: remove unneeded kernel::prelude imports from doctests
Rust doctests implicitly include `kernel::prelude::*`.

Removes explicit `kernel::prelude` imports from doctests.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/1064
Signed-off-by: Nell Shamrell-Harrington <nells@linux.microsoft.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20240411225331.274662-1-nells@linux.microsoft.com
[ Add it back for `module_phy_driver`'s example since it is within a `mod`,
  and thus it cannot be removed. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-05-05 18:09:04 +02:00
Wedson Almeida Filho
2c1092853f rust: kernel: remove usage of allocator_api unstable feature
With the adoption of `BoxExt` and `VecExt`, we don't need the functions
provided by this feature (namely the methods prefixed with `try_` and
different allocator per collection instance).

We do need `AllocError`, but we define our own as it is a trivial empty
struct.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Link: https://lore.kernel.org/r/20240328013603.206764-11-wedsonaf@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-04-16 22:50:04 +02:00
Wedson Almeida Filho
c34aa00d1d rust: init: update init module to take allocation flags
This is the last component in the conversion for allocators to take
allocation flags as parameters.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Link: https://lore.kernel.org/r/20240328013603.206764-10-wedsonaf@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-04-16 22:50:04 +02:00
Wedson Almeida Filho
cc41670e06 rust: sync: update Arc and UniqueArc to take allocation flags
We also remove the `try_` prefix to align with how `Box` and `Vec` are
providing methods now.

`init` is temporarily updated with uses of GFP_KERNEL. These will be
updated in a subsequent patch to take flags as well.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Link: https://lore.kernel.org/r/20240328013603.206764-9-wedsonaf@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-04-16 22:50:04 +02:00
Wedson Almeida Filho
08d3f54928 rust: alloc: introduce the BoxExt trait
Make fallible versions of `new` and `new_uninit` methods available in
`Box` even though it doesn't implement them because we build `alloc`
with the `no_global_oom_handling` config.

They also have an extra `flags` parameter that allows callers to pass
flags to the allocator.

Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20240328013603.206764-7-wedsonaf@gmail.com
[ Used `Box::write()` to avoid one `unsafe` block as suggested by Boqun. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-04-16 22:47:20 +02:00
Laine Taffin Altman
49ceae68a0 rust: init: remove impl Zeroable for Infallible
In Rust, producing an invalid value of any type is immediate undefined
behavior (UB); this includes via zeroing memory.  Therefore, since an
uninhabited type has no valid values, producing any values at all for it is
UB.

The Rust standard library type `core::convert::Infallible` is uninhabited,
by virtue of having been declared as an enum with no cases, which always
produces uninhabited types in Rust.

The current kernel code allows this UB to be triggered, for example by code
like `Box::<core::convert::Infallible>::init(kernel::init::zeroed())`.

Thus, remove the implementation of `Zeroable` for `Infallible`, thereby
avoiding the unsoundness (potential for future UB).

Cc: stable@vger.kernel.org
Fixes: 38cde0bd7b ("rust: init: add `Zeroable` trait and `init::zeroed` function")
Closes: https://github.com/Rust-for-Linux/pinned-init/pull/13
Signed-off-by: Laine Taffin Altman <alexanderaltman@me.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/CA160A4E-561E-4918-837E-3DCEBA74F808@me.com
[ Reformatted the comment slightly. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-04-04 12:56:16 +02:00
Alice Ryhl
e283ee2392 rust: kernel: add reexports for macros
Currently, all macros are reexported with #[macro_export] only, which
means that to access `new_work!` from the workqueue, you need to import
it from the path `kernel::new_work` instead of importing it from the
workqueue module like all other items in the workqueue. By adding
reexports of the macros, it becomes possible to import the macros from
the correct modules.

It's still possible to import the macros from the root, but I don't
think we can do anything about that.

There is no functional change. This is merely a code cleanliness
improvement.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Tested-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20240129145837.1419880-1-aliceryhl@google.com
[ Removed new `use kernel::prelude::*`s, reworded title. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-18 21:22:27 +01:00
Valentin Obst
b6cda913bb rust: kernel: fix multiple typos in documentation
Fixes multiple trivial typos in documentation and comments of the
kernel crate.

allocator:
- Fix a trivial list item alignment issue in the last SAFETY comment of
  `krealloc_aligned`.

init:
- Replace 'type' with 'trait' in the doc comments of the `PinInit` and
  `Init` traits.
- Add colons before starting lists.
- Add spaces between the type and equal sign to respect the code
  formatting rules in example code.
- End a sentence with a full stop instead of a colon.

ioctl:
- Replace 'an' with 'a' where appropriate.

str:
- Replace 'Return' with 'Returns' in the doc comment of `bytes_written`
  as the text describes what the function does.

sync/lock:
- Fix a trivial list item alignment issue in the Safety section of the
  `Backend` trait's description.

sync/lock/spinlock:
- The code in this module operates on spinlocks, not mutexes. Thus,
  replace 'mutex' with 'spinlock' in the SAFETY comment of `unlock`.

workqueue:
- Replace "wont" with "won't" in the doc comment of `__enqueue`.

Signed-off-by: Valentin Obst <kernel@valentinobst.de>
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20240131-doc-fixes-v3-v3-1-0c8af94ed7de@valentinobst.de
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-18 21:22:27 +01:00
Gary Guo
b2516f7af9 rust: kernel: remove #[allow(clippy::new_ret_no_self)]
Clippy triggered a false positive on its `new_ret_no_self` lint
when using the `pin_init!` macro. Since Rust 1.67.0, that does
not happen anymore, since Clippy learnt to not warn about
`-> impl Trait<Self>` [1][2].

The kernel nowadays uses Rust 1.72.1, thus remove the `#[allow]`.

Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Finn Behrens <me@kloenk.dev>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Link: https://github.com/rust-lang/rust-clippy/issues/7344 [1]
Link: https://github.com/rust-lang/rust-clippy/pull/9733 [2]
Link: https://lore.kernel.org/r/20230923024707.47610-1-gary@garyguo.net
[ Reworded slightly and added a couple `Link`s. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-10-05 21:16:13 +02:00
Linus Torvalds
a031fe8d1d Rust changes for v6.6
In terms of lines, most changes this time are on the pinned-init API
 and infrastructure. While we have a Rust version upgrade, and thus a
 bunch of changes from the vendored 'alloc' crate as usual, this time
 those do not account for many lines.
 
 Toolchain and infrastructure:
 
  - Upgrade to Rust 1.71.1. This is the second such upgrade, which is a
    smaller jump compared to the last time.
 
    This version allows us to remove the '__rust_*' allocator functions
    -- the compiler now generates them as expected, thus now our
    'KernelAllocator' is used.
 
    It also introduces the 'offset_of!' macro in the standard library
    (as an unstable feature) which we will need soon. So far, we were
    using a declarative macro as a prerequisite in some not-yet-landed
    patch series, which did not support sub-fields (i.e. nested structs):
 
        #[repr(C)]
        struct S {
            a: u16,
            b: (u8, u8),
        }
 
        assert_eq!(offset_of!(S, b.1), 3);
 
  - Upgrade to bindgen 0.65.1. This is the first time we upgrade its
    version.
 
    Given it is a fairly big jump, it comes with a fair number of
    improvements/changes that affect us, such as a fix needed to support
    LLVM 16 as well as proper support for '__noreturn' C functions, which
    are now mapped to return the '!' type in Rust:
 
        void __noreturn f(void); // C
        pub fn f() -> !;         // Rust
 
  - 'scripts/rust_is_available.sh' improvements and fixes.
 
    This series takes care of all the issues known so far and adds a few
    new checks to cover for even more cases, plus adds some more help
    texts. All this together will hopefully make problematic setups
    easier to identify and to be solved by users building the kernel.
 
    In addition, it adds a test suite which covers all branches of the
    shell script, as well as tests for the issues found so far.
 
  - Support rust-analyzer for out-of-tree modules too.
 
  - Give 'cfg's to rust-analyzer for the 'core' and 'alloc' crates.
 
  - Drop 'scripts/is_rust_module.sh' since it is not needed anymore.
 
 Macros crate:
 
  - New 'paste!' proc macro.
 
    This macro is a more flexible version of 'concat_idents!': it allows
    the resulting identifier to be used to declare new items and it
    allows to transform the identifiers before concatenating them, e.g.
 
        let x_1 = 42;
        paste!(let [<x _2>] = [<x _1>];);
        assert!(x_1 == x_2);
 
    The macro is then used for several of the pinned-init API changes in
    this pull.
 
 Pinned-init API:
 
  - Make '#[pin_data]' compatible with conditional compilation of fields,
    allowing to write code like:
 
        #[pin_data]
        pub struct Foo {
            #[cfg(CONFIG_BAR)]
            a: Bar,
            #[cfg(not(CONFIG_BAR))]
            a: Baz,
        }
 
  - New '#[derive(Zeroable)]' proc macro for the 'Zeroable' trait, which
    allows 'unsafe' implementations for structs where every field
    implements the 'Zeroable' trait, e.g.:
 
        #[derive(Zeroable)]
        pub struct DriverData {
            id: i64,
            buf_ptr: *mut u8,
            len: usize,
        }
 
  - Add '..Zeroable::zeroed()' syntax to the 'pin_init!'  macro for
    zeroing all other fields, e.g.:
 
        pin_init!(Buf {
            buf: [1; 64],
            ..Zeroable::zeroed()
        });
 
  - New '{,pin_}init_array_from_fn()' functions to create array
    initializers given a generator function, e.g.:
 
        let b: Box<[usize; 1_000]> = Box::init::<Error>(
            init_array_from_fn(|i| i)
        ).unwrap();
 
        assert_eq!(b.len(), 1_000);
        assert_eq!(b[123], 123);
 
  - New '{,pin_}chain' methods for '{,Pin}Init<T, E>' that allow to
    execute a closure on the value directly after initialization, e.g.:
 
        let foo = init!(Foo {
            buf <- init::zeroed()
        }).chain(|foo| {
            foo.setup();
            Ok(())
        });
 
  - Support arbitrary paths in init macros, instead of just identifiers
    and generic types.
 
  - Implement the 'Zeroable' trait for the 'UnsafeCell<T>' and
    'Opaque<T>' types.
 
  - Make initializer values inaccessible after initialization.
 
  - Make guards in the init macros hygienic.
 
 'allocator' module:
 
  - Use 'krealloc_aligned()' in 'KernelAllocator::alloc' preventing
    misaligned allocations when the Rust 1.71.1 upgrade is applied later
    in this pull.
 
    The equivalent fix for the previous compiler version (where
    'KernelAllocator' is not yet used) was merged into 6.5 already,
    which added the 'krealloc_aligned()' function used here.
 
  - Implement 'KernelAllocator::{realloc, alloc_zeroed}' for performance,
    using 'krealloc_aligned()' too, which forwards the call to the C API.
 
 'types' module:
 
  - Make 'Opaque' be '!Unpin', removing the need to add a 'PhantomPinned'
    field to Rust structs that contain C structs which must not be moved.
 
  - Make 'Opaque' use 'UnsafeCell' as the outer type, rather than inner.
 
 Documentation:
 
  - Suggest obtaining the source code of the Rust's 'core' library using
    the tarball instead of the repository.
 
 MAINTAINERS:
 
  - Andreas and Alice, from Samsung and Google respectively, are joining
    as reviewers of the "RUST" entry.
 
 As well as a few other minor changes and cleanups.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmTnzOAACgkQGXyLc2ht
 IW0RFg/9FKGAn+JNvLUpB7OIXQZFyDVDpXkL14Dy8At0z609ZhkD36pFAxGua4OC
 BLHpyEQK5bUAQZ4pZ1aexmpFt37z+OPZBMmKoC7eUH2fm8Q277Gm54pno2AzIg3g
 if9lFhIowQTB8pG1YZRF6YMIdIp5JCmT0m8YuXMrr1XYtWIWnyU4twT/bmfk9UKU
 DgmuE1GmpHbWQgIf11eYWxbgfIuY9F/QyHzljW8P+Jgln7F4d8WDVJln8Yw0z/Bm
 w/4kvYv7AHOHQvzjCi971ANvnhsgjeKMSmt2RrcGefn+6t3pNsdZEUYGR9xdAxCz
 fvcje6nUoGjPr9J4F/JdZPmCb7jwSGpF01OvA//H8YjUwP3+msBwxVhRSH1FA1m3
 SVKedXmAUMNAaqtqCNFZmUiNB5LbW4cldFSnNf4CVW9w9bXe2jIKqjjsPi8m57B1
 H4zwr1WTtY2s2n2fdYOAtzmOaOJFXa7PIrGo3onj1mSgcyKOVeoMI5+NR/pwxgIR
 9Z8633bhTfGVHRyC7p0XpakcZd0jbl0yq+bbvgH2sof+RNWYuoZQ92DJ05/g3zOK
 Mj54PNjAgY+Z+TqX/vjlEdWs4SoBcnL3cAy9RFKGRDUoGDPeqiW6qa7Y9oAFZHfk
 PX3oboI0VYn5F9BVGO4i+9cL/CNL4b6sb5FBvL+0EwUBhWTxeKE=
 =BAP+
 -----END PGP SIGNATURE-----

Merge tag 'rust-6.6' of https://github.com/Rust-for-Linux/linux

Pull rust updates from Miguel Ojeda:
 "In terms of lines, most changes this time are on the pinned-init API
  and infrastructure. While we have a Rust version upgrade, and thus a
  bunch of changes from the vendored 'alloc' crate as usual, this time
  those do not account for many lines.

  Toolchain and infrastructure:

   - Upgrade to Rust 1.71.1. This is the second such upgrade, which is a
     smaller jump compared to the last time.

     This version allows us to remove the '__rust_*' allocator functions
     -- the compiler now generates them as expected, thus now our
     'KernelAllocator' is used.

     It also introduces the 'offset_of!' macro in the standard library
     (as an unstable feature) which we will need soon. So far, we were
     using a declarative macro as a prerequisite in some not-yet-landed
     patch series, which did not support sub-fields (i.e. nested
     structs):

         #[repr(C)]
         struct S {
             a: u16,
             b: (u8, u8),
         }

         assert_eq!(offset_of!(S, b.1), 3);

   - Upgrade to bindgen 0.65.1. This is the first time we upgrade its
     version.

     Given it is a fairly big jump, it comes with a fair number of
     improvements/changes that affect us, such as a fix needed to
     support LLVM 16 as well as proper support for '__noreturn' C
     functions, which are now mapped to return the '!' type in Rust:

         void __noreturn f(void); // C
         pub fn f() -> !;         // Rust

   - 'scripts/rust_is_available.sh' improvements and fixes.

     This series takes care of all the issues known so far and adds a
     few new checks to cover for even more cases, plus adds some more
     help texts. All this together will hopefully make problematic
     setups easier to identify and to be solved by users building the
     kernel.

     In addition, it adds a test suite which covers all branches of the
     shell script, as well as tests for the issues found so far.

   - Support rust-analyzer for out-of-tree modules too.

   - Give 'cfg's to rust-analyzer for the 'core' and 'alloc' crates.

   - Drop 'scripts/is_rust_module.sh' since it is not needed anymore.

  Macros crate:

   - New 'paste!' proc macro.

     This macro is a more flexible version of 'concat_idents!': it
     allows the resulting identifier to be used to declare new items and
     it allows to transform the identifiers before concatenating them,
     e.g.

         let x_1 = 42;
         paste!(let [<x _2>] = [<x _1>];);
         assert!(x_1 == x_2);

     The macro is then used for several of the pinned-init API changes
     in this pull.

  Pinned-init API:

   - Make '#[pin_data]' compatible with conditional compilation of
     fields, allowing to write code like:

         #[pin_data]
         pub struct Foo {
             #[cfg(CONFIG_BAR)]
             a: Bar,
             #[cfg(not(CONFIG_BAR))]
             a: Baz,
         }

   - New '#[derive(Zeroable)]' proc macro for the 'Zeroable' trait,
     which allows 'unsafe' implementations for structs where every field
     implements the 'Zeroable' trait, e.g.:

         #[derive(Zeroable)]
         pub struct DriverData {
             id: i64,
             buf_ptr: *mut u8,
             len: usize,
         }

   - Add '..Zeroable::zeroed()' syntax to the 'pin_init!' macro for
     zeroing all other fields, e.g.:

         pin_init!(Buf {
             buf: [1; 64],
             ..Zeroable::zeroed()
         });

   - New '{,pin_}init_array_from_fn()' functions to create array
     initializers given a generator function, e.g.:

         let b: Box<[usize; 1_000]> = Box::init::<Error>(
             init_array_from_fn(|i| i)
         ).unwrap();

         assert_eq!(b.len(), 1_000);
         assert_eq!(b[123], 123);

   - New '{,pin_}chain' methods for '{,Pin}Init<T, E>' that allow to
     execute a closure on the value directly after initialization, e.g.:

         let foo = init!(Foo {
             buf <- init::zeroed()
         }).chain(|foo| {
             foo.setup();
             Ok(())
         });

   - Support arbitrary paths in init macros, instead of just identifiers
     and generic types.

   - Implement the 'Zeroable' trait for the 'UnsafeCell<T>' and
     'Opaque<T>' types.

   - Make initializer values inaccessible after initialization.

   - Make guards in the init macros hygienic.

  'allocator' module:

   - Use 'krealloc_aligned()' in 'KernelAllocator::alloc' preventing
     misaligned allocations when the Rust 1.71.1 upgrade is applied
     later in this pull.

     The equivalent fix for the previous compiler version (where
     'KernelAllocator' is not yet used) was merged into 6.5 already,
     which added the 'krealloc_aligned()' function used here.

   - Implement 'KernelAllocator::{realloc, alloc_zeroed}' for
     performance, using 'krealloc_aligned()' too, which forwards the
     call to the C API.

  'types' module:

   - Make 'Opaque' be '!Unpin', removing the need to add a
     'PhantomPinned' field to Rust structs that contain C structs which
     must not be moved.

   - Make 'Opaque' use 'UnsafeCell' as the outer type, rather than
     inner.

  Documentation:

   - Suggest obtaining the source code of the Rust's 'core' library
     using the tarball instead of the repository.

  MAINTAINERS:

   - Andreas and Alice, from Samsung and Google respectively, are
     joining as reviewers of the "RUST" entry.

  As well as a few other minor changes and cleanups"

* tag 'rust-6.6' of https://github.com/Rust-for-Linux/linux: (42 commits)
  rust: init: update expanded macro explanation
  rust: init: add `{pin_}chain` functions to `{Pin}Init<T, E>`
  rust: init: make `PinInit<T, E>` a supertrait of `Init<T, E>`
  rust: init: implement `Zeroable` for `UnsafeCell<T>` and `Opaque<T>`
  rust: init: add support for arbitrary paths in init macros
  rust: init: add functions to create array initializers
  rust: init: add `..Zeroable::zeroed()` syntax for zeroing all missing fields
  rust: init: make initializer values inaccessible after initializing
  rust: init: wrap type checking struct initializers in a closure
  rust: init: make guards in the init macros hygienic
  rust: add derive macro for `Zeroable`
  rust: init: make `#[pin_data]` compatible with conditional compilation of fields
  rust: init: consolidate init macros
  docs: rust: clarify what 'rustup override' does
  docs: rust: update instructions for obtaining 'core' source
  docs: rust: add command line to rust-analyzer section
  scripts: generate_rust_analyzer: provide `cfg`s for `core` and `alloc`
  rust: bindgen: upgrade to 0.65.1
  rust: enable `no_mangle_with_rust_abi` Clippy lint
  rust: upgrade to Rust 1.71.1
  ...
2023-08-29 08:19:46 -07:00
Benno Lossin
7f8977a7fe rust: init: add {pin_}chain functions to {Pin}Init<T, E>
The `{pin_}chain` functions extend an initializer: it not only
initializes the value, but also executes a closure taking a reference to
the initialized value. This allows to do something with a value directly
after initialization.

Suggested-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20230814084602.25699-13-benno.lossin@proton.me
[ Cleaned a few trivial nits. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:49 +02:00
Benno Lossin
1a8076ac6d rust: init: make PinInit<T, E> a supertrait of Init<T, E>
Remove the blanket implementation of `PinInit<T, E> for I where I:
Init<T, E>`. This blanket implementation prevented custom types that
implement `PinInit`.

Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-12-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:49 +02:00
Benno Lossin
2e704f1883 rust: init: implement Zeroable for UnsafeCell<T> and Opaque<T>
`UnsafeCell<T>` and `T` have the same layout so if `T` is `Zeroable`
then so should `UnsafeCell<T>` be. This allows using the derive macro
for `Zeroable` on types that contain an `UnsafeCell<T>`.
Since `Opaque<T>` contains a `MaybeUninit<T>`, all bytes zero is a valid
bit pattern for that type.

Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-11-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:49 +02:00
Benno Lossin
9e49439077 rust: init: add functions to create array initializers
Add two functions `pin_init_array_from_fn` and `init_array_from_fn` that
take a function that generates initializers for `T` from `usize`, the added
functions then return an initializer for `[T; N]` where every element is
initialized by an element returned from the generator function.

Suggested-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-9-benno.lossin@proton.me
[ Cleaned a couple trivial nits. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:49 +02:00
Benno Lossin
35e7fca2ff rust: init: add ..Zeroable::zeroed() syntax for zeroing all missing fields
Add the struct update syntax to the init macros, but only for
`..Zeroable::zeroed()`. Adding this at the end of the struct initializer
allows one to omit fields from the initializer, these fields will be
initialized with 0x00 set to every byte. Only types that implement the
`Zeroable` trait can utilize this.

Suggested-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-8-benno.lossin@proton.me
[ Rebased on `rust-next` and cleaned a few trivial nits. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:48 +02:00
Benno Lossin
97de919d57 rust: init: make guards in the init macros hygienic
Use hygienic identifiers for the guards instead of the field names. This
makes the init macros feel more like normal struct initializers, since
assigning identifiers with the name of a field does not create
conflicts.

Also change the internals of the guards, no need to make the `forget`
function `unsafe`, since users cannot access the guards anyways. Now the
guards are carried directly on the stack and have no extra `Cell<bool>`
field that marks if they have been forgotten or not, instead they are
just forgotten via `mem::forget`.

Suggested-by: Asahi Lina <lina@asahilina.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-5-benno.lossin@proton.me
[ Cleaned a few trivial nits. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:48 +02:00
Benno Lossin
b3068ac37b rust: init: consolidate init macros
Merges the implementations of `try_init!` and `try_pin_init!`. These two
macros are very similar, but use different traits. The new macro
`__init_internal!` that is now the implementation for both takes these
traits as parameters.

This change does not affect any users, as no public API has been
changed, but it should simplify maintaining the init macros.

Reviewed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230814084602.25699-2-benno.lossin@proton.me
[ Cleaned a couple trivial nits. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-08-21 14:31:33 +02:00
Miguel Ojeda
a30e94c296 rust: init: make doctests compilable/testable
Rust documentation tests are going to be build/run-tested
with the KUnit integration added in a future patch, thus
update them to make them compilable/testable so that we
may start enforcing it.

Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
Reviewed-by: David Gow <davidgow@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 15:38:20 -06:00
Miguel Ojeda
3ed03f4da0 rust: upgrade to Rust 1.68.2
This is the first upgrade to the Rust toolchain since the initial Rust
merge, from 1.62.0 to 1.68.2 (i.e. the latest).

# Context

The kernel currently supports only a single Rust version [1] (rather
than a minimum) given our usage of some "unstable" Rust features [2]
which do not promise backwards compatibility.

The goal is to reach a point where we can declare a minimum version for
the toolchain. For instance, by waiting for some of the features to be
stabilized. Therefore, the first minimum Rust version that the kernel
will support is "in the future".

# Upgrade policy

Given we will eventually need to reach that minimum version, it would be
ideal to upgrade the compiler from time to time to be as close as
possible to that goal and find any issues sooner. In the extreme, we
could upgrade as soon as a new Rust release is out. Of course, upgrading
so often is in stark contrast to what one normally would need for GCC
and LLVM, especially given the release schedule: 6 weeks for Rust vs.
half a year for LLVM and a year for GCC.

Having said that, there is no particular advantage to updating slowly
either: kernel developers in "stable" distributions are unlikely to be
able to use their distribution-provided Rust toolchain for the kernel
anyway [3]. Instead, by routinely upgrading to the latest instead,
kernel developers using Linux distributions that track the latest Rust
release may be able to use those rather than Rust-provided ones,
especially if their package manager allows to pin / hold back /
downgrade the version for some days during windows where the version may
not match. For instance, Arch, Fedora, Gentoo and openSUSE all provide
and track the latest version of Rust as they get released every 6 weeks.

Then, when the minimum version is reached, we will stop upgrading and
decide how wide the window of support will be. For instance, a year of
Rust versions. We will probably want to start small, and then widen it
over time, just like the kernel did originally for LLVM, see commit
3519c4d6e0 ("Documentation: add minimum clang/llvm version").

# Unstable features stabilized

This upgrade allows us to remove the following unstable features since
they were stabilized:

  - `feature(explicit_generic_args_with_impl_trait)` (1.63).
  - `feature(core_ffi_c)` (1.64).
  - `feature(generic_associated_types)` (1.65).
  - `feature(const_ptr_offset_from)` (1.65, *).
  - `feature(bench_black_box)` (1.66, *).
  - `feature(pin_macro)` (1.68).

The ones marked with `*` apply only to our old `rust` branch, not
mainline yet, i.e. only for code that we may potentially upstream.

With this patch applied, the only unstable feature allowed to be used
outside the `kernel` crate is `new_uninit`, though other code to be
upstreamed may increase the list.

Please see [2] for details.

# Other required changes

Since 1.63, `rustdoc` triggers the `broken_intra_doc_links` lint for
links pointing to exported (`#[macro_export]`) `macro_rules`. An issue
was opened upstream [4], but it turns out it is intended behavior. For
the moment, just add an explicit reference for each link. Later we can
revisit this if `rustdoc` removes the compatibility measure.

Nevertheless, this was helpful to discover a link that was pointing to
the wrong place unintentionally. Since that one was actually wrong, it
is fixed in a previous commit independently.

Another change was the addition of `cfg(no_rc)` and `cfg(no_sync)` in
upstream [5], thus remove our original changes for that.

Similarly, upstream now tests that it compiles successfully with
`#[cfg(not(no_global_oom_handling))]` [6], which allow us to get rid
of some changes, such as an `#[allow(dead_code)]`.

In addition, remove another `#[allow(dead_code)]` due to new uses
within the standard library.

Finally, add `try_extend_trusted` and move the code in `spec_extend.rs`
since upstream moved it for the infallible version.

# `alloc` upgrade and reviewing

There are a large amount of changes, but the vast majority of them are
due to our `alloc` fork being upgraded at once.

There are two kinds of changes to be aware of: the ones coming from
upstream, which we should follow as closely as possible, and the updates
needed in our added fallible APIs to keep them matching the newer
infallible APIs coming from upstream.

Instead of taking a look at the diff of this patch, an alternative
approach is reviewing a diff of the changes between upstream `alloc` and
the kernel's. This allows to easily inspect the kernel additions only,
especially to check if the fallible methods we already have still match
the infallible ones in the new version coming from upstream.

Another approach is reviewing the changes introduced in the additions in
the kernel fork between the two versions. This is useful to spot
potentially unintended changes to our additions.

To apply these approaches, one may follow steps similar to the following
to generate a pair of patches that show the differences between upstream
Rust and the kernel (for the subset of `alloc` we use) before and after
applying this patch:

    # Get the difference with respect to the old version.
    git -C rust checkout $(linux/scripts/min-tool-version.sh rustc)
    git -C linux ls-tree -r --name-only HEAD -- rust/alloc |
        cut -d/ -f3- |
        grep -Fv README.md |
        xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH
    git -C linux diff --patch-with-stat --summary -R > old.patch
    git -C linux restore rust/alloc

    # Apply this patch.
    git -C linux am rust-upgrade.patch

    # Get the difference with respect to the new version.
    git -C rust checkout $(linux/scripts/min-tool-version.sh rustc)
    git -C linux ls-tree -r --name-only HEAD -- rust/alloc |
        cut -d/ -f3- |
        grep -Fv README.md |
        xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH
    git -C linux diff --patch-with-stat --summary -R > new.patch
    git -C linux restore rust/alloc

Now one may check the `new.patch` to take a look at the additions (first
approach) or at the difference between those two patches (second
approach). For the latter, a side-by-side tool is recommended.

Link: https://rust-for-linux.com/rust-version-policy [1]
Link: https://github.com/Rust-for-Linux/linux/issues/2 [2]
Link: https://lore.kernel.org/rust-for-linux/CANiq72mT3bVDKdHgaea-6WiZazd8Mvurqmqegbe5JZxVyLR8Yg@mail.gmail.com/ [3]
Link: https://github.com/rust-lang/rust/issues/106142 [4]
Link: https://github.com/rust-lang/rust/pull/89891 [5]
Link: https://github.com/rust-lang/rust/pull/98652 [6]
Reviewed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-By: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Tested-by: Ariel Miculas <amiculas@cisco.com>
Tested-by: David Gow <davidgow@google.com>
Tested-by: Boqun Feng <boqun.feng@gmail.com>
Link: https://lore.kernel.org/r/20230418214347.324156-4-ojeda@kernel.org
[ Removed `feature(core_ffi_c)` from `uapi` ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-05-31 17:35:03 +02:00
Benno Lossin
52a7f2deb4 rust: init: broaden the blanket impl of Init
This makes it possible to use `T` as a `impl Init<T, E>` for every error
type `E` instead of just `Infallible`.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Link: https://lore.kernel.org/r/20230413100157.740697-1-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-21 00:35:26 +02:00
Benno Lossin
692e8935e2 rust: types: add Opaque::ffi_init
This function allows to easily initialize `Opaque` with the pin-init
API. `Opaque::ffi_init` takes a closure and returns a pin-initializer.
This pin-initiailizer calls the given closure with a pointer to the
inner `T`.

Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20230408122429.1103522-14-y86-dev@protonmail.com
[ Fixed typo. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00
Benno Lossin
38cde0bd7b rust: init: add Zeroable trait and init::zeroed function
Add the `Zeroable` trait which marks types that can be initialized by
writing `0x00` to every byte of the type. Also add the `init::zeroed`
function that creates an initializer for a `Zeroable` type that writes
`0x00` to every byte.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20230408122429.1103522-12-y86-dev@protonmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00
Benno Lossin
6841d45a30 rust: init: add stack_pin_init! macro
The `stack_pin_init!` macro allows pin-initializing a value on the
stack. It accepts a `impl PinInit<T, E>` to initialize a `T`. It allows
propagating any errors via `?` or handling it normally via `match`.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20230408122429.1103522-11-y86-dev@protonmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00
Benno Lossin
d0fdc39612 rust: init: add PinnedDrop trait and macros
The `PinnedDrop` trait that facilitates destruction of pinned types.
It has to be implemented via the `#[pinned_drop]` macro, since the
`drop` function should not be called by normal code, only by other
destructors. It also only works on structs that are annotated with
`#[pin_data(PinnedDrop)]`.

Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20230408122429.1103522-10-y86-dev@protonmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00
Benno Lossin
92c4a1e7e8 rust: init/sync: add InPlaceInit trait to pin-initialize smart pointers
The `InPlaceInit` trait that provides two functions, for initializing
using `PinInit<T, E>` and `Init<T>`. It is implemented by `Arc<T>`,
`UniqueArc<T>` and `Box<T>`.

Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20230408122429.1103522-9-y86-dev@protonmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00
Benno Lossin
fc6c6baa1f rust: init: add initialization macros
Add the following initializer macros:
- `#[pin_data]` to annotate structurally pinned fields of structs,
  needed for `pin_init!` and `try_pin_init!` to select the correct
  initializer of fields.
- `pin_init!` create a pin-initializer for a struct with the
  `Infallible` error type.
- `try_pin_init!` create a pin-initializer for a struct with a custom
  error type (`kernel::error::Error` is the default).
- `init!` create an in-place-initializer for a struct with the
  `Infallible` error type.
- `try_init!` create an in-place-initializer for a struct with a custom
  error type (`kernel::error::Error` is the default).

Also add their needed internal helper traits and structs.

Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20230408122429.1103522-8-y86-dev@protonmail.com
[ Fixed three typos. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00
Benno Lossin
90e53c5e70 rust: add pin-init API core
This API is used to facilitate safe pinned initialization of structs. It
replaces cumbersome `unsafe` manual initialization with elegant safe macro
invocations.

Due to the size of this change it has been split into six commits:
1. This commit introducing the basic public interface: traits and
   functions to represent and create initializers.
2. Adds the `#[pin_data]`, `pin_init!`, `try_pin_init!`, `init!` and
   `try_init!` macros along with their internal types.
3. Adds the `InPlaceInit` trait that allows using an initializer to create
   an object inside of a `Box<T>` and other smart pointers.
4. Adds the `PinnedDrop` trait and adds macro support for it in
   the `#[pin_data]` macro.
5. Adds the `stack_pin_init!` macro allowing to pin-initialize a struct on
   the stack.
6. Adds the `Zeroable` trait and `init::zeroed` function to initialize
   types that have `0x00` in all bytes as a valid bit pattern.

--

In this section the problem that the new pin-init API solves is outlined.
This message describes the entirety of the API, not just the parts
introduced in this commit. For a more granular explanation and additional
information on pinning and this issue, view [1].

Pinning is Rust's way of enforcing the address stability of a value. When a
value gets pinned it will be impossible for safe code to move it to another
location. This is done by wrapping pointers to said object with `Pin<P>`.
This wrapper prevents safe code from creating mutable references to the
object, preventing mutable access, which is needed to move the value.
`Pin<P>` provides `unsafe` functions to circumvent this and allow
modifications regardless. It is then the programmer's responsibility to
uphold the pinning guarantee.

Many kernel data structures require a stable address, because there are
foreign pointers to them which would get invalidated by moving the
structure. Since these data structures are usually embedded in structs to
use them, this pinning property propagates to the container struct.
Resulting in most structs in both Rust and C code needing to be pinned.

So if we want to have a `mutex` field in a Rust struct, this struct also
needs to be pinned, because a `mutex` contains a `list_head`. Additionally
initializing a `list_head` requires already having the final memory
location available, because it is initialized by pointing it to itself. But
this presents another challenge in Rust: values have to be initialized at
all times. There is the `MaybeUninit<T>` wrapper type, which allows
handling uninitialized memory, but this requires using the `unsafe` raw
pointers and a casting the type to the initialized variant.

This problem gets exacerbated when considering encapsulation and the normal
safety requirements of Rust code. The fields of the Rust `Mutex<T>` should
not be accessible to normal driver code. After all if anyone can modify
the fields, there is no way to ensure the invariants of the `Mutex<T>` are
upheld. But if the fields are inaccessible, then initialization of a
`Mutex<T>` needs to be somehow achieved via a function or a macro. Because
the `Mutex<T>` must be pinned in memory, the function cannot return it by
value. It also cannot allocate a `Box` to put the `Mutex<T>` into, because
that is an unnecessary allocation and indirection which would hurt
performance.

The solution in the rust tree (e.g. this commit: [2]) that is replaced by
this API is to split this function into two parts:

1. A `new` function that returns a partially initialized `Mutex<T>`,
2. An `init` function that requires the `Mutex<T>` to be pinned and that
   fully initializes the `Mutex<T>`.

Both of these functions have to be marked `unsafe`, since a call to `new`
needs to be accompanied with a call to `init`, otherwise using the
`Mutex<T>` could result in UB. And because calling `init` twice also is not
safe. While `Mutex<T>` initialization cannot fail, other structs might
also have to allocate memory, which would result in conditional successful
initialization requiring even more manual accommodation work.

Combine this with the problem of pin-projections -- the way of accessing
fields of a pinned struct -- which also have an `unsafe` API, pinned
initialization is riddled with `unsafe` resulting in very poor ergonomics.
Not only that, but also having to call two functions possibly multiple
lines apart makes it very easy to forget it outright or during refactoring.

Here is an example of the current way of initializing a struct with two
synchronization primitives (see [3] for the full example):

    struct SharedState {
        state_changed: CondVar,
        inner: Mutex<SharedStateInner>,
    }

    impl SharedState {
        fn try_new() -> Result<Arc<Self>> {
            let mut state = Pin::from(UniqueArc::try_new(Self {
                // SAFETY: `condvar_init!` is called below.
                state_changed: unsafe { CondVar::new() },
                // SAFETY: `mutex_init!` is called below.
                inner: unsafe {
                    Mutex::new(SharedStateInner { token_count: 0 })
                },
            })?);

            // SAFETY: `state_changed` is pinned when `state` is.
            let pinned = unsafe {
                state.as_mut().map_unchecked_mut(|s| &mut s.state_changed)
            };
            kernel::condvar_init!(pinned, "SharedState::state_changed");

            // SAFETY: `inner` is pinned when `state` is.
            let pinned = unsafe {
                state.as_mut().map_unchecked_mut(|s| &mut s.inner)
            };
            kernel::mutex_init!(pinned, "SharedState::inner");

            Ok(state.into())
        }
    }

The pin-init API of this patch solves this issue by providing a
comprehensive solution comprised of macros and traits. Here is the example
from above using the pin-init API:

    #[pin_data]
    struct SharedState {
        #[pin]
        state_changed: CondVar,
        #[pin]
        inner: Mutex<SharedStateInner>,
    }

    impl SharedState {
        fn new() -> impl PinInit<Self> {
            pin_init!(Self {
                state_changed <- new_condvar!("SharedState::state_changed"),
                inner <- new_mutex!(
                    SharedStateInner { token_count: 0 },
                    "SharedState::inner",
                ),
            })
        }
    }

Notably the way the macro is used here requires no `unsafe` and thus comes
with the usual Rust promise of safe code not introducing any memory
violations. Additionally it is now up to the caller of `new()` to decide
the memory location of the `SharedState`. They can choose at the moment
`Arc<T>`, `Box<T>` or the stack.

--

The API has the following architecture:
1. Initializer traits `PinInit<T, E>` and `Init<T, E>` that act like
   closures.
2. Macros to create these initializer traits safely.
3. Functions to allow manually writing initializers.

The initializers (an `impl PinInit<T, E>`) receive a raw pointer pointing
to uninitialized memory and their job is to fully initialize a `T` at that
location. If initialization fails, they return an error (`E`) by value.

This way of initializing cannot be safely exposed to the user, since it
relies upon these properties outside of the control of the trait:
- the memory location (slot) needs to be valid memory,
- if initialization fails, the slot should not be read from,
- the value in the slot should be pinned, so it cannot move and the memory
  cannot be deallocated until the value is dropped.

This is why using an initializer is facilitated by another trait that
ensures these requirements.

These initializers can be created manually by just supplying a closure that
fulfills the same safety requirements as `PinInit<T, E>`. But this is an
`unsafe` operation. To allow safe initializer creation, the `pin_init!` is
provided along with three other variants: `try_pin_init!`, `try_init!` and
`init!`. These take a modified struct initializer as a parameter and
generate a closure that initializes the fields in sequence.
The macros take great care in upholding the safety requirements:
- A shadowed struct type is used as the return type of the closure instead
  of `()`. This is to prevent early returns, as these would prevent full
  initialization.
- To ensure every field is only initialized once, a normal struct
  initializer is placed in unreachable code. The type checker will emit
  errors if a field is missing or specified multiple times.
- When initializing a field fails, the whole initializer will fail and
  automatically drop fields that have been initialized earlier.
- Only the correct initializer type is allowed for unpinned fields. You
  cannot use a `impl PinInit<T, E>` to initialize a structurally not pinned
  field.

To ensure the last point, an additional macro `#[pin_data]` is needed. This
macro annotates the struct itself and the user specifies structurally
pinned and not pinned fields.

Because dropping a pinned struct is also not allowed to break the pinning
invariants, another macro attribute `#[pinned_drop]` is needed. This
macro is introduced in a following commit.

These two macros also have mechanisms to ensure the overall safety of the
API. Additionally, they utilize a combined proc-macro, declarative macro
design: first a proc-macro enables the outer attribute syntax `#[...]` and
does some important pre-parsing. Notably this prepares the generics such
that the declarative macro can handle them using token trees. Then the
actual parsing of the structure and the emission of code is handled by a
declarative macro.

For pin-projections the crates `pin-project` [4] and `pin-project-lite` [5]
had been considered, but were ultimately rejected:
- `pin-project` depends on `syn` [6] which is a very big dependency, around
  50k lines of code.
- `pin-project-lite` is a more reasonable 5k lines of code, but contains a
  very complex declarative macro to parse generics. On top of that it
  would require modification that would need to be maintained
  independently.

Link: https://rust-for-linux.com/the-safe-pinned-initialization-problem [1]
Link: 0a04dc4ddd [2]
Link: f509ede33f/samples/rust/rust_miscdev.rs [3]
Link: https://crates.io/crates/pin-project [4]
Link: https://crates.io/crates/pin-project-lite [5]
Link: https://crates.io/crates/syn [6]
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Wedson Almeida Filho <wedsonaf@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20230408122429.1103522-7-y86-dev@protonmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-04-12 18:41:05 +02:00