taskstats: add e/u/stime for TGID command
authorZhang Xiao <xiao.zhang@windriver.com>
Mon, 8 May 2017 22:56:45 +0000 (15:56 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 May 2017 00:15:12 +0000 (17:15 -0700)
The elapsed time, user CPU time and system CPU time for the thread group
status request are presently left at zero.  Fill these in.

[akpm@linux-foundation.org: run ktime_get_ns() a single time]
[akpm@linux-foundation.org: include linux/sched/cputime.h for task_cputime()]
Link: http://lkml.kernel.org/r/1488508424-12322-1-git-send-email-xiao.zhang@windriver.com
Signed-off-by: Zhang Xiao <xiao.zhang@windriver.com>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/taskstats.c

index 8a5e44236f78d3ba069e0c81ef3304f4be5ba7fd..4559e914452b4b8a47d1cf2efc0320be253e5025 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pid_namespace.h>
 #include <net/genetlink.h>
 #include <linux/atomic.h>
+#include <linux/sched/cputime.h>
 
 /*
  * Maximum length of a cpumask that can be specified in
@@ -210,6 +211,8 @@ static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats)
        struct task_struct *tsk, *first;
        unsigned long flags;
        int rc = -ESRCH;
+       u64 delta, utime, stime;
+       u64 start_time;
 
        /*
         * Add additional stats from live tasks except zombie thread group
@@ -227,6 +230,7 @@ static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats)
                memset(stats, 0, sizeof(*stats));
 
        tsk = first;
+       start_time = ktime_get_ns();
        do {
                if (tsk->exit_state)
                        continue;
@@ -238,6 +242,16 @@ static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats)
                 */
                delayacct_add_tsk(stats, tsk);
 
+               /* calculate task elapsed time in nsec */
+               delta = start_time - tsk->start_time;
+               /* Convert to micro seconds */
+               do_div(delta, NSEC_PER_USEC);
+               stats->ac_etime += delta;
+
+               task_cputime(tsk, &utime, &stime);
+               stats->ac_utime += div_u64(utime, NSEC_PER_USEC);
+               stats->ac_stime += div_u64(stime, NSEC_PER_USEC);
+
                stats->nvcsw += tsk->nvcsw;
                stats->nivcsw += tsk->nivcsw;
        } while_each_thread(first, tsk);