mm: account pud page tables
[linux-block.git] / mm / memory.c
index 42fb30300bb51a0a79942df7df3c04271e41e03b..6bbd4078ec98962cc46c3f1f3c344a74c2ca4a0f 100644 (file)
@@ -506,6 +506,7 @@ static inline void free_pud_range(struct mmu_gather *tlb, p4d_t *p4d,
        pud = pud_offset(p4d, start);
        p4d_clear(p4d);
        pud_free_tlb(tlb, pud, start);
+       mm_dec_nr_puds(tlb->mm);
 }
 
 static inline void free_p4d_range(struct mmu_gather *tlb, pgd_t *pgd,
@@ -4149,15 +4150,17 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address)
 
        spin_lock(&mm->page_table_lock);
 #ifndef __ARCH_HAS_5LEVEL_HACK
-       if (p4d_present(*p4d))          /* Another has populated it */
-               pud_free(mm, new);
-       else
+       if (!p4d_present(*p4d)) {
+               mm_inc_nr_puds(mm);
                p4d_populate(mm, p4d, new);
-#else
-       if (pgd_present(*p4d))          /* Another has populated it */
+       } else  /* Another has populated it */
                pud_free(mm, new);
-       else
+#else
+       if (!pgd_present(*p4d)) {
+               mm_inc_nr_puds(mm);
                pgd_populate(mm, p4d, new);
+       } else  /* Another has populated it */
+               pud_free(mm, new);
 #endif /* __ARCH_HAS_5LEVEL_HACK */
        spin_unlock(&mm->page_table_lock);
        return 0;