Skip to content

Commit 6716184

Browse files
author
Danilo Krummrich
committed
rust: alloc: kbox: implement AsPageIter for VBox
Implement AsPageIter for VBox; this allows to iterate and borrow the backing pages of a VBox. This, for instance, is useful in combination with VBox backing a scatterlist. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://lore.kernel.org/r/20250820145434.94745-6-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
1 parent 866ec3b commit 6716184

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

rust/kernel/alloc/kbox.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Implementation of [`Box`].
44
55
#[allow(unused_imports)] // Used in doc comments.
6-
use super::allocator::{KVmalloc, Kmalloc, Vmalloc};
6+
use super::allocator::{KVmalloc, Kmalloc, Vmalloc, VmallocPageIter};
77
use super::{AllocError, Allocator, Flags};
88
use core::alloc::Layout;
99
use core::borrow::{Borrow, BorrowMut};
@@ -18,6 +18,7 @@ use core::result::Result;
1818

1919
use crate::ffi::c_void;
2020
use crate::init::InPlaceInit;
21+
use crate::page::AsPageIter;
2122
use crate::types::ForeignOwnable;
2223
use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption};
2324

@@ -598,3 +599,40 @@ where
598599
unsafe { A::free(self.0.cast(), layout) };
599600
}
600601
}
602+
603+
/// # Examples
604+
///
605+
/// ```
606+
/// # use kernel::prelude::*;
607+
/// use kernel::alloc::allocator::VmallocPageIter;
608+
/// use kernel::page::{AsPageIter, PAGE_SIZE};
609+
///
610+
/// let mut vbox = VBox::new((), GFP_KERNEL)?;
611+
///
612+
/// assert!(vbox.page_iter().next().is_none());
613+
///
614+
/// let mut vbox = VBox::<[u8; PAGE_SIZE]>::new_uninit(GFP_KERNEL)?;
615+
///
616+
/// let page = vbox.page_iter().next().expect("At least one page should be available.\n");
617+
///
618+
/// // SAFETY: There is no concurrent read or write to the same page.
619+
/// unsafe { page.fill_zero_raw(0, PAGE_SIZE)? };
620+
/// # Ok::<(), Error>(())
621+
/// ```
622+
impl<T> AsPageIter for VBox<T> {
623+
type Iter<'a>
624+
= VmallocPageIter<'a>
625+
where
626+
T: 'a;
627+
628+
fn page_iter(&mut self) -> Self::Iter<'_> {
629+
let ptr = self.0.cast();
630+
let size = core::mem::size_of::<T>();
631+
632+
// SAFETY:
633+
// - `ptr` is a valid pointer to the beginning of a `Vmalloc` allocation.
634+
// - `ptr` is guaranteed to be valid for the lifetime of `'a`.
635+
// - `size` is the size of the `Vmalloc` allocation `ptr` points to.
636+
unsafe { VmallocPageIter::new(ptr, size) }
637+
}
638+
}

0 commit comments

Comments
 (0)