[PATCH 0/3] rust: dma: add the single-buffer streaming DMA API

Maurice Hieronymus <[email protected]>
Newsgroups dev.linux.lists.nova-gpu,dev.linux.lists.driver-core,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
The Rust DMA abstraction covers `dma_alloc_coherent()` only. The streaming
half (`dma_map_single()`) is missing.

A streaming mapping is a temporary lease on memory the caller already owns:
between map and unmap the buffer belongs to the device, and the CPU may only
touch it in between a `dma_sync_single_for_cpu()` /
`dma_sync_single_for_device()` pair. In C that protocol is left to the driver
author, and getting it wrong is silent data corruption on non-coherent
platforms. It is a borrow handover, so it can be expressed in the type
system:

    let mut dma = Streaming::new(dev, buf, DataDirection::Bidirectional)?;

    *dma.for_cpu() = 42;

    let dma = dma.submit();

    // Program `dma.dma_handle()` into the device and wait for the transfer.

    // SAFETY: the transfer has been waited for.
    let mut dma = unsafe { dma.complete() };

    assert_eq!(*dma.for_cpu(), 42);

`submit()` consumes the `Streaming` and returns a `StreamingInFlight`, the
only source of the `DmaAddress`. It owns the buffer, so the contents are
unreachable while a transfer may be in flight, no matter where the driver
stores the address. That is what makes `for_cpu()` safe. Whether the device
has finished cannot be checked by any abstraction, so `complete()` is the
single `unsafe` operation. Dropping a `StreamingInFlight` without
`complete()` leaks the mapping and the storage, with a warning: safe code
cannot prove the device is done, so it is not allowed to unmap or free
memory the device may still be using.

Patch 1 adds `ContiguousBuffer`, describing storage `dma_map_single()`
accepts: a single physically contiguous region in the kernel's linear
mapping. Patch 2 adds the mapping itself. Patch 3 converts nova-core's
`GspFwWprMeta`, a streaming workload written against the coherent API.

One thing to note
=================

`Streaming` borrows a `&'a Device<Bound>` where `Coherent` and
`SGTable<Owned<P>>` both hold an `ARef<Device>`. The DMA API may only be
called while a driver is bound, and `Drop` unmaps, so a refcount does not
express what the mapping needs [1]. The two existing types predate the
`'bound` driver-core infrastructure; converting them is not part of this
series.

Testing
=======

Build-tested on x86_64 with `CLIPPY=1` and `rustfmtcheck`; the kernel crate
doctests, including the new `Streaming` ones, pass under virtme-ng.

Patch 3 is compile-tested only, I have no NVIDIA hardware; it touches the
GSP boot path on all supported chipsets, so a Tested-by would be very
welcome. However, I've tested it on my Rust EDU Driver locally [2] while
using swiotlb=force to emulate bounce buffers on x86.

[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/rust-for-linux/[email protected]/

Signed-off-by: Maurice Hieronymus <[email protected]>
---
Maurice Hieronymus (3):
      rust: dma: add ContiguousBuffer trait for streaming DMA storage
      rust: dma: add abstraction for the single-buffer streaming DMA API
      gpu: nova-core: gsp: map the WPR meta for streaming DMA

 drivers/gpu/nova-core/firmware/booter.rs |  11 +-
 drivers/gpu/nova-core/gsp/boot.rs        |  20 +-
 drivers/gpu/nova-core/gsp/hal.rs         |   4 +-
 drivers/gpu/nova-core/gsp/hal/gh100.rs   |   4 +-
 drivers/gpu/nova-core/gsp/hal/tu102.rs   |   4 +-
 rust/helpers/dma.c                       |  35 +++
 rust/kernel/dma.rs                       | 449 +++++++++++++++++++++++++++++++
 7 files changed, 515 insertions(+), 12 deletions(-)
---
base-commit: dc01dfb37b34beeefcfe1c3055364d41a4070c7e
change-id: 20260719-dma-streaming-9c505a8760cb

Best regards,
-- 
Maurice Hieronymus <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.