linux/rust/alloc/vec/is_zero.rs

205 lines
5.8 KiB
Rust
Raw Normal View History

// SPDX-License-Identifier: Apache-2.0 OR MIT
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
use core::num::{Saturating, Wrapping};
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
use crate::boxed::Box;
#[rustc_specialization_trait]
pub(super) unsafe trait IsZero {
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
/// Whether this value's representation is all zeros,
/// or can be represented with all zeroes.
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
fn is_zero(&self) -> bool;
}
macro_rules! impl_is_zero {
($t:ty, $is_zero:expr) => {
unsafe impl IsZero for $t {
#[inline]
fn is_zero(&self) -> bool {
$is_zero(*self)
}
}
};
}
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
impl_is_zero!(i8, |x| x == 0); // It is needed to impl for arrays and tuples of i8.
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
impl_is_zero!(i16, |x| x == 0);
impl_is_zero!(i32, |x| x == 0);
impl_is_zero!(i64, |x| x == 0);
impl_is_zero!(i128, |x| x == 0);
impl_is_zero!(isize, |x| x == 0);
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
impl_is_zero!(u8, |x| x == 0); // It is needed to impl for arrays and tuples of u8.
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
impl_is_zero!(u16, |x| x == 0);
impl_is_zero!(u32, |x| x == 0);
impl_is_zero!(u64, |x| x == 0);
impl_is_zero!(u128, |x| x == 0);
impl_is_zero!(usize, |x| x == 0);
impl_is_zero!(bool, |x| x == false);
impl_is_zero!(char, |x| x == '\0');
impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
impl_is_zero!(f64, |x: f64| x.to_bits() == 0);
unsafe impl<T> IsZero for *const T {
#[inline]
fn is_zero(&self) -> bool {
(*self).is_null()
}
}
unsafe impl<T> IsZero for *mut T {
#[inline]
fn is_zero(&self) -> bool {
(*self).is_null()
}
}
unsafe impl<T: IsZero, const N: usize> IsZero for [T; N] {
#[inline]
fn is_zero(&self) -> bool {
// Because this is generated as a runtime check, it's not obvious that
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
// it's worth doing if the array is really long. The threshold here
// is largely arbitrary, but was picked because as of 2022-07-01 LLVM
// fails to const-fold the check in `vec![[1; 32]; n]`
// See https://github.com/rust-lang/rust/pull/97581#issuecomment-1166628022
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
// Feel free to tweak if you have better evidence.
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
N <= 16 && self.iter().all(IsZero::is_zero)
}
}
// This is recursive macro.
macro_rules! impl_for_tuples {
// Stopper
() => {
// No use for implementing for empty tuple because it is ZST.
};
($first_arg:ident $(,$rest:ident)*) => {
unsafe impl <$first_arg: IsZero, $($rest: IsZero,)*> IsZero for ($first_arg, $($rest,)*){
#[inline]
fn is_zero(&self) -> bool{
// Destructure tuple to N references
// Rust allows to hide generic params by local variable names.
#[allow(non_snake_case)]
let ($first_arg, $($rest,)*) = self;
$first_arg.is_zero()
$( && $rest.is_zero() )*
}
}
impl_for_tuples!($($rest),*);
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
}
}
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
impl_for_tuples!(A, B, C, D, E, F, G, H);
rust: import upstream `alloc` crate This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: https://github.com/Rust-for-Linux/linux/issues/408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-06 17:52:44 +02:00
// `Option<&T>` and `Option<Box<T>>` are guaranteed to represent `None` as null.
// For fat pointers, the bytes that would be the pointer metadata in the `Some`
// variant are padding in the `None` variant, so ignoring them and
// zero-initializing instead is ok.
// `Option<&mut T>` never implements `Clone`, so there's no need for an impl of
// `SpecFromElem`.
unsafe impl<T: ?Sized> IsZero for Option<&T> {
#[inline]
fn is_zero(&self) -> bool {
self.is_none()
}
}
unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
#[inline]
fn is_zero(&self) -> bool {
self.is_none()
}
}
// `Option<num::NonZeroU32>` and similar have a representation guarantee that
// they're the same size as the corresponding `u32` type, as well as a guarantee
// that transmuting between `NonZeroU32` and `Option<num::NonZeroU32>` works.
// While the documentation officially makes it UB to transmute from `None`,
// we're the standard library so we can make extra inferences, and we know that
// the only niche available to represent `None` is the one that's all zeros.
macro_rules! impl_is_zero_option_of_nonzero {
($($t:ident,)+) => {$(
unsafe impl IsZero for Option<core::num::$t> {
#[inline]
fn is_zero(&self) -> bool {
self.is_none()
}
}
)+};
}
impl_is_zero_option_of_nonzero!(
NonZeroU8,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU128,
NonZeroI8,
NonZeroI16,
NonZeroI32,
NonZeroI64,
NonZeroI128,
NonZeroUsize,
NonZeroIsize,
);
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 3519c4d6e08e ("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-04-18 23:43:47 +02:00
macro_rules! impl_is_zero_option_of_num {
($($t:ty,)+) => {$(
unsafe impl IsZero for Option<$t> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
assert!(none.is_none());
}
self.is_none()
}
}
)+};
}
impl_is_zero_option_of_num!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize,);
unsafe impl<T: IsZero> IsZero for Wrapping<T> {
#[inline]
fn is_zero(&self) -> bool {
self.0.is_zero()
}
}
unsafe impl<T: IsZero> IsZero for Saturating<T> {
#[inline]
fn is_zero(&self) -> bool {
self.0.is_zero()
}
}
macro_rules! impl_for_optional_bool {
($($t:ty,)+) => {$(
unsafe impl IsZero for $t {
#[inline]
fn is_zero(&self) -> bool {
// SAFETY: This is *not* a stable layout guarantee, but
// inside `core` we're allowed to rely on the current rustc
// behaviour that options of bools will be one byte with
// no padding, so long as they're nested less than 254 deep.
let raw: u8 = unsafe { core::mem::transmute(*self) };
raw == 0
}
}
)+};
}
impl_for_optional_bool! {
Option<bool>,
Option<Option<bool>>,
Option<Option<Option<bool>>>,
// Could go further, but not worth the metadata overhead
}