summaryrefslogtreecommitdiff
path: root/rust/kernel/sync
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-18 11:25:09 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-18 11:25:09 -0700
commitd24f5cdbeff8b6a063fca92d0a1f94122a799b59 (patch)
tree1c0c344db3c18572d7176c7caec4a8abdd295647 /rust/kernel/sync
parent2df813c9a6b6704b75aec7538d2225292e6b6fe6 (diff)
parent47f27155f17498fccb1f222f79089642337498a9 (diff)
Merge tag 'rust-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust updates from Miguel Ojeda: "Toolchain and infrastructure: - Warn when using 'bindgen' < 0.72.1 with 'libclang' >= 22, since that combination may fail to build. It includes a probe for the bug in case 'bindgen' happens to be patched, and tests In parallel, Nathan updated the instructions for the kernel.org LLVM+Rust toolchains so that the latest version of 'bindgen' is installed, which should avoid some of these situations - Support testing 'rust_is_available.sh' with 'bash' as '/bin/sh' - Fix an objtool warning by adding one more 'noreturn' function for Rust 1.99.0 (expected 2026-10-01) - Fix build error in the 'rusttest' target due to ambiguity when the 'rustc-dev' component is installed, which was uncovered by the work to support Rust's GCC backend ('rustc_codegen_gcc') - Fix future Clang warnings in the upcoming powerpc support due to macro redefinitions in the UAPI helper header by including the arch-aware 'ioctl.h' header 'kernel' crate: - Rework module ownership support: - Move the module-related types into a new 'module' module and make the 'THIS_MODULE' pointer a constant of 'ModuleMetadata' so that modules can provide the pointer in const contexts, and add a 'this_module' 'const fn' to retrieve it This was enabled by upstream Rust's work on the 'const_mut_refs' and 'const_refs_to_static' features which were stabilized back in Rust 1.83.0 - Teach '#[vtable]' to associate implementations with their owning module, defaulting to the local one, including fallbacks for doctests, uses within the 'kernel' crate (like upcoming KUnit '#[test]'s for DRM) and 'rusttest' - Set 'fops.owner' from the module pointer for DRM and miscdevice - Migrate Rust Binder and configfs away from the old 'THIS_MODULE' 'static' and finally remove it from the 'module!' macro - 'num' module: - Add the new 'casts' module for lossless integer conversions Rust's 'core' library's 'From' implementations do not cover conversions that are not portable or future-proof. However, the kernel supports a narrower set of architectures, which makes it helpful to provide more infallible conversions, instead of having developers use 'as' casts, which carry the risk of silently losing data This goes along with previous work we did to avoid casts in Rust kernel code since they are more powerful than needed Thus, provide safe 'const' conversion functions (e.g. 'usize_as_u64' and 'u64_into_u8'), as well as the 'FromSafeCast' and 'IntoSafeCast' extension traits that provide conversions that are known to be lossless in the kernel, and an 'arch' submodule defining conversions that are known to be lossless on particular architectures (e.g. 64-bit platforms). For instance: // Conversion in const context. const USIZED_CONST: usize = u8_as_usize(255u8); // Non-const conversions. let a = u64::from_safe_cast(4096usize); let b: u64 = 4096usize.into_safe_cast(); - Add 'Bounded::shr_exact' method in the vein of 'try_shrink' which shifts a bounded right only if it loses no set bits - Fix unsoundness issue in the 'Bounded::shr' method by rejecting, at compile-time, shifts of at least the type's bit width - 'fmt' module: - Route '{:p}' raw pointer formatting through the kernel's hashed '%p' format to prevent address leaks, including support for width and padding. Include tests for both 'no_hash_pointers' case and the default (hashed) one - Fix the '{:p}' forwarding implementation, which could print the address of a temporary stack variable - 'time' module: - Make 'Delta' generic over its time unit, with a default unit of nanoseconds ('Nsec'), preserving the existing behavior. Then, add a 'Jiffy' time unit - Add the 'Delta::as_millis_ceil()' method - Fix 'as_micros_ceil()' rounding near 'i64::MAX', which could yield a result one microsecond too small - 'sync' module: - Implement 'ForeignOwnable' for 'ARef<T>', allowing C code to own an 'ARef<T>' - Add a safe abstraction for 'rcu_barrier()' - 'error' module: add all of the remaining error codes, except the deprecated compatibility aliases - 'bug' module: - Fix build error on UML in 'warn_on!' for callers from within the 'kernel' crate - Fix future 'dead_code' warning on arm and loongarch64 and under 'CONFIG_BUG=n' in 'warn_on!', which would trigger with the upcoming SRCU abstractions - Fix future build error in 'rusttest' on cross-compilation cases, which would trigger when 'warn_on!' has callers inside the 'kernel' crate - 'bitfield' module: fix build error for the upcoming support for Rust's GCC backend ('rustc_codegen_gcc') by always inlining a couple conversions used in tests 'pin-init' crate: - User-visible changes: - Merge the '__pinned_init' and '__init' methods and make 'Init' a marker trait - Introduce public APIs 'raw_init' and 'raw_try_init' to prevent users from needing to invoke the internal '__pinned_init' and '__init' methods - Emit errors for duplicate '#[pin]' attributes - Link 'Zeroable::zeroed' and 'pin_init::zeroed' in documentation - Other changes: - Fix unwind safety issues - Clean up lint 'allow' and 'expect's - Overhaul '#[cfg]' handling to pave the way for tuple structs and self-referential structs - Mark many functions as '#[inline]' for better codegen with '-C opt-level=s' ('CC_OPTIMIZE_FOR_SIZE') 'MAINTAINERS': - Update 'MODULE SUPPORT' to cover the new 'module' module And some other fixes, cleanups and improvements" * tag 'rust-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (54 commits) rust: add functions and traits for lossless integer conversions rust: kernel: add `LocalModule` fallback for `#[vtable]` `impl`s rust: fmt: route {:p} through HashedPtr to prevent address leaks rust: fmt: fix {:p} printing stack addresses rust: module: update MAINTAINERS to cover module.rs rust: macros: remove `THIS_MODULE` static from `module!` rust_binder: use `LocalModule` for `THIS_MODULE` rust: configfs: use `LocalModule` for `THIS_MODULE` rust: miscdevice: set fops.owner from driver module pointer rust: drm: set fops.owner from driver module pointer rust: macros: auto-insert OwnerModule in #[vtable] rust: doctest: add LocalModule fallback for #[vtable] ThisModule rust: module: add `THIS_MODULE` const to `ModuleMetadata` trait rust: module: move module types into `module.rs` rust: num: add Bounded::shr_exact rust: num: reject Bounded::shr overshifts at build time rust: num: use const_assert! in Bounded rust: uapi: replace direct asm-generic/ioctl.h include with linux/ioctl.h rust: time: add Delta::as_millis_ceil() rust: time: add jiffies time unit for Delta ...
Diffstat (limited to 'rust/kernel/sync')
-rw-r--r--rust/kernel/sync/arc.rs20
-rw-r--r--rust/kernel/sync/aref.rs50
-rw-r--r--rust/kernel/sync/rcu.rs20
3 files changed, 80 insertions, 10 deletions
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 5ac4961b7cd2..8ae0fe6f19ec 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -154,7 +154,7 @@ impl<T: ?Sized> ArcInner<T> {
///
/// # Safety
///
- /// `ptr` must have been returned by a previous call to [`Arc::into_raw`], and the `Arc` must
+ /// `ptr` must have been returned by a previous call to [`Arc::into_raw`], and the [`Arc`] must
/// not yet have been destroyed.
unsafe fn container_of(ptr: *const T) -> NonNull<ArcInner<T>> {
let refcount_layout = Layout::new::<Refcount>();
@@ -253,7 +253,7 @@ impl<T: ?Sized> Arc<T> {
/// Convert the [`Arc`] into a raw pointer.
///
- /// The raw pointer has ownership of the refcount that this Arc object owned.
+ /// The raw pointer has ownership of the refcount that this [`Arc`] object owned.
pub fn into_raw(self) -> *const T {
let ptr = self.ptr.as_ptr();
core::mem::forget(self);
@@ -261,7 +261,7 @@ impl<T: ?Sized> Arc<T> {
unsafe { core::ptr::addr_of!((*ptr).data) }
}
- /// Return a raw pointer to the data in this arc.
+ /// Return a raw pointer to the data in this [`Arc`].
pub fn as_ptr(this: &Self) -> *const T {
let ptr = this.ptr.as_ptr();
@@ -305,7 +305,7 @@ impl<T: ?Sized> Arc<T> {
/// Converts this [`Arc`] into a [`UniqueArc`], or destroys it if it is not unique.
///
- /// When this destroys the `Arc`, it does so while properly avoiding races. This means that
+ /// When this destroys the [`Arc`], it does so while properly avoiding races. This means that
/// this method will never call the destructor of the value.
///
/// # Examples
@@ -345,11 +345,11 @@ impl<T: ?Sized> Arc<T> {
// If the refcount reaches a non-zero value, then we have destroyed this `Arc` and will
// return without further touching the `Arc`. If the refcount reaches zero, then there are
- // no other arcs, and we can create a `UniqueArc`.
+ // no other `Arc`s, and we can create a `UniqueArc`.
if refcount.dec_and_test() {
refcount.set(1);
- // INVARIANT: We own the only refcount to this arc, so we may create a `UniqueArc`. We
+ // INVARIANT: We own the only refcount to this `Arc`, so we may create a `UniqueArc`. We
// must pin the `UniqueArc` because the values was previously in an `Arc`, and they pin
// their values.
Some(Pin::from(UniqueArc {
@@ -717,7 +717,7 @@ impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid.
- unsafe { init.__init(slot)? };
+ unsafe { pin_init::raw_try_init(slot, init)? };
// SAFETY: All fields have been initialized.
Ok(unsafe { self.assume_init() })
}
@@ -727,7 +727,7 @@ impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
// slot is valid and will not be moved, because we pin it later.
- unsafe { init.__pinned_init(slot)? };
+ unsafe { pin_init::raw_try_init(slot, init)? };
// SAFETY: All fields have been initialized.
Ok(unsafe { self.assume_init() }.into())
}
@@ -795,7 +795,7 @@ impl<T> UniqueArc<MaybeUninit<T>> {
#[inline]
pub fn init_with<E>(mut self, init: impl Init<T, E>) -> core::result::Result<UniqueArc<T>, E> {
// SAFETY: The supplied pointer is valid for initialization.
- match unsafe { init.__init(self.as_mut_ptr()) } {
+ match unsafe { pin_init::raw_try_init(self.as_mut_ptr(), init) } {
// SAFETY: Initialization completed successfully.
Ok(()) => Ok(unsafe { self.assume_init() }),
Err(err) => Err(err),
@@ -810,7 +810,7 @@ impl<T> UniqueArc<MaybeUninit<T>> {
) -> core::result::Result<Pin<UniqueArc<T>>, E> {
// SAFETY: The supplied pointer is valid for initialization and we will later pin the value
// to ensure it does not move.
- match unsafe { init.__pinned_init(self.as_mut_ptr()) } {
+ match unsafe { pin_init::raw_try_init(self.as_mut_ptr(), init) } {
// SAFETY: Initialization completed successfully.
Ok(()) => Ok(unsafe { self.assume_init() }.into()),
Err(err) => Err(err),
diff --git a/rust/kernel/sync/aref.rs b/rust/kernel/sync/aref.rs
index b721b2e00b98..9983ee085248 100644
--- a/rust/kernel/sync/aref.rs
+++ b/rust/kernel/sync/aref.rs
@@ -24,6 +24,11 @@ use core::{
ptr::NonNull, //
};
+use crate::{
+ prelude::*,
+ types::ForeignOwnable, //
+};
+
/// Types that are _always_ reference counted.
///
/// It allows such types to define their own custom ref increment and decrement functions.
@@ -188,6 +193,51 @@ where
}
impl<T: AlwaysRefCounted + Eq> Eq for ARef<T> {}
+// SAFETY: `into_foreign` returns a pointer from `NonNull::as_ptr`, so it's non-null. The
+// `ARef` invariant guarantees that `ptr` points to a valid `T`, so it's aligned to `T`.
+unsafe impl<T: AlwaysRefCounted> ForeignOwnable for ARef<T> {
+ const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
+
+ type Borrowed<'a>
+ = &'a T
+ where
+ Self: 'a;
+ type BorrowedMut<'a>
+ = &'a T
+ where
+ Self: 'a;
+
+ #[inline]
+ fn into_foreign(self) -> *mut c_void {
+ ARef::into_raw(self).as_ptr().cast()
+ }
+
+ #[inline]
+ unsafe fn from_foreign(ptr: *mut c_void) -> Self {
+ // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
+ // call to `Self::into_foreign`.
+ let ptr = unsafe { NonNull::new_unchecked(ptr.cast()) };
+
+ // SAFETY: `ptr` came from `into_foreign`, which consumed an `ARef` without decrementing
+ // the refcount, so we can transfer the ownership to the new `ARef`.
+ unsafe { ARef::from_raw(ptr) }
+ }
+
+ #[inline]
+ unsafe fn borrow<'a>(ptr: *mut c_void) -> &'a T {
+ // SAFETY: The safety requirements of this method ensure that the object remains alive and
+ // immutable for the duration of 'a.
+ unsafe { &*ptr.cast() }
+ }
+
+ #[inline]
+ unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> &'a T {
+ // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety
+ // requirements for `borrow`.
+ unsafe { <Self as ForeignOwnable>::borrow(ptr) }
+ }
+}
+
impl<T, U> PartialEq<&'_ U> for ARef<T>
where
T: AlwaysRefCounted + PartialEq<U>,
diff --git a/rust/kernel/sync/rcu.rs b/rust/kernel/sync/rcu.rs
index a32bef6e490b..42d1b26a2143 100644
--- a/rust/kernel/sync/rcu.rs
+++ b/rust/kernel/sync/rcu.rs
@@ -50,3 +50,23 @@ impl Drop for Guard {
pub fn read_lock() -> Guard {
Guard::new()
}
+
+/// Wait until all in-flight `call_rcu()` callbacks complete.
+///
+/// Note that this primitive does not necessarily wait for an RCU grace period
+/// to complete. For example, if there are no RCU callbacks queued anywhere
+/// in the system, then [`rcu_barrier()`] is within its rights to return
+/// immediately, without waiting for anything, much less an RCU grace period.
+/// In fact, [`rcu_barrier()`] will normally not result in any RCU grace periods
+/// beyond those that were already destined to be executed.
+///
+/// In kernels built with `CONFIG_RCU_LAZY=y`, this function also hurries all
+/// pending lazy RCU callbacks.
+///
+/// Note that this is one of the RCU primitives which must not be called in
+/// atomic context.
+#[inline]
+pub fn rcu_barrier() {
+ // SAFETY: `rcu_barrier()` is always safe to be called. It just might wait for a grace period.
+ unsafe { bindings::rcu_barrier() };
+}