From: Benno Lossin Date: Sat, 8 Mar 2025 11:04:52 +0000 (+0000) Subject: rust: pin-init: remove kernel-crate dependency X-Git-Tag: v6.15-rc1~93^2~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=31547c988257b3ddd1badb23c166c42b5310735c;p=thirdparty%2Flinux.git rust: pin-init: remove kernel-crate dependency In order to make pin-init a standalone crate, remove dependencies on kernel-specific code such as `ScopeGuard` and `KBox`. `ScopeGuard` is only used in the `[pin_]init_array_from_fn` functions and can easily be replaced by a primitive construct. `KBox` is only used for type variance of unsized types and can also easily be replaced. Signed-off-by: Benno Lossin Reviewed-by: Fiona Behrens Reviewed-by: Andreas Hindborg Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20250308110339.2997091-13-benno.lossin@proton.me Signed-off-by: Miguel Ojeda --- diff --git a/rust/pin-init/src/__internal.rs b/rust/pin-init/src/__internal.rs index 0db800819681b..8a53f55e1bbf4 100644 --- a/rust/pin-init/src/__internal.rs +++ b/rust/pin-init/src/__internal.rs @@ -11,6 +11,9 @@ use super::*; /// See the [nomicon] for what subtyping is. See also [this table]. /// +/// The reason for not using `PhantomData<*mut T>` is that that type never implements [`Send`] and +/// [`Sync`]. Hence `fn(*mut T) -> *mut T` is used, as that type always implements them. +/// /// [nomicon]: https://doc.rust-lang.org/nomicon/subtyping.html /// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns pub(super) type Invariant = PhantomData *mut T>; @@ -105,7 +108,7 @@ pub unsafe trait InitData: Copy { } } -pub struct AllData(PhantomData) -> KBox>); +pub struct AllData(Invariant); impl Clone for AllData { fn clone(&self) -> Self { diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs index 47954bc1dc2f5..5f1afd3abb565 100644 --- a/rust/pin-init/src/lib.rs +++ b/rust/pin-init/src/lib.rs @@ -212,7 +212,6 @@ //! [`pin_data`]: ::macros::pin_data //! [`pin_init!`]: crate::pin_init! -use crate::{alloc::KBox, types::ScopeGuard}; use core::{ cell::UnsafeCell, convert::Infallible, @@ -944,7 +943,7 @@ pub unsafe trait PinInit: Sized { } /// An initializer returned by [`PinInit::pin_chain`]. -pub struct ChainPinInit(I, F, __internal::Invariant<(E, KBox)>); +pub struct ChainPinInit(I, F, __internal::Invariant<(E, T)>); // SAFETY: The `__pinned_init` function is implemented such that it // - returns `Ok(())` on successful initialization, @@ -1043,7 +1042,7 @@ pub unsafe trait Init: PinInit { } /// An initializer returned by [`Init::chain`]. -pub struct ChainInit(I, F, __internal::Invariant<(E, KBox)>); +pub struct ChainInit(I, F, __internal::Invariant<(E, T)>); // SAFETY: The `__init` function is implemented such that it // - returns `Ok(())` on successful initialization, @@ -1140,25 +1139,19 @@ where { let init = move |slot: *mut [T; N]| { let slot = slot.cast::(); - // Counts the number of initialized elements and when dropped drops that many elements from - // `slot`. - let mut init_count = ScopeGuard::new_with_data(0, |i| { - // We now free every element that has been initialized before. - // SAFETY: The loop initialized exactly the values from 0..i and since we - // return `Err` below, the caller will consider the memory at `slot` as - // uninitialized. - unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; - }); for i in 0..N { let init = make_init(i); // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`. let ptr = unsafe { slot.add(i) }; // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init` // requirements. - unsafe { init.__init(ptr) }?; - *init_count += 1; + if let Err(e) = unsafe { init.__init(ptr) } { + // SAFETY: The loop has initialized the elements `slot[0..i]` and since we return + // `Err` below, `slot` will be considered uninitialized memory. + unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; + return Err(e); + } } - init_count.dismiss(); Ok(()) }; // SAFETY: The initializer above initializes every element of the array. On failure it drops @@ -1189,25 +1182,19 @@ where { let init = move |slot: *mut [T; N]| { let slot = slot.cast::(); - // Counts the number of initialized elements and when dropped drops that many elements from - // `slot`. - let mut init_count = ScopeGuard::new_with_data(0, |i| { - // We now free every element that has been initialized before. - // SAFETY: The loop initialized exactly the values from 0..i and since we - // return `Err` below, the caller will consider the memory at `slot` as - // uninitialized. - unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; - }); for i in 0..N { let init = make_init(i); // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`. let ptr = unsafe { slot.add(i) }; // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init` // requirements. - unsafe { init.__pinned_init(ptr) }?; - *init_count += 1; + if let Err(e) = unsafe { init.__pinned_init(ptr) } { + // SAFETY: The loop has initialized the elements `slot[0..i]` and since we return + // `Err` below, `slot` will be considered uninitialized memory. + unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; + return Err(e); + } } - init_count.dismiss(); Ok(()) }; // SAFETY: The initializer above initializes every element of the array. On failure it drops