dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
@ 2026-06-30  9:39 Dave Airlie
  2026-06-30 11:24 ` Christian König
  2026-06-30 11:39 ` Jason Gunthorpe
  0 siblings, 2 replies; 12+ messages in thread
From: Dave Airlie @ 2026-06-30  9:39 UTC (permalink / raw)
  To: dri-devel, iommu
  Cc: Jason Gunthorpe, Alistair Popple, Matthew Brost,
	Koenig, Christian

I've been bringing up nouveau on NVIDIA Spark GB10 and fallen down a
hole of why is the GPU writing to pages I've released back to the CPU
page allocator. I've wasted a lot of time on GPU L2 cache and explicit
handling for it, which might be needed but hasn't solved my problem.
I've also invalidated and flushed the GPU TLB excessively.

Today I finally hit up iommu.strict=1 makes things a lot happier,
non-strict IOMMU seems to allow a race between dma_unmap_page and
free_page where the unmap goes into the IOMMU flush queue, where the
actual unmap are delayed until something triggers a flush later, and
the ATS translations stay alive past when they should, and after the
page has been allocated by some subsequent user.

The options I seem to have: (but I'm probably very wrong)
1. force my own iommu domain and use iommu_map/unmap explicitly in the
driver which avoids the flush queue?
2. split ttm page unmap/free into two stages, and force an iommu
flush/ATS sync operation after the unmap before the free. (I don't
think iommu has an interface for this).
3. force untrusted on the PCI device?

I just want to see if anyone else has hit this problem before in this
space and I'm missing something, just feel solving this in the driver
is a workaround for ttm/dma API impedance mismatch.

Thanks,
Dave.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30  9:39 iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward Dave Airlie
@ 2026-06-30 11:24 ` Christian König
  2026-06-30 11:51   ` Jason Gunthorpe
  2026-06-30 11:39 ` Jason Gunthorpe
  1 sibling, 1 reply; 12+ messages in thread
From: Christian König @ 2026-06-30 11:24 UTC (permalink / raw)
  To: Dave Airlie, dri-devel, iommu
  Cc: Jason Gunthorpe, Alistair Popple, Matthew Brost

On 6/30/26 11:39, Dave Airlie wrote:
> I've been bringing up nouveau on NVIDIA Spark GB10 and fallen down a
> hole of why is the GPU writing to pages I've released back to the CPU
> page allocator. I've wasted a lot of time on GPU L2 cache and explicit
> handling for it, which might be needed but hasn't solved my problem.
> I've also invalidated and flushed the GPU TLB excessively.

How does nouveau make sure that all DMA transactions have completed (e.g. caches flushed etc...)?

> Today I finally hit up iommu.strict=1 makes things a lot happier,
> non-strict IOMMU seems to allow a race between dma_unmap_page and
> free_page where the unmap goes into the IOMMU flush queue, where the
> actual unmap are delayed until something triggers a flush later, and
> the ATS translations stay alive past when they should, and after the
> page has been allocated by some subsequent user.

Try disabling ATS, that was a common source of problems during HW bringup for us in the past.

It obviously cripples the performance, but when the problem doesn't happen any more you have at least an additional data point to narrow things down.

> The options I seem to have: (but I'm probably very wrong)
> 1. force my own iommu domain and use iommu_map/unmap explicitly in the
> driver which avoids the flush queue?
> 2. split ttm page unmap/free into two stages, and force an iommu
> flush/ATS sync operation after the unmap before the free. (I don't
> think iommu has an interface for this).

Yeah that idea already came up on similar issues as well. I certainly wouldn't be opposed to that.

> 3. force untrusted on the PCI device?
> 
> I just want to see if anyone else has hit this problem before in this
> space and I'm missing something, just feel solving this in the driver
> is a workaround for ttm/dma API impedance mismatch.

Yeah we have fought with stuff like that on basic every AMD GPU HW generation.

From experience I would say that both MMU implementations inside GPUs/accelerators as well as well as IOMMU are really hard to get 100% reliable in preventing random memory writes.

You either have to use memory fences which use the same path as the DMA operations itself or you have extra heavyweight TLB flushes with just insane overhead or grace periods to make sure that all transactions have actually reached system memory.

So far the record for grace periods you need after a TLB flush is 6 seconds on production HW with up to 10 seconds on engineering samples (because of HW bugs).

Regards,
Christian.

> 
> Thanks,
> Dave.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30  9:39 iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward Dave Airlie
  2026-06-30 11:24 ` Christian König
@ 2026-06-30 11:39 ` Jason Gunthorpe
  2026-06-30 23:21   ` Matthew Brost
  1 sibling, 1 reply; 12+ messages in thread
From: Jason Gunthorpe @ 2026-06-30 11:39 UTC (permalink / raw)
  To: Dave Airlie
  Cc: dri-devel, iommu, Alistair Popple, Matthew Brost,
	Koenig, Christian

On Tue, Jun 30, 2026 at 07:39:44PM +1000, Dave Airlie wrote:
> I've been bringing up nouveau on NVIDIA Spark GB10 and fallen down a
> hole of why is the GPU writing to pages I've released back to the CPU
> page allocator. I've wasted a lot of time on GPU L2 cache and explicit
> handling for it, which might be needed but hasn't solved my problem.
> I've also invalidated and flushed the GPU TLB excessively.
>
> Today I finally hit up iommu.strict=1 makes things a lot happier,
> non-strict IOMMU seems to allow a race between dma_unmap_page and
> free_page where the unmap goes into the IOMMU flush queue, where the
> actual unmap are delayed until something triggers a flush later, and
> the ATS translations stay alive past when they should, and after the
> page has been allocated by some subsequent user.

It is a driver/device bug if it continues to DMA to memory after
dma_unmap is called. Strict mode is intended to increase security
against malicious devices and to aid debugging buggy drivers, it must
not be relied upon to have any functional effect on a correct driver.

This is not an API issue or an impedence mismatch, you have to follow
the DMA API contract when using the DMA API - meaning before unmap is
called the device is not doing DMA any more. It is a purely a
driver/device bug that the device is not quieted prior to unmapping.

You cannot fix this with any of your proposed hacks, the driver must
have control over the device and it must know when the device is done
DMA. Presumably there is a missing flush or fence that is allowing the
GPU to continue to DMA even after the OS thinks it has told it to
stop. There are many unique things about the coherent GPUs, I would
not be surprised if the driver needs some additional fencing
operations to clear the fabric beyond simple cache invalidation, but I
don't know.

Normally strict would convert these bugs from quiet corruptions into
noisy IOMMU logging, however in this case the GPU is using ATS and the
IOMMU does not log non-present ATS responses. Instead the GPU's
internal attempt to DMA will fail and the GPU will do whatever it does
to propogate that failure. Probably the driver has not noticed the
fall out, or it ignored it.

Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 11:24 ` Christian König
@ 2026-06-30 11:51   ` Jason Gunthorpe
  2026-06-30 20:45     ` Dave Airlie
  0 siblings, 1 reply; 12+ messages in thread
From: Jason Gunthorpe @ 2026-06-30 11:51 UTC (permalink / raw)
  To: Christian König
  Cc: Dave Airlie, dri-devel, iommu, Alistair Popple, Matthew Brost

On Tue, Jun 30, 2026 at 01:24:57PM +0200, Christian König wrote:

> > Today I finally hit up iommu.strict=1 makes things a lot happier,
> > non-strict IOMMU seems to allow a race between dma_unmap_page and
> > free_page where the unmap goes into the IOMMU flush queue, where the
> > actual unmap are delayed until something triggers a flush later, and
> > the ATS translations stay alive past when they should, and after the
> > page has been allocated by some subsequent user.
> 
> Try disabling ATS, that was a common source of problems during HW
> bringup for us in the past.

The spark HW cannot run without ATS.

> > 2. split ttm page unmap/free into two stages, and force an iommu
> > flush/ATS sync operation after the unmap before the free. (I don't
> > think iommu has an interface for this).
> 
> Yeah that idea already came up on similar issues as well. I
> certainly wouldn't be opposed to that.

Only for debugging, it is completely wrong to rely on this for
functionality.

> You either have to use memory fences which use the same path as the
> DMA operations itself

Yes, in a PCIe system generally something like the GPU TLB
invalidation command will complete and flush the fabric path to quiet
the DMAs. That won't be true on spark though.

Dave could be facing a fabric issue. AFAIK the ATS invalidation that
the iommu=strict pushses should fence the fabric so would resolve a
missing fabric fence. I suppose if you don't see any evidence of a
non-present ATS response explosion with strict then this would be a
really good theory.

However, the GPU must have another way to inject a fabric fence. The
production driver does not rely on ATS fencing to synchronize memory
operations!

> So far the record for grace periods you need after a TLB flush is 6
> seconds on production HW with up to 10 seconds on engineering
> samples (because of HW bugs).

Yeah, if the HW mechanism to fence the fabric don't work spark would
need similar times to guarentee a fabric drain.

Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 11:51   ` Jason Gunthorpe
@ 2026-06-30 20:45     ` Dave Airlie
  2026-06-30 21:00       ` Dave Airlie
  2026-06-30 23:59       ` Jason Gunthorpe
  0 siblings, 2 replies; 12+ messages in thread
From: Dave Airlie @ 2026-06-30 20:45 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christian König, dri-devel, iommu, Alistair Popple,
	Matthew Brost

On Tue, 30 Jun 2026 at 21:51, Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> On Tue, Jun 30, 2026 at 01:24:57PM +0200, Christian König wrote:
>
> > > Today I finally hit up iommu.strict=1 makes things a lot happier,
> > > non-strict IOMMU seems to allow a race between dma_unmap_page and
> > > free_page where the unmap goes into the IOMMU flush queue, where the
> > > actual unmap are delayed until something triggers a flush later, and
> > > the ATS translations stay alive past when they should, and after the
> > > page has been allocated by some subsequent user.
> >
> > Try disabling ATS, that was a common source of problems during HW
> > bringup for us in the past.
>
> The spark HW cannot run without ATS.
>
> > > 2. split ttm page unmap/free into two stages, and force an iommu
> > > flush/ATS sync operation after the unmap before the free. (I don't
> > > think iommu has an interface for this).
> >
> > Yeah that idea already came up on similar issues as well. I
> > certainly wouldn't be opposed to that.
>
> Only for debugging, it is completely wrong to rely on this for
> functionality.
>
> > You either have to use memory fences which use the same path as the
> > DMA operations itself
>
> Yes, in a PCIe system generally something like the GPU TLB
> invalidation command will complete and flush the fabric path to quiet
> the DMAs. That won't be true on spark though.
>
> Dave could be facing a fabric issue. AFAIK the ATS invalidation that
> the iommu=strict pushses should fence the fabric so would resolve a
> missing fabric fence. I suppose if you don't see any evidence of a
> non-present ATS response explosion with strict then this would be a
> really good theory.

It's definitely a fabric issue, the iommu ATS invalidation is what
"fixes" it, but I'm not figuring out how to flush it from the GPU
side, and I'm not seeing where the official driver does this either,
guess I have to keep digging. Maybe Alistair knows something.

>
> However, the GPU must have another way to inject a fabric fence. The
> production driver does not rely on ATS fencing to synchronize memory
> operations!
>
> > So far the record for grace periods you need after a TLB flush is 6
> > seconds on production HW with up to 10 seconds on engineering
> > samples (because of HW bugs).
>
> Yeah, if the HW mechanism to fence the fabric don't work spark would
> need similar times to guarentee a fabric drain.

From the ubuntu kernel this thing ships with:
https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-6.14/+bug/2132033

"Add two more Spark iGPU IDs for the existing iommu quirk "

diff -u linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
--- linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3654,7 +3654,9 @@
  if (IS_HISI_PTT_DEVICE(pdev))
  return IOMMU_DOMAIN_IDENTITY;

- if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && pdev->device == 0x2E12)
+ if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
+    (pdev->device == 0x2E12 || pdev->device == 0x2E2A ||
+     pdev->device == 0x2E2B))
  return IOMMU_DOMAIN_DMA;
  }


I should probably work out if anything upstream does this or if I can
mess up the production driver against an upstream kernel.

Dave.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 20:45     ` Dave Airlie
@ 2026-06-30 21:00       ` Dave Airlie
  2026-07-01  0:17         ` Jason Gunthorpe
  2026-06-30 23:59       ` Jason Gunthorpe
  1 sibling, 1 reply; 12+ messages in thread
From: Dave Airlie @ 2026-06-30 21:00 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christian König, dri-devel, iommu, Alistair Popple,
	Matthew Brost

On Wed, 1 Jul 2026 at 06:45, Dave Airlie <airlied@gmail.com> wrote:
>
> On Tue, 30 Jun 2026 at 21:51, Jason Gunthorpe <jgg@nvidia.com> wrote:
> >
> > On Tue, Jun 30, 2026 at 01:24:57PM +0200, Christian König wrote:
> >
> > > > Today I finally hit up iommu.strict=1 makes things a lot happier,
> > > > non-strict IOMMU seems to allow a race between dma_unmap_page and
> > > > free_page where the unmap goes into the IOMMU flush queue, where the
> > > > actual unmap are delayed until something triggers a flush later, and
> > > > the ATS translations stay alive past when they should, and after the
> > > > page has been allocated by some subsequent user.
> > >
> > > Try disabling ATS, that was a common source of problems during HW
> > > bringup for us in the past.
> >
> > The spark HW cannot run without ATS.
> >
> > > > 2. split ttm page unmap/free into two stages, and force an iommu
> > > > flush/ATS sync operation after the unmap before the free. (I don't
> > > > think iommu has an interface for this).
> > >
> > > Yeah that idea already came up on similar issues as well. I
> > > certainly wouldn't be opposed to that.
> >
> > Only for debugging, it is completely wrong to rely on this for
> > functionality.
> >
> > > You either have to use memory fences which use the same path as the
> > > DMA operations itself
> >
> > Yes, in a PCIe system generally something like the GPU TLB
> > invalidation command will complete and flush the fabric path to quiet
> > the DMAs. That won't be true on spark though.
> >
> > Dave could be facing a fabric issue. AFAIK the ATS invalidation that
> > the iommu=strict pushses should fence the fabric so would resolve a
> > missing fabric fence. I suppose if you don't see any evidence of a
> > non-present ATS response explosion with strict then this would be a
> > really good theory.
>
> It's definitely a fabric issue, the iommu ATS invalidation is what
> "fixes" it, but I'm not figuring out how to flush it from the GPU
> side, and I'm not seeing where the official driver does this either,
> guess I have to keep digging. Maybe Alistair knows something.
>
> >
> > However, the GPU must have another way to inject a fabric fence. The
> > production driver does not rely on ATS fencing to synchronize memory
> > operations!

From the production driver, there definitely was some issues in the
past, however this seems possibly fixed with mmu notifiers, but for
these memory allocations I'm doing I'm not using MMU notifiers at all.

#if defined(NV_MMU_NOTIFIER_OPS_HAS_ARCH_INVALIDATE_SECONDARY_TLBS)
    #define UVM_ATS_SMMU_WAR_REQUIRED() 0
#elif NVCPU_IS_AARCH64
    #define UVM_ATS_SMMU_WAR_REQUIRED() 1
#else
    #define UVM_ATS_SMMU_WAR_REQUIRED() 0
#endif

#if UVM_ATS_SMMU_WAR_REQUIRED()
void uvm_ats_smmu_invalidate_tlbs(uvm_gpu_va_space_t *gpu_va_space,
NvU64 addr, size_t size)
{
    struct mm_struct *mm = gpu_va_space->va_space->va_space_mm.mm;
    uvm_parent_gpu_t *parent_gpu = gpu_va_space->gpu->parent;
    struct {
        NvU64 low;
        NvU64 high;
    } *vcmdq;
    unsigned long vcmdq_prod;
    NvU64 end;
    uvm_spin_loop_t spin;
    NvU16 asid;

    if (!parent_gpu->ats.smmu_war.smmu_cmdqv_base)
        return;

    asid = arm64_mm_context_get(mm);
    vcmdq = kmap(parent_gpu->ats.smmu_war.smmu_cmdq);
    uvm_mutex_lock(&parent_gpu->ats.smmu_war.smmu_lock);
    vcmdq_prod = parent_gpu->ats.smmu_war.smmu_prod;

    // Our queue management is very simple. The mutex prevents multiple
    // producers writing to the queue and all our commands require waiting for
    // the queue to drain so we know it's empty. If we can't fit enough commands
    // in the queue we just invalidate the whole ASID.
    //
    // The command queue is a cirular buffer with the MSB representing a wrap
    // bit that must toggle on each wrap. See the SMMU architecture
    // specification for more details.
    //
    // SMMU_VCMDQ_CMDQ_ENTRIES - 1 because we need to leave space for the
    // CMD_SYNC.
    if ((size >> PAGE_SHIFT) > min(UVM_MAX_TLBI_OPS,
SMMU_VCMDQ_CMDQ_ENTRIES - 1)) {
        vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].low = CMDQ_OP_TLBI_EL2_ASID;
        vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].low |= (NvU64) asid << 48;
        vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].high = 0;
        vcmdq_prod++;
    }
    else {
        for (end = addr + size; addr < end; addr += PAGE_SIZE) {
            vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].low =
CMDQ_OP_TLBI_EL2_VA;
            vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].low |= (NvU64)
asid << 48;
            vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].high = addr &
~((1UL << 12) - 1);
            vcmdq_prod++;
        }
    }

    vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].low = CMDQ_OP_CMD_SYNC;
    vcmdq[vcmdq_prod % SMMU_VCMDQ_CMDQ_ENTRIES].high = 0x0;
    vcmdq_prod++;

    // MSB is the wrap bit
    vcmdq_prod &= (1UL << (SMMU_VCMDQ_CMDQ_BASE_LOG2SIZE + 1)) - 1;
    parent_gpu->ats.smmu_war.smmu_prod = vcmdq_prod;
    smmu_vcmdq_write32(parent_gpu->ats.smmu_war.smmu_cmdqv_base,
SMMU_VCMDQ_PROD, parent_gpu->ats.smmu_war.smmu_prod);

    UVM_SPIN_WHILE(
        (smmu_vcmdq_read32(parent_gpu->ats.smmu_war.smmu_cmdqv_base,
SMMU_VCMDQ_CONS) & GENMASK(19, 0)) != vcmdq_prod,
        &spin);

    uvm_mutex_unlock(&parent_gpu->ats.smmu_war.smmu_lock);
    kunmap(parent_gpu->ats.smmu_war.smmu_cmdq);
    arm64_mm_context_put(mm);
}
#endif

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 11:39 ` Jason Gunthorpe
@ 2026-06-30 23:21   ` Matthew Brost
  2026-07-01  1:30     ` Alistair Popple
  0 siblings, 1 reply; 12+ messages in thread
From: Matthew Brost @ 2026-06-30 23:21 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Dave Airlie, dri-devel, iommu, Alistair Popple, Koenig, Christian

On Tue, Jun 30, 2026 at 08:39:19AM -0300, Jason Gunthorpe wrote:
> On Tue, Jun 30, 2026 at 07:39:44PM +1000, Dave Airlie wrote:
> > I've been bringing up nouveau on NVIDIA Spark GB10 and fallen down a
> > hole of why is the GPU writing to pages I've released back to the CPU
> > page allocator. I've wasted a lot of time on GPU L2 cache and explicit
> > handling for it, which might be needed but hasn't solved my problem.
> > I've also invalidated and flushed the GPU TLB excessively.
> >
> > Today I finally hit up iommu.strict=1 makes things a lot happier,
> > non-strict IOMMU seems to allow a race between dma_unmap_page and
> > free_page where the unmap goes into the IOMMU flush queue, where the
> > actual unmap are delayed until something triggers a flush later, and
> > the ATS translations stay alive past when they should, and after the
> > page has been allocated by some subsequent user.
> 
> It is a driver/device bug if it continues to DMA to memory after
> dma_unmap is called. Strict mode is intended to increase security
> against malicious devices and to aid debugging buggy drivers, it must
> not be relied upon to have any functional effect on a correct driver.
> 

I think I agree here. In Xe, AFAIK, we never call dma_unmap until all
fences have been signaled (dma-fence or preempt-fence mode), after which
GPU translations are rebuilt before the next fence is installed, or
until the GPU page tables have been invalidated (GPU page faults). TTM
is a little harder to reason about, as we DMA-unmap via
->ttm_tt_unpopulate(), but I just audited the call sites and TTM looks
correct.

> This is not an API issue or an impedence mismatch, you have to follow
> the DMA API contract when using the DMA API - meaning before unmap is
> called the device is not doing DMA any more. It is a purely a
> driver/device bug that the device is not quieted prior to unmapping.
> 
> You cannot fix this with any of your proposed hacks, the driver must
> have control over the device and it must know when the device is done
> DMA. Presumably there is a missing flush or fence that is allowing the
> GPU to continue to DMA even after the OS thinks it has told it to
> stop. There are many unique things about the coherent GPUs, I would
> not be surprised if the driver needs some additional fencing
> operations to clear the fabric beyond simple cache invalidation, but I
> don't know.
> 
> Normally strict would convert these bugs from quiet corruptions into
> noisy IOMMU logging, however in this case the GPU is using ATS and the
> IOMMU does not log non-present ATS responses. Instead the GPU's
> internal attempt to DMA will fail and the GPU will do whatever it does
> to propogate that failure. Probably the driver has not noticed the
> fall out, or it ignored it.

Right. We only have ATS enabled in Xe for experimentation, but whenever
we've had issues with dma_unmap ordering in Xe without ATS, they have
resulted in DMAR-related dmesg spam.

So TL;DR I'm guessing Nouveau has dma_unmap before GPU idle bug
somewhere.

Matt

> 
> Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 20:45     ` Dave Airlie
  2026-06-30 21:00       ` Dave Airlie
@ 2026-06-30 23:59       ` Jason Gunthorpe
  1 sibling, 0 replies; 12+ messages in thread
From: Jason Gunthorpe @ 2026-06-30 23:59 UTC (permalink / raw)
  To: Dave Airlie
  Cc: Christian König, dri-devel, iommu, Alistair Popple,
	Matthew Brost

On Wed, Jul 01, 2026 at 06:45:11AM +1000, Dave Airlie wrote:
> > Dave could be facing a fabric issue. AFAIK the ATS invalidation that
> > the iommu=strict pushses should fence the fabric so would resolve a
> > missing fabric fence. I suppose if you don't see any evidence of a
> > non-present ATS response explosion with strict then this would be a
> > really good theory.
> 
> It's definitely a fabric issue, the iommu ATS invalidation is what
> "fixes" it, but I'm not figuring out how to flush it from the GPU
> side, and I'm not seeing where the official driver does this either,
> guess I have to keep digging. Maybe Alistair knows something.

Well, as I said the ATS does two things, it fences the fabric and it
will fail DMAs with ATS non-present (which doesn't trigger an iommu
log). If you are confident there are no ATS non-present events inside
the GPU then fabric is the best guess, but most likely the fabric will
clear in microseconds after the last GPU DMA so it would be a pretty
narrow race.

> From the ubuntu kernel this thing ships with:
> https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-6.14/+bug/2132033
> 
> "Add two more Spark iGPU IDs for the existing iommu quirk "
> 
> diff -u linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> --- linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ linux-nvidia-6.14-6.14.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3654,7 +3654,9 @@
>   if (IS_HISI_PTT_DEVICE(pdev))
>   return IOMMU_DOMAIN_IDENTITY;
> 
> - if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && pdev->device == 0x2E12)
> + if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
> +    (pdev->device == 0x2E12 || pdev->device == 0x2E2A ||
> +     pdev->device == 0x2E2B))
>   return IOMMU_DOMAIN_DMA;
>   }
> 
> 
> I should probably work out if anything upstream does this or if I can
> mess up the production driver against an upstream kernel.

Latest upstream has this fixed now in a different way, this is about
forcing ATS mode on inside the SMMU driver because spark can't work if
ATS is disabled.

Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 21:00       ` Dave Airlie
@ 2026-07-01  0:17         ` Jason Gunthorpe
  2026-07-01  1:22           ` Alistair Popple
  0 siblings, 1 reply; 12+ messages in thread
From: Jason Gunthorpe @ 2026-07-01  0:17 UTC (permalink / raw)
  To: Dave Airlie
  Cc: Christian König, dri-devel, iommu, Alistair Popple,
	Matthew Brost

On Wed, Jul 01, 2026 at 07:00:01AM +1000, Dave Airlie wrote:

> From the production driver, there definitely was some issues in the
> past, however this seems possibly fixed with mmu notifiers, but for
> these memory allocations I'm doing I'm not using MMU notifiers at all.

Well, the comment on that is this:

// Fix for Bug 4130089: [GH180][r535] WAR for kernel not issuing SMMU
// TLB invalidates on read-only to read-write upgrades

And the upstream kernel has that issue fixed, so it looks like that
whole disaster compiles out.

Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-07-01  0:17         ` Jason Gunthorpe
@ 2026-07-01  1:22           ` Alistair Popple
  0 siblings, 0 replies; 12+ messages in thread
From: Alistair Popple @ 2026-07-01  1:22 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Dave Airlie, Christian König, dri-devel, iommu,
	Matthew Brost

On 2026-07-01 at 10:17 +1000, Jason Gunthorpe <jgg@nvidia.com> wrote...
> On Wed, Jul 01, 2026 at 07:00:01AM +1000, Dave Airlie wrote:
> 
> > From the production driver, there definitely was some issues in the
> > past, however this seems possibly fixed with mmu notifiers, but for
> > these memory allocations I'm doing I'm not using MMU notifiers at all.
> 
> Well, the comment on that is this:
> 
> // Fix for Bug 4130089: [GH180][r535] WAR for kernel not issuing SMMU
> // TLB invalidates on read-only to read-write upgrades
> 
> And the upstream kernel has that issue fixed, so it looks like that
> whole disaster compiles out.

Yeah that whole disaster is something we should never have tried to work around
in the driver. However I don't think anything ATS in UVM is related to the
problem your trying to debug. UVM ATS deals specifically with SAM/SVM - ie. the
ability for the GPU to directly access system allocated memory (think userspace
mmap/malloc). This has nothing to do with dma_map/unmap() as these aren't needed
for PASID ATS. We're also not using mmu notifiers to workaround any issues like
what you have described.

 - Alistair

> Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-06-30 23:21   ` Matthew Brost
@ 2026-07-01  1:30     ` Alistair Popple
  2026-07-01 23:34       ` Jason Gunthorpe
  0 siblings, 1 reply; 12+ messages in thread
From: Alistair Popple @ 2026-07-01  1:30 UTC (permalink / raw)
  To: Matthew Brost
  Cc: Jason Gunthorpe, Dave Airlie, dri-devel, iommu, Koenig, Christian

On 2026-07-01 at 09:21 +1000, Matthew Brost <matthew.brost@intel.com> wrote...
> On Tue, Jun 30, 2026 at 08:39:19AM -0300, Jason Gunthorpe wrote:
> > On Tue, Jun 30, 2026 at 07:39:44PM +1000, Dave Airlie wrote:
> > > I've been bringing up nouveau on NVIDIA Spark GB10 and fallen down a
> > > hole of why is the GPU writing to pages I've released back to the CPU
> > > page allocator. I've wasted a lot of time on GPU L2 cache and explicit
> > > handling for it, which might be needed but hasn't solved my problem.
> > > I've also invalidated and flushed the GPU TLB excessively.
> > >
> > > Today I finally hit up iommu.strict=1 makes things a lot happier,
> > > non-strict IOMMU seems to allow a race between dma_unmap_page and
> > > free_page where the unmap goes into the IOMMU flush queue, where the
> > > actual unmap are delayed until something triggers a flush later, and
> > > the ATS translations stay alive past when they should, and after the
> > > page has been allocated by some subsequent user.
> > 
> > It is a driver/device bug if it continues to DMA to memory after
> > dma_unmap is called. Strict mode is intended to increase security
> > against malicious devices and to aid debugging buggy drivers, it must
> > not be relied upon to have any functional effect on a correct driver.
> > 
> 
> I think I agree here. In Xe, AFAIK, we never call dma_unmap until all
> fences have been signaled (dma-fence or preempt-fence mode), after which
> GPU translations are rebuilt before the next fence is installed, or
> until the GPU page tables have been invalidated (GPU page faults). TTM
> is a little harder to reason about, as we DMA-unmap via
> ->ttm_tt_unpopulate(), but I just audited the call sites and TTM looks
> correct.
> 
> > This is not an API issue or an impedence mismatch, you have to follow
> > the DMA API contract when using the DMA API - meaning before unmap is
> > called the device is not doing DMA any more. It is a purely a
> > driver/device bug that the device is not quieted prior to unmapping.
> > 
> > You cannot fix this with any of your proposed hacks, the driver must
> > have control over the device and it must know when the device is done
> > DMA. Presumably there is a missing flush or fence that is allowing the
> > GPU to continue to DMA even after the OS thinks it has told it to
> > stop. There are many unique things about the coherent GPUs, I would
> > not be surprised if the driver needs some additional fencing
> > operations to clear the fabric beyond simple cache invalidation, but I
> > don't know.
> > 
> > Normally strict would convert these bugs from quiet corruptions into
> > noisy IOMMU logging, however in this case the GPU is using ATS and the
> > IOMMU does not log non-present ATS responses. Instead the GPU's
> > internal attempt to DMA will fail and the GPU will do whatever it does
> > to propogate that failure. Probably the driver has not noticed the
> > fall out, or it ignored it.
> 
> Right. We only have ATS enabled in Xe for experimentation, but whenever
> we've had issues with dma_unmap ordering in Xe without ATS, they have
> resulted in DMAR-related dmesg spam.
> 
> So TL;DR I'm guessing Nouveau has dma_unmap before GPU idle bug
> somewhere.

Agree with most of the above and this seems the most likely explaination. ATS
doesn't change much here - most of our driver still goes via dma_map/unmap to
access host memory via an IOMMU IOVA so non-present entries there would be fatal
at the IOMMU level. So even with ATS enabled a non-present DMA mapping should
still result in noisy IOMMU faults.

 - Alistair

> Matt
> 
> > 
> > Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward
  2026-07-01  1:30     ` Alistair Popple
@ 2026-07-01 23:34       ` Jason Gunthorpe
  0 siblings, 0 replies; 12+ messages in thread
From: Jason Gunthorpe @ 2026-07-01 23:34 UTC (permalink / raw)
  To: Alistair Popple
  Cc: Matthew Brost, Dave Airlie, dri-devel, iommu, Koenig, Christian

On Wed, Jul 01, 2026 at 11:30:08AM +1000, Alistair Popple wrote:
 
> Agree with most of the above and this seems the most likely explaination. ATS
> doesn't change much here - most of our driver still goes via dma_map/unmap to
> access host memory via an IOMMU IOVA so non-present entries there would be fatal
> at the IOMMU level. So even with ATS enabled a non-present DMA mapping should
> still result in noisy IOMMU faults.

AFAIK, the iommu driver does not log ATS non-present replies, those
are considered normal events. The device itself is the only source of
reporting.

Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-07-01 23:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30  9:39 iommu/smmu/PCI ATS + TTM unmaps + nouveau best way forward Dave Airlie
2026-06-30 11:24 ` Christian König
2026-06-30 11:51   ` Jason Gunthorpe
2026-06-30 20:45     ` Dave Airlie
2026-06-30 21:00       ` Dave Airlie
2026-07-01  0:17         ` Jason Gunthorpe
2026-07-01  1:22           ` Alistair Popple
2026-06-30 23:59       ` Jason Gunthorpe
2026-06-30 11:39 ` Jason Gunthorpe
2026-06-30 23:21   ` Matthew Brost
2026-07-01  1:30     ` Alistair Popple
2026-07-01 23:34       ` Jason Gunthorpe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox