Skip to contentSkip to conversation

mm: handle device-private PMDs in walk callbacks

PATCH Superseded Usama Arif 5 participants 21 messages Jul 7 – Jul 8

Subsystems (4)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Usama Arif

author reviewer
#0 lore raw

cover mm: handle device-private PMDs in walk callbacks

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)
Signature · 1 line
2.53.0-Meta
author reviewer
#1 lore raw

PATCH 1/3 mm/mempolicy: skip device-private PMDs when queueing folios

queue_folios_pmd() is called under pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for any non-present, non-none huge PMD - including a device-private swap entry. Passing such a PMD to pmd_folio() extracts garbage bits as a PFN and returns a bogus folio pointer.

Potential trigger: an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages(), leaving a device-private PMD. Userspace then calls mbind(), migrate_pages() or set_mempolicy_home_node() on that range.

Skip device-private PMDs, matching how queue_folios_pte_range() skips device-private PTE entries by checking !pte_present().

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/mempolicy.c | 2 ++
 1 file changed, 2 insertions(+)
mm/mempolicy.c +2 -0
index 914f81863db5..eda817539c77 100644
@@ -659,6 +659,8 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
 		qp->nr_failed++;
 		return;
 	}
+	if (unlikely(pmd_is_device_private_entry(*pmd)))
+		return;
 	folio = pmd_folio(*pmd);
 	if (is_huge_zero_folio(folio)) {
 		walk->action = ACTION_CONTINUE;
Signature · 1 line
2.53.0-Meta
reviewer
#2 lore raw

Re: [PATCH 1/3] mm/mempolicy: skip device-private PMDs when queueing folios

Quoted 27 lines · Usama Arif

queue_folios_pmd() is called under pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for any non-present, non-none huge PMD - including a device-private swap entry. Passing such a PMD to pmd_folio() extracts garbage bits as a PFN and returns a bogus folio pointer.

Potential trigger: an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages(), leaving a device-private PMD. Userspace then calls mbind(), migrate_pages() or set_mempolicy_home_node() on that range.

Skip device-private PMDs, matching how queue_folios_pte_range() skips device-private PTE entries by checking !pte_present().

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/mempolicy.c | 2 ++
 1 file changed, 2 insertions(+)
mm/mempolicy.c +0 -0
index 914f81863db5..eda817539c77 100644

mm/mempolicy.c static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk) · line 663

Quoted 5 lines
mm/mempolicy.c +2 -0
@@ -659,6 +659,8 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
 		qp->nr_failed++;
 		return;
 	}
+	if (unlikely(pmd_is_device_private_entry(*pmd)))
+		return;

Should it also increase qp->nr_failed like pmd migration entry above? It also applies to your "if (unlikely(pmd_is_swap_entry(*pmd)))" in the PMD-level swap patchset.

In addition, since pmd_is_huge() returns true for all non-present non-none pmds, other softleaf entries should also be excluded here? Oh, because there is no PMD level hwpoison or pmd marker.

Signature · 2 lines
Best Regards,
Yan, Zi
author reviewer
#3 lore raw

Re: [PATCH 1/3] mm/mempolicy: skip device-private PMDs when queueing folios

Quoted 23 lines · Zi Yan
Quoted 22 lines · Usama Arif

queue_folios_pmd() is called under pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for any non-present, non-none huge PMD - including a device-private swap entry. Passing such a PMD to pmd_folio() extracts garbage bits as a PFN and returns a bogus folio pointer.

Potential trigger: an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages(), leaving a device-private PMD. Userspace then calls mbind(), migrate_pages() or set_mempolicy_home_node() on that range.

Skip device-private PMDs, matching how queue_folios_pte_range() skips device-private PTE entries by checking !pte_present().

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/mempolicy.c | 2 ++
 1 file changed, 2 insertions(+)
Quoted 14 lines

mm/mempolicy.c static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk) · line 663

Quoted 10 lines
mm/mempolicy.c +2 -0
index 914f81863db5..eda817539c77 100644
@@ -659,6 +659,8 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
 		qp->nr_failed++;
 		return;
 	}
+	if (unlikely(pmd_is_device_private_entry(*pmd)))
+		return;

Should it also increase qp->nr_failed like pmd migration entry above? It also applies to your "if (unlikely(pmd_is_swap_entry(*pmd)))" in the PMD-level swap patchset.

The PTE path only increments nr_failed for migration entries, other non-present entries, including device-private and swap, are skipped. I kept things aligned with the PTE path.

Quoted 4 lines

In addition, since pmd_is_huge() returns true for all non-present non-none pmds, other softleaf entries should also be excluded here? Oh, because there is no PMD level hwpoison or pmd marker.

I think what Joshua recommended in [1] makes sense, I will change the PMD code to gate on !pmd_present() instead. That keeps migration entry accounting, skips device-private now, and will also avoid calling pmd_folio() on any future non-present PMD softleaf such as PMD swap.

[1] https://lore.kernel.org/all/[email protected]/

reviewer
#4 lore raw

Re: [PATCH 1/3] mm/mempolicy: skip device-private PMDs when queueing folios

Quoted 48 lines · Usama Arif
Quoted 23 lines · Zi Yan
Quoted 22 lines · Usama Arif

queue_folios_pmd() is called under pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for any non-present, non-none huge PMD - including a device-private swap entry. Passing such a PMD to pmd_folio() extracts garbage bits as a PFN and returns a bogus folio pointer.

Potential trigger: an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages(), leaving a device-private PMD. Userspace then calls mbind(), migrate_pages() or set_mempolicy_home_node() on that range.

Skip device-private PMDs, matching how queue_folios_pte_range() skips device-private PTE entries by checking !pte_present().

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/mempolicy.c | 2 ++
 1 file changed, 2 insertions(+)
Quoted 14 lines

mm/mempolicy.c static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk) · line 663

Quoted 10 lines
mm/mempolicy.c +2 -0
index 914f81863db5..eda817539c77 100644
@@ -659,6 +659,8 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
 		qp->nr_failed++;
 		return;
 	}
+	if (unlikely(pmd_is_device_private_entry(*pmd)))
+		return;

Should it also increase qp->nr_failed like pmd migration entry above? It also applies to your "if (unlikely(pmd_is_swap_entry(*pmd)))" in the PMD-level swap patchset.

The PTE path only increments nr_failed for migration entries, other non-present entries, including device-private and swap, are skipped. I kept things aligned with the PTE path.

Quoted 4 lines

In addition, since pmd_is_huge() returns true for all non-present non-none pmds, other softleaf entries should also be excluded here? Oh, because there is no PMD level hwpoison or pmd marker.

Quoted 6 lines

I think what Joshua recommended in [1] makes sense, I will change the PMD code to gate on !pmd_present() instead. That keeps migration entry accounting, skips device-private now, and will also avoid calling pmd_folio() on any future non-present PMD softleaf such as PMD swap.

[1] https://lore.kernel.org/all/[email protected]/

Makes sense. Thank you for the explanation.

Best Regards,
Yan, Zi

#5 lore raw

Re: [PATCH 1/3] mm/mempolicy: skip device-private PMDs when queueing folios

In reply to Usama Arif
Quoted 27 lines · Usama Arif

queue_folios_pmd() is called under pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for any non-present, non-none huge PMD - including a device-private swap entry. Passing such a PMD to pmd_folio() extracts garbage bits as a PFN and returns a bogus folio pointer.

Potential trigger: an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages(), leaving a device-private PMD. Userspace then calls mbind(), migrate_pages() or set_mempolicy_home_node() on that range.

Skip device-private PMDs, matching how queue_folios_pte_range() skips device-private PTE entries by checking !pte_present().

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/mempolicy.c | 2 ++
 1 file changed, 2 insertions(+)
mm/mempolicy.c +0 -0
index 914f81863db5..eda817539c77 100644

mm/mempolicy.c static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk) · line 663

Quoted 5 lines
mm/mempolicy.c +2 -0
@@ -659,6 +659,8 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
 		qp->nr_failed++;
 		return;
 	}
+	if (unlikely(pmd_is_device_private_entry(*pmd)))
+		return;

The changelog lead me to believe that this is skipped via !pmd_present()? Do we need to skip just device private entries Shouldn't we set qp->nr_failed++ similar to what we do for migration entries or do we silently ignore them?

mm/mempolicy.c static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk) · line 666

Quoted 4 lines
mm/mempolicy.c +0 -0
 	folio = pmd_folio(*pmd);
 	if (is_huge_zero_folio(folio)) {
 		walk->action = ACTION_CONTINUE;

Thanks,
Balbir

author reviewer
#6 lore raw

PATCH 2/3 mm/madvise: skip device-private PMDs in cold and pageout walks

In reply to Usama Arif

madvise_cold_or_pageout_pte_range() takes pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for a device-private PMD. The subsequent !pmd_present() branch has a VM_BUG_ON() asserting migration is the only allowed non-present case; a device-private PMD trips it.

Potential trigger: an HMM-based GPU driver races with madvise(MADV_COLD)/MADV_PAGEOUT: pmd_trans_huge(*pmd) reads true, then migrate_vma_pages() flips the PMD to a device-private entry before the PMD lock is acquired.

Skip device-private PMDs after taking the lock, before the !pmd_present() check.

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/madvise.c | 3 +++
 1 file changed, 3 insertions(+)
mm/madvise.c +3 -0
index 9292f60b19aa..870be398c6f3 100644
@@ -384,6 +384,9 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
 			return 0;
 
 		orig_pmd = *pmd;
+		if (pmd_is_device_private_entry(orig_pmd))
+			goto huge_unlock;
+
 		if (is_huge_zero_pmd(orig_pmd))
 			goto huge_unlock;
 
Signature · 1 line
2.53.0-Meta
reviewer Reviewed-by on v1 2/3
#7 lore raw

Re: [PATCH 2/3] mm/madvise: skip device-private PMDs in cold and pageout walks

Quoted 13 lines · Usama Arif

madvise_cold_or_pageout_pte_range() takes pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for a device-private PMD. The subsequent !pmd_present() branch has a VM_BUG_ON() asserting migration is the only allowed non-present case; a device-private PMD trips it.

Potential trigger: an HMM-based GPU driver races with madvise(MADV_COLD)/MADV_PAGEOUT: pmd_trans_huge(*pmd) reads true, then migrate_vma_pages() flips the PMD to a device-private entry before the PMD lock is acquired.

Skip device-private PMDs after taking the lock, before the !pmd_present() check.

Quoted 8 lines
Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/madvise.c | 3 +++
 1 file changed, 3 insertions(+)

LGTM.

Since it could trigger VM_BUG_ON(), probably cc stable?

Signature · 2 lines
Best Regards,
Yan, Zi
Reviewed-by on v1 2/3
#8 lore raw

Re: [PATCH 2/3] mm/madvise: skip device-private PMDs in cold and pageout walks

In reply to Usama Arif
Quoted 27 lines · Usama Arif

madvise_cold_or_pageout_pte_range() takes pmd_trans_huge_lock(), whose pmd_is_huge() check returns true for a device-private PMD. The subsequent !pmd_present() branch has a VM_BUG_ON() asserting migration is the only allowed non-present case; a device-private PMD trips it.

Potential trigger: an HMM-based GPU driver races with madvise(MADV_COLD)/MADV_PAGEOUT: pmd_trans_huge(*pmd) reads true, then migrate_vma_pages() flips the PMD to a device-private entry before the PMD lock is acquired.

Skip device-private PMDs after taking the lock, before the !pmd_present() check.

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/madvise.c | 3 +++
 1 file changed, 3 insertions(+)
mm/madvise.c +0 -0
index 9292f60b19aa..870be398c6f3 100644

mm/madvise.c static int madvise_cold_or_pageout_pte_range(pmd_t *pmd, · line 392

Quoted 9 lines
mm/madvise.c +3 -0
@@ -384,6 +384,9 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
 			return 0;
 
 		orig_pmd = *pmd;
+		if (pmd_is_device_private_entry(orig_pmd))
+			goto huge_unlock;
+
 		if (is_huge_zero_pmd(orig_pmd))
 			goto huge_unlock;
 
author reviewer
#9 lore raw

PATCH 3/3 mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

In reply to Usama Arif

madvise_free_pte_range() checks pmd_trans_huge(*pmd) unlocked, then madvise_free_huge_pmd() takes pmd_trans_huge_lock(). pmd_is_huge() returns true for a device-private PMD, so orig_pmd can be device-private and hit the VM_BUG_ON() on the !pmd_present() branch.

Potential trigger: an HMM-based GPU driver races with madvise(MADV_FREE):
migrate_vma_pages() flips the PMD to a device-private entry between the caller's pmd_trans_huge() check and the callee's pmd_trans_huge_lock().

Skip device-private PMDs after taking the lock, before the !pmd_present() check.

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/huge_memory.c | 3 +++
 1 file changed, 3 insertions(+)
mm/huge_memory.c +3 -0
index c0892cc533a9..cfce9f31b30e 100644
@@ -2296,6 +2296,9 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	if (is_huge_zero_pmd(orig_pmd))
 		goto out;
 
+	if (pmd_is_device_private_entry(orig_pmd))
+		goto out;
+
 	if (unlikely(!pmd_present(orig_pmd))) {
 		VM_BUG_ON(thp_migration_supported() &&
 				  !pmd_is_migration_entry(orig_pmd));
Signature · 1 line
2.53.0-Meta
reviewer Reviewed-by on v1 3/3
#10 lore raw

Re: [PATCH 3/3] mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

Quoted 9 lines · Usama Arif

madvise_free_pte_range() checks pmd_trans_huge(*pmd) unlocked, then madvise_free_huge_pmd() takes pmd_trans_huge_lock(). pmd_is_huge() returns true for a device-private PMD, so orig_pmd can be device-private and hit the VM_BUG_ON() on the !pmd_present() branch.

Potential trigger: an HMM-based GPU driver races with madvise(MADV_FREE):
migrate_vma_pages() flips the PMD to a device-private entry between the caller's pmd_trans_huge() check and the callee's pmd_trans_huge_lock().

Quoted 9 lines

Skip device-private PMDs after taking the lock, before the !pmd_present() check.

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/huge_memory.c | 3 +++
 1 file changed, 3 insertions(+)

LGTM. cc stable as well.

Signature · 2 lines
Best Regards,
Yan, Zi
Reviewed-by on v1 3/3
#11 lore raw

Re: [PATCH 3/3] mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

In reply to Usama Arif
Quoted 24 lines · Usama Arif

madvise_free_pte_range() checks pmd_trans_huge(*pmd) unlocked, then madvise_free_huge_pmd() takes pmd_trans_huge_lock(). pmd_is_huge() returns true for a device-private PMD, so orig_pmd can be device-private and hit the VM_BUG_ON() on the !pmd_present() branch.

Potential trigger: an HMM-based GPU driver races with madvise(MADV_FREE):
migrate_vma_pages() flips the PMD to a device-private entry between the caller's pmd_trans_huge() check and the callee's pmd_trans_huge_lock().

Skip device-private PMDs after taking the lock, before the !pmd_present() check.

Fixes 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
---
 mm/huge_memory.c | 3 +++
 1 file changed, 3 insertions(+)
mm/huge_memory.c +0 -0
index c0892cc533a9..cfce9f31b30e 100644

mm/huge_memory.c bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, · line 2304

Quoted 9 lines
mm/huge_memory.c +3 -0
@@ -2296,6 +2296,9 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	if (is_huge_zero_pmd(orig_pmd))
 		goto out;
 
+	if (pmd_is_device_private_entry(orig_pmd))
+		goto out;
+
 	if (unlikely(!pmd_present(orig_pmd))) {
 		VM_BUG_ON(thp_migration_supported() &&
 				  !pmd_is_migration_entry(orig_pmd));

The change makes sense, I spent some time thinking if we should make madvise pmd free work for THP PMD entries, but that should be a separate patchset, it is much more complex and involved.

maintainer
#12 lore raw
In reply to Usama Arif

+cc Balbir

Thanks for the series!

I think Balbir should be cc'd no?

Quoted 12 lines · Usama Arif

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Yeah I don't love these 'existing problem' reports (distracting from other work, add workload, really it feels like that should be a passive reporting mode for sashiko not arbitrarily added to other series), but sending it as a separate series is indeed the right way :)

These of course should never block an unrelated series.

Quoted 2 lines

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Hmm we've had a whole host of issues with device-private PMDs recently.

Balbir - would it be possible to audit all of the code paths and proactively see if there's anything else that could hit problems here?

Quoted 6 lines

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

Quoted 8 lines
 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)

--
2.53.0-Meta

Cheers, Lorenzo

author reviewer
#13 lore raw
Quoted 6 lines · Lorenzo Stoakes

+cc Balbir

Thanks for the series!

I think Balbir should be cc'd no?

Ah yes, sorry about that! I just sent the patches to the list I got from get_maintainers.pl.

I think maybe we should modify get_maintainers.pl so that if there is a "Fixes" in commit message, than the author of that commit is also in the output from that script?

Quoted 17 lines · Usama Arif
Quoted 12 lines

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Quoted 7 lines

Yeah I don't love these 'existing problem' reports (distracting from other work, add workload, really it feels like that should be a passive reporting mode for sashiko not arbitrarily added to other series), but sending it as a separate series is indeed the right way :)

These of course should never block an unrelated series.

Yes agreed!

Quoted 24 lines
Quoted 2 lines

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Hmm we've had a whole host of issues with device-private PMDs recently.

Balbir - would it be possible to audit all of the code paths and proactively see if there's anything else that could hit problems here?

Quoted 6 lines

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

Quoted 8 lines
 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)

--
2.53.0-Meta

Cheers, Lorenzo

maintainer
#14 lore raw
Quoted 4 lines · Usama Arif

I think maybe we should modify get_maintainers.pl so that if there is a "Fixes" in commit message, than the author of that commit is also in the output from that script?

I thought it did that already, but it's forbidden perl magic that I dare not look at so who knows :P

Wasn't nagging per se about that (for once :P), often people who'd be good to cc- get missed anyway even doing all the right things, so just wanted to make sure Balbir was aware, also so we can make sure there's no other device private PMD stuff lurking! :)

Cheers, Lorenzo

#15 lore raw
Quoted 6 lines · Lorenzo Stoakes
Quoted 4 lines · Usama Arif

I think maybe we should modify get_maintainers.pl so that if there is a "Fixes" in commit message, than the author of that commit is also in the output from that script?

Quoted 8 lines

I thought it did that already, but it's forbidden perl magic that I dare not look at so who knows :P

Wasn't nagging per se about that (for once :P), often people who'd be good to cc- get missed anyway even doing all the right things, so just wanted to make sure Balbir was aware, also so we can make sure there's no other device private PMD stuff lurking! :)

Yes, thanks for brining it to my attention! I have started looking at the set of changes again to see if

1. I can improve test coverage (mempolicy tests for example) and madvise
2. If there is lurking code that has not been tested at my end or covered.

It's a slow burn, but I do appreciate a Cc, I skim through linux-mm, but the volume may make me miss topics of interest due to TZ and other factors depending on when I check email.

Quoted 1 line

Cheers, Lorenzo

Cheers, Balbir

reviewer
#16 lore raw
In reply to Lorenzo Stoakes

+Alistair as well.

Quoted 49 lines · Lorenzo Stoakes

+cc Balbir

Thanks for the series!

I think Balbir should be cc'd no?

Quoted 12 lines · Usama Arif

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Yeah I don't love these 'existing problem' reports (distracting from other work, add workload, really it feels like that should be a passive reporting mode for sashiko not arbitrarily added to other series), but sending it as a separate series is indeed the right way :)

These of course should never block an unrelated series.

Quoted 2 lines

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Hmm we've had a whole host of issues with device-private PMDs recently.

Balbir - would it be possible to audit all of the code paths and proactively see if there's anything else that could hit problems here?

Quoted 11 lines

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)
Quoted 5 lines
Quoted 3 lines

--
2.53.0-Meta

Cheers, Lorenzo

Best Regards,
Yan, Zi

#17 lore raw
In reply to Lorenzo Stoakes
Quoted 6 lines · Lorenzo Stoakes

+cc Balbir

Thanks for the series!

I think Balbir should be cc'd no?

Thanks, my linux-mm monitoring has been largely skimming through the list. Explict cc's are always appreciated.

Quoted 25 lines · Usama Arif
Quoted 12 lines

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Yeah I don't love these 'existing problem' reports (distracting from other work, add workload, really it feels like that should be a passive reporting mode for sashiko not arbitrarily added to other series), but sending it as a separate series is indeed the right way :)

These of course should never block an unrelated series.

Quoted 1 line
Quoted 7 lines
Quoted 1 line

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Hmm we've had a whole host of issues with device-private PMDs recently.

Balbir - would it be possible to audit all of the code paths and proactively see if there's anything else that could hit problems here?

Let me run through this and audit them. My usage of device private PMD did not expose them, but I can see a bunch of reports in the link above

Quoted 6 lines
Quoted 6 lines

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

Quoted 9 lines
Quoted 8 lines
 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)

--
2.53.0-Meta

Thanks Lorenzo!

Balbir

maintainer
#18 lore raw
Quoted 10 lines · Balbir Singh
Quoted 6 lines · Lorenzo Stoakes

+cc Balbir

Thanks for the series!

I think Balbir should be cc'd no?

Thanks, my linux-mm monitoring has been largely skimming through the list. Explict cc's are always appreciated.

Honestly I don't know how you do it, I gave up on linux-mm a long time ago and pretty much rely on cc- now (which isn't always perfect ofc... :)

Quoted 28 lines
Quoted 28 lines · Usama Arif
Quoted 12 lines

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Yeah I don't love these 'existing problem' reports (distracting from other work, add workload, really it feels like that should be a passive reporting mode for sashiko not arbitrarily added to other series), but sending it as a separate series is indeed the right way :)

These of course should never block an unrelated series.

Quoted 2 lines

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Quoted 8 lines
Quoted 5 lines

Hmm we've had a whole host of issues with device-private PMDs recently.

Balbir - would it be possible to audit all of the code paths and proactively see if there's anything else that could hit problems here?

Let me run through this and audit them. My usage of device private PMD did not expose them, but I can see a bunch of reports in the link above

Great thanks :)

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)
Quoted 6 lines
Quoted 4 lines
Quoted 3 lines

--
2.53.0-Meta

Thanks Lorenzo!

You're welcome! :)

Quoted 2 lines

Balbir

Cheers, Lorenzo

reviewer Reviewed-by on the v1 series
#19 lore raw
In reply to Usama Arif
Quoted 12 lines · On Tue, 7 Jul 2026 06:45:06 -0700 Usama Arif <[email protected]> wrote:

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Hello Usama,

Thank you for the fixes! I think all of them look good and they are fixes so please feel free to add my

One thing I wanted to maybe consider is for 1/3, whether it could be good to gate by !pmd_present() like the sites in 2/3 and 3/3, maybe that will be more robust in the future if there are other cases we should protect against (and the same as queue_folios_pte_range, which uses the !pte_present() check too).

For 2/3 and 3/3 we already have the !pmd_present() check, would it be worth considering just changing the VM_BUG_ON condition to include !pmd_is_device_private_entry()?

Just wanted to toss my 2c. Thanks again for the fixes Usama! Joshua

Quoted 14 lines

[1] https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=6

Usama Arif (3):
mm/mempolicy: skip device-private PMDs when queueing folios mm/madvise: skip device-private PMDs in cold and pageout walks mm/huge_memory: skip device-private PMDs in madvise_free_huge_pmd

 mm/huge_memory.c | 3 +++
 mm/madvise.c     | 3 +++
 mm/mempolicy.c   | 2 ++
 3 files changed, 8 insertions(+)
Signature · 1 line
2.53.0-Meta
author reviewer
#20 lore raw
Quoted 31 lines · Joshua Hahn
Quoted 12 lines · On Tue, 7 Jul 2026 06:45:06 -0700 Usama Arif <[email protected]> wrote:

Since commit 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") a PMD may hold a device-private swap entry whenever an HMM-based GPU driver migrates an anonymous THP folio to device memory via migrate_vma_pages().

pmd_trans_huge_lock() succeeds for such PMDs (pmd_is_huge() returns true for any non-present, non-none huge PMD), so several MM walk callbacks that used to assume present THP or migration entry are now reachable with a device-private PMD. The results range from a VM_BUG_ON() firing on debug kernels, to an oops on a bogus vmemmap dereference, to silently isolating an unrelated live folio from LRU in the aliasing case.

Quoted 3 lines

The first 2 fixes were reported as pre-existing issues by sashiko in my PMD swap entry series [1]. Hopefully sashiko won't point these out in the next PMD swap entry series :)

Hello Usama,

Thank you for the fixes! I think all of them look good and they are fixes so please feel free to add my

One thing I wanted to maybe consider is for 1/3, whether it could be good to gate by !pmd_present() like the sites in 2/3 and 3/3, maybe that will be more robust in the future if there are other cases we should protect against (and the same as queue_folios_pte_range, which uses the !pte_present() check too).

Quoted 7 lines

For 2/3 and 3/3 we already have the !pmd_present() check, would it be worth considering just changing the VM_BUG_ON condition to include !pmd_is_device_private_entry()?

Just wanted to toss my 2c. Thanks again for the fixes Usama! Joshua

Thanks for the reviews Joshua, I think they all made sense. I have sent v2 [1] following your suggestions.

[1] https://lore.kernel.org/all/[email protected]/