History

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

Linus Torvalds committed 1 year ago

Commit cd3a56a2 parents eb88e6b a1eb95d13 files · +85 −57Browse files

Unified · Split

13 files
  1. Documentation/rust/quick-start.rst +1 −1
  2. Documentation/rust/testing.rst +1 −1
  3. init/Kconfig +1 −1
  4. rust/kernel/alloc/allocator_test.rs +18 −0
  5. rust/kernel/error.rs +1 −1
  6. rust/kernel/init.rs +10 −13
  7. rust/kernel/init/macros.rs +3 −3
  8. rust/kernel/lib.rs +1 −1
  9. rust/kernel/sync/locked_by.rs +1 −1
  10. rust/kernel/task.rs +1 −1
  11. rust/kernel/workqueue.rs +3 −3
  12. scripts/generate_rust_analyzer.py +42 −29
  13. scripts/rustdoc_test_gen.rs +2 −2
Documentation/rust/quick-start.rst+1−1
@@ -145,7 +145,7 @@ Rust standard library source · 144 unmodified lines
145****************************145****************************
146 146
147The Rust standard library source is required because the build system will147The Rust standard library source is required because the build system will
148cross-compile ``core`` and ``alloc``.148cross-compile ``core``.
149 149
150If ``rustup`` is being used, run::150If ``rustup`` is being used, run::
151 151
Documentation/rust/testing.rst+1−1
@@ -97,7 +97,7 @@ operator are also supported as usual, e.g.: · 96 unmodified lines
97 97
98 /// ```98 /// ```
99 /// # use kernel::{spawn_work_item, workqueue};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 /// # Ok::<(), Error>(())101 /// # Ok::<(), Error>(())
102 /// ```102 /// ```
103 103
init/Kconfig+1−1
@@ -1973,7 +1973,7 @@ config RUST · 1972 unmodified lines
1973 depends on !MODVERSIONS || GENDWARFKSYMS1973 depends on !MODVERSIONS || GENDWARFKSYMS
1974 depends on !GCC_PLUGIN_RANDSTRUCT1974 depends on !GCC_PLUGIN_RANDSTRUCT
1975 depends on !RANDSTRUCT1975 depends on !RANDSTRUCT
1976 depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE1976 depends on !DEBUG_INFO_BTF || (PAHOLE_HAS_LANG_EXCLUDE && !LTO)
1977 depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC1977 depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
1978 select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG1978 select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
1979 depends on !CALL_PADDING || RUSTC_VERSION >= 1081001979 depends on !CALL_PADDING || RUSTC_VERSION >= 108100
rust/kernel/alloc/allocator_test.rs+18−0
@@ -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 // SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or83 // SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or
66 // exceeds the given size and alignment requirements.84 // exceeds the given size and alignment requirements.
67 let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8;85 let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8;
rust/kernel/error.rs+1−1
@@ -107,7 +107,7 @@ impl Error { · 106 unmodified lines
107 } else {107 } else {
108 // TODO: Make it a `WARN_ONCE` once available.108 // TODO: Make it a `WARN_ONCE` once available.
109 crate::pr_warn!(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 errno111 errno
112 );112 );
113 code::EINVAL113 code::EINVAL
rust/kernel/init.rs+10−13
@@ -259,7 +259,7 @@ pub mod macros; · 258 unmodified lines
259/// },259/// },
260/// }));260/// }));
261/// let foo: Pin<&mut Foo> = foo;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/// # Syntax265/// # Syntax
@@ -319,7 +319,7 @@ macro_rules! stack_pin_init { · 53 unmodified lines
319/// }, GFP_KERNEL)?,319/// }, GFP_KERNEL)?,
320/// }));320/// }));
321/// let foo = foo.unwrap();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/// ```rust,ignore325/// ```rust,ignore
@@ -352,7 +352,7 @@ macro_rules! stack_pin_init { · 26 unmodified lines
352/// x: 64,352/// x: 64,
353/// }, GFP_KERNEL)?,353/// }, GFP_KERNEL)?,
354/// }));354/// }));
355/// pr_info!("a: {}", &*foo.a.lock());355/// pr_info!("a: {}\n", &*foo.a.lock());
356/// # Ok::<_, AllocError>(())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 /// impl Foo {883 /// impl Foo {
884 /// fn setup(self: Pin<&mut Self>) {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 /// impl Foo {987 /// impl Foo {
988 /// fn setup(&mut self) {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/// #[pinned_drop]1336/// #[pinned_drop]
1337/// impl PinnedDrop for Foo {1337/// impl PinnedDrop for Foo {
1338/// fn drop(self: Pin<&mut Self>) {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 // SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.1418 // SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.
1419 {<T: ?Sized + Zeroable>} UnsafeCell<T>,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 Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>,1423 Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>,
1423 Option<NonZeroU128>, Option<NonZeroUsize>,1424 Option<NonZeroU128>, Option<NonZeroUsize>,
1424 Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>,1425 Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>,
1425 Option<NonZeroI128>, Option<NonZeroIsize>,1426 Option<NonZeroI128>, Option<NonZeroIsize>,
1426 1427 {<T>} Option<NonNull<T>>,
1427 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).1428 {<T>} Option<KBox<T>>,
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>>,
1432 1429
1433 // SAFETY: `null` pointer is valid.1430 // SAFETY: `null` pointer is valid.
1434 //1431 //
rust/kernel/init/macros.rs+3−3
@@ -45,7 +45,7 @@ · 44 unmodified lines
45//! #[pinned_drop]45//! #[pinned_drop]
46//! impl PinnedDrop for Foo {46//! impl PinnedDrop for Foo {
47//! fn drop(self: Pin<&mut Self>) {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//! #[pinned_drop]412//! #[pinned_drop]
413//! impl PinnedDrop for Foo {413//! impl PinnedDrop for Foo {
414//! fn drop(self: Pin<&mut Self>) {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//! // `unsafe`, full path and the token parameter are added, everything else stays the same.423//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
424//! unsafe impl ::kernel::init::PinnedDrop for Foo {424//! unsafe impl ::kernel::init::PinnedDrop for Foo {
425//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {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//! ```
rust/kernel/lib.rs+1−1
@@ -6,7 +6,7 @@ · 5 unmodified lines
6//! usage by Rust code in the kernel and is shared by all of them.6//! usage by Rust code in the kernel and is shared by all of them.
7//!7//!
8//! In other words, all the rest of the Rust code in the kernel (e.g. kernel8//! 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//! If you need a kernel C API that is not ported or wrapped yet here, then11//! If you need a kernel C API that is not ported or wrapped yet here, then
12//! do so first instead of bypassing this crate.12//! do so first instead of bypassing this crate.
rust/kernel/sync/locked_by.rs+1−1
@@ -55,7 +55,7 @@ use core::{cell::UnsafeCell, mem::size_of, ptr}; · 54 unmodified lines
55/// fn print_bytes_used(dir: &Directory, file: &File) {55/// fn print_bytes_used(dir: &Directory, file: &File) {
56/// let guard = dir.inner.lock();56/// let guard = dir.inner.lock();
57/// let inner_file = file.inner.access(&guard);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/// /// Increments `bytes_used` for both the directory and file.61/// /// Increments `bytes_used` for both the directory and file.
rust/kernel/task.rs+1−1
@@ -320,7 +320,7 @@ impl Task { · 319 unmodified lines
320 320
321 /// Wakes up the task.321 /// Wakes up the task.
322 pub fn wake_up(&self) {322 pub fn wake_up(&self) {
323 // SAFETY: It's always safe to call `signal_pending` on a valid task, even if the task323 // SAFETY: It's always safe to call `wake_up_process` on a valid task, even if the task
324 // running.324 // running.
325 unsafe { bindings::wake_up_process(self.as_ptr()) };325 unsafe { bindings::wake_up_process(self.as_ptr()) };
326 }326 }
rust/kernel/workqueue.rs+3−3
@@ -60,7 +60,7 @@ · 59 unmodified lines
60//! type Pointer = Arc<MyStruct>;60//! type Pointer = Arc<MyStruct>;
61//!61//!
62//! fn run(this: Arc<MyStruct>) {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//! type Pointer = Arc<MyStruct>;108//! type Pointer = Arc<MyStruct>;
109//!109//!
110//! fn run(this: Arc<MyStruct>) {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//! type Pointer = Arc<MyStruct>;116//! type Pointer = Arc<MyStruct>;
117//!117//!
118//! fn run(this: Arc<MyStruct>) {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//!
scripts/generate_rust_analyzer.py+42−29
@@ -57,14 +57,26 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): · 56 unmodified lines
57 crates_indexes[display_name] = len(crates)57 crates_indexes[display_name] = len(crates)
58 crates.append(crate)58 crates.append(crate)
59 59
60 # First, the ones in `rust/` since they are a bit special.60 def append_sysroot_crate(
61 append_crate(61 display_name,
62 "core",62 deps,
63 sysroot_src / "core" / "src" / "lib.rs",63 cfg=[],
64 [],64 ):
65 cfg=crates_cfgs.get("core", []),65 append_crate(
66 is_workspace_member=False,66 display_name,
67 )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 append_crate(81 append_crate(
70 "compiler_builtins",82 "compiler_builtins",
@@ -75,7 +87,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): · 4 unmodified lines
75 append_crate(87 append_crate(
76 "macros",88 "macros",
77 srctree / "rust" / "macros" / "lib.rs",89 srctree / "rust" / "macros" / "lib.rs",
78 [],90 ["std", "proc_macro"],
79 is_proc_macro=True,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 ["core", "compiler_builtins"],97 ["core", "compiler_builtins"],
86 )98 )
87 99
88 append_crate(100 def append_crate_with_generated(
89 "bindings",101 display_name,
90 srctree / "rust"/ "bindings" / "lib.rs",102 deps,
91 ["core"],103 ):
92 cfg=cfg,104 append_crate(
93 )105 display_name,
94 crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))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(119 append_crate_with_generated("bindings", ["core"])
97 "kernel",120 append_crate_with_generated("uapi", ["core"])
98 srctree / "rust" / "kernel" / "lib.rs",121 append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "uapi"])
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 }
109 122
110 def is_root_crate(build_file, target):123 def is_root_crate(build_file, target):
111 try:124 try:
scripts/rustdoc_test_gen.rs+2−2
@@ -15,8 +15,8 @@ · 14 unmodified lines
15//! - Test code should be able to define functions and call them, without having to carry15//! - Test code should be able to define functions and call them, without having to carry
16//! the context.16//! the context.
17//!17//!
18//! - Later on, we may want to be able to test non-kernel code (e.g. `core`, `alloc` or18//! - Later on, we may want to be able to test non-kernel code (e.g. `core` or third-party
19//! third-party crates) which likely use the standard library `assert*!` macros.19//! crates) which likely use the standard library `assert*!` macros.
20//!20//!
21//! For this reason, instead of the passed context, `kunit_get_current_test()` is used instead21//! For this reason, instead of the passed context, `kunit_get_current_test()` is used instead
22//! (i.e. `current->kunit_test`).22//! (i.e. `current->kunit_test`).