Now that all existing `Vec` users were moved to the kernel `Vec` type,
remove the `VecExt` extension.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
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};
--
2.46.0
On Thu, 12 Sep 2024 00:52:53 +0200 Danilo Krummrich <dakr@kernel.org> wrote: > Now that all existing `Vec` users were moved to the kernel `Vec` type, > remove the `VecExt` extension. > > Reviewed-by: Alice Ryhl <aliceryhl@google.com> > Reviewed-by: Benno Lossin <benno.lossin@proton.me> > Signed-off-by: Danilo Krummrich <dakr@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> > --- > 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};
© 2016 - 2024 Red Hat, Inc.