* 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 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 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 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 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: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 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