rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Additional methods for Vec
@ 2025-03-21 12:09 Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 1/7] rust: alloc: add Vec::clear Alice Ryhl
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:09 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl,
	Benno Lossin, Tamir Duberstein

This adds various Vec methods. Some of them are needed by Rust Binder,
and others are needed in other places. Each commit explains where it is
needed.

I'm not sure what we concluded on the set_len / dec_len changes, so I
don't depend on that series for now.

This series is based on top of Vec::truncate from
https://lore.kernel.org/rust-for-linux/20250316111644.154602-1-andrewjballance@gmail.com/

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
Changes in v2:
- Add two more methods that I needed.
- Introduce some uses of set_len.
- Add example to retain.
- Simplify pop.
- Adjust 11 to 10 in push_within_capacity example.
- Link to v1: https://lore.kernel.org/r/20250320-vec-methods-v1-0-7dff5cf25fe8@google.com

---
Alice Ryhl (7):
      rust: alloc: add Vec::clear
      rust: alloc: add Vec::pop
      rust: alloc: add Vec::push_within_capacity
      rust: alloc: add Vec::drain_all
      rust: alloc: add Vec::retain
      rust: alloc: add Vec::remove
      rust: alloc: add Vec::insert_within_capacity

 rust/kernel/alloc/kvec.rs | 202 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)
---
base-commit: a337a03281efc4553191b432d757d4c04884bf4c
change-id: 20250320-vec-methods-adfa41e55311

Best regards,
-- 
Alice Ryhl <aliceryhl@google.com>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 1/7] rust: alloc: add Vec::clear
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
@ 2025-03-21 12:09 ` Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 2/7] rust: alloc: add Vec::pop Alice Ryhl
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:09 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl,
	Benno Lossin, Tamir Duberstein

Our custom Vec type is missing the stdlib method `clear`, thus add it.
It will be used in the miscdevice sample.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Tamir Duberstein <tamird@gmail.com>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index eb6d40a1bf8ba45126bd47f1dd4a7b7ef86112c4..95e752ed27395fce72d372976b74fb1b0e957194 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -395,6 +395,26 @@ pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
         (ptr, len, capacity)
     }
 
+    /// Clears the vector, removing all values.
+    ///
+    /// Note that this method has no effect on the allocated capacity
+    /// of the vector.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = kernel::kvec![1, 2, 3]?;
+    ///
+    /// v.clear();
+    ///
+    /// assert!(v.is_empty());
+    /// # Ok::<(), Error>(())
+    /// ```
+    #[inline]
+    pub fn clear(&mut self) {
+        self.truncate(0);
+    }
+
     /// Ensures that the capacity exceeds the length by at least `additional` elements.
     ///
     /// # Examples

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 2/7] rust: alloc: add Vec::pop
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 1/7] rust: alloc: add Vec::clear Alice Ryhl
@ 2025-03-21 12:09 ` Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 3/7] rust: alloc: add Vec::push_within_capacity Alice Ryhl
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:09 UTC (permalink / raw)
  To: Danilo Krummrich; +Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl

This introduces a basic method that our custom Vec is missing. I expect
that it will be used in many places, but at the time of writing, Rust
Binder has six calls to Vec::pop.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index 95e752ed27395fce72d372976b74fb1b0e957194..e42c5c40c992c796409505da70975f970524fc24 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -302,6 +302,35 @@ pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> {
         Ok(())
     }
 
+    /// Removes the last element from a vector and returns it, or `None` if it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = KVec::new();
+    /// v.push(1, GFP_KERNEL)?;
+    /// v.push(2, GFP_KERNEL)?;
+    /// assert_eq!(&v, &[1, 2]);
+    ///
+    /// assert_eq!(v.pop(), Some(2));
+    /// assert_eq!(v.pop(), Some(1));
+    /// assert_eq!(v.pop(), None);
+    /// # Ok::<(), Error>(())
+    /// ```
+    pub fn pop(&mut self) -> Option<T> {
+        let len_sub_1 = self.len.checked_sub(1)?;
+
+        // SAFETY: If the first `len` elements are valid, then the first `len - 1` elements are
+        // valid.
+        self.set_len(len_sub_1);
+
+        // This invalidates a value in this vector's allocation, but the Vec invariants do not
+        // require it to be valid because `self.len <= len_sub_1`.
+        // SAFETY: Since `len_sub_1` is less than the value `self.len` had at the beginning of
+        // `pop`, this index holds a valid value.
+        Some(unsafe { self.as_mut_ptr().add(len_sub_1).read() })
+    }
+
     /// Creates a new [`Vec`] instance with at least the given capacity.
     ///
     /// # Examples

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3/7] rust: alloc: add Vec::push_within_capacity
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 1/7] rust: alloc: add Vec::clear Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 2/7] rust: alloc: add Vec::pop Alice Ryhl
@ 2025-03-21 12:09 ` Alice Ryhl
  2025-03-21 12:09 ` [PATCH v2 4/7] rust: alloc: add Vec::drain_all Alice Ryhl
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:09 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl,
	Benno Lossin

This introduces a new method called `push_within_capacity` for appending
to a vector without attempting to allocate if the capacity is full. Rust
Binder will use this in various places to safely push to a vector while
holding a spinlock.

The existing Vec::push method is reimplemented in terms of the new
method.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index e42c5c40c992c796409505da70975f970524fc24..c9de619466eed1590fda039a291207100729a96a 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -284,6 +284,31 @@ pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
     /// ```
     pub fn push(&mut self, v: T, flags: Flags) -> Result<(), AllocError> {
         self.reserve(1, flags)?;
+        let err = self.push_within_capacity(v);
+        // SAFETY: The call to `reserve` was successful, so `push_within_capacity` cannot fail.
+        unsafe { err.unwrap_unchecked() };
+        Ok(())
+    }
+
+    /// Appends an element to the back of the [`Vec`] instance.
+    ///
+    /// Fails if the vector does not have capacity for the new element.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = KVec::with_capacity(10, GFP_KERNEL);
+    /// for i in 0..10 {
+    ///     v.push_within_capacity(i).unwrap();
+    /// }
+    ///
+    /// assert!(v.push_within_capacity(10).is_err());
+    /// # Ok::<(), Error>(())
+    /// ```
+    pub fn push_within_capacity(&mut self, v: T) -> Result<(), T> {
+        if self.len() >= self.capacity() {
+            return Err(v);
+        }
 
         // SAFETY:
         // - `self.len` is smaller than `self.capacity` and hence, the resulting pointer is

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 4/7] rust: alloc: add Vec::drain_all
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (2 preceding siblings ...)
  2025-03-21 12:09 ` [PATCH v2 3/7] rust: alloc: add Vec::push_within_capacity Alice Ryhl
@ 2025-03-21 12:09 ` Alice Ryhl
  2025-03-21 12:10 ` [PATCH v2 5/7] rust: alloc: add Vec::retain Alice Ryhl
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:09 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl,
	Benno Lossin

This is like the stdlib method drain, except that it's hard-coded to use
the entire vector's range. Rust Binder uses it in the range allocator to
take ownership of everything in a vector in a case where reusing the
vector is desirable.

Implementing `DrainAll` in terms of `slice::IterMut` lets us reuse some
nice optimizations in core for the case where T is a ZST.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index c9de619466eed1590fda039a291207100729a96a..d16360c3156b9bb4fc57cddcfd076adb70abd3c9 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -562,6 +562,30 @@ pub fn truncate(&mut self, len: usize) {
         //   len, therefore we have exclusive access to [`new_len`, `old_len`)
         unsafe { ptr::drop_in_place(ptr) };
     }
+
+    /// Takes ownership of all items in this vector without consuming the allocation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = kernel::kvec![0, 1, 2, 3]?;
+    ///
+    /// for (i, j) in v.drain_all().enumerate() {
+    ///     assert_eq!(i, j);
+    /// }
+    ///
+    /// assert!(v.capacity() >= 4);
+    /// ```
+    pub fn drain_all(&mut self) -> DrainAll<'_, T> {
+        let len = self.len();
+        // SAFETY: The first 0 elements are valid.
+        self.set_len(0);
+        // INVARIANT: The first `len` elements of the spare capacity are valid values, and as we
+        // just set the length to zero, we may transfer ownership to the `DrainAll` object.
+        DrainAll {
+            elements: self.spare_capacity_mut()[..len].iter_mut(),
+        }
+    }
 }
 
 impl<T: Clone, A: Allocator> Vec<T, A> {
@@ -1047,3 +1071,36 @@ fn into_iter(self) -> Self::IntoIter {
         }
     }
 }
+
+/// An iterator that owns all items in a vector, but does not own its allocation.
+///
+/// # Invariants
+///
+/// Every `&mut MaybeUninit<T>` returned by the iterator contains a valid `T` owned by this
+/// `DrainAll`.
+pub struct DrainAll<'vec, T> {
+    elements: slice::IterMut<'vec, MaybeUninit<T>>,
+}
+
+impl<'vec, T> Iterator for DrainAll<'vec, T> {
+    type Item = T;
+
+    fn next(&mut self) -> Option<T> {
+        let elem = self.elements.next()?;
+        // SAFETY: By the type invariants, we may take ownership of the value in this
+        // `MaybeUninit<T>`.
+        Some(unsafe { elem.assume_init_read() })
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.elements.size_hint()
+    }
+}
+
+impl<'vec, T> Drop for DrainAll<'vec, T> {
+    fn drop(&mut self) {
+        if core::mem::needs_drop::<T>() {
+            while self.next().is_some() {}
+        }
+    }
+}

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 5/7] rust: alloc: add Vec::retain
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (3 preceding siblings ...)
  2025-03-21 12:09 ` [PATCH v2 4/7] rust: alloc: add Vec::drain_all Alice Ryhl
@ 2025-03-21 12:10 ` Alice Ryhl
  2025-03-21 12:10 ` [PATCH v2 6/7] rust: alloc: add Vec::remove Alice Ryhl
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:10 UTC (permalink / raw)
  To: Danilo Krummrich; +Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl

This adds a common Vec method called `retain` that removes all elements
that don't match a certain condition. Rust Binder uses it to find all
processes that match a given pid.

The stdlib retain method takes &T rather than &mut T and has a separate
retain_mut for the &mut T case. However, this is considered an API
mistake that can't be fixed now due to backwards compatibility. There's
no reason for us to repeat that mistake.

To verify the correctness of this implementation, you may run the
following program in userspace:

    fn retain<T>(vec: &mut Vec<T>, f: impl Fn(&T) -> bool) {
        let mut num_kept = 0;
        let mut next_to_check = 0;
        while let Some(to_check) = vec.get_mut(next_to_check) {
            if f(to_check) {
                vec.swap(num_kept, next_to_check);
                num_kept += 1;
            }
            next_to_check += 1;
        }
        vec.truncate(num_kept);
    }

    fn verify(c: &[bool]) {
        let mut vec1: Vec<usize> = (0..c.len()).collect();
        let mut vec2: Vec<usize> = (0..c.len()).collect();

        vec1.retain(|i| c[*i]);
        retain(&mut vec2, |i| c[*i]);

        assert_eq!(vec1, vec2);
    }

    // Used to loop through all 2^n bit vectors.
    fn add(value: &mut [bool]) -> bool {
        let mut carry = true;
        for v in value {
            let new_v = carry != *v;
            carry = carry && *v;
            *v = new_v;
        }
        carry
    }

    fn main() {
        for len in 0..10 {
            let mut retain = vec![false; len];
            while !add(&mut retain) {
                verify(&retain);
            }
        }
        println!("ok!");
    }

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index d16360c3156b9bb4fc57cddcfd076adb70abd3c9..866369406ea95e68adea366828552e76e451e24f 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -586,6 +586,28 @@ pub fn drain_all(&mut self) -> DrainAll<'_, T> {
             elements: self.spare_capacity_mut()[..len].iter_mut(),
         }
     }
+
+    /// Removes all elements that don't match the provided closure.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = kernel::kvec![1, 2, 3, 4]?;
+    /// v.retain(|i| i % 2 == 0);
+    /// assert_eq!(v, [2, 4]);
+    /// ```
+    pub fn retain(&mut self, mut f: impl FnMut(&mut T) -> bool) {
+        let mut num_kept = 0;
+        let mut next_to_check = 0;
+        while let Some(to_check) = self.get_mut(next_to_check) {
+            if f(to_check) {
+                self.swap(num_kept, next_to_check);
+                num_kept += 1;
+            }
+            next_to_check += 1;
+        }
+        self.truncate(num_kept);
+    }
 }
 
 impl<T: Clone, A: Allocator> Vec<T, A> {

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 6/7] rust: alloc: add Vec::remove
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (4 preceding siblings ...)
  2025-03-21 12:10 ` [PATCH v2 5/7] rust: alloc: add Vec::retain Alice Ryhl
@ 2025-03-21 12:10 ` Alice Ryhl
  2025-03-21 12:10 ` [PATCH v2 7/7] rust: alloc: add Vec::insert_within_capacity Alice Ryhl
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:10 UTC (permalink / raw)
  To: Danilo Krummrich; +Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl

This is needed by Rust Binder in the range allocator, and by upcoming
GPU drivers during firmware initialization.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index 866369406ea95e68adea366828552e76e451e24f..f7f7f9c650f8167ad6f53b0d83e328203445aa1f 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -356,6 +356,34 @@ pub fn pop(&mut self) -> Option<T> {
         Some(unsafe { self.as_mut_ptr().add(len_sub_1).read() })
     }
 
+    /// Removes the element at the given index.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = kernel::kvec![1, 2, 3]?;
+    /// assert_eq!(v.remove(1), 2);
+    /// assert_eq!(v, [1, 3]);
+    /// # Ok::<(), Error>(())
+    /// ```
+    pub fn remove(&mut self, i: idx) -> T {
+        // INVARIANT: This breaks the invariants by invalidating the value at index `i`, but we
+        // restore the invariants below.
+        // SAFETY: Since `&self[i]` did not result in a panic, the value at index `i` is valid.
+        let value = unsafe { ptr::read(&self[i]) };
+
+        // SAFETY: We checked that `i` is in-bounds.
+        let p = unsafe { self.as_mut_ptr().add(i) };
+        // INVARIANT: The invariants are still broken, but now the invalid value is the last
+        // element of the vector.
+        // SAFETY: `p.add(1).add(self.len - i - 1)` is `i+1+len-i-1 == len` elements after the
+        // beginning of the vector, so this is in-bounds of the vector.
+        unsafe { ptr::copy(p.add(1), p, self.len - i - 1) };
+        // INVARIANT: This restores the invariants since the invalid element no longer needs to be
+        // valid.
+        self.len = self.len - 1;
+    }
+
     /// Creates a new [`Vec`] instance with at least the given capacity.
     ///
     /// # Examples

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 7/7] rust: alloc: add Vec::insert_within_capacity
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (5 preceding siblings ...)
  2025-03-21 12:10 ` [PATCH v2 6/7] rust: alloc: add Vec::remove Alice Ryhl
@ 2025-03-21 12:10 ` Alice Ryhl
  2025-03-21 12:25 ` [PATCH v2 0/7] Additional methods for Vec Danilo Krummrich
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:10 UTC (permalink / raw)
  To: Danilo Krummrich; +Cc: Matthew Maurer, rust-for-linux, linux-kernel, Alice Ryhl

This adds a variant of Vec::insert that does not allocate memory. This
makes it safe to use this function while holding a spinlock. Rust Binder
uses it for the range allocator fast path.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/kernel/alloc/kvec.rs | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index f7f7f9c650f8167ad6f53b0d83e328203445aa1f..38ffd0cf2af6e375f8d4fc2f9afe9295b29e7db0 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -327,6 +327,27 @@ pub fn push_within_capacity(&mut self, v: T) -> Result<(), T> {
         Ok(())
     }
 
+    pub fn insert_within_capacity(&mut self, index: usize, element: T) -> Result<(), T> {
+        assert!(index <= self.len());
+
+        if self.len() >= self.capacity() {
+            return Err(element);
+        }
+
+        // SAFETY: This is in bounds since `index <= len < capacity`.
+        let p = unsafe { vec.as_mut_ptr().add(index) };
+        // INVARIANT: This breaks the Vec invariants by making `index` contain an invalid element,
+        // but we restore the invariants below.
+        // SAFETY: Both the src and dst ranges end no later than one element after the length.
+        // Since the length is less than the capacity, both ranges are in bounds of the allocation.
+        unsafe { ptr::copy(p, p.add(1), len - index) };
+        // INVARIANT: This restores the Vec invariants.
+        // SAFETY: The pointer is in-bounds of the allocation.
+        unsafe { ptr::write(p, element) };
+        // SAFETY: Index `len` contains a valid element due to the above copy and write.
+        unsafe { vec.set_len(len + 1) };
+    }
+
     /// Removes the last element from a vector and returns it, or `None` if it is empty.
     ///
     /// # Examples

-- 
2.49.0.395.g12beb8f557-goog


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/7] Additional methods for Vec
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (6 preceding siblings ...)
  2025-03-21 12:10 ` [PATCH v2 7/7] rust: alloc: add Vec::insert_within_capacity Alice Ryhl
@ 2025-03-21 12:25 ` Danilo Krummrich
  2025-03-21 13:10   ` Benno Lossin
  2025-03-21 12:28 ` Alice Ryhl
  2025-03-21 15:47 ` Tamir Duberstein
  9 siblings, 1 reply; 13+ messages in thread
From: Danilo Krummrich @ 2025-03-21 12:25 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Benno Lossin,
	Tamir Duberstein

On Fri, Mar 21, 2025 at 12:09:55PM +0000, Alice Ryhl wrote:
> This adds various Vec methods. Some of them are needed by Rust Binder,
> and others are needed in other places. Each commit explains where it is
> needed.
> 
> I'm not sure what we concluded on the set_len / dec_len changes, so I
> don't depend on that series for now.

So far I see no reason to assume otherwise, so it probably makes sense to
rebase. Unless Tamir is fine to rebase his changes onto this series.

> 
> This series is based on top of Vec::truncate from
> https://lore.kernel.org/rust-for-linux/20250316111644.154602-1-andrewjballance@gmail.com/
> 
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> ---
> Changes in v2:
> - Add two more methods that I needed.
> - Introduce some uses of set_len.

I think the added Vec::remove() modifies self.len directly.

> - Add example to retain.
> - Simplify pop.
> - Adjust 11 to 10 in push_within_capacity example.
> - Link to v1: https://lore.kernel.org/r/20250320-vec-methods-v1-0-7dff5cf25fe8@google.com
> 
> ---
> Alice Ryhl (7):
>       rust: alloc: add Vec::clear
>       rust: alloc: add Vec::pop
>       rust: alloc: add Vec::push_within_capacity
>       rust: alloc: add Vec::drain_all
>       rust: alloc: add Vec::retain
>       rust: alloc: add Vec::remove
>       rust: alloc: add Vec::insert_within_capacity
> 
>  rust/kernel/alloc/kvec.rs | 202 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 202 insertions(+)
> ---
> base-commit: a337a03281efc4553191b432d757d4c04884bf4c
> change-id: 20250320-vec-methods-adfa41e55311
> 
> Best regards,
> -- 
> Alice Ryhl <aliceryhl@google.com>
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/7] Additional methods for Vec
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (7 preceding siblings ...)
  2025-03-21 12:25 ` [PATCH v2 0/7] Additional methods for Vec Danilo Krummrich
@ 2025-03-21 12:28 ` Alice Ryhl
  2025-03-21 15:47 ` Tamir Duberstein
  9 siblings, 0 replies; 13+ messages in thread
From: Alice Ryhl @ 2025-03-21 12:28 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Benno Lossin,
	Tamir Duberstein

On Fri, Mar 21, 2025 at 12:09:55PM +0000, Alice Ryhl wrote:
> This adds various Vec methods. Some of them are needed by Rust Binder,
> and others are needed in other places. Each commit explains where it is
> needed.
> 
> I'm not sure what we concluded on the set_len / dec_len changes, so I
> don't depend on that series for now.
> 
> This series is based on top of Vec::truncate from
> https://lore.kernel.org/rust-for-linux/20250316111644.154602-1-andrewjballance@gmail.com/
> 
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>

Oops, this doesn't compile. Looks like I've already gone on vacation
mentally. Sorry guys!

Alice

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/7] Additional methods for Vec
  2025-03-21 12:25 ` [PATCH v2 0/7] Additional methods for Vec Danilo Krummrich
@ 2025-03-21 13:10   ` Benno Lossin
  2025-03-21 22:10     ` Danilo Krummrich
  0 siblings, 1 reply; 13+ messages in thread
From: Benno Lossin @ 2025-03-21 13:10 UTC (permalink / raw)
  To: Danilo Krummrich, Alice Ryhl
  Cc: Matthew Maurer, rust-for-linux, linux-kernel, Tamir Duberstein

On Fri Mar 21, 2025 at 1:25 PM CET, Danilo Krummrich wrote:
> On Fri, Mar 21, 2025 at 12:09:55PM +0000, Alice Ryhl wrote:
>> This adds various Vec methods. Some of them are needed by Rust Binder,
>> and others are needed in other places. Each commit explains where it is
>> needed.
>> 
>> I'm not sure what we concluded on the set_len / dec_len changes, so I
>> don't depend on that series for now.
>
> So far I see no reason to assume otherwise, so it probably makes sense to
> rebase. Unless Tamir is fine to rebase his changes onto this series.

I haven't yet taken a look at the reworked version of dec_len, so I'd
wait until we have finished discussion on that.

---
Cheers,
Benno


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/7] Additional methods for Vec
  2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
                   ` (8 preceding siblings ...)
  2025-03-21 12:28 ` Alice Ryhl
@ 2025-03-21 15:47 ` Tamir Duberstein
  9 siblings, 0 replies; 13+ messages in thread
From: Tamir Duberstein @ 2025-03-21 15:47 UTC (permalink / raw)
  To: Alice Ryhl
  Cc: Danilo Krummrich, Matthew Maurer, rust-for-linux, linux-kernel,
	Benno Lossin

On Fri, Mar 21, 2025 at 8:10 AM Alice Ryhl <aliceryhl@google.com> wrote:
>
> This adds various Vec methods. Some of them are needed by Rust Binder,
> and others are needed in other places. Each commit explains where it is
> needed.
>
> I'm not sure what we concluded on the set_len / dec_len changes, so I
> don't depend on that series for now.
>
> This series is based on top of Vec::truncate from
> https://lore.kernel.org/rust-for-linux/20250316111644.154602-1-andrewjballance@gmail.com/
>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> ---
> Changes in v2:
> - Add two more methods that I needed.
> - Introduce some uses of set_len.
> - Add example to retain.
> - Simplify pop.
> - Adjust 11 to 10 in push_within_capacity example.
> - Link to v1: https://lore.kernel.org/r/20250320-vec-methods-v1-0-7dff5cf25fe8@google.com
>
> ---
> Alice Ryhl (7):
>       rust: alloc: add Vec::clear
>       rust: alloc: add Vec::pop
>       rust: alloc: add Vec::push_within_capacity
>       rust: alloc: add Vec::drain_all
>       rust: alloc: add Vec::retain
>       rust: alloc: add Vec::remove
>       rust: alloc: add Vec::insert_within_capacity
>
>  rust/kernel/alloc/kvec.rs | 202 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 202 insertions(+)
> ---
> base-commit: a337a03281efc4553191b432d757d4c04884bf4c
> change-id: 20250320-vec-methods-adfa41e55311

I think this doesn't specify the dependencies properly. The
base-commit looks to be
https://lore.kernel.org/all/20250316111644.154602-3-andrewjballance@gmail.com/
locally applied. This prevents `b4 shazam` from working with this
series.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/7] Additional methods for Vec
  2025-03-21 13:10   ` Benno Lossin
@ 2025-03-21 22:10     ` Danilo Krummrich
  0 siblings, 0 replies; 13+ messages in thread
From: Danilo Krummrich @ 2025-03-21 22:10 UTC (permalink / raw)
  To: Benno Lossin
  Cc: Alice Ryhl, Matthew Maurer, rust-for-linux, linux-kernel,
	Tamir Duberstein

On Fri, Mar 21, 2025 at 01:10:43PM +0000, Benno Lossin wrote:
> On Fri Mar 21, 2025 at 1:25 PM CET, Danilo Krummrich wrote:
> > On Fri, Mar 21, 2025 at 12:09:55PM +0000, Alice Ryhl wrote:
> >> This adds various Vec methods. Some of them are needed by Rust Binder,
> >> and others are needed in other places. Each commit explains where it is
> >> needed.
> >> 
> >> I'm not sure what we concluded on the set_len / dec_len changes, so I
> >> don't depend on that series for now.
> >
> > So far I see no reason to assume otherwise, so it probably makes sense to
> > rebase. Unless Tamir is fine to rebase his changes onto this series.
> 
> I haven't yet taken a look at the reworked version of dec_len, so I'd
> wait until we have finished discussion on that.

What I mean is, everything looks like I'll pick them up eventually, so it makes
sense to base a subsequent version of this series onto Tramir's (even if the
current one of dec_len() is not the final one).

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2025-03-21 22:10 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-21 12:09 [PATCH v2 0/7] Additional methods for Vec Alice Ryhl
2025-03-21 12:09 ` [PATCH v2 1/7] rust: alloc: add Vec::clear Alice Ryhl
2025-03-21 12:09 ` [PATCH v2 2/7] rust: alloc: add Vec::pop Alice Ryhl
2025-03-21 12:09 ` [PATCH v2 3/7] rust: alloc: add Vec::push_within_capacity Alice Ryhl
2025-03-21 12:09 ` [PATCH v2 4/7] rust: alloc: add Vec::drain_all Alice Ryhl
2025-03-21 12:10 ` [PATCH v2 5/7] rust: alloc: add Vec::retain Alice Ryhl
2025-03-21 12:10 ` [PATCH v2 6/7] rust: alloc: add Vec::remove Alice Ryhl
2025-03-21 12:10 ` [PATCH v2 7/7] rust: alloc: add Vec::insert_within_capacity Alice Ryhl
2025-03-21 12:25 ` [PATCH v2 0/7] Additional methods for Vec Danilo Krummrich
2025-03-21 13:10   ` Benno Lossin
2025-03-21 22:10     ` Danilo Krummrich
2025-03-21 12:28 ` Alice Ryhl
2025-03-21 15:47 ` Tamir Duberstein

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).