mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
Merge tag 'rust-fixes-6.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull rust fixes from Miguel Ojeda:
"Toolchain and infrastructure:
- Disallow BTF generation with Rust + LTO
- Improve rust-analyzer support
'kernel' crate:
- 'init' module: remove 'Zeroable' implementation for a couple types
that should not have it
- 'alloc' module: fix macOS failure in host test by satisfying POSIX
alignment requirement
- Add missing '\n's to 'pr_*!()' calls
And a couple other minor cleanups"
* tag 'rust-fixes-6.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux:
scripts: generate_rust_analyzer: add uapi crate
scripts: generate_rust_analyzer: add missing include_dirs
scripts: generate_rust_analyzer: add missing macros deps
rust: Disallow BTF generation with Rust + LTO
rust: task: fix `SAFETY` comment in `Task::wake_up`
rust: workqueue: add missing newline to pr_info! examples
rust: sync: add missing newline in locked_by log example
rust: init: add missing newline to pr_info! calls
rust: error: add missing newline to pr_warn! calls
rust: docs: add missing newline to printing macro examples
rust: alloc: satisfy POSIX alignment requirement
rust: init: fix `Zeroable` implementation for `Option<NonNull<T>>` and `Option<KBox<T>>`
rust: remove leftover mentions of the `alloc` crate
This commit is contained in:
@@ -145,7 +145,7 @@ Rust standard library source
|
||||
****************************
|
||||
|
||||
The Rust standard library source is required because the build system will
|
||||
cross-compile ``core`` and ``alloc``.
|
||||
cross-compile ``core``.
|
||||
|
||||
If ``rustup`` is being used, run::
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ operator are also supported as usual, e.g.:
|
||||
|
||||
/// ```
|
||||
/// # use kernel::{spawn_work_item, workqueue};
|
||||
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
|
||||
/// spawn_work_item!(workqueue::system(), || pr_info!("x\n"))?;
|
||||
/// # Ok::<(), Error>(())
|
||||
/// ```
|
||||
|
||||
|
||||
@@ -1973,7 +1973,7 @@ config RUST
|
||||
depends on !MODVERSIONS || GENDWARFKSYMS
|
||||
depends on !GCC_PLUGIN_RANDSTRUCT
|
||||
depends on !RANDSTRUCT
|
||||
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
|
||||
depends on !DEBUG_INFO_BTF || (PAHOLE_HAS_LANG_EXCLUDE && !LTO)
|
||||
depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
|
||||
select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
|
||||
depends on !CALL_PADDING || RUSTC_VERSION >= 108100
|
||||
|
||||
@@ -62,6 +62,24 @@ unsafe fn realloc(
|
||||
));
|
||||
}
|
||||
|
||||
// ISO C (ISO/IEC 9899:2011) defines `aligned_alloc`:
|
||||
//
|
||||
// > The value of alignment shall be a valid alignment supported by the implementation
|
||||
// [...].
|
||||
//
|
||||
// As an example of the "supported by the implementation" requirement, POSIX.1-2001 (IEEE
|
||||
// 1003.1-2001) defines `posix_memalign`:
|
||||
//
|
||||
// > The value of alignment shall be a power of two multiple of sizeof (void *).
|
||||
//
|
||||
// and POSIX-based implementations of `aligned_alloc` inherit this requirement. At the time
|
||||
// of writing, this is known to be the case on macOS (but not in glibc).
|
||||
//
|
||||
// Satisfy the stricter requirement to avoid spurious test failures on some platforms.
|
||||
let min_align = core::mem::size_of::<*const crate::ffi::c_void>();
|
||||
let layout = layout.align_to(min_align).map_err(|_| AllocError)?;
|
||||
let layout = layout.pad_to_align();
|
||||
|
||||
// SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or
|
||||
// exceeds the given size and alignment requirements.
|
||||
let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8;
|
||||
|
||||
@@ -107,7 +107,7 @@ pub fn from_errno(errno: crate::ffi::c_int) -> Error {
|
||||
} else {
|
||||
// TODO: Make it a `WARN_ONCE` once available.
|
||||
crate::pr_warn!(
|
||||
"attempted to create `Error` with out of range `errno`: {}",
|
||||
"attempted to create `Error` with out of range `errno`: {}\n",
|
||||
errno
|
||||
);
|
||||
code::EINVAL
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
/// },
|
||||
/// }));
|
||||
/// let foo: Pin<&mut Foo> = foo;
|
||||
/// pr_info!("a: {}", &*foo.a.lock());
|
||||
/// pr_info!("a: {}\n", &*foo.a.lock());
|
||||
/// ```
|
||||
///
|
||||
/// # Syntax
|
||||
@@ -319,7 +319,7 @@ macro_rules! stack_pin_init {
|
||||
/// }, GFP_KERNEL)?,
|
||||
/// }));
|
||||
/// let foo = foo.unwrap();
|
||||
/// pr_info!("a: {}", &*foo.a.lock());
|
||||
/// pr_info!("a: {}\n", &*foo.a.lock());
|
||||
/// ```
|
||||
///
|
||||
/// ```rust,ignore
|
||||
@@ -352,7 +352,7 @@ macro_rules! stack_pin_init {
|
||||
/// x: 64,
|
||||
/// }, GFP_KERNEL)?,
|
||||
/// }));
|
||||
/// pr_info!("a: {}", &*foo.a.lock());
|
||||
/// pr_info!("a: {}\n", &*foo.a.lock());
|
||||
/// # Ok::<_, AllocError>(())
|
||||
/// ```
|
||||
///
|
||||
@@ -882,7 +882,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn setup(self: Pin<&mut Self>) {
|
||||
/// pr_info!("Setting up foo");
|
||||
/// pr_info!("Setting up foo\n");
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
@@ -986,7 +986,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn setup(&mut self) {
|
||||
/// pr_info!("Setting up foo");
|
||||
/// pr_info!("Setting up foo\n");
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
@@ -1336,7 +1336,7 @@ fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Ini
|
||||
/// #[pinned_drop]
|
||||
/// impl PinnedDrop for Foo {
|
||||
/// fn drop(self: Pin<&mut Self>) {
|
||||
/// pr_info!("Foo is being dropped!");
|
||||
/// pr_info!("Foo is being dropped!\n");
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
@@ -1418,17 +1418,14 @@ macro_rules! impl_zeroable {
|
||||
// SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.
|
||||
{<T: ?Sized + Zeroable>} UnsafeCell<T>,
|
||||
|
||||
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
|
||||
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:
|
||||
// https://doc.rust-lang.org/stable/std/option/index.html#representation).
|
||||
Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>,
|
||||
Option<NonZeroU128>, Option<NonZeroUsize>,
|
||||
Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>,
|
||||
Option<NonZeroI128>, Option<NonZeroIsize>,
|
||||
|
||||
// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
|
||||
//
|
||||
// In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant.
|
||||
{<T: ?Sized>} Option<NonNull<T>>,
|
||||
{<T: ?Sized>} Option<KBox<T>>,
|
||||
{<T>} Option<NonNull<T>>,
|
||||
{<T>} Option<KBox<T>>,
|
||||
|
||||
// SAFETY: `null` pointer is valid.
|
||||
//
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
//! #[pinned_drop]
|
||||
//! impl PinnedDrop for Foo {
|
||||
//! fn drop(self: Pin<&mut Self>) {
|
||||
//! pr_info!("{self:p} is getting dropped.");
|
||||
//! pr_info!("{self:p} is getting dropped.\n");
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
@@ -412,7 +412,7 @@
|
||||
//! #[pinned_drop]
|
||||
//! impl PinnedDrop for Foo {
|
||||
//! fn drop(self: Pin<&mut Self>) {
|
||||
//! pr_info!("{self:p} is getting dropped.");
|
||||
//! pr_info!("{self:p} is getting dropped.\n");
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
@@ -423,7 +423,7 @@
|
||||
//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
|
||||
//! unsafe impl ::kernel::init::PinnedDrop for Foo {
|
||||
//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
|
||||
//! pr_info!("{self:p} is getting dropped.");
|
||||
//! pr_info!("{self:p} is getting dropped.\n");
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! usage by Rust code in the kernel and is shared by all of them.
|
||||
//!
|
||||
//! In other words, all the rest of the Rust code in the kernel (e.g. kernel
|
||||
//! modules written in Rust) depends on [`core`], [`alloc`] and this crate.
|
||||
//! modules written in Rust) depends on [`core`] and this crate.
|
||||
//!
|
||||
//! If you need a kernel C API that is not ported or wrapped yet here, then
|
||||
//! do so first instead of bypassing this crate.
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
/// fn print_bytes_used(dir: &Directory, file: &File) {
|
||||
/// let guard = dir.inner.lock();
|
||||
/// let inner_file = file.inner.access(&guard);
|
||||
/// pr_info!("{} {}", guard.bytes_used, inner_file.bytes_used);
|
||||
/// pr_info!("{} {}\n", guard.bytes_used, inner_file.bytes_used);
|
||||
/// }
|
||||
///
|
||||
/// /// Increments `bytes_used` for both the directory and file.
|
||||
|
||||
@@ -320,7 +320,7 @@ pub fn tgid_nr_ns(&self, pidns: Option<&PidNamespace>) -> Pid {
|
||||
|
||||
/// Wakes up the task.
|
||||
pub fn wake_up(&self) {
|
||||
// SAFETY: It's always safe to call `signal_pending` on a valid task, even if the task
|
||||
// SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task
|
||||
// running.
|
||||
unsafe { bindings::wake_up_process(self.as_ptr()) };
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
//! type Pointer = Arc<MyStruct>;
|
||||
//!
|
||||
//! fn run(this: Arc<MyStruct>) {
|
||||
//! pr_info!("The value is: {}", this.value);
|
||||
//! pr_info!("The value is: {}\n", this.value);
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
@@ -108,7 +108,7 @@
|
||||
//! type Pointer = Arc<MyStruct>;
|
||||
//!
|
||||
//! fn run(this: Arc<MyStruct>) {
|
||||
//! pr_info!("The value is: {}", this.value_1);
|
||||
//! pr_info!("The value is: {}\n", this.value_1);
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
@@ -116,7 +116,7 @@
|
||||
//! type Pointer = Arc<MyStruct>;
|
||||
//!
|
||||
//! fn run(this: Arc<MyStruct>) {
|
||||
//! pr_info!("The second value is: {}", this.value_2);
|
||||
//! pr_info!("The second value is: {}\n", this.value_2);
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
|
||||
@@ -57,14 +57,26 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
||||
crates_indexes[display_name] = len(crates)
|
||||
crates.append(crate)
|
||||
|
||||
# First, the ones in `rust/` since they are a bit special.
|
||||
append_crate(
|
||||
"core",
|
||||
sysroot_src / "core" / "src" / "lib.rs",
|
||||
[],
|
||||
cfg=crates_cfgs.get("core", []),
|
||||
is_workspace_member=False,
|
||||
)
|
||||
def append_sysroot_crate(
|
||||
display_name,
|
||||
deps,
|
||||
cfg=[],
|
||||
):
|
||||
append_crate(
|
||||
display_name,
|
||||
sysroot_src / display_name / "src" / "lib.rs",
|
||||
deps,
|
||||
cfg,
|
||||
is_workspace_member=False,
|
||||
)
|
||||
|
||||
# NB: sysroot crates reexport items from one another so setting up our transitive dependencies
|
||||
# here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth
|
||||
# for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`.
|
||||
append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []))
|
||||
append_sysroot_crate("alloc", ["core"])
|
||||
append_sysroot_crate("std", ["alloc", "core"])
|
||||
append_sysroot_crate("proc_macro", ["core", "std"])
|
||||
|
||||
append_crate(
|
||||
"compiler_builtins",
|
||||
@@ -75,7 +87,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
||||
append_crate(
|
||||
"macros",
|
||||
srctree / "rust" / "macros" / "lib.rs",
|
||||
[],
|
||||
["std", "proc_macro"],
|
||||
is_proc_macro=True,
|
||||
)
|
||||
|
||||
@@ -85,27 +97,28 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
||||
["core", "compiler_builtins"],
|
||||
)
|
||||
|
||||
append_crate(
|
||||
"bindings",
|
||||
srctree / "rust"/ "bindings" / "lib.rs",
|
||||
["core"],
|
||||
cfg=cfg,
|
||||
)
|
||||
crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
|
||||
def append_crate_with_generated(
|
||||
display_name,
|
||||
deps,
|
||||
):
|
||||
append_crate(
|
||||
display_name,
|
||||
srctree / "rust"/ display_name / "lib.rs",
|
||||
deps,
|
||||
cfg=cfg,
|
||||
)
|
||||
crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
|
||||
crates[-1]["source"] = {
|
||||
"include_dirs": [
|
||||
str(srctree / "rust" / display_name),
|
||||
str(objtree / "rust")
|
||||
],
|
||||
"exclude_dirs": [],
|
||||
}
|
||||
|
||||
append_crate(
|
||||
"kernel",
|
||||
srctree / "rust" / "kernel" / "lib.rs",
|
||||
["core", "macros", "build_error", "bindings"],
|
||||
cfg=cfg,
|
||||
)
|
||||
crates[-1]["source"] = {
|
||||
"include_dirs": [
|
||||
str(srctree / "rust" / "kernel"),
|
||||
str(objtree / "rust")
|
||||
],
|
||||
"exclude_dirs": [],
|
||||
}
|
||||
append_crate_with_generated("bindings", ["core"])
|
||||
append_crate_with_generated("uapi", ["core"])
|
||||
append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "uapi"])
|
||||
|
||||
def is_root_crate(build_file, target):
|
||||
try:
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
//! - Test code should be able to define functions and call them, without having to carry
|
||||
//! the context.
|
||||
//!
|
||||
//! - Later on, we may want to be able to test non-kernel code (e.g. `core`, `alloc` or
|
||||
//! third-party crates) which likely use the standard library `assert*!` macros.
|
||||
//! - Later on, we may want to be able to test non-kernel code (e.g. `core` or third-party
|
||||
//! crates) which likely use the standard library `assert*!` macros.
|
||||
//!
|
||||
//! For this reason, instead of the passed context, `kunit_get_current_test()` is used instead
|
||||
//! (i.e. `current->kunit_test`).
|
||||
|
||||
Reference in New Issue
Block a user