Re: [PATCH 2/2] rust: dma: add CoherentHandle for DMA allocations without kernel mapping

Danilo Krummrich
2026-03-25T17:18:13Z

On Wed Mar 25, 2026 at 2:09 PM CET, Gary Guo wrote:
> This only gives you fixed size, though. If you want the same type that supports
> both a fixed size and dynamic size, then a generic that is either array/slice is
> the way to go.

[...]

> You still can use `io_project!(handle, [start..end]?)` to do the bounds
> checking. But as you said, the benefit might be minimal.

I think we shouldn't overengineer this for now, and wait for actual use-cases
that require any of that.

The only thing we need right now in practice is an API that takes the size and
returns a handle to the buffer of this size exposing the DMA address that is
subsequently passed to the device without further modification.

So, if we want to re-use dma::Coherent<T>, we can just do this

pub struct CoherentHandle(Coherent<[u8]>);

impl CoherentHandle {
pub fn alloc_with_attrs(
dev: &device::Device<Bound>,
size: usize,
gfp_flags: kernel::alloc::Flags,
dma_attrs: Attrs,
) -> Result<Self> {
let dma_attrs = dma_attrs | Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING);
Coherent::<u8>::alloc_slice_with_attrs(dev, size, gfp_flags, dma_attrs).map(Self)
}

#[inline]
pub fn alloc(
dev: &device::Device<Bound>,
size: usize,
gfp_flags: kernel::alloc::Flags,
) -> Result<Self> {
Self::alloc_with_attrs(dev, size, gfp_flags, Attrs(0))
}

#[inline]
pub fn dma_handle(&self) -> DmaAddress {
self.0.dma_handle()
}

#[inline]
pub fn size(&self) -> usize {
self.0.size()
}
}

and add a guarantee that Coherent::alloc_with_attrs() and Coherent::drop() never
touch the cpu_ptr.