diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 32 |
1 files changed, 30 insertions, 2 deletions
@@ -164,6 +164,25 @@ out: | |||
164 | 164 | ||
165 | #ifdef CONFIG_MMU | 165 | #ifdef CONFIG_MMU |
166 | 166 | ||
167 | static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | ||
168 | { | ||
169 | struct mm_struct *mm = current->mm; | ||
170 | long diff = (long)(pages - bprm->vma_pages); | ||
171 | |||
172 | if (!mm || !diff) | ||
173 | return; | ||
174 | |||
175 | bprm->vma_pages = pages; | ||
176 | |||
177 | #ifdef SPLIT_RSS_COUNTING | ||
178 | add_mm_counter(mm, MM_ANONPAGES, diff); | ||
179 | #else | ||
180 | spin_lock(&mm->page_table_lock); | ||
181 | add_mm_counter(mm, MM_ANONPAGES, diff); | ||
182 | spin_unlock(&mm->page_table_lock); | ||
183 | #endif | ||
184 | } | ||
185 | |||
167 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 186 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, |
168 | int write) | 187 | int write) |
169 | { | 188 | { |
@@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
186 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 205 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
187 | struct rlimit *rlim; | 206 | struct rlimit *rlim; |
188 | 207 | ||
208 | acct_arg_size(bprm, size / PAGE_SIZE); | ||
209 | |||
189 | /* | 210 | /* |
190 | * We've historically supported up to 32 pages (ARG_MAX) | 211 | * We've historically supported up to 32 pages (ARG_MAX) |
191 | * of argument strings even with small stacks | 212 | * of argument strings even with small stacks |
@@ -276,6 +297,10 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) | |||
276 | 297 | ||
277 | #else | 298 | #else |
278 | 299 | ||
300 | static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | ||
301 | { | ||
302 | } | ||
303 | |||
279 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 304 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, |
280 | int write) | 305 | int write) |
281 | { | 306 | { |
@@ -1003,6 +1028,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1003 | /* | 1028 | /* |
1004 | * Release all of the old mmap stuff | 1029 | * Release all of the old mmap stuff |
1005 | */ | 1030 | */ |
1031 | acct_arg_size(bprm, 0); | ||
1006 | retval = exec_mmap(bprm->mm); | 1032 | retval = exec_mmap(bprm->mm); |
1007 | if (retval) | 1033 | if (retval) |
1008 | goto out; | 1034 | goto out; |
@@ -1426,8 +1452,10 @@ int do_execve(const char * filename, | |||
1426 | return retval; | 1452 | return retval; |
1427 | 1453 | ||
1428 | out: | 1454 | out: |
1429 | if (bprm->mm) | 1455 | if (bprm->mm) { |
1430 | mmput (bprm->mm); | 1456 | acct_arg_size(bprm, 0); |
1457 | mmput(bprm->mm); | ||
1458 | } | ||
1431 | 1459 | ||
1432 | out_file: | 1460 | out_file: |
1433 | if (bprm->file) { | 1461 | if (bprm->file) { |