Search code examples
linuxlinux-kernelprocess-accounting

taskstats stats not adding up


I am trying to figure out how the stats in the taskstats struct are adding up. I wrote a simple C program that runs for some time doing IO and exits. I monitor the stats of this program using the taskstats struct, which I get from the taskstats netlink multicast group. When I sum the values of cpu_delay_total, blkio_delay_total, swapin_delay_total, freepages_delay_total, ac_utime and ac_stime, I get a value that is about 0.5 seconds larger than the value of elapsed time (ac_etime)

Here are the statistics for a 3.5-second run:

ac_etime: 3536036 ac_utime: 172000 ac_stime: 3032000 cpu_delay_total: 792528445 blkio_delay_total: 46320128 swapin_delay_total: 0 freepages_delay_total: 0

Summing up values for delays, utime and stime yields 4042848.573 (divide the delays by 1000 to convert to microseconds), while etime is only 3536036!

Interestingly, the wall clock time gives the value that is practically equal to utime+stime: cpu_run_real_total: 3204000129, while ac_utime + ac_stime: 3204000

Does the cpu_run_real_total field give the cpu time, despite that the comment in taskstats.h clearly states that this is a wall clock time? And what could be the reason that the sum of these fields is larger than the elapsed time?

My kernel version is 3.2.0-38.


Solution

  • (1) cpu_run_real_total = ac_utime + ac_stime, I check the codes in ./kernel/delayacct.c, function __delayacct_add_tsk():

    tmp = (s64)d->cpu_run_real_total;
    cputime_to_timespec(tsk->utime + tsk->stime, &ts);
    tmp += timespec_to_ns(&ts);
    d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
    

    From the above codes, we know cpu_run_real_total is sum the utime and stime up.

    (2) Why sum the values of cpu_delay_total, blkio_delay_total, swapin_delay_total, freepages_delay_total, ac_utime and ac_stime, the value is larger than the value of ac_etime?

    I have not figured out why. But I have guess: the stime may somewhat overlap with the various *_delay_total counters.