@@ -73,6 +73,7 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pgtable)
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
+ pagetable_pgd_dtor(virt_to_ptdesc(pgd));
pagetable_free(virt_to_ptdesc(pgd));
}
@@ -84,6 +85,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
if (!ptdesc)
return NULL;
+ pagetable_pgd_ctor(ptdesc);
new_pgd = ptdesc_address(ptdesc);
memcpy(new_pgd, swapper_pg_dir, PTRS_PER_PGD * sizeof(pgd_t));
@@ -169,6 +169,9 @@ void *get_pointer_table(int type)
case TABLE_PMD:
pagetable_pmd_ctor(virt_to_ptdesc(page));
break;
+ case TABLE_PGD:
+ pagetable_pgd_ctor(virt_to_ptdesc(page));
+ break;
}
mmu_page_ctor(page);
@@ -215,6 +218,9 @@ int free_pointer_table(void *table, int type)
case TABLE_PMD:
pagetable_pmd_dtor(virt_to_ptdesc((void *)page));
break;
+ case TABLE_PGD:
+ pagetable_pgd_dtor(virt_to_ptdesc((void *)page));
+ break;
}
free_page (page);
@@ -126,11 +126,17 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
- return (pgd_t *) crst_table_alloc(mm);
+ unsigned long *table = crst_table_alloc(mm);
+
+ if (!table)
+ return NULL;
+ pagetable_pgd_ctor(virt_to_ptdesc(table));
+ return (pgd_t *) table;
}
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
+ pagetable_pgd_dtor(virt_to_ptdesc(pgd));
crst_table_free(mm, (unsigned long *) pgd);
}
@@ -275,6 +275,7 @@ static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order
if (!ptdesc)
return NULL;
+ pagetable_pgd_ctor(ptdesc);
return ptdesc_address(ptdesc);
}
#define __pgd_alloc(...) alloc_hooks(__pgd_alloc_noprof(__VA_ARGS__))
@@ -284,6 +285,7 @@ static inline void __pgd_free(struct mm_struct *mm, pgd_t *pgd)
struct ptdesc *ptdesc = virt_to_ptdesc(pgd);
BUG_ON((unsigned long)pgd & (PAGE_SIZE-1));
+ pagetable_pgd_dtor(ptdesc);
pagetable_free(ptdesc);
}
@@ -3171,6 +3171,16 @@ static inline void pagetable_p4d_dtor(struct ptdesc *ptdesc)
__pagetable_dtor(ptdesc);
}
+static inline void pagetable_pgd_ctor(struct ptdesc *ptdesc)
+{
+ __pagetable_ctor(ptdesc);
+}
+
+static inline void pagetable_pgd_dtor(struct ptdesc *ptdesc)
+{
+ __pagetable_dtor(ptdesc);
+}
+
extern void __init pagecache_init(void);
extern void free_initmem(void);
Following on from the introduction of P4D-level ctor/dtor, let's finish the job and introduce ctor/dtor at PGD level. The incurred improvement in page accounting is minimal - the main motivation is to create a single, generic place where construction/destruction hooks can be added for all page table pages. This patch should cover all architectures and all configurations where PGDs are one or more regular pages. This excludes any configuration where PGDs are allocated from a kmem_cache object. Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com> --- arch/m68k/include/asm/mcf_pgalloc.h | 2 ++ arch/m68k/mm/motorola.c | 6 ++++++ arch/s390/include/asm/pgalloc.h | 8 +++++++- include/asm-generic/pgalloc.h | 2 ++ include/linux/mm.h | 10 ++++++++++ 5 files changed, 27 insertions(+), 1 deletion(-)