All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matteo Kloiber <kernel@matt3o12.de>
To: dakr@kernel.org, acourbot@nvidia.com
Cc: aliceryhl@google.com, ojeda@kernel.org, airlied@gmail.com,
	simona@ffwll.ch, abdiel.janulgue@gmail.com,
	daniel.almeida@collabora.com, robin.murphy@arm.com,
	a.hindborg@kernel.org, nova-gpu@lists.linux.dev,
	dri-devel@lists.freedesktop.org, driver-core@lists.linux.dev,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	Matteo Kloiber <kernel@matt3o12.de>
Subject: [PATCH v2 0/2] rust: honor the maximum DMA segment size
Date: Sun, 13 Sep 2026 23:08:26 +0200	[thread overview]
Message-ID: <20260913210828.125655-1-kernel@matt3o12.de> (raw)

Booting nova-core against a real GSP with CONFIG_DMA_API_DEBUG=y warns
when the ~60 MiB firmware image is mapped as a scatter-gather table:

  DMA-API: nova-core 0000:00:03.0: mapping sg segment longer than
  device claims to support [len=62914560] [max=65536]

There are two separate issues behind it.

Patch 1 has nova-core declare the segment size it actually supports. It
re-decomposes every segment into 4 KiB GSP page-table entries, so it has
no upper bound on segment length.

Furthermore, I also checked what other GPUs do, and most do the same:
set the max segment size u32::MAX. So this should be the correct
behavior for nova as well.

Patch 2 has SGTable::new() honor dma_get_max_seg_size() in addition to
dma_max_mapping_size(). The abstraction is generic, so a driver with a
real hardware segment limit would otherwise silently be handed segments
it cannot express in a single descriptor.

Tested on an RTX 5080 (GB203) passed through to a QEMU guest via VFIO
with CONFIG_DMA_API_DEBUG=y: the warning is gone, and GSP boot and RPC
still work.

Discussed on Zulip:
https://rust-for-linux.zulipchat.com/#narrow/channel/509436-Nova/topic/nova.20core.3A.20DMA-API.3A.20nova-core.200000.3A00.3A03.2E0.3A.20mapping.20sg.20segme/with/618319830

Changes in v2, all from Alexandre Courbot's review:
- Patch 1: use the `Assisted-by: LLM` form documented in
  Documentation/process/coding-assistants.rst, and place the tag before
  the Signed-off-by.
- Patch 1: trim the comment above dma_set_max_seg_size(), and state the
  SAFETY invariant in full instead of referring to the comment above it.
- Patch 2: rename max_mapping -> max_mapping_size.
- Patch 2: drop the paragraph claiming nova-core is the only user; the
  Rust DMA sample is one too, and neither is broken by this patch
  landing without patch 1.
- Patch 2: picked up Alexandre's Reviewed-by.

No functional change since v1.

v1: https://lore.kernel.org/r/20260831233215.287881-1-kernel@matt3o12.de

Matteo Kloiber (2):
  gpu: nova-core: declare unlimited DMA max segment size
  rust: scatterlist: honor the device's maximum segment size

 drivers/gpu/nova-core/gpu.rs |  7 +++++++
 rust/helpers/dma.c           |  5 +++++
 rust/kernel/scatterlist.rs   | 12 ++++++++++--
 3 files changed, 22 insertions(+), 2 deletions(-)

Range-diff against v1:
1:  bd1a05a64e05 ! 1:  8a8637f02fa1 gpu: nova-core: declare unlimited DMA max segment size
    @@ Commit message
     
         CONFIG_DMA_API_DEBUG=y is required to see this warning.
     
    +    Assisted-by: LLM
         Signed-off-by: Matteo Kloiber <kernel@matt3o12.de>
    -    Assisted-by: Claude:claude-opus-4-8
     
      ## drivers/gpu/nova-core/gpu.rs ##
     @@ drivers/gpu/nova-core/gpu.rs: pub(crate) fn new<'a>(
                      // still constructing it, so no concurrent DMA allocations can exist.
                      unsafe { pdev.dma_set_mask_and_coherent(dma_mask)? };
      
    -+                // Nova re-decomposes SG segments into 4 KiB page-table entries, so it
    -+                // has no upper bound on segment length; declare that to the DMA layer.
    ++                // Nova walks SG segments to build page tables, so their length is
    ++                // irrelevant to the device.
     +                //
    -+                // SAFETY: same invariant as above -- still constructing, no concurrent
    -+                // DMA mapping can exist.
    ++                // SAFETY: `Gpu` owns all DMA allocations for this device, and we are
    ++                // still constructing it, so no concurrent DMA allocations can exist.
     +                unsafe { pdev.dma_set_max_seg_size(u32::MAX) };
     +
                      hal.wait_gfw_boot_completion(bar)
2:  69ea96f9290b ! 2:  4f8a19794529 rust: scatterlist: honor the device's maximum segment size
    @@ Commit message
         potentially causing problems for future drivers that use this
         abstraction.
     
    -    nova-core declares an unlimited segment size, so this does not change
    -    its behavior.
    -
         Fixes: 05aa6fb1c21d ("rust: scatterlist: Add abstraction for sg_table")
         Signed-off-by: Matteo Kloiber <kernel@matt3o12.de>
    +    Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
     
      ## rust/helpers/dma.c ##
     @@ rust/helpers/dma.c: __rust_helper void rust_helper_dma_set_max_seg_size(struct device *dev,
    @@ rust/kernel/scatterlist.rs: fn new(
              //
              // SAFETY: `dev.as_raw()` is a valid pointer to a `struct device`.
     -        let max_segment = match unsafe { bindings::dma_max_mapping_size(dev.as_raw()) } {
    -+        let max_mapping = match unsafe { bindings::dma_max_mapping_size(dev.as_raw()) } {
    ++        let max_mapping_size = match unsafe { bindings::dma_max_mapping_size(dev.as_raw()) } {
                  0 => u32::MAX,
     -            max_segment => u32::try_from(max_segment).unwrap_or(u32::MAX),
    -+            max_mapping => u32::try_from(max_mapping).unwrap_or(u32::MAX),
    ++            max_mapping_size => u32::try_from(max_mapping_size).unwrap_or(u32::MAX),
              };
      
     +        // SAFETY: `dev.as_raw()` is a valid pointer to a `struct device`.
     +        let max_seg_size = unsafe { bindings::dma_get_max_seg_size(dev.as_raw()) };
     +
    -+        let max_segment = max_mapping.min(max_seg_size);
    ++        let max_segment = max_mapping_size.min(max_seg_size);
     +
              Ok(try_pin_init!(&this in Self {
                  // SAFETY:

base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
-- 
2.51.2

             reply	other threads:[~2026-09-13 21:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-13 21:08 Matteo Kloiber [this message]
2026-09-13 21:08 ` [PATCH v2 1/2] gpu: nova-core: declare unlimited DMA max segment size Matteo Kloiber
2026-09-21  3:44   ` Alexandre Courbot
2026-09-13 21:08 ` [PATCH v2 2/2] rust: scatterlist: honor the device's maximum " Matteo Kloiber
2026-09-24 15:51 ` (subset) [PATCH v2 0/2] rust: honor the maximum DMA " Danilo Krummrich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260913210828.125655-1-kernel@matt3o12.de \
    --to=kernel@matt3o12.de \
    --cc=a.hindborg@kernel.org \
    --cc=abdiel.janulgue@gmail.com \
    --cc=acourbot@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=driver-core@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nova-gpu@lists.linux.dev \
    --cc=ojeda@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=simona@ffwll.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.