aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sys.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index f2a451366953..e423d0d9e6ff 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}