dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP
@ 2026-08-11 14:28 Zhenhao Wan
  2026-08-11 14:28 ` [PATCH 1/2] drm/nouveau/dmem: fix mismatched DMA unmap size for large folios Zhenhao Wan
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Zhenhao Wan @ 2026-08-11 14:28 UTC (permalink / raw)
  To: Lyude Paul, Danilo Krummrich, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Andrew Morton,
	Balbir Singh
  Cc: dri-devel, nouveau, linux-kernel, Zhenhao Wan, Yuhao Jiang,
	stable

Two independent, stable-worthy fixes to the device-private THP migration
path in nouveau, both introduced by commit c32287471077 ("gpu/drm/nouveau:
enable THP support for GPU memory migration") and still present in
mainline.

Patch 1 fixes two dma_unmap_page() sites that pass a literal PAGE_SIZE
instead of the mapped page_size(). For an order > 0 folio this unmaps
less than was mapped and leaks the remainder of the IOMMU/IOVA mapping.

Patch 2 accounts for large-folio splits in the ->folio_split() hook,
which previously left chunk->callocated unchanged. A folio counted once
at allocation (+1) is later freed as N sub-folios (-N), so the unsigned
counter underflows on the first split/free cycle and the chunk leaks.

Both are confined to nouveau and orthogonal to the in-flight "Remove
device private pages from the physical address space" rework, which
touches nouveau_dmem_page_addr()/nouveau_dmem_chunk_alloc()/
nouveau_dmem_fini() rather than these teardown/accounting sites; they
apply and are needed independently.

Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com>
---
Zhenhao Wan (2):
      drm/nouveau/dmem: fix mismatched DMA unmap size for large folios
      drm/nouveau/dmem: fix callocated underflow on large folio split

 drivers/gpu/drm/nouveau/nouveau_dmem.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
---
base-commit: db2ddb87143519e20a95aa36c60b36107b736a58
change-id: 20260811-b4-nouveau-dmem-thp-fixes-e8ef1afff282

Best regards,
--  
Zhenhao Wan <whi4ed0g@gmail.com>


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

* [PATCH 1/2] drm/nouveau/dmem: fix mismatched DMA unmap size for large folios
  2026-08-11 14:28 [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Zhenhao Wan
@ 2026-08-11 14:28 ` Zhenhao Wan
  2026-08-11 14:28 ` [PATCH 2/2] drm/nouveau/dmem: fix callocated underflow on large folio split Zhenhao Wan
  2026-09-01 14:04 ` [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Danilo Krummrich
  2 siblings, 0 replies; 5+ messages in thread
From: Zhenhao Wan @ 2026-08-11 14:28 UTC (permalink / raw)
  To: Lyude Paul, Danilo Krummrich, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Andrew Morton,
	Balbir Singh
  Cc: dri-devel, nouveau, linux-kernel, Zhenhao Wan, Yuhao Jiang,
	stable

Device-private THP migration maps migration buffers with page_size()
and records that length in dma_info->size.  For a compound folio
page_size() is PAGE_SIZE << order, but two teardown sites still pass a
literal PAGE_SIZE to dma_unmap_page():

  - nouveau_dmem_migrate_to_ram() on the success path, and
  - nouveau_dmem_migrate_copy_one() on the copy-error path.

For an order > 0 folio this unmaps less than was mapped, leaking the
remainder of the IOMMU/IOVA mapping.  The other unmap sites, in
nouveau_dmem_migrate_chunk() and nouveau_dmem_evict_chunk(), already
use the saved size; use it here too.

Fixes: c32287471077 ("gpu/drm/nouveau: enable THP support for GPU memory migration")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Assisted-by: Claude:claude-opus-5
Cc: stable@vger.kernel.org
Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_dmem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index 9442ec6e1f6c..d2abee3efb9a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -267,7 +267,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
 	nouveau_fence_new(&fence, dmem->migrate.chan);
 	migrate_vma_pages(&args);
 	nouveau_dmem_fence_done(&fence);
-	dma_unmap_page(drm->dev->dev, dma_info.dma_addr, PAGE_SIZE,
+	dma_unmap_page(drm->dev->dev, dma_info.dma_addr, dma_info.size,
 				DMA_BIDIRECTIONAL);
 done:
 	migrate_vma_finalize(&args);
@@ -772,7 +772,7 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm,
 	return mpfn;
 
 out_dma_unmap:
-	dma_unmap_page(dev, dma_info->dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+	dma_unmap_page(dev, dma_info->dma_addr, dma_info->size, DMA_BIDIRECTIONAL);
 out_free_page:
 	nouveau_dmem_page_free_locked(drm, dpage);
 out:

-- 
2.34.1


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

* [PATCH 2/2] drm/nouveau/dmem: fix callocated underflow on large folio split
  2026-08-11 14:28 [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Zhenhao Wan
  2026-08-11 14:28 ` [PATCH 1/2] drm/nouveau/dmem: fix mismatched DMA unmap size for large folios Zhenhao Wan
@ 2026-08-11 14:28 ` Zhenhao Wan
  2026-08-11 21:14   ` lyude
  2026-09-01 14:04 ` [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Danilo Krummrich
  2 siblings, 1 reply; 5+ messages in thread
From: Zhenhao Wan @ 2026-08-11 14:28 UTC (permalink / raw)
  To: Lyude Paul, Danilo Krummrich, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Andrew Morton,
	Balbir Singh
  Cc: dri-devel, nouveau, linux-kernel, Zhenhao Wan, Yuhao Jiang,
	stable

nouveau_dmem_folio_free() drops chunk->callocated once per freed folio,
while a large (compound) device-private folio is only counted once when
it is allocated.  When such a folio is split, the mm core invokes
->folio_split() (nouveau_dmem_folio_split()) once for each new
sub-folio, but the hook only fixes up the sub-folio metadata and leaves
chunk->callocated unchanged.

Each resulting sub-folio is later freed separately, so after a split
the single allocation (+1) is met by N frees (-N), leaving
chunk->callocated short by N-1.  On the first split/free cycle it
underflows: WARN_ON(!chunk->callocated) fires, the unsigned counter
wraps and never returns to zero, so the chunk can no longer be
reclaimed (nouveau_dmem_fini() also warns on the leaked count).

Account for the new sub-folio in the split hook, under the same lock as
nouveau_dmem_folio_free(), so the count stays balanced.

Fixes: c32287471077 ("gpu/drm/nouveau: enable THP support for GPU memory migration")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Assisted-by: Claude:claude-opus-5
Cc: stable@vger.kernel.org
Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_dmem.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index d2abee3efb9a..ad4570c50be7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -279,11 +279,25 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
 
 static void nouveau_dmem_folio_split(struct folio *head, struct folio *tail)
 {
+	struct nouveau_dmem_chunk *chunk;
+	struct nouveau_dmem *dmem;
+
 	if (tail == NULL)
 		return;
 	tail->pgmap = head->pgmap;
 	tail->mapping = head->mapping;
 	folio_set_zone_device_data(tail, folio_zone_device_data(head));
+
+	/*
+	 * The split hands out a new independently-freeable folio that will
+	 * later be released via nouveau_dmem_folio_free(); account for it so
+	 * chunk->callocated stays balanced.
+	 */
+	chunk = nouveau_page_to_chunk(&head->page);
+	dmem = chunk->drm->dmem;
+	spin_lock(&dmem->lock);
+	chunk->callocated++;
+	spin_unlock(&dmem->lock);
 }
 
 static const struct dev_pagemap_ops nouveau_dmem_pagemap_ops = {

-- 
2.34.1


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

* Re: [PATCH 2/2] drm/nouveau/dmem: fix callocated underflow on large folio split
  2026-08-11 14:28 ` [PATCH 2/2] drm/nouveau/dmem: fix callocated underflow on large folio split Zhenhao Wan
@ 2026-08-11 21:14   ` lyude
  0 siblings, 0 replies; 5+ messages in thread
From: lyude @ 2026-08-11 21:14 UTC (permalink / raw)
  To: Zhenhao Wan, Danilo Krummrich, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Andrew Morton,
	Balbir Singh
  Cc: dri-devel, nouveau, linux-kernel, Yuhao Jiang, stable

This patch looks suspiciously human written (or at the very least, the
commit message sure does). FWIW: if the code wasn't itself generated by
an LLM, it's fine by me to avoid adding the tag. Most of us are
concerned about generated LLM code that gets submitted, not human
written code written to fix a legitimate issue that an LLM managed to
help find. If we were concerned about the latter, I think anything
sashiko touched would end up having an assisted-by tag on it :).

Either way, this whole patch series is:

Reviewed-by: Lyude Paul <lyude@redhat.com>

Issue looks quite legitimate, fix seems fine to me.

On Tue, 2026-08-11 at 22:28 +0800, Zhenhao Wan wrote:
> nouveau_dmem_folio_free() drops chunk->callocated once per freed
> folio,
> while a large (compound) device-private folio is only counted once
> when
> it is allocated.  When such a folio is split, the mm core invokes
> ->folio_split() (nouveau_dmem_folio_split()) once for each new
> sub-folio, but the hook only fixes up the sub-folio metadata and
> leaves
> chunk->callocated unchanged.
> 
> Each resulting sub-folio is later freed separately, so after a split
> the single allocation (+1) is met by N frees (-N), leaving
> chunk->callocated short by N-1.  On the first split/free cycle it
> underflows: WARN_ON(!chunk->callocated) fires, the unsigned counter
> wraps and never returns to zero, so the chunk can no longer be
> reclaimed (nouveau_dmem_fini() also warns on the leaked count).
> 
> Account for the new sub-folio in the split hook, under the same lock
> as
> nouveau_dmem_folio_free(), so the count stays balanced.
> 
> Fixes: c32287471077 ("gpu/drm/nouveau: enable THP support for GPU
> memory migration")
> Reported-by: Yuhao Jiang <danisjiang@gmail.com>
> Assisted-by: Claude:claude-opus-5
> Cc: stable@vger.kernel.org
> Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com>
> ---
>  drivers/gpu/drm/nouveau/nouveau_dmem.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c
> b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> index d2abee3efb9a..ad4570c50be7 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
> @@ -279,11 +279,25 @@ static vm_fault_t
> nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
>  
>  static void nouveau_dmem_folio_split(struct folio *head, struct
> folio *tail)
>  {
> +	struct nouveau_dmem_chunk *chunk;
> +	struct nouveau_dmem *dmem;
> +
>  	if (tail == NULL)
>  		return;
>  	tail->pgmap = head->pgmap;
>  	tail->mapping = head->mapping;
>  	folio_set_zone_device_data(tail,
> folio_zone_device_data(head));
> +
> +	/*
> +	 * The split hands out a new independently-freeable folio
> that will
> +	 * later be released via nouveau_dmem_folio_free(); account
> for it so
> +	 * chunk->callocated stays balanced.
> +	 */
> +	chunk = nouveau_page_to_chunk(&head->page);
> +	dmem = chunk->drm->dmem;
> +	spin_lock(&dmem->lock);
> +	chunk->callocated++;
> +	spin_unlock(&dmem->lock);
>  }
>  
>  static const struct dev_pagemap_ops nouveau_dmem_pagemap_ops = {


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

* Re: [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP
  2026-08-11 14:28 [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Zhenhao Wan
  2026-08-11 14:28 ` [PATCH 1/2] drm/nouveau/dmem: fix mismatched DMA unmap size for large folios Zhenhao Wan
  2026-08-11 14:28 ` [PATCH 2/2] drm/nouveau/dmem: fix callocated underflow on large folio split Zhenhao Wan
@ 2026-09-01 14:04 ` Danilo Krummrich
  2 siblings, 0 replies; 5+ messages in thread
From: Danilo Krummrich @ 2026-09-01 14:04 UTC (permalink / raw)
  To: Zhenhao Wan
  Cc: Lyude Paul, Danilo Krummrich, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Andrew Morton,
	Balbir Singh, dri-devel, nouveau, linux-kernel, Yuhao Jiang,
	stable

On Tue, 11 Aug 2026 22:28:49 +0800, Zhenhao Wan wrote:
> [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP

Applied, thanks!

  Branch: drm-misc-fixes
  Tree:   https://gitlab.freedesktop.org/drm/misc/kernel.git

[1/2] drm/nouveau/dmem: fix mismatched DMA unmap size for large folios
      commit: caa1bc2a0a6c
[2/2] drm/nouveau/dmem: fix callocated underflow on large folio split
      commit: c2256c044a1d

The patches will appear in the next linux-next integration (typically within 24
hours on weekdays).

The patches are queued up for Linus's tree and should land in the next -rc
release.

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

end of thread, other threads:[~2026-09-01 14:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 14:28 [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Zhenhao Wan
2026-08-11 14:28 ` [PATCH 1/2] drm/nouveau/dmem: fix mismatched DMA unmap size for large folios Zhenhao Wan
2026-08-11 14:28 ` [PATCH 2/2] drm/nouveau/dmem: fix callocated underflow on large folio split Zhenhao Wan
2026-08-11 21:14   ` lyude
2026-09-01 14:04 ` [PATCH 0/2] drm/nouveau/dmem: fix DMA unmap size and callocated accounting for THP Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).