From: Peder Bergan via B4 Relay <devnull+peder.bergan.gmail.com@kernel.org>
To: dakr@kernel.org, aliceryhl@google.com
Cc: ljs@kernel.org, vbabka@kernel.org, liam@infradead.org,
urezki@gmail.com, ojeda@kernel.org, boqun@kernel.org,
gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org,
a.hindborg@kernel.org, tmgross@umich.edu,
daniel.almeida@collabora.com, tamird@kernel.org,
acourbot@nvidia.com, work@onurozkan.dev,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
Miguel Ojeda <ojeda@kernel.org>,
Peder Bergan <peder.bergan@gmail.com>
Subject: [PATCH v3] rust: alloc: test drop behavior of Vec::drain_all
Date: Tue, 03 Nov 2026 12:50:54 +0100 [thread overview]
Message-ID: <20261103-test-drain-all-drop-v3-1-5f936d67b099@gmail.com> (raw)
From: Peder Bergan <peder.bergan@gmail.com>
The drain_all example consumes the entire iterator and uses integers, so
it cannot detect missing drops of unconsumed values or premature drops
of values yielded to the caller.
Add KUnit tests with per-element drop counters for partially consumed,
unconsumed and exhausted drains, plus an empty-vector case. Keep a
yielded value alive after both the drain and vector are dropped to check
that its ownership stays with the caller. Also check that draining
empties the vector without changing its capacity.
Signed-off-by: Peder Bergan <peder.bergan@gmail.com>
---
v3:
- Remove the repeated commit summary from the submission notes.
- Keep the base in git format-patch's machine-readable base-commit footer.
- Restore the original comment instead of changing it for mail transport.
- Send with b4 through the kernel.org web endpoint.
v2:
- Split a long test comment to avoid mail transport line wrapping.
Based on alloc-next. The original v1 test source is restored exactly.
Previous revision:
https://lore.kernel.org/rust-for-linux/CAKHwh-E_A7Bp1oP5PYkgE62hh0cJMQRuxOM6yXGF7OB1QR0BhQ@mail.gmail.com/
Validation on x86_64 under QEMU:
- The original rust_kvec suite passed before the change.
- All nine tests passed with the change, including a CLIPPY=1 build.
- Making DrainAll::drop temporarily empty caused exactly the partial and
unconsumed tests to fail. Restoring it returned the suite to passing.
The tests used Rust 1.99.1, LLVM 23.1.4, bindgen 0.73.2 and QEMU 11.1.3.
The minimal configuration has an existing unused-function warning in
io/resource.rs, also seen before this change.
OpenAI Codex assisted with coding and testing this issue.
The requested work was to test Vec::drain_all ownership and destruction,
validate the tests under QEMU, and prove that they detect skipped
destruction.
---
rust/kernel/alloc/kvec.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index c7546b9da..fe113c7ff 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -1540,6 +1540,94 @@ fn drop(&mut self) {
mod tests {
use super::*;
use crate::prelude::*;
+ use core::cell::Cell;
+
+ struct DropSpy<'a>(&'a Cell<usize>);
+
+ impl Drop for DropSpy<'_> {
+ fn drop(&mut self) {
+ self.0.set(self.0.get() + 1);
+ }
+ }
+
+ #[test]
+ fn test_kvec_drain_all_partial() -> Result {
+ let drops = [const { Cell::new(0) }; 3];
+ let mut v = KVec::new();
+ for counter in &drops {
+ v.push(DropSpy(counter), GFP_KERNEL)?;
+ }
+ let capacity = v.capacity();
+
+ let mut drain = v.drain_all();
+ let first = drain.next().ok_or(EINVAL)?;
+ drop(drain);
+
+ // The caller owns the yielded value, while the drain drops the remaining values.
+ assert_eq!(drops.each_ref().map(Cell::get), [0, 1, 1]);
+ assert!(v.is_empty());
+ assert_eq!(v.capacity(), capacity);
+
+ drop(v);
+ assert_eq!(drops.each_ref().map(Cell::get), [0, 1, 1]);
+
+ drop(first);
+ assert_eq!(drops.each_ref().map(Cell::get), [1, 1, 1]);
+ Ok(())
+ }
+
+ #[test]
+ fn test_kvec_drain_all_unconsumed() -> Result {
+ let drops = [const { Cell::new(0) }; 3];
+ let mut v = KVec::new();
+ for counter in &drops {
+ v.push(DropSpy(counter), GFP_KERNEL)?;
+ }
+ let capacity = v.capacity();
+
+ drop(v.drain_all());
+ assert_eq!(drops.each_ref().map(Cell::get), [1, 1, 1]);
+ assert!(v.is_empty());
+ assert_eq!(v.capacity(), capacity);
+
+ drop(v);
+ assert_eq!(drops.each_ref().map(Cell::get), [1, 1, 1]);
+ Ok(())
+ }
+
+ #[test]
+ fn test_kvec_drain_all_consumed() -> Result {
+ let drops = [const { Cell::new(0) }; 3];
+ let mut v = KVec::new();
+ for counter in &drops {
+ v.push(DropSpy(counter), GFP_KERNEL)?;
+ }
+ let capacity = v.capacity();
+
+ let mut drain = v.drain_all();
+ for value in drain.by_ref() {
+ drop(value);
+ }
+ assert_eq!(drops.each_ref().map(Cell::get), [1, 1, 1]);
+ drop(drain);
+ assert!(v.is_empty());
+ assert_eq!(v.capacity(), capacity);
+
+ drop(v);
+ assert_eq!(drops.each_ref().map(Cell::get), [1, 1, 1]);
+ Ok(())
+ }
+
+ #[test]
+ fn test_kvec_drain_all_empty() {
+ let mut v = KVec::<DropSpy<'_>>::new();
+ let capacity = v.capacity();
+ let mut drain = v.drain_all();
+ assert!(drain.next().is_none());
+ drop(drain);
+ assert!(v.is_empty());
+ assert_eq!(v.capacity(), capacity);
+ }
#[test]
fn test_kvec_retain() {
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261103-test-drain-all-drop-e115b4b1a150
Best regards,
--
Peder Bergan <peder.bergan@gmail.com>
reply other threads:[~2026-11-03 11:50 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103-test-drain-all-drop-v3-1-5f936d67b099@gmail.com \
--to=devnull+peder.bergan.gmail.com@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=peder.bergan@gmail.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=urezki@gmail.com \
--cc=vbabka@kernel.org \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®