aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/resource.h1
-rw-r--r--kernel/sys.c31
2 files changed, 23 insertions, 9 deletions
diff --git a/include/linux/resource.h b/include/linux/resource.h
index ae13db71474..aaa423a6f3d 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -19,6 +19,7 @@ struct task_struct;
19#define RUSAGE_SELF 0 19#define RUSAGE_SELF 0
20#define RUSAGE_CHILDREN (-1) 20#define RUSAGE_CHILDREN (-1)
21#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */ 21#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
22#define RUSAGE_THREAD 1 /* only the calling thread */
22 23
23struct rusage { 24struct rusage {
24 struct timeval ru_utime; /* user time used */ 25 struct timeval ru_utime; /* user time used */
diff --git a/kernel/sys.c b/kernel/sys.c
index f2a45136695..e423d0d9e6f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1545,6 +1545,19 @@ out:
1545 * 1545 *
1546 */ 1546 */
1547 1547
1548static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r,
1549 cputime_t *utimep, cputime_t *stimep)
1550{
1551 *utimep = cputime_add(*utimep, t->utime);
1552 *stimep = cputime_add(*stimep, t->stime);
1553 r->ru_nvcsw += t->nvcsw;
1554 r->ru_nivcsw += t->nivcsw;
1555 r->ru_minflt += t->min_flt;
1556 r->ru_majflt += t->maj_flt;
1557 r->ru_inblock += task_io_get_inblock(t);
1558 r->ru_oublock += task_io_get_oublock(t);
1559}
1560
1548static void k_getrusage(struct task_struct *p, int who, struct rusage *r) 1561static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1549{ 1562{
1550 struct task_struct *t; 1563 struct task_struct *t;
@@ -1554,6 +1567,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1554 memset((char *) r, 0, sizeof *r); 1567 memset((char *) r, 0, sizeof *r);
1555 utime = stime = cputime_zero; 1568 utime = stime = cputime_zero;
1556 1569
1570 if (who == RUSAGE_THREAD) {
1571 accumulate_thread_rusage(p, r, &utime, &stime);
1572 goto out;
1573 }
1574
1557 rcu_read_lock(); 1575 rcu_read_lock();
1558 if (!lock_task_sighand(p, &flags)) { 1576 if (!lock_task_sighand(p, &flags)) {
1559 rcu_read_unlock(); 1577 rcu_read_unlock();
@@ -1586,14 +1604,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1586 r->ru_oublock += p->signal->oublock; 1604 r->ru_oublock += p->signal->oublock;
1587 t = p; 1605 t = p;
1588 do { 1606 do {
1589 utime = cputime_add(utime, t->utime); 1607 accumulate_thread_rusage(t, r, &utime, &stime);
1590 stime = cputime_add(stime, t->stime);
1591 r->ru_nvcsw += t->nvcsw;
1592 r->ru_nivcsw += t->nivcsw;
1593 r->ru_minflt += t->min_flt;
1594 r->ru_majflt += t->maj_flt;
1595 r->ru_inblock += task_io_get_inblock(t);
1596 r->ru_oublock += task_io_get_oublock(t);
1597 t = next_thread(t); 1608 t = next_thread(t);
1598 } while (t != p); 1609 } while (t != p);
1599 break; 1610 break;
@@ -1605,6 +1616,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1605 unlock_task_sighand(p, &flags); 1616 unlock_task_sighand(p, &flags);
1606 rcu_read_unlock(); 1617 rcu_read_unlock();
1607 1618
1619out:
1608 cputime_to_timeval(utime, &r->ru_utime); 1620 cputime_to_timeval(utime, &r->ru_utime);
1609 cputime_to_timeval(stime, &r->ru_stime); 1621 cputime_to_timeval(stime, &r->ru_stime);
1610} 1622}
@@ -1618,7 +1630,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
1618 1630
1619asmlinkage long sys_getrusage(int who, struct rusage __user *ru) 1631asmlinkage long sys_getrusage(int who, struct rusage __user *ru)
1620{ 1632{
1621 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) 1633 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN &&
1634 who != RUSAGE_THREAD)
1622 return -EINVAL; 1635 return -EINVAL;
1623 return getrusage(current, who, ru); 1636 return getrusage(current, who, ru);
1624} 1637}