From: William Lee Irwin III Andi Kleen requested that the number of pagetable pages in use by a process be reported in /proc/$PID/status; this patch implements that. Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/mm/hugetlbpage.c | 1 + 25-akpm/arch/ppc64/mm/hugetlbpage.c | 1 + 25-akpm/fs/proc/task_mmu.c | 6 ++++-- 25-akpm/include/linux/sched.h | 2 +- 25-akpm/kernel/fork.c | 1 + 25-akpm/mm/memory.c | 3 ++- 6 files changed, 10 insertions(+), 4 deletions(-) diff -puN arch/i386/mm/hugetlbpage.c~report-per-process-pagetable-usage arch/i386/mm/hugetlbpage.c --- 25/arch/i386/mm/hugetlbpage.c~report-per-process-pagetable-usage 2004-09-30 22:37:02.661345632 -0700 +++ 25-akpm/arch/i386/mm/hugetlbpage.c 2004-09-30 22:37:02.672343960 -0700 @@ -247,6 +247,7 @@ int hugetlb_prefault(struct address_spac page = pmd_page(*pmd); pmd_clear(pmd); + mm->nr_ptes--; dec_page_state(nr_page_table_pages); page_cache_release(page); } diff -puN arch/ppc64/mm/hugetlbpage.c~report-per-process-pagetable-usage arch/ppc64/mm/hugetlbpage.c --- 25/arch/ppc64/mm/hugetlbpage.c~report-per-process-pagetable-usage 2004-09-30 22:37:02.663345328 -0700 +++ 25-akpm/arch/ppc64/mm/hugetlbpage.c 2004-09-30 22:37:02.672343960 -0700 @@ -213,6 +213,7 @@ static int prepare_low_seg_for_htlb(stru } page = pmd_page(*pmd); pmd_clear(pmd); + mm->nr_ptes--; dec_page_state(nr_page_table_pages); pte_free_tlb(tlb, page); } diff -puN fs/proc/task_mmu.c~report-per-process-pagetable-usage fs/proc/task_mmu.c --- 25/fs/proc/task_mmu.c~report-per-process-pagetable-usage 2004-09-30 22:37:02.664345176 -0700 +++ 25-akpm/fs/proc/task_mmu.c 2004-09-30 22:37:02.673343808 -0700 @@ -18,12 +18,14 @@ char *task_mem(struct mm_struct *mm, cha "VmData:\t%8lu kB\n" "VmStk:\t%8lu kB\n" "VmExe:\t%8lu kB\n" - "VmLib:\t%8lu kB\n", + "VmLib:\t%8lu kB\n" + "VmPTE:\t%8lu kB\n", (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), mm->locked_vm << (PAGE_SHIFT-10), mm->rss << (PAGE_SHIFT-10), data << (PAGE_SHIFT-10), - mm->stack_vm << (PAGE_SHIFT-10), text, lib); + mm->stack_vm << (PAGE_SHIFT-10), text, lib, + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); return buffer; } diff -puN include/linux/sched.h~report-per-process-pagetable-usage include/linux/sched.h --- 25/include/linux/sched.h~report-per-process-pagetable-usage 2004-09-30 22:37:02.666344872 -0700 +++ 25-akpm/include/linux/sched.h 2004-09-30 22:37:02.674343656 -0700 @@ -228,7 +228,7 @@ struct mm_struct { unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm, shared_vm; - unsigned long exec_vm, stack_vm, reserved_vm, def_flags; + unsigned long exec_vm, stack_vm, reserved_vm, def_flags, nr_ptes; unsigned long saved_auxv[42]; /* for /proc/PID/auxv */ diff -puN kernel/fork.c~report-per-process-pagetable-usage kernel/fork.c --- 25/kernel/fork.c~report-per-process-pagetable-usage 2004-09-30 22:37:02.667344720 -0700 +++ 25-akpm/kernel/fork.c 2004-09-30 22:37:02.675343504 -0700 @@ -296,6 +296,7 @@ static struct mm_struct * mm_init(struct init_rwsem(&mm->mmap_sem); INIT_LIST_HEAD(&mm->mmlist); mm->core_waiters = 0; + mm->nr_ptes = 0; mm->page_table_lock = SPIN_LOCK_UNLOCKED; mm->ioctx_list_lock = RW_LOCK_UNLOCKED; mm->ioctx_list = NULL; diff -puN mm/memory.c~report-per-process-pagetable-usage mm/memory.c --- 25/mm/memory.c~report-per-process-pagetable-usage 2004-09-30 22:37:02.668344568 -0700 +++ 25-akpm/mm/memory.c 2004-09-30 22:37:02.677343200 -0700 @@ -114,6 +114,7 @@ static inline void free_one_pmd(struct m page = pmd_page(*dir); pmd_clear(dir); dec_page_state(nr_page_table_pages); + tlb->mm->nr_ptes--; pte_free_tlb(tlb, page); } @@ -163,7 +164,6 @@ pte_t fastcall * pte_alloc_map(struct mm spin_lock(&mm->page_table_lock); if (!new) return NULL; - /* * Because we dropped the lock, we should re-check the * entry, as somebody else could have populated it.. @@ -172,6 +172,7 @@ pte_t fastcall * pte_alloc_map(struct mm pte_free(new); goto out; } + mm->nr_ptes++; inc_page_state(nr_page_table_pages); pmd_populate(mm, pmd, new); } _