From 6ac0a8d7d5033027e0ae999525d11750ee4337ca Mon Sep 17 00:00:00 2001 From: William Lee Irwin III Date: Thu, 26 Aug 2004 20:36:15 -0700 Subject: [PATCH] O(1) proc_pid_statm() Merely removing down_read(&mm->mmap_sem) from task_vsize() is too half-assed to let stand. The following patch removes the vma iteration as well as the down_read(&mm->mmap_sem) from both task_mem() and task_statm() and callers for the CONFIG_MMU=y case in favor of accounting the various stats reported at the times of vma creation, destruction, and modification. Unlike the 2.4.x patches of the same name, this has no per-pte-modification overhead whatsoever. This patch quashes end user complaints of top(1) being slow as well as kernel hacker complaints of per-pte accounting overhead simultaneously. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 13 +++++++++++++ include/linux/proc_fs.h | 2 ++ include/linux/sched.h | 4 ++-- 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 42dca234d166..8d61ba9895ab 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -752,6 +752,19 @@ extern struct page * follow_page(struct mm_struct *mm, unsigned long address, int write); extern int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); +void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); + +static inline void vm_stat_account(struct vm_area_struct *vma) +{ + __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, + vma_pages(vma)); +} + +static inline void vm_stat_unaccount(struct vm_area_struct *vma) +{ + __vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, + -vma_pages(vma)); +} #ifndef CONFIG_DEBUG_PAGEALLOC static inline void diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 96a7db053781..65f18e551529 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -93,6 +93,8 @@ struct dentry *proc_pid_unhash(struct task_struct *p); void proc_pid_flush(struct dentry *proc_dentry); int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); unsigned long task_vsize(struct mm_struct *); +int task_statm(struct mm_struct *, int *, int *, int *, int *); +char *task_mem(struct mm_struct *, char *); extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent); diff --git a/include/linux/sched.h b/include/linux/sched.h index edc30e989fea..dcbde5c93739 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -224,8 +224,8 @@ struct mm_struct { unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; - unsigned long rss, total_vm, locked_vm; - unsigned long def_flags; + unsigned long rss, total_vm, locked_vm, shared_vm; + unsigned long exec_vm, stack_vm, def_flags; unsigned long saved_auxv[40]; /* for /proc/PID/auxv */ -- cgit v1.2.3