* [PATCH 0/2] rust: honor the maximum DMA segment size
@ 2026-08-31 23:32 Matteo Kloiber
2026-08-31 23:32 ` [PATCH 1/2] gpu: nova-core: declare unlimited DMA max " Matteo Kloiber
2026-08-31 23:32 ` [PATCH 2/2] rust: scatterlist: honor the device's maximum " Matteo Kloiber
0 siblings, 2 replies; 13+ messages in thread
From: Matteo Kloiber @ 2026-08-31 23:32 UTC (permalink / raw)
To: dakr, acourbot
Cc: aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel, Matteo Kloiber
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
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(-)
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.51.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/2] gpu: nova-core: declare unlimited DMA max segment size
2026-08-31 23:32 [PATCH 0/2] rust: honor the maximum DMA segment size Matteo Kloiber
@ 2026-08-31 23:32 ` Matteo Kloiber
2026-09-07 2:10 ` Alexandre Courbot
2026-08-31 23:32 ` [PATCH 2/2] rust: scatterlist: honor the device's maximum " Matteo Kloiber
1 sibling, 1 reply; 13+ messages in thread
From: Matteo Kloiber @ 2026-08-31 23:32 UTC (permalink / raw)
To: dakr, acourbot
Cc: aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel, Matteo Kloiber
The PCI default max_seg_size is 64 KiB. nova-core never raises it, so
mapping the GSP firmware image (~60 MiB) as a scatter-gather table
triggers a DMA-API debug warning when contiguous pages coalesce into
segments that exceed the default:
DMA-API: nova-core 0000:00:03.0: mapping sg segment longer than
device claims to support [len=62914560] [max=65536]
CONFIG_DMA_API_DEBUG=y is required to see this warning.
Signed-off-by: Matteo Kloiber <kernel@matt3o12.de>
Assisted-by: Claude:claude-opus-4-8
---
drivers/gpu/nova-core/gpu.rs | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index fd1414004dd0..233ef2dc9688 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -343,6 +343,13 @@ 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.
+ //
+ // SAFETY: same invariant as above -- still constructing, no concurrent
+ // DMA mapping can exist.
+ unsafe { pdev.dma_set_max_seg_size(u32::MAX) };
+
hal.wait_gfw_boot_completion(bar)
.inspect_err(|_| dev_err!(dev, "GFW boot did not complete\n"))?;
},
--
2.51.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-08-31 23:32 [PATCH 0/2] rust: honor the maximum DMA segment size Matteo Kloiber
2026-08-31 23:32 ` [PATCH 1/2] gpu: nova-core: declare unlimited DMA max " Matteo Kloiber
@ 2026-08-31 23:32 ` Matteo Kloiber
2026-09-07 2:43 ` Alexandre Courbot
1 sibling, 1 reply; 13+ messages in thread
From: Matteo Kloiber @ 2026-08-31 23:32 UTC (permalink / raw)
To: dakr, acourbot
Cc: aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel, Matteo Kloiber
SGTable::new() caps segment length at dma_max_mapping_size() only, which
limits the DMA mapping path (e.g. swiotlb), not the device itself. The
per-device limit from dma_set_max_seg_size() is ignored, so contiguous
page segments can be longer than the declared max segment size,
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>
---
rust/helpers/dma.c | 5 +++++
rust/kernel/scatterlist.rs | 12 ++++++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/rust/helpers/dma.c b/rust/helpers/dma.c
index 9fbeb507b08c..ff8f24dae9df 100644
--- a/rust/helpers/dma.c
+++ b/rust/helpers/dma.c
@@ -49,3 +49,8 @@ __rust_helper void rust_helper_dma_set_max_seg_size(struct device *dev,
{
dma_set_max_seg_size(dev, size);
}
+
+__rust_helper unsigned int rust_helper_dma_get_max_seg_size(struct device *dev)
+{
+ return dma_get_max_seg_size(dev);
+}
diff --git a/rust/kernel/scatterlist.rs b/rust/kernel/scatterlist.rs
index b83c468b5c63..d677dcbe7aac 100644
--- a/rust/kernel/scatterlist.rs
+++ b/rust/kernel/scatterlist.rs
@@ -350,15 +350,23 @@ fn new(
page_vec.push(page.as_ptr(), flags)?;
}
+ // Cap segments at both the DMA mapping-path limit and the device's declared
+ // max segment size.
+ //
// `dma_max_mapping_size` returns `size_t`, but `sg_alloc_table_from_pages_segment()` takes
// an `unsigned int`.
//
// 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()) } {
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),
};
+ // 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);
+
Ok(try_pin_init!(&this in Self {
// SAFETY:
// - `page_vec` is a `KVec` of valid `struct page *` obtained from `pages`.
--
2.51.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] gpu: nova-core: declare unlimited DMA max segment size
2026-08-31 23:32 ` [PATCH 1/2] gpu: nova-core: declare unlimited DMA max " Matteo Kloiber
@ 2026-09-07 2:10 ` Alexandre Courbot
2026-09-13 21:07 ` Matteo Kloiber
0 siblings, 1 reply; 13+ messages in thread
From: Alexandre Courbot @ 2026-09-07 2:10 UTC (permalink / raw)
To: Matteo Kloiber
Cc: dakr, aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On Tue Sep 1, 2026 at 8:32 AM JST, Matteo Kloiber wrote:
> The PCI default max_seg_size is 64 KiB. nova-core never raises it, so
> mapping the GSP firmware image (~60 MiB) as a scatter-gather table
> triggers a DMA-API debug warning when contiguous pages coalesce into
> segments that exceed the default:
>
> DMA-API: nova-core 0000:00:03.0: mapping sg segment longer than
> device claims to support [len=62914560] [max=65536]
>
> CONFIG_DMA_API_DEBUG=y is required to see this warning.
>
> Signed-off-by: Matteo Kloiber <kernel@matt3o12.de>
> Assisted-by: Claude:claude-opus-4-8
Note: new kernel policy [1] asks that the specific model is not named, so
this should just be `Assisted-by: LLM`.
(also should be placed before your `Signed-off-by`)
[1] https://docs.kernel.org/process/coding-assistants.html
> ---
> drivers/gpu/nova-core/gpu.rs | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
> index fd1414004dd0..233ef2dc9688 100644
> --- a/drivers/gpu/nova-core/gpu.rs
> +++ b/drivers/gpu/nova-core/gpu.rs
> @@ -343,6 +343,13 @@ 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.
> + //
> + // SAFETY: same invariant as above -- still constructing, no concurrent
> + // DMA mapping can exist.
> + unsafe { pdev.dma_set_max_seg_size(u32::MAX) };
Thanks, this patch looks correct and I would like to merge it early, but
one thing about the comment: it carries way more context than needed and
reads heavily, as is often the case when AI-generated. For instance,
"declare that to the DMA layer" is obvious from the method we are
calling. Make sure to give a human pass to such comments as they can
make the code tedious when they accumulate.
Conversely, `as above` is risky because the above in question might
change and we then lose the reference, so here it's actually better to
state the invariant in a self-contained way. Copy-pasting is ok. For
instance:
// Nova walks SG segments to build page tables, so their length is
// irrelevant to the device.
//
// SAFETY: `Gpu` owns all DMA allocations for this device, and we are
// still constructing it, so no concurrent DMA allocations can exist.
Since this seems to be your first patch, this is a good opportunity to
practice sending a v2. :)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-08-31 23:32 ` [PATCH 2/2] rust: scatterlist: honor the device's maximum " Matteo Kloiber
@ 2026-09-07 2:43 ` Alexandre Courbot
2026-09-13 21:08 ` Matteo Kloiber
0 siblings, 1 reply; 13+ messages in thread
From: Alexandre Courbot @ 2026-09-07 2:43 UTC (permalink / raw)
To: Matteo Kloiber
Cc: dakr, aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On Tue Sep 1, 2026 at 8:32 AM JST, Matteo Kloiber wrote:
> SGTable::new() caps segment length at dma_max_mapping_size() only, which
> limits the DMA mapping path (e.g. swiotlb), not the device itself. The
> per-device limit from dma_set_max_seg_size() is ignored, so contiguous
> page segments can be longer than the declared max segment size,
> potentially causing problems for future drivers that use this
> abstraction.
>
> nova-core declares an unlimited segment size, so this does not change
> its behavior.
I guess what this last paragraph wants to state is that no user is
affected by this patch? There is another subtle user though: the Rust
DMA sample.
In any case, this patch without patch 1 wouldn't break either of those
(only waste a bit more memory in SG entries with nova-core), so maybe we
can skip it.
>
> Fixes: 05aa6fb1c21d ("rust: scatterlist: Add abstraction for sg_table")
> Signed-off-by: Matteo Kloiber <kernel@matt3o12.de>
> ---
> rust/helpers/dma.c | 5 +++++
> rust/kernel/scatterlist.rs | 12 ++++++++++--
> 2 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/rust/helpers/dma.c b/rust/helpers/dma.c
> index 9fbeb507b08c..ff8f24dae9df 100644
> --- a/rust/helpers/dma.c
> +++ b/rust/helpers/dma.c
> @@ -49,3 +49,8 @@ __rust_helper void rust_helper_dma_set_max_seg_size(struct device *dev,
> {
> dma_set_max_seg_size(dev, size);
> }
> +
> +__rust_helper unsigned int rust_helper_dma_get_max_seg_size(struct device *dev)
> +{
> + return dma_get_max_seg_size(dev);
> +}
> diff --git a/rust/kernel/scatterlist.rs b/rust/kernel/scatterlist.rs
> index b83c468b5c63..d677dcbe7aac 100644
> --- a/rust/kernel/scatterlist.rs
> +++ b/rust/kernel/scatterlist.rs
> @@ -350,15 +350,23 @@ fn new(
> page_vec.push(page.as_ptr(), flags)?;
> }
>
> + // Cap segments at both the DMA mapping-path limit and the device's declared
> + // max segment size.
> + //
> // `dma_max_mapping_size` returns `size_t`, but `sg_alloc_table_from_pages_segment()` takes
> // an `unsigned int`.
> //
> // 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()) } {
> 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),
nit: if we rename this variable, let's name it `max_mapping_size` for
consistency.
> };
>
> + // 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);
This looks like the correct thing to do indeed.
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
(the following is a related thought, not a request for this patch)
It also means that without patch 1, nova-core would split the firmware
into hundreds of 64KB SG entries, which is not breaking but still
something we want to avoid. The correct fix is to make sure that
`dma_set_max_seg_size` is called by the driver, and while we are at it
we also want every driver to call `dma_set_mask_and_coherent`. Ideally
we would use the type system to make sure that both functions are called
before any DMA operation can take place (using a safe interface), but
I'm not quite sure yet how we can do this.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] gpu: nova-core: declare unlimited DMA max segment size
2026-09-07 2:10 ` Alexandre Courbot
@ 2026-09-13 21:07 ` Matteo Kloiber
0 siblings, 0 replies; 13+ messages in thread
From: Matteo Kloiber @ 2026-09-13 21:07 UTC (permalink / raw)
To: Alexandre Courbot
Cc: dakr, aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On Mon Sep 7, 2026 at 11:10 AM JST, Alexandre Courbot wrote:
> Note: new kernel policy [1] asks that the specific model is not named, so
> this should just be `Assisted-by: LLM`.
Got it, thanks! I was checking what other people did and noticed a lot of
mentions of Claude, etc., so I went with it. Changed for v2.
> Thanks, this patch looks correct and I would like to merge it early, but
> one thing about the comment: it carries way more context than needed and
> reads heavily, as is often the case when AI-generated. For instance,
> "declare that to the DMA layer" is obvious from the method we are
> calling. Make sure to give a human pass to such comments as they can
> make the code tedious when they accumulate.
Thanks! I agree. I was unsure about that and decided to leave a bit more
in for the review. I'll just use your comment verbatim.
> Since this seems to be your first patch, this is a good opportunity to
> practice sending a v2. :)
Yes, submitting patches to the mailing list was certainly a new experience.
Thank you for your help and time so far!
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-07 2:43 ` Alexandre Courbot
@ 2026-09-13 21:08 ` Matteo Kloiber
2026-09-14 0:45 ` Alexandre Courbot
0 siblings, 1 reply; 13+ messages in thread
From: Matteo Kloiber @ 2026-09-13 21:08 UTC (permalink / raw)
To: Alexandre Courbot
Cc: dakr, aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
> I guess what this last paragraph wants to state is that no user is
> affected by this patch? There is another subtle user though: the Rust
> DMA sample.
Yes, that's what I meant. I missed the sample, but it wouldn't make a
difference anyway. So I just removed the paragraph in v2.
> nit: if we rename this variable, let's name it `max_mapping_size` for
> consistency.
Agreed. Fixed. Let me know if everything is fixed in v2.
> It also means that without patch 1, nova-core would split the firmware
> into hundreds of 64KB SG entries, which is not breaking but still
> something we want to avoid. The correct fix is to make sure that
> `dma_set_max_seg_size` is called by the driver, and while we are at it
> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
> we would use the type system to make sure that both functions are called
> before any DMA operation can take place (using a safe interface), but
> I'm not quite sure yet how we can do this.
This sounds sensible indeed. Should I open a thread regarding that on Zulip?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-13 21:08 ` Matteo Kloiber
@ 2026-09-14 0:45 ` Alexandre Courbot
2026-09-14 9:58 ` Danilo Krummrich
0 siblings, 1 reply; 13+ messages in thread
From: Alexandre Courbot @ 2026-09-14 0:45 UTC (permalink / raw)
To: Matteo Kloiber
Cc: dakr, aliceryhl, ojeda, airlied, simona, abdiel.janulgue,
daniel.almeida, robin.murphy, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On Mon Sep 14, 2026 at 6:08 AM JST, Matteo Kloiber wrote:
> On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
>> It also means that without patch 1, nova-core would split the firmware
>> into hundreds of 64KB SG entries, which is not breaking but still
>> something we want to avoid. The correct fix is to make sure that
>> `dma_set_max_seg_size` is called by the driver, and while we are at it
>> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
>> we would use the type system to make sure that both functions are called
>> before any DMA operation can take place (using a safe interface), but
>> I'm not quite sure yet how we can do this.
>
> This sounds sensible indeed. Should I open a thread regarding that on Zulip?
Probably not necessary, the mailing-list has a larger audience and is
the right place for this. I expect people will jump in here with their
thoughts.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-14 0:45 ` Alexandre Courbot
@ 2026-09-14 9:58 ` Danilo Krummrich
2026-09-14 10:22 ` Gary Guo
0 siblings, 1 reply; 13+ messages in thread
From: Danilo Krummrich @ 2026-09-14 9:58 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Matteo Kloiber, aliceryhl, ojeda, airlied, simona,
abdiel.janulgue, daniel.almeida, robin.murphy, a.hindborg,
nova-gpu, dri-devel, driver-core, rust-for-linux, linux-kernel
On Mon Sep 14, 2026 at 2:45 AM CEST, Alexandre Courbot wrote:
> On Mon Sep 14, 2026 at 6:08 AM JST, Matteo Kloiber wrote:
>> On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
>>> It also means that without patch 1, nova-core would split the firmware
>>> into hundreds of 64KB SG entries, which is not breaking but still
>>> something we want to avoid. The correct fix is to make sure that
>>> `dma_set_max_seg_size` is called by the driver, and while we are at it
>>> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
>>> we would use the type system to make sure that both functions are called
>>> before any DMA operation can take place (using a safe interface), but
>>> I'm not quite sure yet how we can do this.
>>
>> This sounds sensible indeed. Should I open a thread regarding that on Zulip?
>
> Probably not necessary, the mailing-list has a larger audience and is
> the right place for this. I expect people will jump in here with their
> thoughts.
The problem with those is not that they must strictly be called before
allocating DMA memory, but they must not be called concurrently with other DMA
operations, such as allocating DMA memory, as it would technically be a data
race.
Now, we can't really have drivers define them statically (e.g. in the driver
trait) as there may be cases where it depends on the runtime state or properties
of the device queried at runtime. Sometimes it is also defined through OF
properties (which from a kernel perspective are runtime values too).
For the same reason it is also pretty hard to invent a type state pattern for
those setters that is not getting ridiculously complex without much value, which
is why we just kept them unsafe for the time being.
The best option to get rid of the unsafe would probably be to use atomics
instead. It would however be a rather big change, what makes it a bit of a hard
sell, given that the reason of this unsafe is more on the theoretical side of
things.
Theoretically, we could also optimize the situation for when it is statically
known, e.g. some dma::Config trait that can be implemented, such that the bus
can set the before calling probe(). But we'd really want this to work per device
ID table entry, as it may differ between supported devices. But that might not
be quite straight forward without associated_type_defaults. The simplest thing I
could think of is some callback, such as
fn dma_info(id_info: Option<&Self::IdInfo>) -> DmaInfo
which is called before probe(), but that's not great either. Maybe there is a
good solution for this, but I'd first want to exhaust getting the setters safe.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-14 9:58 ` Danilo Krummrich
@ 2026-09-14 10:22 ` Gary Guo
2026-09-14 12:17 ` Robin Murphy
0 siblings, 1 reply; 13+ messages in thread
From: Gary Guo @ 2026-09-14 10:22 UTC (permalink / raw)
To: Danilo Krummrich, Alexandre Courbot
Cc: Matteo Kloiber, aliceryhl, ojeda, airlied, simona,
abdiel.janulgue, daniel.almeida, robin.murphy, a.hindborg,
nova-gpu, dri-devel, driver-core, rust-for-linux, linux-kernel
On Mon Sep 14, 2026 at 10:58 AM BST, Danilo Krummrich wrote:
> On Mon Sep 14, 2026 at 2:45 AM CEST, Alexandre Courbot wrote:
>> On Mon Sep 14, 2026 at 6:08 AM JST, Matteo Kloiber wrote:
>>> On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
>>>> It also means that without patch 1, nova-core would split the firmware
>>>> into hundreds of 64KB SG entries, which is not breaking but still
>>>> something we want to avoid. The correct fix is to make sure that
>>>> `dma_set_max_seg_size` is called by the driver, and while we are at it
>>>> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
>>>> we would use the type system to make sure that both functions are called
>>>> before any DMA operation can take place (using a safe interface), but
>>>> I'm not quite sure yet how we can do this.
>>>
>>> This sounds sensible indeed. Should I open a thread regarding that on Zulip?
>>
>> Probably not necessary, the mailing-list has a larger audience and is
>> the right place for this. I expect people will jump in here with their
>> thoughts.
>
> The problem with those is not that they must strictly be called before
> allocating DMA memory, but they must not be called concurrently with other DMA
> operations, such as allocating DMA memory, as it would technically be a data
> race.
Do they really have to be called *before* allocating DMA memory, not do they
just need not be called *concurrent* to DMA memory allocation?
If it's the former, we can require these to require mutable reference instead,
so the probe takes `Pin<&'bound mut Device<Core<'_>>>` which still derefs to
`&'bound Device<Bound>`, but Rust will require the shared reference to not
co-exist with the mutable reference.
Best,
Gary
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-14 10:22 ` Gary Guo
@ 2026-09-14 12:17 ` Robin Murphy
2026-09-14 13:17 ` Gary Guo
0 siblings, 1 reply; 13+ messages in thread
From: Robin Murphy @ 2026-09-14 12:17 UTC (permalink / raw)
To: Gary Guo, Danilo Krummrich, Alexandre Courbot
Cc: Matteo Kloiber, aliceryhl, ojeda, airlied, simona,
abdiel.janulgue, daniel.almeida, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On 14/09/2026 11:22 am, Gary Guo wrote:
> On Mon Sep 14, 2026 at 10:58 AM BST, Danilo Krummrich wrote:
>> On Mon Sep 14, 2026 at 2:45 AM CEST, Alexandre Courbot wrote:
>>> On Mon Sep 14, 2026 at 6:08 AM JST, Matteo Kloiber wrote:
>>>> On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
>>>>> It also means that without patch 1, nova-core would split the firmware
>>>>> into hundreds of 64KB SG entries, which is not breaking but still
>>>>> something we want to avoid. The correct fix is to make sure that
>>>>> `dma_set_max_seg_size` is called by the driver, and while we are at it
>>>>> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
>>>>> we would use the type system to make sure that both functions are called
>>>>> before any DMA operation can take place (using a safe interface), but
>>>>> I'm not quite sure yet how we can do this.
>>>>
>>>> This sounds sensible indeed. Should I open a thread regarding that on Zulip?
>>>
>>> Probably not necessary, the mailing-list has a larger audience and is
>>> the right place for this. I expect people will jump in here with their
>>> thoughts.
>>
>> The problem with those is not that they must strictly be called before
>> allocating DMA memory, but they must not be called concurrently with other DMA
>> operations, such as allocating DMA memory, as it would technically be a data
>> race.
>
> Do they really have to be called *before* allocating DMA memory, not do they
> just need not be called *concurrent* to DMA memory allocation?
Similar to DMA masks, the segment parameters should be set appropriately
before any dma_map_sg() operation. Plus since they likely influence
scatterlist geometry, that means typically they're also going to need to
be set before building the scatterlist to be mapped in the first place.
I don't think there's any expectation that they would ever change
*between* different mappings - especially given the underlying hardware
properties they represent - so while that might technically be possible
in the C API if the caller can enforce sufficient ordering, it should be
fine to rule it out in the Rust abstraction if that makes things easier
to reason about.
Thanks,
Robin.
> If it's the former, we can require these to require mutable reference instead,
> so the probe takes `Pin<&'bound mut Device<Core<'_>>>` which still derefs to
> `&'bound Device<Bound>`, but Rust will require the shared reference to not
> co-exist with the mutable reference.
>
> Best,
> Gary
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-14 12:17 ` Robin Murphy
@ 2026-09-14 13:17 ` Gary Guo
2026-09-14 13:57 ` Danilo Krummrich
0 siblings, 1 reply; 13+ messages in thread
From: Gary Guo @ 2026-09-14 13:17 UTC (permalink / raw)
To: Robin Murphy, Gary Guo, Danilo Krummrich, Alexandre Courbot
Cc: Matteo Kloiber, aliceryhl, ojeda, airlied, simona,
abdiel.janulgue, daniel.almeida, a.hindborg, nova-gpu, dri-devel,
driver-core, rust-for-linux, linux-kernel
On Mon Sep 14, 2026 at 1:17 PM BST, Robin Murphy wrote:
> On 14/09/2026 11:22 am, Gary Guo wrote:
>> On Mon Sep 14, 2026 at 10:58 AM BST, Danilo Krummrich wrote:
>>> On Mon Sep 14, 2026 at 2:45 AM CEST, Alexandre Courbot wrote:
>>>> On Mon Sep 14, 2026 at 6:08 AM JST, Matteo Kloiber wrote:
>>>>> On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
>>>>>> It also means that without patch 1, nova-core would split the firmware
>>>>>> into hundreds of 64KB SG entries, which is not breaking but still
>>>>>> something we want to avoid. The correct fix is to make sure that
>>>>>> `dma_set_max_seg_size` is called by the driver, and while we are at it
>>>>>> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
>>>>>> we would use the type system to make sure that both functions are called
>>>>>> before any DMA operation can take place (using a safe interface), but
>>>>>> I'm not quite sure yet how we can do this.
>>>>>
>>>>> This sounds sensible indeed. Should I open a thread regarding that on Zulip?
>>>>
>>>> Probably not necessary, the mailing-list has a larger audience and is
>>>> the right place for this. I expect people will jump in here with their
>>>> thoughts.
>>>
>>> The problem with those is not that they must strictly be called before
>>> allocating DMA memory, but they must not be called concurrently with other DMA
>>> operations, such as allocating DMA memory, as it would technically be a data
>>> race.
>>
>> Do they really have to be called *before* allocating DMA memory, not do they
>> just need not be called *concurrent* to DMA memory allocation?
>
> Similar to DMA masks, the segment parameters should be set appropriately
> before any dma_map_sg() operation. Plus since they likely influence
> scatterlist geometry, that means typically they're also going to need to
> be set before building the scatterlist to be mapped in the first place.
Right, in that case I think we have the following options:
1. Have setters these being unsafe, with precondition that they must be done
before creation of DMA mappings.
2. Have a `dma_info()` method like Danilo mentioned. However, we cannot expose
`&Device<Core<'_>>` inside such callbacks, because otherwise driver would be
able create DMA mappings. This however is too restrictive to be the only way
of setting DMA masks, because Nova needs to access the bar before setting the
DMA masks.
3. Use wrapper type instead of generics for typestate. Then, we can express the
pattern of typestate transformation (generics cannot do this because we
always place it behind a reference).
For example, we can have `Device` to mean `Device<Normal>`, and then have
`Bound<Device>` to mean `Device<Bound>` (both of which are behind a shared
reference, like today, and `Bound<D>` can deref to `&D`).
Then, for `Core` typestate, we can instead have
struct Core<'a, D>(&'a Bound<Device>);
where it's passed by value. We can then define the DMA setters methods to
operate on `Core` like we did today, but safely. Instead of providing a
`Deref` impl that turns `&Core<'_, D>` to `&Bound<D>`, we only implement
forwarding functions for APIs that can work without DMA configured (e.g. PCI
bar).
Then, provide a `into_bound()` method which *consumes* `Core<'a, D>` and
give out `&'a Bound<Device>` (this is why typestate generics cannot work,
because `&'a Device<Core<'_>>` is Copy and we cannot represent the ownership
consumption).
>
> I don't think there's any expectation that they would ever change
> *between* different mappings - especially given the underlying hardware
> properties they represent - so while that might technically be possible
> in the C API if the caller can enforce sufficient ordering, it should be
> fine to rule it out in the Rust abstraction if that makes things easier
> to reason about.
>
> Thanks,
> Robin.
>
>> If it's the former, we can require these to require mutable reference instead,
Correction: this should say "latter".
Best,
Gary
>> so the probe takes `Pin<&'bound mut Device<Core<'_>>>` which still derefs to
>> `&'bound Device<Bound>`, but Rust will require the shared reference to not
>> co-exist with the mutable reference.
>>
>> Best,
>> Gary
>>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] rust: scatterlist: honor the device's maximum segment size
2026-09-14 13:17 ` Gary Guo
@ 2026-09-14 13:57 ` Danilo Krummrich
0 siblings, 0 replies; 13+ messages in thread
From: Danilo Krummrich @ 2026-09-14 13:57 UTC (permalink / raw)
To: Gary Guo
Cc: Robin Murphy, Alexandre Courbot, Matteo Kloiber, aliceryhl,
ojeda, airlied, simona, abdiel.janulgue, daniel.almeida,
a.hindborg, nova-gpu, dri-devel, driver-core, rust-for-linux,
linux-kernel
On Mon Sep 14, 2026 at 3:17 PM CEST, Gary Guo wrote:
> On Mon Sep 14, 2026 at 1:17 PM BST, Robin Murphy wrote:
>> On 14/09/2026 11:22 am, Gary Guo wrote:
>>> On Mon Sep 14, 2026 at 10:58 AM BST, Danilo Krummrich wrote:
>>>> On Mon Sep 14, 2026 at 2:45 AM CEST, Alexandre Courbot wrote:
>>>>> On Mon Sep 14, 2026 at 6:08 AM JST, Matteo Kloiber wrote:
>>>>>> On Mon Sep 7, 2026 at 11:43 AM JST, Alexandre Courbot wrote:
>>>>>>> It also means that without patch 1, nova-core would split the firmware
>>>>>>> into hundreds of 64KB SG entries, which is not breaking but still
>>>>>>> something we want to avoid. The correct fix is to make sure that
>>>>>>> `dma_set_max_seg_size` is called by the driver, and while we are at it
>>>>>>> we also want every driver to call `dma_set_mask_and_coherent`. Ideally
>>>>>>> we would use the type system to make sure that both functions are called
>>>>>>> before any DMA operation can take place (using a safe interface), but
>>>>>>> I'm not quite sure yet how we can do this.
>>>>>>
>>>>>> This sounds sensible indeed. Should I open a thread regarding that on Zulip?
>>>>>
>>>>> Probably not necessary, the mailing-list has a larger audience and is
>>>>> the right place for this. I expect people will jump in here with their
>>>>> thoughts.
>>>>
>>>> The problem with those is not that they must strictly be called before
>>>> allocating DMA memory, but they must not be called concurrently with other DMA
>>>> operations, such as allocating DMA memory, as it would technically be a data
>>>> race.
>>>
>>> Do they really have to be called *before* allocating DMA memory, not do they
>>> just need not be called *concurrent* to DMA memory allocation?
>>
>> Similar to DMA masks, the segment parameters should be set appropriately
>> before any dma_map_sg() operation. Plus since they likely influence
>> scatterlist geometry, that means typically they're also going to need to
>> be set before building the scatterlist to be mapped in the first place.
>
> Right, in that case I think we have the following options:
>
> 1. Have setters these being unsafe, with precondition that they must be done
> before creation of DMA mappings.
As mentioned, I don't think the safety requirement has to be before using other
DMA APIs, but just requiring to not do it concurrently. Not doing it would be a
semantic bug, but it shouldn't have any safety implications.
> 2. Have a `dma_info()` method like Danilo mentioned. However, we cannot expose
> `&Device<Core<'_>>` inside such callbacks, because otherwise driver would be
> able create DMA mappings. This however is too restrictive to be the only way
> of setting DMA masks, because Nova needs to access the bar before setting the
> DMA masks.
Just to clarify, I mentioned this to be something we could do in addition to (1)
for drivers where those values are statically known.
> 3. Use wrapper type instead of generics for typestate. Then, we can express the
> pattern of typestate transformation (generics cannot do this because we
> always place it behind a reference).
>
> For example, we can have `Device` to mean `Device<Normal>`, and then have
> `Bound<Device>` to mean `Device<Bound>` (both of which are behind a shared
> reference, like today, and `Bound<D>` can deref to `&D`).
>
> Then, for `Core` typestate, we can instead have
>
> struct Core<'a, D>(&'a Bound<Device>);
>
> where it's passed by value. We can then define the DMA setters methods to
> operate on `Core` like we did today, but safely. Instead of providing a
> `Deref` impl that turns `&Core<'_, D>` to `&Bound<D>`, we only implement
> forwarding functions for APIs that can work without DMA configured (e.g. PCI
> bar).
>
> Then, provide a `into_bound()` method which *consumes* `Core<'a, D>` and
> give out `&'a Bound<Device>` (this is why typestate generics cannot work,
> because `&'a Device<Core<'_>>` is Copy and we cannot represent the ownership
> consumption).
Yeah, we had this discussion in the past with similar ideas; it is the kind of
complication that we concluded not to be worth it and that I mentioned in my
initial reply.
The only safety relevant issue should really be the data race of the primitives
values being set, which is more on the theoretical side of things.
>> I don't think there's any expectation that they would ever change
>> *between* different mappings - especially given the underlying hardware
>> properties they represent - so while that might technically be possible
>> in the C API if the caller can enforce sufficient ordering, it should be
>> fine to rule it out in the Rust abstraction if that makes things easier
>> to reason about.
>>
>>> If it's the former, we can require these to require mutable reference instead,
>
> Correction: this should say "latter".
>
>>> so the probe takes `Pin<&'bound mut Device<Core<'_>>>` which still derefs to
>>> `&'bound Device<Bound>`, but Rust will require the shared reference to not
>>> co-exist with the mutable reference.
I think that doesn't work, there are drivers that need to perform MMIO before
knowing e.g. the DMA mask, i.e. we can't have Pin<&'bound mut Device<Core<'_>>>
at the same time as e.g. pci::Bar<'_>, which borrows a &Device<Bound>.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-09-14 13:57 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-31 23:32 [PATCH 0/2] rust: honor the maximum DMA segment size Matteo Kloiber
2026-08-31 23:32 ` [PATCH 1/2] gpu: nova-core: declare unlimited DMA max " Matteo Kloiber
2026-09-07 2:10 ` Alexandre Courbot
2026-09-13 21:07 ` Matteo Kloiber
2026-08-31 23:32 ` [PATCH 2/2] rust: scatterlist: honor the device's maximum " Matteo Kloiber
2026-09-07 2:43 ` Alexandre Courbot
2026-09-13 21:08 ` Matteo Kloiber
2026-09-14 0:45 ` Alexandre Courbot
2026-09-14 9:58 ` Danilo Krummrich
2026-09-14 10:22 ` Gary Guo
2026-09-14 12:17 ` Robin Murphy
2026-09-14 13:17 ` Gary Guo
2026-09-14 13:57 ` Danilo Krummrich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®