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
Unified · Split
| @@ -145,7 +145,7 @@ Rust standard library source · 144 unmodified lines | ||
| 145 | 145 | **************************** |
| 146 | 146 | |
| 147 | 147 | The Rust standard library source is required because the build system will |
| 148 | −cross-compile ``core`` and ``alloc``. | |
| 148 | +cross-compile ``core``. | |
| 149 | 149 | |
| 150 | 150 | If ``rustup`` is being used, run:: |
| 151 | 151 | |
| @@ -97,7 +97,7 @@ operator are also supported as usual, e.g.: · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | /// ``` |
| 99 | 99 | /// # use kernel::{spawn_work_item, workqueue}; |
| 100 | − /// spawn_work_item!(workqueue::system(), || pr_info!("x"))?; | |
| 100 | + /// spawn_work_item!(workqueue::system(), || pr_info!("x\n"))?; | |
| 101 | 101 | /// # Ok::<(), Error>(()) |
| 102 | 102 | /// ``` |
| 103 | 103 | |
| @@ -1973,7 +1973,7 @@ config RUST · 1972 unmodified lines | ||
| 1973 | 1973 | depends on !MODVERSIONS || GENDWARFKSYMS |
| 1974 | 1974 | depends on !GCC_PLUGIN_RANDSTRUCT |
| 1975 | 1975 | depends on !RANDSTRUCT |
| 1976 | − depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE | |
| 1976 | + depends on !DEBUG_INFO_BTF || (PAHOLE_HAS_LANG_EXCLUDE && !LTO) | |
| 1977 | 1977 | depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC |
| 1978 | 1978 | select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG |
| 1979 | 1979 | depends on !CALL_PADDING || RUSTC_VERSION >= 108100 |
| @@ -62,6 +62,24 @@ unsafe impl Allocator for Cmalloc { · 61 unmodified lines | ||
| 62 | 62 | )); |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | + // ISO C (ISO/IEC 9899:2011) defines `aligned_alloc`: | |
| 66 | + // | |
| 67 | + // > The value of alignment shall be a valid alignment supported by the implementation | |
| 68 | + // [...]. | |
| 69 | + // | |
| 70 | + // As an example of the "supported by the implementation" requirement, POSIX.1-2001 (IEEE | |
| 71 | + // 1003.1-2001) defines `posix_memalign`: | |
| 72 | + // | |
| 73 | + // > The value of alignment shall be a power of two multiple of sizeof (void *). | |
| 74 | + // | |
| 75 | + // and POSIX-based implementations of `aligned_alloc` inherit this requirement. At the time | |
| 76 | + // of writing, this is known to be the case on macOS (but not in glibc). | |
| 77 | + // | |
| 78 | + // Satisfy the stricter requirement to avoid spurious test failures on some platforms. | |
| 79 | + let min_align = core::mem::size_of::<*const crate::ffi::c_void>(); | |
| 80 | + let layout = layout.align_to(min_align).map_err(|_| AllocError)?; | |
| 81 | + let layout = layout.pad_to_align(); | |
| 82 | + | |
| 65 | 83 | // SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or |
| 66 | 84 | // exceeds the given size and alignment requirements. |
| 67 | 85 | let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8; |
| @@ -107,7 +107,7 @@ impl Error { · 106 unmodified lines | ||
| 107 | 107 | } else { |
| 108 | 108 | // TODO: Make it a `WARN_ONCE` once available. |
| 109 | 109 | crate::pr_warn!( |
| 110 | − "attempted to create `Error` with out of range `errno`: {}", | |
| 110 | + "attempted to create `Error` with out of range `errno`: {}\n", | |
| 111 | 111 | errno |
| 112 | 112 | ); |
| 113 | 113 | code::EINVAL |
| @@ -259,7 +259,7 @@ pub mod macros; · 258 unmodified lines | ||
| 259 | 259 | /// }, |
| 260 | 260 | /// })); |
| 261 | 261 | /// let foo: Pin<&mut Foo> = foo; |
| 262 | −/// pr_info!("a: {}", &*foo.a.lock()); | |
| 262 | +/// pr_info!("a: {}\n", &*foo.a.lock()); | |
| 263 | 263 | /// ``` |
| 264 | 264 | /// |
| 265 | 265 | /// # Syntax |
| @@ -319,7 +319,7 @@ macro_rules! stack_pin_init { · 53 unmodified lines | ||
| 319 | 319 | /// }, GFP_KERNEL)?, |
| 320 | 320 | /// })); |
| 321 | 321 | /// let foo = foo.unwrap(); |
| 322 | −/// pr_info!("a: {}", &*foo.a.lock()); | |
| 322 | +/// pr_info!("a: {}\n", &*foo.a.lock()); | |
| 323 | 323 | /// ``` |
| 324 | 324 | /// |
| 325 | 325 | /// ```rust,ignore |
| @@ -352,7 +352,7 @@ macro_rules! stack_pin_init { · 26 unmodified lines | ||
| 352 | 352 | /// x: 64, |
| 353 | 353 | /// }, GFP_KERNEL)?, |
| 354 | 354 | /// })); |
| 355 | −/// pr_info!("a: {}", &*foo.a.lock()); | |
| 355 | +/// pr_info!("a: {}\n", &*foo.a.lock()); | |
| 356 | 356 | /// # Ok::<_, AllocError>(()) |
| 357 | 357 | /// ``` |
| 358 | 358 | /// |
| @@ -882,7 +882,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized { · 523 unmodified lines | ||
| 882 | 882 | /// |
| 883 | 883 | /// impl Foo { |
| 884 | 884 | /// fn setup(self: Pin<&mut Self>) { |
| 885 | − /// pr_info!("Setting up foo"); | |
| 885 | + /// pr_info!("Setting up foo\n"); | |
| 886 | 886 | /// } |
| 887 | 887 | /// } |
| 888 | 888 | /// |
| @@ -986,7 +986,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> { · 97 unmodified lines | ||
| 986 | 986 | /// |
| 987 | 987 | /// impl Foo { |
| 988 | 988 | /// fn setup(&mut self) { |
| 989 | − /// pr_info!("Setting up foo"); | |
| 989 | + /// pr_info!("Setting up foo\n"); | |
| 990 | 990 | /// } |
| 991 | 991 | /// } |
| 992 | 992 | /// |
| @@ -1336,7 +1336,7 @@ impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> { · 343 unmodified lines | ||
| 1336 | 1336 | /// #[pinned_drop] |
| 1337 | 1337 | /// impl PinnedDrop for Foo { |
| 1338 | 1338 | /// fn drop(self: Pin<&mut Self>) { |
| 1339 | −/// pr_info!("Foo is being dropped!"); | |
| 1339 | +/// pr_info!("Foo is being dropped!\n"); | |
| 1340 | 1340 | /// } |
| 1341 | 1341 | /// } |
| 1342 | 1342 | /// ``` |
| @@ -1418,17 +1418,14 @@ impl_zeroable! { · 75 unmodified lines | ||
| 1418 | 1418 | // SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`. |
| 1419 | 1419 | {<T: ?Sized + Zeroable>} UnsafeCell<T>, |
| 1420 | 1420 | |
| 1421 | − // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee). | |
| 1421 | + // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee: | |
| 1422 | + // https://doc.rust-lang.org/stable/std/option/index.html#representation). | |
| 1422 | 1423 | Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>, |
| 1423 | 1424 | Option<NonZeroU128>, Option<NonZeroUsize>, |
| 1424 | 1425 | Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>, |
| 1425 | 1426 | Option<NonZeroI128>, Option<NonZeroIsize>, |
| 1426 | − | |
| 1427 | − // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee). | |
| 1428 | − // | |
| 1429 | − // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant. | |
| 1430 | − {<T: ?Sized>} Option<NonNull<T>>, | |
| 1431 | − {<T: ?Sized>} Option<KBox<T>>, | |
| 1427 | + {<T>} Option<NonNull<T>>, | |
| 1428 | + {<T>} Option<KBox<T>>, | |
| 1432 | 1429 | |
| 1433 | 1430 | // SAFETY: `null` pointer is valid. |
| 1434 | 1431 | // |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | //! #[pinned_drop] |
| 46 | 46 | //! impl PinnedDrop for Foo { |
| 47 | 47 | //! fn drop(self: Pin<&mut Self>) { |
| 48 | −//! pr_info!("{self:p} is getting dropped."); | |
| 48 | +//! pr_info!("{self:p} is getting dropped.\n"); | |
| 49 | 49 | //! } |
| 50 | 50 | //! } |
| 51 | 51 | //! |
| @@ -412,7 +412,7 @@ · 360 unmodified lines | ||
| 412 | 412 | //! #[pinned_drop] |
| 413 | 413 | //! impl PinnedDrop for Foo { |
| 414 | 414 | //! fn drop(self: Pin<&mut Self>) { |
| 415 | −//! pr_info!("{self:p} is getting dropped."); | |
| 415 | +//! pr_info!("{self:p} is getting dropped.\n"); | |
| 416 | 416 | //! } |
| 417 | 417 | //! } |
| 418 | 418 | //! ``` |
| @@ -423,7 +423,7 @@ · 4 unmodified lines | ||
| 423 | 423 | //! // `unsafe`, full path and the token parameter are added, everything else stays the same. |
| 424 | 424 | //! unsafe impl ::kernel::init::PinnedDrop for Foo { |
| 425 | 425 | //! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) { |
| 426 | −//! pr_info!("{self:p} is getting dropped."); | |
| 426 | +//! pr_info!("{self:p} is getting dropped.\n"); | |
| 427 | 427 | //! } |
| 428 | 428 | //! } |
| 429 | 429 | //! ``` |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | //! usage by Rust code in the kernel and is shared by all of them. |
| 7 | 7 | //! |
| 8 | 8 | //! In other words, all the rest of the Rust code in the kernel (e.g. kernel |
| 9 | −//! modules written in Rust) depends on [`core`], [`alloc`] and this crate. | |
| 9 | +//! modules written in Rust) depends on [`core`] and this crate. | |
| 10 | 10 | //! |
| 11 | 11 | //! If you need a kernel C API that is not ported or wrapped yet here, then |
| 12 | 12 | //! do so first instead of bypassing this crate. |
| @@ -55,7 +55,7 @@ use core::{cell::UnsafeCell, mem::size_of, ptr}; · 54 unmodified lines | ||
| 55 | 55 | /// fn print_bytes_used(dir: &Directory, file: &File) { |
| 56 | 56 | /// let guard = dir.inner.lock(); |
| 57 | 57 | /// let inner_file = file.inner.access(&guard); |
| 58 | −/// pr_info!("{} {}", guard.bytes_used, inner_file.bytes_used); | |
| 58 | +/// pr_info!("{} {}\n", guard.bytes_used, inner_file.bytes_used); | |
| 59 | 59 | /// } |
| 60 | 60 | /// |
| 61 | 61 | /// /// Increments `bytes_used` for both the directory and file. |
| @@ -320,7 +320,7 @@ impl Task { · 319 unmodified lines | ||
| 320 | 320 | |
| 321 | 321 | /// Wakes up the task. |
| 322 | 322 | pub fn wake_up(&self) { |
| 323 | − // SAFETY: It's always safe to call `signal_pending` on a valid task, even if the task | |
| 323 | + // SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task | |
| 324 | 324 | // running. |
| 325 | 325 | unsafe { bindings::wake_up_process(self.as_ptr()) }; |
| 326 | 326 | } |
| @@ -60,7 +60,7 @@ · 59 unmodified lines | ||
| 60 | 60 | //! type Pointer = Arc<MyStruct>; |
| 61 | 61 | //! |
| 62 | 62 | //! fn run(this: Arc<MyStruct>) { |
| 63 | −//! pr_info!("The value is: {}", this.value); | |
| 63 | +//! pr_info!("The value is: {}\n", this.value); | |
| 64 | 64 | //! } |
| 65 | 65 | //! } |
| 66 | 66 | //! |
| @@ -108,7 +108,7 @@ · 41 unmodified lines | ||
| 108 | 108 | //! type Pointer = Arc<MyStruct>; |
| 109 | 109 | //! |
| 110 | 110 | //! fn run(this: Arc<MyStruct>) { |
| 111 | −//! pr_info!("The value is: {}", this.value_1); | |
| 111 | +//! pr_info!("The value is: {}\n", this.value_1); | |
| 112 | 112 | //! } |
| 113 | 113 | //! } |
| 114 | 114 | //! |
| @@ -116,7 +116,7 @@ · 1 unmodified line | ||
| 116 | 116 | //! type Pointer = Arc<MyStruct>; |
| 117 | 117 | //! |
| 118 | 118 | //! fn run(this: Arc<MyStruct>) { |
| 119 | −//! pr_info!("The second value is: {}", this.value_2); | |
| 119 | +//! pr_info!("The second value is: {}\n", this.value_2); | |
| 120 | 120 | //! } |
| 121 | 121 | //! } |
| 122 | 122 | //! |
| @@ -57,14 +57,26 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): · 56 unmodified lines | ||
| 57 | 57 | crates_indexes[display_name] = len(crates) |
| 58 | 58 | crates.append(crate) |
| 59 | 59 | |
| 60 | − # First, the ones in `rust/` since they are a bit special. | |
| 61 | − append_crate( | |
| 62 | − "core", | |
| 63 | − sysroot_src / "core" / "src" / "lib.rs", | |
| 64 | − [], | |
| 65 | − cfg=crates_cfgs.get("core", []), | |
| 66 | − is_workspace_member=False, | |
| 67 | − ) | |
| 60 | + def append_sysroot_crate( | |
| 61 | + display_name, | |
| 62 | + deps, | |
| 63 | + cfg=[], | |
| 64 | + ): | |
| 65 | + append_crate( | |
| 66 | + display_name, | |
| 67 | + sysroot_src / display_name / "src" / "lib.rs", | |
| 68 | + deps, | |
| 69 | + cfg, | |
| 70 | + is_workspace_member=False, | |
| 71 | + ) | |
| 72 | + | |
| 73 | + # NB: sysroot crates reexport items from one another so setting up our transitive dependencies | |
| 74 | + # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth | |
| 75 | + # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`. | |
| 76 | + append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", [])) | |
| 77 | + append_sysroot_crate("alloc", ["core"]) | |
| 78 | + append_sysroot_crate("std", ["alloc", "core"]) | |
| 79 | + append_sysroot_crate("proc_macro", ["core", "std"]) | |
| 68 | 80 | |
| 69 | 81 | append_crate( |
| 70 | 82 | "compiler_builtins", |
| @@ -75,7 +87,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): · 4 unmodified lines | ||
| 75 | 87 | append_crate( |
| 76 | 88 | "macros", |
| 77 | 89 | srctree / "rust" / "macros" / "lib.rs", |
| 78 | − [], | |
| 90 | + ["std", "proc_macro"], | |
| 79 | 91 | is_proc_macro=True, |
| 80 | 92 | ) |
| 81 | 93 | |
| @@ -85,27 +97,28 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): · 3 unmodified lines | ||
| 85 | 97 | ["core", "compiler_builtins"], |
| 86 | 98 | ) |
| 87 | 99 | |
| 88 | − append_crate( | |
| 89 | − "bindings", | |
| 90 | − srctree / "rust"/ "bindings" / "lib.rs", | |
| 91 | − ["core"], | |
| 92 | − cfg=cfg, | |
| 93 | − ) | |
| 94 | − crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) | |
| 100 | + def append_crate_with_generated( | |
| 101 | + display_name, | |
| 102 | + deps, | |
| 103 | + ): | |
| 104 | + append_crate( | |
| 105 | + display_name, | |
| 106 | + srctree / "rust"/ display_name / "lib.rs", | |
| 107 | + deps, | |
| 108 | + cfg=cfg, | |
| 109 | + ) | |
| 110 | + crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) | |
| 111 | + crates[-1]["source"] = { | |
| 112 | + "include_dirs": [ | |
| 113 | + str(srctree / "rust" / display_name), | |
| 114 | + str(objtree / "rust") | |
| 115 | + ], | |
| 116 | + "exclude_dirs": [], | |
| 117 | + } | |
| 95 | 118 | |
| 96 | − append_crate( | |
| 97 | − "kernel", | |
| 98 | − srctree / "rust" / "kernel" / "lib.rs", | |
| 99 | − ["core", "macros", "build_error", "bindings"], | |
| 100 | − cfg=cfg, | |
| 101 | − ) | |
| 102 | − crates[-1]["source"] = { | |
| 103 | − "include_dirs": [ | |
| 104 | − str(srctree / "rust" / "kernel"), | |
| 105 | − str(objtree / "rust") | |
| 106 | − ], | |
| 107 | − "exclude_dirs": [], | |
| 108 | − } | |
| 119 | + append_crate_with_generated("bindings", ["core"]) | |
| 120 | + append_crate_with_generated("uapi", ["core"]) | |
| 121 | + append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "uapi"]) | |
| 109 | 122 | |
| 110 | 123 | def is_root_crate(build_file, target): |
| 111 | 124 | try: |
| @@ -15,8 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | //! - Test code should be able to define functions and call them, without having to carry |
| 16 | 16 | //! the context. |
| 17 | 17 | //! |
| 18 | −//! - Later on, we may want to be able to test non-kernel code (e.g. `core`, `alloc` or | |
| 19 | −//! third-party crates) which likely use the standard library `assert*!` macros. | |
| 18 | +//! - Later on, we may want to be able to test non-kernel code (e.g. `core` or third-party | |
| 19 | +//! crates) which likely use the standard library `assert*!` macros. | |
| 20 | 20 | //! |
| 21 | 21 | //! For this reason, instead of the passed context, `kunit_get_current_test()` is used instead |
| 22 | 22 | //! (i.e. `current->kunit_test`). |