* [PATCH v9 10/32] mm/migrate_device: avoid leaking folio references during THP splitting
[not found] <20261105183940.2236717-1-usama.arif@linux.dev>
@ 2026-11-05 18:38 ` Usama Arif
0 siblings, 0 replies; only message in thread
From: Usama Arif @ 2026-11-05 18:38 UTC (permalink / raw)
To: Andrew Morton, david, chrisl, kasong, ljs, ziy, linux-mm
Cc: chenhuacai, ying.huang, Baoquan He, willy, youngjun.park, hannes,
riel, shakeel.butt, alex, kas, baohua, dev.jain, baolin.wang,
Nico Pache, Liam R. Howlett, ryan.roberts, Vlastimil Babka,
lance.yang, linux-kernel, nphamcs, shikemeng, yosry, qi.zheng,
luizcap, kernel-team, Usama Arif, stable
migrate_vma_split_unmapped_folio() takes an extra folio reference because
split_huge_pmd_address(..., true) drops one when it splits a PMD.
However, migrate_vma only holds mmap_lock for reading. A concurrent
MADV_DONTNEED can clear the migration PMD, or split it into PTE migration
entries, before the split helper takes the PMD lock. The helper then does
nothing and leaves the extra reference behind. folio_split_unmapped()
fails with -EAGAIN due to the unexpected reference, and the reference is
never dropped.
An existing migration PMD is expanded into PTE migration entries even
with freeze=false. Use that mode and remove the extra folio_get(). The
reference already held by migration keeps the source folio alive whether
or not its PMD migration entry still exists.
Reported-by: Zi Yan <ziy@nvidia.com>
Fixes: 4265d67e405a ("mm/migrate_device: add THP splitting during migration")
Cc: stable@vger.kernel.org
Signed-off-by: Usama Arif <usama.arif@linux.dev>
---
mm/migrate_device.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 9e19fadfa65c6..3286bb8a4b73e 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -920,12 +920,7 @@ static int migrate_vma_split_unmapped_folio(struct migrate_vma *migrate,
unsigned long flags;
int ret = 0;
- /*
- * take a reference, since split_huge_pmd_address() with freeze = true
- * drops a reference at the end.
- */
- folio_get(folio);
- split_huge_pmd_address(migrate->vma, addr, true);
+ split_huge_pmd_address(migrate->vma, addr, false);
ret = folio_split_unmapped(folio, 0);
if (ret)
return ret;
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] only message in thread