From 3ee682035f4aafdbf01af38453cb6ab18c2a0d37 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 30 Nov 2010 20:55:34 +0100 Subject: [PATCH] --- yaml --- r: 222727 b: refs/heads/master c: 3c77f845722158206a7209c45ccddc264d19319c h: refs/heads/master i: 222725: 4bf51fbccf9b3cb82e201c14e3e80a89fdb0b538 222723: cfb0ab380553c4b6518dc9b699520f935902ecf8 222719: f858628c05c2cf2a7c4c3664ead73db24663958a v: v3 --- [refs] | 2 +- trunk/fs/exec.c | 32 ++++++++++++++++++++++++++++++-- trunk/include/linux/binfmts.h | 1 + 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index b63d024f2d40..5f8f83685d8b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 37a09f07459753e7c98d4e21f1c61e8756923f81 +refs/heads/master: 3c77f845722158206a7209c45ccddc264d19319c diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 99d33a1371e9..4303b9035fe7 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -164,6 +164,25 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) #ifdef CONFIG_MMU +static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) +{ + struct mm_struct *mm = current->mm; + long diff = (long)(pages - bprm->vma_pages); + + if (!mm || !diff) + return; + + bprm->vma_pages = pages; + +#ifdef SPLIT_RSS_COUNTING + add_mm_counter(mm, MM_ANONPAGES, diff); +#else + spin_lock(&mm->page_table_lock); + add_mm_counter(mm, MM_ANONPAGES, diff); + spin_unlock(&mm->page_table_lock); +#endif +} + static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { @@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; struct rlimit *rlim; + acct_arg_size(bprm, size / PAGE_SIZE); + /* * We've historically supported up to 32 pages (ARG_MAX) * of argument strings even with small stacks @@ -276,6 +297,10 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) #else +static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) +{ +} + static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { @@ -1003,6 +1028,7 @@ int flush_old_exec(struct linux_binprm * bprm) /* * Release all of the old mmap stuff */ + acct_arg_size(bprm, 0); retval = exec_mmap(bprm->mm); if (retval) goto out; @@ -1426,8 +1452,10 @@ int do_execve(const char * filename, return retval; out: - if (bprm->mm) - mmput (bprm->mm); + if (bprm->mm) { + acct_arg_size(bprm, 0); + mmput(bprm->mm); + } out_file: if (bprm->file) { diff --git a/trunk/include/linux/binfmts.h b/trunk/include/linux/binfmts.h index a065612fc928..7c87796d20da 100644 --- a/trunk/include/linux/binfmts.h +++ b/trunk/include/linux/binfmts.h @@ -29,6 +29,7 @@ struct linux_binprm{ char buf[BINPRM_BUF_SIZE]; #ifdef CONFIG_MMU struct vm_area_struct *vma; + unsigned long vma_pages; #else # define MAX_ARG_PAGES 32 struct page *page[MAX_ARG_PAGES];