Skip to content

Commit 779db37

Browse files
author
Danilo Krummrich
committed
rust: alloc: kvec: implement AsPageIter for VVec
Implement AsPageIter for VVec; this allows to iterate and borrow the backing pages of a VVec. This, for instance, is useful in combination with VVec backing a scatterlist. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> Link: https://lore.kernel.org/r/20250820145434.94745-8-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
1 parent 9acb4e6 commit 779db37

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

rust/kernel/alloc/kvec.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
//! Implementation of [`Vec`].
44
55
use super::{
6-
allocator::{KVmalloc, Kmalloc, Vmalloc},
6+
allocator::{KVmalloc, Kmalloc, Vmalloc, VmallocPageIter},
77
layout::ArrayLayout,
88
AllocError, Allocator, Box, Flags,
99
};
10+
use crate::page::AsPageIter;
1011
use core::{
1112
borrow::{Borrow, BorrowMut},
1213
fmt,
@@ -1017,6 +1018,43 @@ where
10171018
}
10181019
}
10191020

1021+
/// # Examples
1022+
///
1023+
/// ```
1024+
/// # use kernel::prelude::*;
1025+
/// use kernel::alloc::allocator::VmallocPageIter;
1026+
/// use kernel::page::{AsPageIter, PAGE_SIZE};
1027+
///
1028+
/// let mut vec = VVec::<u8>::new();
1029+
///
1030+
/// assert!(vec.page_iter().next().is_none());
1031+
///
1032+
/// vec.reserve(PAGE_SIZE, GFP_KERNEL)?;
1033+
///
1034+
/// let page = vec.page_iter().next().expect("At least one page should be available.\n");
1035+
///
1036+
/// // SAFETY: There is no concurrent read or write to the same page.
1037+
/// unsafe { page.fill_zero_raw(0, PAGE_SIZE)? };
1038+
/// # Ok::<(), Error>(())
1039+
/// ```
1040+
impl<T> AsPageIter for VVec<T> {
1041+
type Iter<'a>
1042+
= VmallocPageIter<'a>
1043+
where
1044+
T: 'a;
1045+
1046+
fn page_iter(&mut self) -> Self::Iter<'_> {
1047+
let ptr = self.ptr.cast();
1048+
let size = self.layout.size();
1049+
1050+
// SAFETY:
1051+
// - `ptr` is a valid pointer to the beginning of a `Vmalloc` allocation.
1052+
// - `ptr` is guaranteed to be valid for the lifetime of `'a`.
1053+
// - `size` is the size of the `Vmalloc` allocation `ptr` points to.
1054+
unsafe { VmallocPageIter::new(ptr, size) }
1055+
}
1056+
}
1057+
10201058
/// An [`Iterator`] implementation for [`Vec`] that moves elements out of a vector.
10211059
///
10221060
/// This structure is created by the [`Vec::into_iter`] method on [`Vec`] (provided by the

0 commit comments

Comments
 (0)