aboutsummaryrefslogtreecommitdiffstats
path: root/rust
diff options
authorDanilo Krummrich <dakr@kernel.org>2026-03-20 20:45:40 +0100
committerDanilo Krummrich <dakr@kernel.org>2026-03-23 22:36:00 +0100
commit40251bac0e00818b0b632d2d154e4f1f815849eb (patch)
tree690280aba08687b5bda630533f22fa10cad1550f /rust
parent80f4a7b5138d1c427ee5626e8a796aa6b2994a95 (diff)
downloadlinux-next-history-40251bac0e00818b0b632d2d154e4f1f815849eb.tar.gz
rust: dma: add Coherent:init() and Coherent::init_with_attrs()
Analogous to Coherent::zeroed() and Coherent::zeroed_with_attrs(), add Coherent:init() and Coherent::init_with_attrs() which both take an impl Init<T, E> argument initializing the DMA coherent memory. Compared to CoherentInit, Coherent::init() is a one-shot constructor that runs an Init closure and immediately exposes the DMA handle, whereas CoherentInit is a multi-stage initializer that provides safe &mut T access by withholding the DMA address until converted to Coherent. Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260320194626.36263-6-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'rust')
-rw-r--r--rust/kernel/dma.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index 5b41603cee2e6..be44ec99af5f7 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -715,6 +715,44 @@ impl<T: AsBytes + FromBytes> Coherent<T> {
Self::zeroed_with_attrs(dev, gfp_flags, Attrs(0))
}
+ /// Same as [`Coherent::zeroed_with_attrs`], but instead of a zero-initialization the memory is
+ /// initialized with `init`.
+ pub fn init_with_attrs<E>(
+ dev: &device::Device<Bound>,
+ gfp_flags: kernel::alloc::Flags,
+ dma_attrs: Attrs,
+ init: impl Init<T, E>,
+ ) -> Result<Self>
+ where
+ Error: From<E>,
+ {
+ let dmem = Self::alloc_with_attrs(dev, gfp_flags, dma_attrs)?;
+ let ptr = dmem.as_mut_ptr();
+
+ // SAFETY:
+ // - `ptr` is valid, properly aligned, and points to exclusively owned memory.
+ // - If `__init` fails, `self` is dropped, which safely frees the underlying `Coherent`'s
+ // DMA memory. `T: AsBytes + FromBytes` ensures there are no complex `Drop` requirements
+ // we are bypassing.
+ unsafe { init.__init(ptr)? };
+
+ Ok(dmem)
+ }
+
+ /// Same as [`Coherent::zeroed`], but instead of a zero-initialization the memory is initialized
+ /// with `init`.
+ #[inline]
+ pub fn init<E>(
+ dev: &device::Device<Bound>,
+ gfp_flags: kernel::alloc::Flags,
+ init: impl Init<T, E>,
+ ) -> Result<Self>
+ where
+ Error: From<E>,
+ {
+ Self::init_with_attrs(dev, gfp_flags, Attrs(0), init)
+ }
+
/// Allocates a region of `[T; len]` of coherent memory.
fn alloc_slice_with_attrs(
dev: &device::Device<Bound>,