Skip to contentSkip to conversation

mm/huge_memory: Mark moved huge zero page PMD as special

PATCH Superseded Chris Down 2 participants 2 messages Feb 18

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Chris Down

author
#0 lore raw

PATCH 2/2 mm/huge_memory: Mark moved huge zero page PMD as special

Without pmd_mkspecial(), vm_normal_page_pmd() on architectures with CONFIG_ARCH_HAS_PTE_SPECIAL does not recognise the moved huge zero page as special, incorrectly treating it as a normal page and corrupting its refcount.

Fixes d82d09e48219 ("mm/huge_memory: mark PMD mappings of the huge zero folio special")
---
 mm/huge_memory.c | 1 +
 1 file changed, 1 insertion(+)
mm/huge_memory.c +1 -0
index fed57951a7cd..5f908cdb11f1 100644
@@ -2795,6 +2795,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pm
 	} else {
 		src_pmdval = pmdp_huge_clear_flush(src_vma, src_addr, src_pmd);
 		_dst_pmd = folio_mk_pmd(page_folio(src_page), dst_vma->vm_page_prot);
+		_dst_pmd = pmd_mkspecial(_dst_pmd);
 	}
 	set_pmd_at(mm, dst_addr, dst_pmd, _dst_pmd);
 
Signature · 1 line
2.51.2
#1 lore raw
Quoted 17 lines · Chris Down

Without pmd_mkspecial(), vm_normal_page_pmd() on architectures with CONFIG_ARCH_HAS_PTE_SPECIAL does not recognise the moved huge zero page as special, incorrectly treating it as a normal page and corrupting its refcount.

Fixes d82d09e48219 ("mm/huge_memory: mark PMD mappings of the huge zero folio special")
---
  mm/huge_memory.c | 1 +
  1 file changed, 1 insertion(+)
mm/huge_memory.c +0 -0
index fed57951a7cd..5f908cdb11f1 100644

mm/huge_memory.c int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pm · line 2801

Quoted 7 lines
mm/huge_memory.c +1 -0
@@ -2795,6 +2795,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pm
  	} else {
  		src_pmdval = pmdp_huge_clear_flush(src_vma, src_addr, src_pmd);
  		_dst_pmd = folio_mk_pmd(page_folio(src_page), dst_vma->vm_page_prot);
+		_dst_pmd = pmd_mkspecial(_dst_pmd);
  	}
  	set_pmd_at(mm, dst_addr, dst_pmd, _dst_pmd);
 

In theory that's correct, but we should look into just moving the PMD instead of reconstructing things. See my reply to patch #1.

Signature · 3 lines
Cheers,

David