]> granicus.if.org Git - sysstat/commitdiff
workaround for /proc/stat go backward
authorKOSAKI Motohiro <kosaki.motohiro@gmail.com>
Tue, 24 Jun 2014 02:17:36 +0000 (22:17 -0400)
committerKOSAKI Motohiro <kosaki.motohiro@gmail.com>
Tue, 24 Jun 2014 15:46:04 +0000 (11:46 -0400)
Since dyn-tick feature was introduced (at kernel 2.6.21),
/proc/stat is unreliable and unstable. Stopped cpu can't provide
reliable stat. kernel try to provide a maximum guess. But it is
not 100% accurate.

Unfortunately, the fields are unsigned. So, stepping backward
can make overflow and some command (e.g. mpstat) show very big
number.

This patch provide a workaround.

Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
common.c

index 0562993b33dc1ff0ce702135476390bdf54818e1..e96c8810d2ae4c559637d443d690bc40da43cfca 100644 (file)
--- a/common.c
+++ b/common.c
@@ -504,13 +504,23 @@ void get_HZ(void)
 double ll_sp_value(unsigned long long value1, unsigned long long value2,
                   unsigned long long itv)
 {
-       return SP_VALUE(value1, value2, itv);
+       /* Workaround: dyn-tick kernel has a race issue and /proc/stat values
+          could be backward. */
+       if (value2 < value1)
+               return 0;
+       else
+               return SP_VALUE(value1, value2, itv);
 }
 
 double ll_s_value(unsigned long long value1, unsigned long long value2,
                  unsigned long long itv)
 {
-       return S_VALUE(value1, value2, itv);
+       /* Workaround: dyn-tick kernel has a race issue and /proc/stat values
+          could be backward. */
+       if (value2 < value1)
+               return 0;
+       else
+               return S_VALUE(value1, value2, itv);
 }
 
 /*