On Thu, 12 Sep 2024 00:52:53 +0200 Danilo Krummrich <dakr@xxxxxxxxxx> wrote: > Now that all existing `Vec` users were moved to the kernel `Vec` type, > remove the `VecExt` extension. > > Reviewed-by: Alice Ryhl <aliceryhl@xxxxxxxxxx> > Reviewed-by: Benno Lossin <benno.lossin@xxxxxxxxx> > Signed-off-by: Danilo Krummrich <dakr@xxxxxxxxxx> Reviewed-by: Gary Guo <gary@xxxxxxxxxxx> > --- > rust/kernel/alloc.rs | 1 - > rust/kernel/alloc/vec_ext.rs | 185 ----------------------------------- > rust/kernel/prelude.rs | 5 +- > 3 files changed, 1 insertion(+), 190 deletions(-) > delete mode 100644 rust/kernel/alloc/vec_ext.rs > > diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs > index e8fbae2adadb..aabdf80e4f7b 100644 > --- a/rust/kernel/alloc.rs > +++ b/rust/kernel/alloc.rs > @@ -6,7 +6,6 @@ > pub mod allocator; > pub mod kbox; > pub mod kvec; > -pub mod vec_ext; > > #[cfg(any(test, testlib))] > pub mod allocator_test; > diff --git a/rust/kernel/alloc/vec_ext.rs b/rust/kernel/alloc/vec_ext.rs > deleted file mode 100644 > index 1297a4be32e8..000000000000 > --- a/rust/kernel/alloc/vec_ext.rs > +++ /dev/null > @@ -1,185 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0 > - > -//! Extensions to [`Vec`] for fallible allocations. > - > -use super::{AllocError, Flags}; > -use alloc::vec::Vec; > - > -/// Extensions to [`Vec`]. > -pub trait VecExt<T>: Sized { > - /// Creates a new [`Vec`] instance with at least the given capacity. > - /// > - /// # Examples > - /// > - /// ``` > - /// let v = Vec::<u32>::with_capacity(20, GFP_KERNEL)?; > - /// > - /// assert!(v.capacity() >= 20); > - /// # Ok::<(), Error>(()) > - /// ``` > - fn with_capacity(capacity: usize, flags: Flags) -> Result<Self, AllocError>; > - > - /// Appends an element to the back of the [`Vec`] instance. > - /// > - /// # Examples > - /// > - /// ``` > - /// let mut v = Vec::new(); > - /// v.push(1, GFP_KERNEL)?; > - /// assert_eq!(&v, &[1]); > - /// > - /// v.push(2, GFP_KERNEL)?; > - /// assert_eq!(&v, &[1, 2]); > - /// # Ok::<(), Error>(()) > - /// ``` > - fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError>; > - > - /// Pushes clones of the elements of slice into the [`Vec`] instance. > - /// > - /// # Examples > - /// > - /// ``` > - /// let mut v = Vec::new(); > - /// v.push(1, GFP_KERNEL)?; > - /// > - /// v.extend_from_slice(&[20, 30, 40], GFP_KERNEL)?; > - /// assert_eq!(&v, &[1, 20, 30, 40]); > - /// > - /// v.extend_from_slice(&[50, 60], GFP_KERNEL)?; > - /// assert_eq!(&v, &[1, 20, 30, 40, 50, 60]); > - /// # Ok::<(), Error>(()) > - /// ``` > - fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(), AllocError> > - where > - T: Clone; > - > - /// Ensures that the capacity exceeds the length by at least `additional` elements. > - /// > - /// # Examples > - /// > - /// ``` > - /// let mut v = Vec::new(); > - /// v.push(1, GFP_KERNEL)?; > - /// > - /// v.reserve(10, GFP_KERNEL)?; > - /// let cap = v.capacity(); > - /// assert!(cap >= 10); > - /// > - /// v.reserve(10, GFP_KERNEL)?; > - /// let new_cap = v.capacity(); > - /// assert_eq!(new_cap, cap); > - /// > - /// # Ok::<(), Error>(()) > - /// ``` > - fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), AllocError>; > -} > - > -impl<T> VecExt<T> for Vec<T> { > - fn with_capacity(capacity: usize, flags: Flags) -> Result<Self, AllocError> { > - let mut v = Vec::new(); > - <Self as VecExt<_>>::reserve(&mut v, capacity, flags)?; > - Ok(v) > - } > - > - fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> { > - <Self as VecExt<_>>::reserve(self, 1, flags)?; > - let s = self.spare_capacity_mut(); > - s[0].write(v); > - > - // SAFETY: We just initialised the first spare entry, so it is safe to increase the length > - // by 1. We also know that the new length is <= capacity because of the previous call to > - // `reserve` above. > - unsafe { self.set_len(self.len() + 1) }; > - Ok(()) > - } > - > - fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Result<(), AllocError> > - where > - T: Clone, > - { > - <Self as VecExt<_>>::reserve(self, other.len(), flags)?; > - for (slot, item) in core::iter::zip(self.spare_capacity_mut(), other) { > - slot.write(item.clone()); > - } > - > - // SAFETY: We just initialised the `other.len()` spare entries, so it is safe to increase > - // the length by the same amount. We also know that the new length is <= capacity because > - // of the previous call to `reserve` above. > - unsafe { self.set_len(self.len() + other.len()) }; > - Ok(()) > - } > - > - #[cfg(any(test, testlib))] > - fn reserve(&mut self, additional: usize, _flags: Flags) -> Result<(), AllocError> { > - Vec::reserve(self, additional); > - Ok(()) > - } > - > - #[cfg(not(any(test, testlib)))] > - fn reserve(&mut self, additional: usize, flags: Flags) -> Result<(), AllocError> { > - let len = self.len(); > - let cap = self.capacity(); > - > - if cap - len >= additional { > - return Ok(()); > - } > - > - if core::mem::size_of::<T>() == 0 { > - // The capacity is already `usize::MAX` for SZTs, we can't go higher. > - return Err(AllocError); > - } > - > - // We know cap is <= `isize::MAX` because `Layout::array` fails if the resulting byte size > - // is greater than `isize::MAX`. So the multiplication by two won't overflow. > - let new_cap = core::cmp::max(cap * 2, len.checked_add(additional).ok_or(AllocError)?); > - let layout = core::alloc::Layout::array::<T>(new_cap).map_err(|_| AllocError)?; > - > - let (old_ptr, len, cap) = destructure(self); > - > - // We need to make sure that `ptr` is either NULL or comes from a previous call to > - // `krealloc_aligned`. A `Vec<T>`'s `ptr` value is not guaranteed to be NULL and might be > - // dangling after being created with `Vec::new`. Instead, we can rely on `Vec<T>`'s capacity > - // to be zero if no memory has been allocated yet. > - let ptr = if cap == 0 { > - core::ptr::null_mut() > - } else { > - old_ptr > - }; > - > - // SAFETY: `ptr` is valid because it's either NULL or comes from a previous call to > - // `krealloc_aligned`. We also verified that the type is not a ZST. > - let new_ptr = unsafe { super::allocator::krealloc_aligned(ptr.cast(), layout, flags) }; > - if new_ptr.is_null() { > - // SAFETY: We are just rebuilding the existing `Vec` with no changes. > - unsafe { rebuild(self, old_ptr, len, cap) }; > - Err(AllocError) > - } else { > - // SAFETY: `ptr` has been reallocated with the layout for `new_cap` elements. New cap > - // is greater than `cap`, so it continues to be >= `len`. > - unsafe { rebuild(self, new_ptr.cast::<T>(), len, new_cap) }; > - Ok(()) > - } > - } > -} > - > -#[cfg(not(any(test, testlib)))] > -fn destructure<T>(v: &mut Vec<T>) -> (*mut T, usize, usize) { > - let mut tmp = Vec::new(); > - core::mem::swap(&mut tmp, v); > - let mut tmp = core::mem::ManuallyDrop::new(tmp); > - let len = tmp.len(); > - let cap = tmp.capacity(); > - (tmp.as_mut_ptr(), len, cap) > -} > - > -/// Rebuilds a `Vec` from a pointer, length, and capacity. > -/// > -/// # Safety > -/// > -/// The same as [`Vec::from_raw_parts`]. > -#[cfg(not(any(test, testlib)))] > -unsafe fn rebuild<T>(v: &mut Vec<T>, ptr: *mut T, len: usize, cap: usize) { > - // SAFETY: The safety requirements from this function satisfy those of `from_raw_parts`. > - let mut tmp = unsafe { Vec::from_raw_parts(ptr, len, cap) }; > - core::mem::swap(&mut tmp, v); > -} > diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs > index 80223cdaa485..07daccf6ca8e 100644 > --- a/rust/kernel/prelude.rs > +++ b/rust/kernel/prelude.rs > @@ -14,10 +14,7 @@ > #[doc(no_inline)] > pub use core::pin::Pin; > > -pub use crate::alloc::{flags::*, vec_ext::VecExt, Box, KBox, KVBox, KVVec, KVec, VBox, VVec}; > - > -#[doc(no_inline)] > -pub use alloc::vec::Vec; > +pub use crate::alloc::{flags::*, Box, KBox, KVBox, KVVec, KVec, VBox, VVec}; > > #[doc(no_inline)] > pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable};