From: Sebastien Godard Date: Fri, 24 Feb 2012 15:04:06 +0000 (+0100) Subject: The number of jiffies spent by a CPU in guest mode given by the X-Git-Tag: v10.0.4~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=efde5fbe4847873e14b2e7f1af34ade49ad85f4d;p=sysstat The number of jiffies spent by a CPU in guest mode given by the corresponding counter in /proc/stat may be slightly different from that included in the user counter. Take this into account when calculating current time interval value. This should be a very rare case, and the difference barely noticeable. Mail from Peter Schiffer 23/02/2012: Hello Sebastien, I've done all my work on sysstat for now, but there were no new patches for you. However, there is one patch I don't know origin of. I am sending it to you as attachment. It's in Fedora since sysstat 10.0.0, but there's no bug related to it. Did Ivana send it to you already? Do you have it included in the next development version? Anyways, you can release next sysstat version now, thank you for waiting. peter sysstat-10.0.0-cpu.patch diff -up sysstat-10.0.0/mpstat.c.pom sysstat-10.0.0/mpstat.c --- sysstat-10.0.0/mpstat.c.pom 2011-03-11 18:09:57.000000000 +0100 +++ sysstat-10.0.0/mpstat.c 2011-04-04 11:22:20.000000000 +0200 @@ -418,6 +418,9 @@ void write_stats_core(int prev, int curr /* Recalculate itv for current proc */ pc_itv = get_per_cpu_interval(scc, scp); + if ((scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest)) + pc_itv = pc_itv + (scp->cpu_user - scp->cpu_guest) - + (scc->cpu_user - scc->cpu_guest); if (!pc_itv) { /* --- diff --git a/CHANGES b/CHANGES index f483cb7..cdb6d04 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ xxxx/xx/xx: Version 10.0.4 - Sebastien Godard (sysstat orange.fr) * [Peter Schiffer]: iostat didn't display target device information when a symbolic link was specified as a parameter. This is now fixed. + * The number of jiffies spent by a CPU in guest mode given by the + corresponding counter in /proc/stat may be slightly different + from that included in the user counter. Take this into account + when calculating current time interval value. * configure script updated: Added --disable-stripping option. Using this option tells configure to NOT strip object files. * FAQ updated. diff --git a/common.c b/common.c index 2e3aa70..eb63389 100644 --- a/common.c +++ b/common.c @@ -565,6 +565,18 @@ unsigned long long get_interval(unsigned long long prev_uptime, unsigned long long get_per_cpu_interval(struct stats_cpu *scc, struct stats_cpu *scp) { + unsigned long long ishift = 0LL; + + if ((scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest)) { + /* + * Sometimes the nr of jiffies spent in guest mode given by the guest + * counter in /proc/stat is slightly higher than that included in + * the user counter. Update the interval value accordingly. + */ + ishift = (scp->cpu_user - scp->cpu_guest) - + (scc->cpu_user - scc->cpu_guest); + } + /* Don't take cpu_guest into account because cpu_user already includes it */ return ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys + scc->cpu_iowait + @@ -573,7 +585,8 @@ unsigned long long get_per_cpu_interval(struct stats_cpu *scc, (scp->cpu_user + scp->cpu_nice + scp->cpu_sys + scp->cpu_iowait + scp->cpu_idle + scp->cpu_steal + - scp->cpu_hardirq + scp->cpu_softirq)); + scp->cpu_hardirq + scp->cpu_softirq) + + ishift); } /* diff --git a/rndr_stats.c b/rndr_stats.c index d280bf3..037ed30 100644 --- a/rndr_stats.c +++ b/rndr_stats.c @@ -1,6 +1,6 @@ /* * rndr_stats.c: Funtions used by sadf to display statistics in selected format. - * (C) 1999-2011 by Sebastien GODARD (sysstat orange.fr) + * (C) 1999-2012 by Sebastien GODARD (sysstat orange.fr) * *************************************************************************** * This program is free software; you can redistribute it and/or modify it * @@ -312,7 +312,7 @@ __print_funct_t render_cpu_stats(struct activity *a, int isdb, char *pre, NOVAL, (!g_itv || ((scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest))) ? - 0.0 : /* CPU is offline or tickless */ + 0.0 : ll_sp_value(scp->cpu_user - scp->cpu_guest, scc->cpu_user - scc->cpu_guest, g_itv), NULL);