From b04e12b1e8887a439b24f109e2dddf05d928b18c Mon Sep 17 00:00:00 2001 From: William Lee Irwin III Date: Mon, 18 Oct 2004 18:12:08 -0700 Subject: [PATCH] [PATCH] report per-process pagetable usage 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 Signed-off-by: Linus Torvalds --- arch/i386/mm/hugetlbpage.c | 1 + arch/ppc64/mm/hugetlbpage.c | 1 + fs/proc/task_mmu.c | 6 ++++-- include/linux/sched.h | 2 +- kernel/fork.c | 1 + mm/memory.c | 3 ++- 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 7e4b12121df2d..5f6e3e4b66c93 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -247,6 +247,7 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) page = pmd_page(*pmd); pmd_clear(pmd); + mm->nr_ptes--; dec_page_state(nr_page_table_pages); page_cache_release(page); } diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index f9d47ac8f6d56..bf7022c948525 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c @@ -213,6 +213,7 @@ static int prepare_low_seg_for_htlb(struct mm_struct *mm, unsigned long seg) } page = pmd_page(*pmd); pmd_clear(pmd); + mm->nr_ptes--; dec_page_state(nr_page_table_pages); pte_free_tlb(tlb, page); } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 98a507d4c06b3..01b3793102766 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -18,12 +18,14 @@ char *task_mem(struct mm_struct *mm, char *buffer) "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 --git a/include/linux/sched.h b/include/linux/sched.h index e369a601ae0b0..c8f981f108d46 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -227,7 +227,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 --git a/kernel/fork.c b/kernel/fork.c index bb28c1f1e551f..96714c501cc83 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -302,6 +302,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm) atomic_set(&mm->mm_count, 1); init_rwsem(&mm->mmap_sem); 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 --git a/mm/memory.c b/mm/memory.c index f10dc9bb7fe2c..52f96233a13cf 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -114,6 +114,7 @@ static inline void free_one_pmd(struct mmu_gather *tlb, pmd_t * dir) 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_struct *mm, pmd_t *pmd, unsigned long a 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_struct *mm, pmd_t *pmd, unsigned long a pte_free(new); goto out; } + mm->nr_ptes++; inc_page_state(nr_page_table_pages); pmd_populate(mm, pmd, new); } -- 2.53.0