[PATCH RFC 1/9] mm/huge_memory: read the huge PMD entry once when splitting it
From: Yin Tirui
Date: Fri Aug 28 2026 - 14:40:24 EST
__split_huge_pmd_locked() re-reads *pmd several times to classify the same
entry. The PMD page table lock is held throughout, so read it once into
old_pmd and classify from that.
No functional change intended.
Signed-off-by: Yin Tirui <yintirui@xxxxxxxxx>
---
mm/huge_memory.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index afbb5974bd22..8feabdcf6307 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3143,10 +3143,11 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long haddr, bool freeze)
{
struct mm_struct *mm = vma->vm_mm;
+ pmd_t old_pmd = *pmd;
struct folio *folio;
struct page *page;
pgtable_t pgtable;
- pmd_t old_pmd, _pmd;
+ pmd_t _pmd;
bool soft_dirty, uffd_wp = false, young = false, write = false;
bool anon_exclusive = false, dirty = false;
unsigned long addr;
@@ -3157,7 +3158,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PMD_SIZE, vma);
- VM_WARN_ON_ONCE(!pmd_is_valid_softleaf(*pmd) && !pmd_trans_huge(*pmd));
+ VM_WARN_ON_ONCE(!pmd_is_valid_softleaf(old_pmd) &&
+ !pmd_trans_huge(old_pmd));
count_vm_event(THP_SPLIT_PMD);
@@ -3193,7 +3195,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
return;
}
- if (is_huge_zero_pmd(*pmd)) {
+ if (is_huge_zero_pmd(old_pmd)) {
/*
* FIXME: Do we want to invalidate secondary mmu by calling
* mmu_notifier_arch_invalidate_secondary_tlbs() see comments below
@@ -3206,10 +3208,9 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
return __split_huge_zero_page_pmd(vma, haddr, pmd);
}
- if (pmd_is_migration_entry(*pmd)) {
+ if (pmd_is_migration_entry(old_pmd)) {
softleaf_t entry;
- old_pmd = *pmd;
entry = softleaf_from_pmd(old_pmd);
page = softleaf_to_page(entry);
folio = page_folio(page);
@@ -3222,10 +3223,9 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
anon_exclusive = softleaf_is_migration_read_exclusive(entry);
young = softleaf_is_migration_young(entry);
dirty = softleaf_is_migration_dirty(entry);
- } else if (pmd_is_device_private_entry(*pmd)) {
+ } else if (pmd_is_device_private_entry(old_pmd)) {
softleaf_t entry;
- old_pmd = *pmd;
entry = softleaf_from_pmd(old_pmd);
page = softleaf_to_page(entry);
folio = page_folio(page);
@@ -3417,7 +3417,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
}
pte_unmap(pte);
- if (!pmd_is_migration_entry(*pmd))
+ if (!pmd_is_migration_entry(old_pmd))
folio_remove_rmap_pmd(folio, page, vma);
if (freeze)
put_page(page);
--
2.34.1