Only a huge zero PMD in an anonymous VMA is split, into a page table of shared zero page mappings. Any other huge zero PMD is simply unmapped. vm_normal_folio_pmd() returns NULL for a huge zero PMD, and the split path unmaps any entry which has no folio. So make the decision before the folio is looked up, in huge_zero_pmd_can_split(). No functional change intended. Signed-off-by: Yin Tirui --- mm/huge_memory.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index b643e264ca23..dbcacc7b1374 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3184,6 +3184,15 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, pmd_populate(mm, pmd, pgtable); } +/* + * Only a huge zero PMD in an anonymous VMA is split, into a page table of + * shared zero page mappings. Any other huge zero PMD is simply unmapped. + */ +static bool huge_zero_pmd_can_split(struct vm_area_struct *vma, pmd_t pmdval) +{ + return is_huge_zero_pmd(pmdval) && vma_is_anonymous(vma); +} + static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, unsigned long haddr, bool freeze) { @@ -3208,6 +3217,20 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, count_vm_event(THP_SPLIT_PMD); + /* + * FIXME: Do we want to invalidate secondary mmu by calling + * mmu_notifier_arch_invalidate_secondary_tlbs() see comments below + * inside __split_huge_pmd() ? + * + * We are going from a zero huge page write protected to zero small + * page also write protected so it does not seems useful to invalidate + * secondary mmu at this time. + */ + if (huge_zero_pmd_can_split(vma, old_pmd)) { + __split_huge_zero_page_pmd(vma, haddr, pmd); + return; + } + if (!vma_is_anonymous(vma)) { old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); /* @@ -3240,19 +3263,6 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, return; } - 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 - * inside __split_huge_pmd() ? - * - * We are going from a zero huge page write protected to zero - * small page also write protected so it does not seems useful - * to invalidate secondary mmu at this time. - */ - return __split_huge_zero_page_pmd(vma, haddr, pmd); - } - if (pmd_is_migration_entry(old_pmd)) { softleaf_t entry; -- 2.34.1