From cd1ed11a6704638e94ccafe0ba1c3b4a11aab8f3 Mon Sep 17 00:00:00 2001 From: Borys Tyran Date: Fri, 7 Feb 2025 14:25:07 +0000 Subject: rust: improve lifetimes markup Improve lifetimes markup; e.g. from: /// ... 'a ... to: /// ... `'a` ... This will make lifetimes display as code span with Markdown and make it more consistent with rest of the docs. Link: https://github.com/Rust-for-Linux/linux/issues/1138 Signed-off-by: Borys Tyran Link: https://lore.kernel.org/r/20250207142437.112435-1-borys.tyran@protonmail.com [ Reworded and changed Closes tag to Link. - Miguel ] Signed-off-by: Miguel Ojeda --- rust/kernel/sync/poll.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rust/kernel/sync') diff --git a/rust/kernel/sync/poll.rs b/rust/kernel/sync/poll.rs index d5f17153b424..e105477a3cb1 100644 --- a/rust/kernel/sync/poll.rs +++ b/rust/kernel/sync/poll.rs @@ -43,11 +43,11 @@ impl PollTable { /// /// # Safety /// - /// The caller must ensure that for the duration of 'a, the pointer will point at a valid poll + /// The caller must ensure that for the duration of `'a`, the pointer will point at a valid poll /// table (as defined in the type invariants). /// /// The caller must also ensure that the `poll_table` is only accessed via the returned - /// reference for the duration of 'a. + /// reference for the duration of `'a`. pub unsafe fn from_ptr<'a>(ptr: *mut bindings::poll_table) -> &'a mut PollTable { // SAFETY: The safety requirements guarantee the validity of the dereference, while the // `PollTable` type being transparent makes the cast ok. -- cgit v1.2.3 From a0c6fa8b8a59f8901e182fada6ac0e1f65beaa00 Mon Sep 17 00:00:00 2001 From: Andreas Hindborg Date: Sun, 9 Mar 2025 16:18:53 +0100 Subject: rust: sync: add `Arc::as_ptr` Add a method to get a pointer to the data contained in an `Arc`. Reviewed-by: Lyude Paul Reviewed-by: Alice Ryhl Reviewed-by: Benno Lossin Link: https://lore.kernel.org/r/20250309-hrtimer-v3-v6-12-rc2-v12-2-73586e2bd5f1@kernel.org Signed-off-by: Andreas Hindborg --- rust/kernel/sync/arc.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'rust/kernel/sync') diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 3cefda7a4372..1dfa75714f9d 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -246,6 +246,15 @@ impl Arc { unsafe { core::ptr::addr_of!((*ptr).data) } } + /// Return a raw pointer to the data in this arc. + pub fn as_ptr(this: &Self) -> *const T { + let ptr = this.ptr.as_ptr(); + + // SAFETY: As `ptr` points to a valid allocation of type `ArcInner`, + // field projection to `data`is within bounds of the allocation. + unsafe { core::ptr::addr_of!((*ptr).data) } + } + /// Recreates an [`Arc`] instance previously deconstructed via [`Arc::into_raw`]. /// /// # Safety @@ -539,11 +548,11 @@ impl ArcBorrow<'_, T> { } /// Creates an [`ArcBorrow`] to an [`Arc`] that has previously been deconstructed with - /// [`Arc::into_raw`]. + /// [`Arc::into_raw`] or [`Arc::as_ptr`]. /// /// # Safety /// - /// * The provided pointer must originate from a call to [`Arc::into_raw`]. + /// * The provided pointer must originate from a call to [`Arc::into_raw`] or [`Arc::as_ptr`]. /// * For the duration of the lifetime annotated on this `ArcBorrow`, the reference count must /// not hit zero. /// * For the duration of the lifetime annotated on this `ArcBorrow`, there must not be a -- cgit v1.2.3 From 114ca41fe7922ce85fcac30fa2b06b42b4956520 Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:04:34 +0000 Subject: rust: pin-init: move `InPlaceInit` and impls of `InPlaceWrite` into the kernel crate In order to make pin-init a standalone crate, move kernel-specific code directly into the kernel crate. This includes the `InPlaceInit` trait, its implementations and the implementations of `InPlaceWrite` for `Arc` and `UniqueArc`. All of these use the kernel's error type which will become unavailable in pin-init. Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-9-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/sync/arc.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'rust/kernel/sync') diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 3cefda7a4372..31c26b692c6d 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -19,7 +19,8 @@ use crate::{ alloc::{AllocError, Flags, KBox}, bindings, - init::{self, InPlaceInit, Init, PinInit}, + init::{self, InPlaceWrite, Init, PinInit}, + init_ext::InPlaceInit, try_init, types::{ForeignOwnable, Opaque}, }; @@ -202,6 +203,26 @@ unsafe impl Send for Arc {} // the reference count reaches zero and `T` is dropped. unsafe impl Sync for Arc {} +impl InPlaceInit for Arc { + type PinnedSelf = Self; + + #[inline] + fn try_pin_init(init: impl PinInit, flags: Flags) -> Result + where + E: From, + { + UniqueArc::try_pin_init(init, flags).map(|u| u.into()) + } + + #[inline] + fn try_init(init: impl Init, flags: Flags) -> Result + where + E: From, + { + UniqueArc::try_init(init, flags).map(|u| u.into()) + } +} + impl Arc { /// Constructs a new reference counted instance of `T`. pub fn new(contents: T, flags: Flags) -> Result { @@ -659,6 +680,48 @@ pub struct UniqueArc { inner: Arc, } +impl InPlaceInit for UniqueArc { + type PinnedSelf = Pin; + + #[inline] + fn try_pin_init(init: impl PinInit, flags: Flags) -> Result + where + E: From, + { + UniqueArc::new_uninit(flags)?.write_pin_init(init) + } + + #[inline] + fn try_init(init: impl Init, flags: Flags) -> Result + where + E: From, + { + UniqueArc::new_uninit(flags)?.write_init(init) + } +} + +impl InPlaceWrite for UniqueArc> { + type Initialized = UniqueArc; + + fn write_init(mut self, init: impl Init) -> Result { + 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)? }; + // SAFETY: All fields have been initialized. + Ok(unsafe { self.assume_init() }) + } + + fn write_pin_init(mut self, init: impl PinInit) -> Result, E> { + 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)? }; + // SAFETY: All fields have been initialized. + Ok(unsafe { self.assume_init() }.into()) + } +} + impl UniqueArc { /// Tries to allocate a new [`UniqueArc`] instance. pub fn new(value: T, flags: Flags) -> Result { -- cgit v1.2.3 From 129e97be8e2856884e01340e4070c003345e1cdc Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:04:48 +0000 Subject: rust: pin-init: fix documentation links Before switching to compile the `pin-init` crate directly, change any links that would be invalid to links that are valid both before and after the switch. Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-12-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/sync/condvar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rust/kernel/sync') diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs index 7df565038d7d..5aa7fa7c7002 100644 --- a/rust/kernel/sync/condvar.rs +++ b/rust/kernel/sync/condvar.rs @@ -37,7 +37,7 @@ pub use new_condvar; /// spuriously. /// /// Instances of [`CondVar`] need a lock class and to be pinned. The recommended way to create such -/// instances is with the [`pin_init`](crate::pin_init) and [`new_condvar`] macros. +/// instances is with the [`pin_init`](crate::pin_init!) and [`new_condvar`] macros. /// /// # Examples /// -- cgit v1.2.3 From dbd5058ba60c3499b24a7133a4e2e24dba6ea77b Mon Sep 17 00:00:00 2001 From: Benno Lossin Date: Sat, 8 Mar 2025 11:05:09 +0000 Subject: rust: make pin-init its own crate Rename relative paths inside of the crate to still refer to the same items, also rename paths inside of the kernel crate and adjust the build system to build the crate. [ Remove the `expect` (and thus the `lint_reasons` feature) since the tree now uses `quote!` from `rust/macros/export.rs`. Remove the `TokenStream` import removal, since it is now used as well. In addition, temporarily (i.e. just for this commit) use an `--extern force:alloc` to prevent an unknown `new_uninit` error in the `rustdoc` target. For context, please see a similar case in: https://lore.kernel.org/lkml/20240422090644.525520-1-ojeda@kernel.org/ And adjusted the message above. - Miguel ] Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-16-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- rust/kernel/sync/arc.rs | 7 +++---- rust/kernel/sync/condvar.rs | 4 +--- rust/kernel/sync/lock.rs | 4 +--- rust/kernel/sync/lock/mutex.rs | 2 +- rust/kernel/sync/lock/spinlock.rs | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) (limited to 'rust/kernel/sync') diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 31c26b692c6d..c64eac8b4235 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -19,8 +19,7 @@ use crate::{ alloc::{AllocError, Flags, KBox}, bindings, - init::{self, InPlaceWrite, Init, PinInit}, - init_ext::InPlaceInit, + init::InPlaceInit, try_init, types::{ForeignOwnable, Opaque}, }; @@ -33,7 +32,7 @@ use core::{ pin::Pin, ptr::NonNull, }; -use macros::pin_data; +use pin_init::{self, pin_data, InPlaceWrite, Init, PinInit}; mod std_vendor; @@ -738,7 +737,7 @@ impl UniqueArc { try_init!(ArcInner { // SAFETY: There are no safety requirements for this FFI call. refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), - data <- init::uninit::(), + data <- pin_init::uninit::(), }? AllocError), flags, )?; diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs index 5aa7fa7c7002..c2535db9e0f8 100644 --- a/rust/kernel/sync/condvar.rs +++ b/rust/kernel/sync/condvar.rs @@ -8,8 +8,6 @@ use super::{lock::Backend, lock::Guard, LockClassKey}; use crate::{ ffi::{c_int, c_long}, - init::PinInit, - pin_init, str::CStr, task::{MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE}, time::Jiffies, @@ -17,7 +15,7 @@ use crate::{ }; use core::marker::PhantomPinned; use core::ptr; -use macros::pin_data; +use pin_init::{pin_data, pin_init, PinInit}; /// Creates a [`CondVar`] initialiser with the given name and a newly-created lock class. #[macro_export] diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs index eb80048e0110..7f611b59ac57 100644 --- a/rust/kernel/sync/lock.rs +++ b/rust/kernel/sync/lock.rs @@ -7,13 +7,11 @@ use super::LockClassKey; use crate::{ - init::PinInit, - pin_init, str::CStr, types::{NotThreadSafe, Opaque, ScopeGuard}, }; use core::{cell::UnsafeCell, marker::PhantomPinned}; -use macros::pin_data; +use pin_init::{pin_data, pin_init, PinInit}; pub mod mutex; pub mod spinlock; diff --git a/rust/kernel/sync/lock/mutex.rs b/rust/kernel/sync/lock/mutex.rs index 70cadbc2e8e2..581cee7ab842 100644 --- a/rust/kernel/sync/lock/mutex.rs +++ b/rust/kernel/sync/lock/mutex.rs @@ -26,7 +26,7 @@ pub use new_mutex; /// Since it may block, [`Mutex`] needs to be used with care in atomic contexts. /// /// Instances of [`Mutex`] need a lock class and to be pinned. The recommended way to create such -/// instances is with the [`pin_init`](crate::pin_init) and [`new_mutex`] macros. +/// instances is with the [`pin_init`](pin_init::pin_init) and [`new_mutex`] macros. /// /// # Examples /// diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spinlock.rs index ab2f8d075311..d7be38ccbdc7 100644 --- a/rust/kernel/sync/lock/spinlock.rs +++ b/rust/kernel/sync/lock/spinlock.rs @@ -24,7 +24,7 @@ pub use new_spinlock; /// unlocked, at which point another CPU will be allowed to make progress. /// /// Instances of [`SpinLock`] need a lock class and to be pinned. The recommended way to create such -/// instances is with the [`pin_init`](crate::pin_init) and [`new_spinlock`] macros. +/// instances is with the [`pin_init`](pin_init::pin_init) and [`new_spinlock`] macros. /// /// # Examples /// -- cgit v1.2.3