Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull Rust updates from Miguel Ojeda:
"Another routine one in terms of features. In terms of lines, this time
the 'alloc' version upgrade is less prominent, given that it was
fairly small (and we did not have two upgrades)

Toolchain and infrastructure:

- Upgrade to Rust 1.74.1

The patch release includes a fix for an ICE that the Apple AGX GPU
driver was hitting

- Support 'srctree'-relative links in Rust code documentation

- Automate part of the manual constants handling (i.e. the ones not
recognised by 'bindgen')

- Suppress searching builtin sysroot to avoid confusion with
installed sysroots, needed for the to-be-merged arm64 support which
uses a builtin target

- Ignore '__preserve_most' functions for 'bindgen'

- Reduce header inclusion bloat in exports

'kernel' crate:

- Implement 'Debug' for 'CString'

- Make 'CondVar::wait()' an uninterruptible wait

'macros' crate:

- Update 'paste!' to accept string literals

- Improve '#[vtable]' documentation

Documentation:

- Add testing section (KUnit and 'rusttest' target)

- Remove 'CC=clang' mentions

- Clarify that 'rustup override' applies to build directory"

* tag 'rust-6.8' of https://github.com/Rust-for-Linux/linux:
docs: rust: Clarify that 'rustup override' applies to build directory
docs: rust: Add rusttest info
docs: rust: remove `CC=clang` mentions
rust: support `srctree`-relative links
rust: sync: Makes `CondVar::wait()` an uninterruptible wait
rust: upgrade to Rust 1.74.1
rust: Suppress searching builtin sysroot
rust: macros: improve `#[vtable]` documentation
rust: macros: update 'paste!' macro to accept string literals
rust: bindings: rename const binding using sed
rust: Ignore preserve-most functions
rust: replace <linux/module.h> with <linux/export.h> in rust/exports.c
rust: kernel: str: Implement Debug for CString

+275 -73
+1 -1
Documentation/process/changes.rst
··· 31 31 ====================== =============== ======================================== 32 32 GNU C 5.1 gcc --version 33 33 Clang/LLVM (optional) 11.0.0 clang --version 34 - Rust (optional) 1.73.0 rustc --version 34 + Rust (optional) 1.74.1 rustc --version 35 35 bindgen (optional) 0.65.1 bindgen --version 36 36 GNU make 3.82 make --version 37 37 bash 4.2 bash --version
+13
Documentation/rust/coding-guidelines.rst
··· 177 177 178 178 https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html 179 179 180 + In addition, the kernel supports creating links relative to the source tree by 181 + prefixing the link destination with ``srctree/``. For instance: 182 + 183 + .. code-block:: rust 184 + 185 + //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h) 186 + 187 + or: 188 + 189 + .. code-block:: rust 190 + 191 + /// [`struct mutex`]: srctree/include/linux/mutex.h 192 + 180 193 181 194 Naming 182 195 ------
+24
Documentation/rust/general-information.rst
··· 77 77 #[cfg(CONFIG_X="y")] // Enabled as a built-in (`y`) 78 78 #[cfg(CONFIG_X="m")] // Enabled as a module (`m`) 79 79 #[cfg(not(CONFIG_X))] // Disabled 80 + 81 + 82 + Testing 83 + ------- 84 + 85 + There are the tests that come from the examples in the Rust documentation 86 + and get transformed into KUnit tests. These can be run via KUnit. For example 87 + via ``kunit_tool`` (``kunit.py``) on the command line:: 88 + 89 + ./tools/testing/kunit/kunit.py run --make_options LLVM=1 --arch x86_64 --kconfig_add CONFIG_RUST=y 90 + 91 + Alternatively, KUnit can run them as kernel built-in at boot. Refer to 92 + Documentation/dev-tools/kunit/index.rst for the general KUnit documentation 93 + and Documentation/dev-tools/kunit/architecture.rst for the details of kernel 94 + built-in vs. command line testing. 95 + 96 + Additionally, there are the ``#[test]`` tests. These can be run using 97 + the ``rusttest`` Make target:: 98 + 99 + make LLVM=1 rusttest 100 + 101 + This requires the kernel ``.config`` and downloads external repositories. 102 + It runs the ``#[test]`` tests on the host (currently) and thus is fairly 103 + limited in what these tests can test.
+9 -9
Documentation/rust/quick-start.rst
··· 33 33 may not work because, for the moment, the kernel depends on some unstable 34 34 Rust features. 35 35 36 - If ``rustup`` is being used, enter the checked out source code directory 37 - and run:: 36 + If ``rustup`` is being used, enter the kernel build directory (or use 37 + ``--path=<build-dir>`` argument to the ``set`` sub-command) and run:: 38 38 39 39 rustup override set $(scripts/min-tool-version.sh rustc) 40 40 41 41 This will configure your working directory to use the correct version of 42 - ``rustc`` without affecting your default toolchain. If you are not using 43 - ``rustup``, fetch a standalone installer from: 42 + ``rustc`` without affecting your default toolchain. 43 + 44 + Note that the override applies to the current working directory (and its 45 + sub-directories). 46 + 47 + If you are not using ``rustup``, fetch a standalone installer from: 44 48 45 49 https://forge.rust-lang.org/infra/other-installation-methods.html#standalone 46 50 ··· 80 76 81 77 ``libclang`` (part of LLVM) is used by ``bindgen`` to understand the C code 82 78 in the kernel, which means LLVM needs to be installed; like when the kernel 83 - is compiled with ``CC=clang`` or ``LLVM=1``. 79 + is compiled with ``LLVM=1``. 84 80 85 81 Linux distributions are likely to have a suitable one available, so it is 86 82 best to check that first. ··· 232 228 at the moment. That is:: 233 229 234 230 make LLVM=1 235 - 236 - For architectures that do not support a full LLVM toolchain, use:: 237 - 238 - make CC=clang 239 231 240 232 Using GCC also works for some configurations, but it is very experimental at 241 233 the moment.
+7 -1
rust/Makefile
··· 78 78 $(rustc_target_flags) -L$(objtree)/$(obj) \ 79 79 --output $(rustdoc_output) \ 80 80 --crate-name $(subst rustdoc-,,$@) \ 81 + $(if $(rustdoc_host),,--sysroot=/dev/null) \ 81 82 @$(objtree)/include/generated/rustc_cfg $< 82 83 83 84 # The `html_logo_url` and `html_favicon_url` forms of the `doc` attribute ··· 99 98 $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \ 100 99 -e 's:rust-logo-[0-9a-f]+\.svg:logo.svg:g' \ 101 100 -e 's:favicon-[0-9a-f]+\.svg:logo.svg:g' \ 102 - -e 's:<link rel="alternate icon" type="image/png" href="[/.]+/static\.files/favicon-(16x16|32x32)-[0-9a-f]+\.png">::g' 101 + -e 's:<link rel="alternate icon" type="image/png" href="[/.]+/static\.files/favicon-(16x16|32x32)-[0-9a-f]+\.png">::g' \ 102 + -e 's:<a href="srctree/([^"]+)">:<a href="$(abs_srctree)/\1">:g' 103 103 $(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \ 104 104 echo ".logo-container > img { object-fit: contain; }" >> $$f; done 105 105 ··· 180 178 --extern build_error --extern macros \ 181 179 --extern bindings --extern uapi \ 182 180 --no-run --crate-name kernel -Zunstable-options \ 181 + --sysroot=/dev/null \ 183 182 --test-builder $(objtree)/scripts/rustdoc_test_builder \ 184 183 $< $(rustdoc_test_kernel_quiet); \ 185 184 $(objtree)/scripts/rustdoc_test_gen ··· 340 337 341 338 $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ 342 339 $(shell grep -Ev '^#|^$$' $(srctree)/$(src)/bindgen_parameters) 340 + $(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \ 341 + sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@ 343 342 $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ 344 343 $(src)/bindgen_parameters FORCE 345 344 $(call if_changed_dep,bindgen) ··· 407 402 --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ 408 403 --crate-type rlib -L$(objtree)/$(obj) \ 409 404 --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ 405 + --sysroot=/dev/null \ 410 406 $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) 411 407 412 408 rust-analyzer:
+23 -9
rust/alloc/alloc.rs
··· 345 345 fn __rust_alloc_error_handler(size: usize, align: usize) -> !; 346 346 } 347 347 348 - /// Abort on memory allocation error or failure. 348 + /// Signal a memory allocation error. 349 349 /// 350 - /// Callers of memory allocation APIs wishing to abort computation 350 + /// Callers of memory allocation APIs wishing to cease execution 351 351 /// in response to an allocation error are encouraged to call this function, 352 - /// rather than directly invoking `panic!` or similar. 352 + /// rather than directly invoking [`panic!`] or similar. 353 353 /// 354 - /// The default behavior of this function is to print a message to standard error 355 - /// and abort the process. 356 - /// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`]. 354 + /// This function is guaranteed to diverge (not return normally with a value), but depending on 355 + /// global configuration, it may either panic (resulting in unwinding or aborting as per 356 + /// configuration for all panics), or abort the process (with no unwinding). 357 + /// 358 + /// The default behavior is: 359 + /// 360 + /// * If the binary links against `std` (typically the case), then 361 + /// print a message to standard error and abort the process. 362 + /// This behavior can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`]. 363 + /// Future versions of Rust may panic by default instead. 364 + /// 365 + /// * If the binary does not link against `std` (all of its crates are marked 366 + /// [`#![no_std]`][no_std]), then call [`panic!`] with a message. 367 + /// [The panic handler] applies as to any panic. 357 368 /// 358 369 /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html 359 370 /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html 371 + /// [The panic handler]: https://doc.rust-lang.org/reference/runtime.html#the-panic_handler-attribute 372 + /// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute 360 373 #[stable(feature = "global_alloc", since = "1.28.0")] 361 374 #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] 362 375 #[cfg(all(not(no_global_oom_handling), not(test)))] ··· 410 397 if unsafe { __rust_alloc_error_handler_should_panic != 0 } { 411 398 panic!("memory allocation of {size} bytes failed") 412 399 } else { 413 - core::panicking::panic_nounwind_fmt(format_args!( 414 - "memory allocation of {size} bytes failed" 415 - )) 400 + core::panicking::panic_nounwind_fmt( 401 + format_args!("memory allocation of {size} bytes failed"), 402 + /* force_no_backtrace */ false, 403 + ) 416 404 } 417 405 } 418 406 }
+3 -3
rust/alloc/lib.rs
··· 90 90 #![warn(missing_docs)] 91 91 #![allow(explicit_outlives_requirements)] 92 92 #![warn(multiple_supertrait_upcastable)] 93 - #![cfg_attr(not(bootstrap), allow(internal_features))] 94 - #![cfg_attr(not(bootstrap), allow(rustdoc::redundant_explicit_links))] 93 + #![allow(internal_features)] 94 + #![allow(rustdoc::redundant_explicit_links)] 95 95 // 96 96 // Library features: 97 97 // tidy-alphabetical-start ··· 122 122 #![feature(const_waker)] 123 123 #![feature(core_intrinsics)] 124 124 #![feature(core_panic)] 125 + #![feature(deprecated_suggestion)] 125 126 #![feature(dispatch_from_dyn)] 126 127 #![feature(error_generic_member_access)] 127 128 #![feature(error_in_core)] ··· 146 145 #![feature(ptr_metadata)] 147 146 #![feature(ptr_sub_ptr)] 148 147 #![feature(receiver_trait)] 149 - #![feature(saturating_int_impl)] 150 148 #![feature(set_ptr_value)] 151 149 #![feature(sized_type_properties)] 152 150 #![feature(slice_from_ptr_range)]
+1 -1
rust/alloc/slice.rs
··· 594 594 /// ``` 595 595 #[rustc_allow_incoherent_impl] 596 596 #[stable(feature = "rust1", since = "1.0.0")] 597 - #[deprecated(since = "1.3.0", note = "renamed to join")] 597 + #[deprecated(since = "1.3.0", note = "renamed to join", suggestion = "join")] 598 598 pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output 599 599 where 600 600 Self: Join<Separator>,
+85 -2
rust/alloc/vec/mod.rs
··· 1228 1228 /// Shortens the vector, keeping the first `len` elements and dropping 1229 1229 /// the rest. 1230 1230 /// 1231 - /// If `len` is greater than the vector's current length, this has no 1232 - /// effect. 1231 + /// If `len` is greater or equal to the vector's current length, this has 1232 + /// no effect. 1233 1233 /// 1234 1234 /// The [`drain`] method can emulate `truncate`, but causes the excess 1235 1235 /// elements to be returned instead of dropped. ··· 1336 1336 /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer 1337 1337 /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`]. 1338 1338 /// 1339 + /// This method guarantees that for the purpose of the aliasing model, this method 1340 + /// does not materialize a reference to the underlying slice, and thus the returned pointer 1341 + /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. 1342 + /// Note that calling other methods that materialize mutable references to the slice, 1343 + /// or mutable references to specific elements you are planning on accessing through this pointer, 1344 + /// as well as writing to those elements, may still invalidate this pointer. 1345 + /// See the second example below for how this guarantee can be used. 1346 + /// 1347 + /// 1339 1348 /// # Examples 1340 1349 /// 1341 1350 /// ``` ··· 1358 1349 /// } 1359 1350 /// ``` 1360 1351 /// 1352 + /// Due to the aliasing guarantee, the following code is legal: 1353 + /// 1354 + /// ```rust 1355 + /// unsafe { 1356 + /// let mut v = vec![0, 1, 2]; 1357 + /// let ptr1 = v.as_ptr(); 1358 + /// let _ = ptr1.read(); 1359 + /// let ptr2 = v.as_mut_ptr().offset(2); 1360 + /// ptr2.write(2); 1361 + /// // Notably, the write to `ptr2` did *not* invalidate `ptr1` 1362 + /// // because it mutated a different element: 1363 + /// let _ = ptr1.read(); 1364 + /// } 1365 + /// ``` 1366 + /// 1361 1367 /// [`as_mut_ptr`]: Vec::as_mut_ptr 1368 + /// [`as_ptr`]: Vec::as_ptr 1362 1369 #[stable(feature = "vec_as_ptr", since = "1.37.0")] 1370 + #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] 1363 1371 #[inline] 1364 1372 pub fn as_ptr(&self) -> *const T { 1365 1373 // We shadow the slice method of the same name to avoid going through ··· 1391 1365 /// function returns, or else it will end up pointing to garbage. 1392 1366 /// Modifying the vector may cause its buffer to be reallocated, 1393 1367 /// which would also make any pointers to it invalid. 1368 + /// 1369 + /// This method guarantees that for the purpose of the aliasing model, this method 1370 + /// does not materialize a reference to the underlying slice, and thus the returned pointer 1371 + /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`]. 1372 + /// Note that calling other methods that materialize references to the slice, 1373 + /// or references to specific elements you are planning on accessing through this pointer, 1374 + /// may still invalidate this pointer. 1375 + /// See the second example below for how this guarantee can be used. 1376 + /// 1394 1377 /// 1395 1378 /// # Examples 1396 1379 /// ··· 1418 1383 /// } 1419 1384 /// assert_eq!(&*x, &[0, 1, 2, 3]); 1420 1385 /// ``` 1386 + /// 1387 + /// Due to the aliasing guarantee, the following code is legal: 1388 + /// 1389 + /// ```rust 1390 + /// unsafe { 1391 + /// let mut v = vec![0]; 1392 + /// let ptr1 = v.as_mut_ptr(); 1393 + /// ptr1.write(1); 1394 + /// let ptr2 = v.as_mut_ptr(); 1395 + /// ptr2.write(2); 1396 + /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`: 1397 + /// ptr1.write(3); 1398 + /// } 1399 + /// ``` 1400 + /// 1401 + /// [`as_mut_ptr`]: Vec::as_mut_ptr 1402 + /// [`as_ptr`]: Vec::as_ptr 1421 1403 #[stable(feature = "vec_as_ptr", since = "1.37.0")] 1404 + #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)] 1422 1405 #[inline] 1423 1406 pub fn as_mut_ptr(&mut self) -> *mut T { 1424 1407 // We shadow the slice method of the same name to avoid going through ··· 3453 3400 #[cfg(test)] 3454 3401 fn from(s: &mut [T]) -> Vec<T> { 3455 3402 crate::slice::to_vec(s, Global) 3403 + } 3404 + } 3405 + 3406 + #[cfg(not(no_global_oom_handling))] 3407 + #[stable(feature = "vec_from_array_ref", since = "1.74.0")] 3408 + impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> { 3409 + /// Allocate a `Vec<T>` and fill it by cloning `s`'s items. 3410 + /// 3411 + /// # Examples 3412 + /// 3413 + /// ``` 3414 + /// assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]); 3415 + /// ``` 3416 + fn from(s: &[T; N]) -> Vec<T> { 3417 + Self::from(s.as_slice()) 3418 + } 3419 + } 3420 + 3421 + #[cfg(not(no_global_oom_handling))] 3422 + #[stable(feature = "vec_from_array_ref", since = "1.74.0")] 3423 + impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> { 3424 + /// Allocate a `Vec<T>` and fill it by cloning `s`'s items. 3425 + /// 3426 + /// # Examples 3427 + /// 3428 + /// ``` 3429 + /// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]); 3430 + /// ``` 3431 + fn from(s: &mut [T; N]) -> Vec<T> { 3432 + Self::from(s.as_mut_slice()) 3456 3433 } 3457 3434 } 3458 3435
+4
rust/bindgen_parameters
··· 20 20 21 21 # `seccomp`'s comment gets understood as a doctest 22 22 --no-doc-comments 23 + 24 + # These functions use the `__preserve_most` calling convention, which neither bindgen 25 + # nor Rust currently understand, and which Clang currently declares to be unstable. 26 + --blocklist-function __list_.*_report
+3 -3
rust/bindings/bindings_helper.h
··· 18 18 #include <linux/workqueue.h> 19 19 20 20 /* `bindgen` gets confused at certain things. */ 21 - const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; 22 - const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL; 23 - const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO; 21 + const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; 22 + const gfp_t RUST_CONST_HELPER_GFP_KERNEL = GFP_KERNEL; 23 + const gfp_t RUST_CONST_HELPER___GFP_ZERO = __GFP_ZERO;
-3
rust/bindings/lib.rs
··· 48 48 } 49 49 50 50 pub use bindings_raw::*; 51 - 52 - pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL; 53 - pub const __GFP_ZERO: gfp_t = BINDINGS___GFP_ZERO;
+1 -1
rust/exports.c
··· 11 11 * accidentally exposed. 12 12 */ 13 13 14 - #include <linux/module.h> 14 + #include <linux/export.h> 15 15 16 16 #define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym) 17 17
+1 -1
rust/kernel/allocator.rs
··· 21 21 22 22 let mut size = layout.size(); 23 23 24 - if layout.align() > bindings::BINDINGS_ARCH_SLAB_MINALIGN { 24 + if layout.align() > bindings::ARCH_SLAB_MINALIGN { 25 25 // The alignment requirement exceeds the slab guarantee, thus try to enlarge the size 26 26 // to use the "power-of-two" size/alignment guarantee (see comments in `kmalloc()` for 27 27 // more information).
+5 -1
rust/kernel/error.rs
··· 2 2 3 3 //! Kernel errors. 4 4 //! 5 - //! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h) 5 + //! C header: [`include/uapi/asm-generic/errno-base.h`](srctree/include/uapi/asm-generic/errno-base.h) 6 6 7 7 use crate::str::CStr; 8 8 ··· 335 335 Err(e) => T::from(e.to_errno() as i16), 336 336 } 337 337 } 338 + 339 + /// Error message for calling a default function of a [`#[vtable]`](macros::vtable) trait. 340 + pub const VTABLE_DEFAULT_ERROR: &str = 341 + "This function must not be called, see the #[vtable] documentation.";
+1 -1
rust/kernel/ioctl.rs
··· 2 2 3 3 //! ioctl() number definitions 4 4 //! 5 - //! C header: [`include/asm-generic/ioctl.h`](../../../../include/asm-generic/ioctl.h) 5 + //! C header: [`include/asm-generic/ioctl.h`](srctree/include/asm-generic/ioctl.h) 6 6 7 7 #![allow(non_snake_case)] 8 8
+1 -1
rust/kernel/kunit.rs
··· 2 2 3 3 //! KUnit-based macros for Rust unit tests. 4 4 //! 5 - //! C header: [`include/kunit/test.h`](../../../../../include/kunit/test.h) 5 + //! C header: [`include/kunit/test.h`](srctree/include/kunit/test.h) 6 6 //! 7 7 //! Reference: <https://docs.kernel.org/dev-tools/kunit/index.html> 8 8
+4 -4
rust/kernel/print.rs
··· 2 2 3 3 //! Printing facilities. 4 4 //! 5 - //! C header: [`include/linux/printk.h`](../../../../include/linux/printk.h) 5 + //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h) 6 6 //! 7 7 //! Reference: <https://www.kernel.org/doc/html/latest/core-api/printk-basics.html> 8 8 ··· 48 48 /// The format string is always the same for a given level, i.e. for a 49 49 /// given `prefix`, which are the kernel's `KERN_*` constants. 50 50 /// 51 - /// [`_printk`]: ../../../../include/linux/printk.h 51 + /// [`_printk`]: srctree/include/linux/printk.h 52 52 const fn generate(is_cont: bool, prefix: &[u8; 3]) -> [u8; LENGTH] { 53 53 // Ensure the `KERN_*` macros are what we expect. 54 54 assert!(prefix[0] == b'\x01'); ··· 97 97 /// The format string must be one of the ones in [`format_strings`], and 98 98 /// the module name must be null-terminated. 99 99 /// 100 - /// [`_printk`]: ../../../../include/linux/_printk.h 100 + /// [`_printk`]: srctree/include/linux/_printk.h 101 101 #[doc(hidden)] 102 102 #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))] 103 103 pub unsafe fn call_printk( ··· 120 120 /// 121 121 /// Public but hidden since it should only be used from public macros. 122 122 /// 123 - /// [`_printk`]: ../../../../include/linux/printk.h 123 + /// [`_printk`]: srctree/include/linux/printk.h 124 124 #[doc(hidden)] 125 125 #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))] 126 126 pub fn call_printk_cont(args: fmt::Arguments<'_>) {
+6
rust/kernel/str.rs
··· 608 608 } 609 609 } 610 610 611 + impl fmt::Debug for CString { 612 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 613 + fmt::Debug::fmt(&**self, f) 614 + } 615 + } 616 + 611 617 /// A convenience alias for [`core::format_args`]. 612 618 #[macro_export] 613 619 macro_rules! fmt {
+16 -16
rust/kernel/sync/condvar.rs
··· 50 50 /// fn wait_for_value(e: &Example, v: u32) { 51 51 /// let mut guard = e.value.lock(); 52 52 /// while *guard != v { 53 - /// e.value_changed.wait_uninterruptible(&mut guard); 53 + /// e.value_changed.wait(&mut guard); 54 54 /// } 55 55 /// } 56 56 /// ··· 69 69 /// } 70 70 /// ``` 71 71 /// 72 - /// [`struct wait_queue_head`]: ../../../include/linux/wait.h 72 + /// [`struct wait_queue_head`]: srctree/include/linux/wait.h 73 73 #[pin_data] 74 74 pub struct CondVar { 75 75 #[pin] ··· 120 120 unsafe { bindings::finish_wait(self.wait_list.get(), wait.get()) }; 121 121 } 122 122 123 - /// Releases the lock and waits for a notification in interruptible mode. 123 + /// Releases the lock and waits for a notification in uninterruptible mode. 124 124 /// 125 125 /// Atomically releases the given lock (whose ownership is proven by the guard) and puts the 126 126 /// thread to sleep, reacquiring the lock on wake up. It wakes up when notified by 127 - /// [`CondVar::notify_one`] or [`CondVar::notify_all`], or when the thread receives a signal. 128 - /// It may also wake up spuriously. 129 - /// 130 - /// Returns whether there is a signal pending. 131 - #[must_use = "wait returns if a signal is pending, so the caller must check the return value"] 132 - pub fn wait<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) -> bool { 133 - self.wait_internal(bindings::TASK_INTERRUPTIBLE, guard); 134 - crate::current!().signal_pending() 127 + /// [`CondVar::notify_one`] or [`CondVar::notify_all`]. Note that it may also wake up 128 + /// spuriously. 129 + pub fn wait<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) { 130 + self.wait_internal(bindings::TASK_UNINTERRUPTIBLE, guard); 135 131 } 136 132 137 - /// Releases the lock and waits for a notification in uninterruptible mode. 133 + /// Releases the lock and waits for a notification in interruptible mode. 138 134 /// 139 - /// Similar to [`CondVar::wait`], except that the wait is not interruptible. That is, the 140 - /// thread won't wake up due to signals. It may, however, wake up supirously. 141 - pub fn wait_uninterruptible<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) { 142 - self.wait_internal(bindings::TASK_UNINTERRUPTIBLE, guard) 135 + /// Similar to [`CondVar::wait`], except that the wait is interruptible. That is, the thread may 136 + /// wake up due to signals. It may also wake up spuriously. 137 + /// 138 + /// Returns whether there is a signal pending. 139 + #[must_use = "wait_interruptible returns if a signal is pending, so the caller must check the return value"] 140 + pub fn wait_interruptible<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) -> bool { 141 + self.wait_internal(bindings::TASK_INTERRUPTIBLE, guard); 142 + crate::current!().signal_pending() 143 143 } 144 144 145 145 /// Calls the kernel function to notify the appropriate number of threads with the given flags.
+1 -1
rust/kernel/sync/lock/mutex.rs
··· 84 84 /// } 85 85 /// ``` 86 86 /// 87 - /// [`struct mutex`]: ../../../../include/linux/mutex.h 87 + /// [`struct mutex`]: srctree/include/linux/mutex.h 88 88 pub type Mutex<T> = super::Lock<T, MutexBackend>; 89 89 90 90 /// A kernel `struct mutex` lock backend.
+1 -1
rust/kernel/sync/lock/spinlock.rs
··· 82 82 /// } 83 83 /// ``` 84 84 /// 85 - /// [`spinlock_t`]: ../../../../include/linux/spinlock.h 85 + /// [`spinlock_t`]: srctree/include/linux/spinlock.h 86 86 pub type SpinLock<T> = super::Lock<T, SpinLockBackend>; 87 87 88 88 /// A kernel `spinlock_t` lock backend.
+1 -1
rust/kernel/task.rs
··· 2 2 3 3 //! Tasks (threads and processes). 4 4 //! 5 - //! C header: [`include/linux/sched.h`](../../../../include/linux/sched.h). 5 + //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h). 6 6 7 7 use crate::{bindings, types::Opaque}; 8 8 use core::{marker::PhantomData, ops::Deref, ptr};
+1 -1
rust/kernel/workqueue.rs
··· 132 132 //! } 133 133 //! ``` 134 134 //! 135 - //! C header: [`include/linux/workqueue.h`](../../../../include/linux/workqueue.h) 135 + //! C header: [`include/linux/workqueue.h`](srctree/include/linux/workqueue.h) 136 136 137 137 use crate::{bindings, prelude::*, sync::Arc, sync::LockClassKey, types::Opaque}; 138 138 use alloc::alloc::AllocError;
+52 -10
rust/macros/lib.rs
··· 20 20 /// The `type` argument should be a type which implements the [`Module`] 21 21 /// trait. Also accepts various forms of kernel metadata. 22 22 /// 23 - /// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h) 23 + /// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h) 24 24 /// 25 25 /// [`Module`]: ../kernel/trait.Module.html 26 26 /// ··· 87 87 /// implementation could just return `Error::EINVAL`); Linux typically use C 88 88 /// `NULL` pointers to represent these functions. 89 89 /// 90 - /// This attribute is intended to close the gap. Traits can be declared and 91 - /// implemented with the `#[vtable]` attribute, and a `HAS_*` associated constant 92 - /// will be generated for each method in the trait, indicating if the implementor 93 - /// has overridden a method. 90 + /// This attribute closes that gap. A trait can be annotated with the 91 + /// `#[vtable]` attribute. Implementers of the trait will then also have to 92 + /// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*` 93 + /// associated constant bool for each method in the trait that is set to true if 94 + /// the implementer has overridden the associated method. 94 95 /// 95 - /// This attribute is not needed if all methods are required. 96 + /// For a trait method to be optional, it must have a default implementation. 97 + /// This is also the case for traits annotated with `#[vtable]`, but in this 98 + /// case the default implementation will never be executed. The reason for this 99 + /// is that the functions will be called through function pointers installed in 100 + /// C side vtables. When an optional method is not implemented on a `#[vtable]` 101 + /// trait, a NULL entry is installed in the vtable. Thus the default 102 + /// implementation is never called. Since these traits are not designed to be 103 + /// used on the Rust side, it should not be possible to call the default 104 + /// implementation. This is done to ensure that we call the vtable methods 105 + /// through the C vtable, and not through the Rust vtable. Therefore, the 106 + /// default implementation should call `kernel::build_error`, which prevents 107 + /// calls to this function at compile time: 108 + /// 109 + /// ```compile_fail 110 + /// # use kernel::error::VTABLE_DEFAULT_ERROR; 111 + /// kernel::build_error(VTABLE_DEFAULT_ERROR) 112 + /// ``` 113 + /// 114 + /// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`]. 115 + /// 116 + /// This macro should not be used when all functions are required. 96 117 /// 97 118 /// # Examples 98 119 /// 99 120 /// ```ignore 121 + /// use kernel::error::VTABLE_DEFAULT_ERROR; 100 122 /// use kernel::prelude::*; 101 123 /// 102 124 /// // Declares a `#[vtable]` trait 103 125 /// #[vtable] 104 126 /// pub trait Operations: Send + Sync + Sized { 105 127 /// fn foo(&self) -> Result<()> { 106 - /// Err(EINVAL) 128 + /// kernel::build_error(VTABLE_DEFAULT_ERROR) 107 129 /// } 108 130 /// 109 131 /// fn bar(&self) -> Result<()> { 110 - /// Err(EINVAL) 132 + /// kernel::build_error(VTABLE_DEFAULT_ERROR) 111 133 /// } 112 134 /// } 113 135 /// ··· 147 125 /// assert_eq!(<Foo as Operations>::HAS_FOO, true); 148 126 /// assert_eq!(<Foo as Operations>::HAS_BAR, false); 149 127 /// ``` 128 + /// 129 + /// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html 150 130 #[proc_macro_attribute] 151 131 pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream { 152 132 vtable::vtable(attr, ts) ··· 278 254 /// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a 279 255 /// single identifier. 280 256 /// 281 - /// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers 282 - /// (literals, lifetimes and documentation strings are not supported). There is a difference in 257 + /// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and 258 + /// literals (lifetimes and documentation strings are not supported). There is a difference in 283 259 /// supported modifiers as well. 284 260 /// 285 261 /// # Example ··· 359 335 /// ); 360 336 /// 361 337 /// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK); 338 + /// ``` 339 + /// 340 + /// # Literals 341 + /// 342 + /// Literals can also be concatenated with other identifiers: 343 + /// 344 + /// ```ignore 345 + /// macro_rules! create_numbered_fn { 346 + /// ($name:literal, $val:literal) => { 347 + /// kernel::macros::paste! { 348 + /// fn [<some_ $name _fn $val>]() -> u32 { $val } 349 + /// } 350 + /// }; 351 + /// } 352 + /// 353 + /// create_numbered_fn!("foo", 100); 354 + /// 355 + /// assert_eq!(some_foo_fn100(), 100) 362 356 /// ``` 363 357 /// 364 358 /// [`paste`]: https://docs.rs/paste/
+9 -1
rust/macros/paste.rs
··· 9 9 loop { 10 10 match tokens.next() { 11 11 None => break, 12 - Some(TokenTree::Literal(lit)) => segments.push((lit.to_string(), lit.span())), 12 + Some(TokenTree::Literal(lit)) => { 13 + // Allow us to concat string literals by stripping quotes 14 + let mut value = lit.to_string(); 15 + if value.starts_with('"') && value.ends_with('"') { 16 + value.remove(0); 17 + value.pop(); 18 + } 19 + segments.push((value, lit.span())); 20 + } 13 21 Some(TokenTree::Ident(ident)) => { 14 22 let mut value = ident.to_string(); 15 23 if value.starts_with("r#") {
+1
scripts/Makefile.build
··· 275 275 --extern alloc --extern kernel \ 276 276 --crate-type rlib -L $(objtree)/rust/ \ 277 277 --crate-name $(basename $(notdir $@)) \ 278 + --sysroot=/dev/null \ 278 279 --out-dir $(dir $@) --emit=dep-info=$(depfile) 279 280 280 281 # `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit
+1 -1
scripts/min-tool-version.sh
··· 31 31 fi 32 32 ;; 33 33 rustc) 34 - echo 1.73.0 34 + echo 1.74.1 35 35 ;; 36 36 bindgen) 37 37 echo 0.65.1