aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exec.c3
-rw-r--r--include/linux/sched.h10
-rw-r--r--kernel/exit.c6
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/sys.c14
5 files changed, 34 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 434dba778ccc..69bb9d899791 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -845,6 +845,9 @@ static int de_thread(struct task_struct *tsk)
845 sig->notify_count = 0; 845 sig->notify_count = 0;
846 846
847no_thread_group: 847no_thread_group:
848 if (current->mm)
849 setmax_mm_hiwater_rss(&sig->maxrss, current->mm);
850
848 exit_itimers(sig); 851 exit_itimers(sig);
849 flush_itimer_signals(); 852 flush_itimer_signals();
850 853
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 97b10da0a3ea..6448bbc6406b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -426,6 +426,15 @@ static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm)
426 return max(mm->hiwater_rss, get_mm_rss(mm)); 426 return max(mm->hiwater_rss, get_mm_rss(mm));
427} 427}
428 428
429static inline void setmax_mm_hiwater_rss(unsigned long *maxrss,
430 struct mm_struct *mm)
431{
432 unsigned long hiwater_rss = get_mm_hiwater_rss(mm);
433
434 if (*maxrss < hiwater_rss)
435 *maxrss = hiwater_rss;
436}
437
429static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm) 438static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm)
430{ 439{
431 return max(mm->hiwater_vm, mm->total_vm); 440 return max(mm->hiwater_vm, mm->total_vm);
@@ -612,6 +621,7 @@ struct signal_struct {
612 unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; 621 unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
613 unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt; 622 unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
614 unsigned long inblock, oublock, cinblock, coublock; 623 unsigned long inblock, oublock, cinblock, coublock;
624 unsigned long maxrss, cmaxrss;
615 struct task_io_accounting ioac; 625 struct task_io_accounting ioac;
616 626
617 /* 627 /*
diff --git a/kernel/exit.c b/kernel/exit.c
index 61bb1761c7b8..60d6fdcc9265 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -947,6 +947,8 @@ NORET_TYPE void do_exit(long code)
947 if (group_dead) { 947 if (group_dead) {
948 hrtimer_cancel(&tsk->signal->real_timer); 948 hrtimer_cancel(&tsk->signal->real_timer);
949 exit_itimers(tsk->signal); 949 exit_itimers(tsk->signal);
950 if (tsk->mm)
951 setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm);
950 } 952 }
951 acct_collect(code, group_dead); 953 acct_collect(code, group_dead);
952 if (group_dead) 954 if (group_dead)
@@ -1210,6 +1212,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
1210 if (likely(!traced) && likely(!task_detached(p))) { 1212 if (likely(!traced) && likely(!task_detached(p))) {
1211 struct signal_struct *psig; 1213 struct signal_struct *psig;
1212 struct signal_struct *sig; 1214 struct signal_struct *sig;
1215 unsigned long maxrss;
1213 1216
1214 /* 1217 /*
1215 * The resource counters for the group leader are in its 1218 * The resource counters for the group leader are in its
@@ -1258,6 +1261,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
1258 psig->coublock += 1261 psig->coublock +=
1259 task_io_get_oublock(p) + 1262 task_io_get_oublock(p) +
1260 sig->oublock + sig->coublock; 1263 sig->oublock + sig->coublock;
1264 maxrss = max(sig->maxrss, sig->cmaxrss);
1265 if (psig->cmaxrss < maxrss)
1266 psig->cmaxrss = maxrss;
1261 task_io_accounting_add(&psig->ioac, &p->ioac); 1267 task_io_accounting_add(&psig->ioac, &p->ioac);
1262 task_io_accounting_add(&psig->ioac, &sig->ioac); 1268 task_io_accounting_add(&psig->ioac, &sig->ioac);
1263 spin_unlock_irq(&p->real_parent->sighand->siglock); 1269 spin_unlock_irq(&p->real_parent->sighand->siglock);
diff --git a/kernel/fork.c b/kernel/fork.c
index 1020977b57ca..7cf45812ce84 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -866,6 +866,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
866 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 866 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
867 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; 867 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
868 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; 868 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
869 sig->maxrss = sig->cmaxrss = 0;
869 task_io_accounting_init(&sig->ioac); 870 task_io_accounting_init(&sig->ioac);
870 sig->sum_sched_runtime = 0; 871 sig->sum_sched_runtime = 0;
871 taskstats_tgid_init(sig); 872 taskstats_tgid_init(sig);
diff --git a/kernel/sys.c b/kernel/sys.c
index ea5c3bcac881..ebcb15611728 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1338,6 +1338,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1338 unsigned long flags; 1338 unsigned long flags;
1339 cputime_t utime, stime; 1339 cputime_t utime, stime;
1340 struct task_cputime cputime; 1340 struct task_cputime cputime;
1341 unsigned long maxrss = 0;
1341 1342
1342 memset((char *) r, 0, sizeof *r); 1343 memset((char *) r, 0, sizeof *r);
1343 utime = stime = cputime_zero; 1344 utime = stime = cputime_zero;
@@ -1346,6 +1347,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1346 utime = task_utime(current); 1347 utime = task_utime(current);
1347 stime = task_stime(current); 1348 stime = task_stime(current);
1348 accumulate_thread_rusage(p, r); 1349 accumulate_thread_rusage(p, r);
1350 maxrss = p->signal->maxrss;
1349 goto out; 1351 goto out;
1350 } 1352 }
1351 1353
@@ -1363,6 +1365,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1363 r->ru_majflt = p->signal->cmaj_flt; 1365 r->ru_majflt = p->signal->cmaj_flt;
1364 r->ru_inblock = p->signal->cinblock; 1366 r->ru_inblock = p->signal->cinblock;
1365 r->ru_oublock = p->signal->coublock; 1367 r->ru_oublock = p->signal->coublock;
1368 maxrss = p->signal->cmaxrss;
1366 1369
1367 if (who == RUSAGE_CHILDREN) 1370 if (who == RUSAGE_CHILDREN)
1368 break; 1371 break;
@@ -1377,6 +1380,8 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1377 r->ru_majflt += p->signal->maj_flt; 1380 r->ru_majflt += p->signal->maj_flt;
1378 r->ru_inblock += p->signal->inblock; 1381 r->ru_inblock += p->signal->inblock;
1379 r->ru_oublock += p->signal->oublock; 1382 r->ru_oublock += p->signal->oublock;
1383 if (maxrss < p->signal->maxrss)
1384 maxrss = p->signal->maxrss;
1380 t = p; 1385 t = p;
1381 do { 1386 do {
1382 accumulate_thread_rusage(t, r); 1387 accumulate_thread_rusage(t, r);
@@ -1392,6 +1397,15 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1392out: 1397out:
1393 cputime_to_timeval(utime, &r->ru_utime); 1398 cputime_to_timeval(utime, &r->ru_utime);
1394 cputime_to_timeval(stime, &r->ru_stime); 1399 cputime_to_timeval(stime, &r->ru_stime);
1400
1401 if (who != RUSAGE_CHILDREN) {
1402 struct mm_struct *mm = get_task_mm(p);
1403 if (mm) {
1404 setmax_mm_hiwater_rss(&maxrss, mm);
1405 mmput(mm);
1406 }
1407 }
1408 r->ru_maxrss = maxrss * (PAGE_SIZE / 1024); /* convert pages to KBs */
1395} 1409}
1396 1410
1397int getrusage(struct task_struct *p, int who, struct rusage __user *ru) 1411int getrusage(struct task_struct *p, int who, struct rusage __user *ru)