summaryrefslogtreecommitdiffstats
path: root/tools/power
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2016-04-06 17:16:00 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-04-07 22:18:40 +0200
commit9185e988e9d5bb70b690362e84bb2e4a9d71f2c5 (patch)
tree8ee83e7750e2a51a63ccd2a6a4f41150af382d7b /tools/power
parentcdc57272ea0a0e952c4609b56e157e4d0ec8e956 (diff)
downloadlinux-9185e988e9d5bb70b690362e84bb2e4a9d71f2c5.tar.gz
linux-9185e988e9d5bb70b690362e84bb2e4a9d71f2c5.tar.bz2
linux-9185e988e9d5bb70b690362e84bb2e4a9d71f2c5.zip
tools/power turbostat: work around RC6 counter wrap
Sometimes the rc6 sysfs counter spontaneously resets, causing turbostat prints a very large number as it tries to calcuate % = 100 * (old - new) / interval When we see (old > new), print ***.**% instead of a bogus huge number. Note that this detection is not fool-proof, as the counter could reset several times and still result in new > old. Signed-off-by: Len Brown <len.brown@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'tools/power')
-rw-r--r--tools/power/x86/turbostat/turbostat.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 277e0321e590..d2ae87d148ed 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -189,7 +189,7 @@ struct pkg_data {
unsigned long long pkg_any_core_c0;
unsigned long long pkg_any_gfxe_c0;
unsigned long long pkg_both_core_gfxe_c0;
- unsigned long long gfx_rc6_ms;
+ long long gfx_rc6_ms;
unsigned int gfx_mhz;
unsigned int package_id;
unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
@@ -623,8 +623,14 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "%8d", p->pkg_temp_c);
/* GFXrc6 */
- if (do_gfx_rc6_ms)
- outp += sprintf(outp, "%8.2f", 100.0 * p->gfx_rc6_ms / 1000.0 / interval_float);
+ if (do_gfx_rc6_ms) {
+ if (p->gfx_rc6_ms == -1) { /* detect counter reset */
+ outp += sprintf(outp, " ***.**");
+ } else {
+ outp += sprintf(outp, "%8.2f",
+ p->gfx_rc6_ms / 10.0 / interval_float);
+ }
+ }
/* GFXMHz */
if (do_gfx_mhz)
@@ -768,7 +774,12 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
old->pc10 = new->pc10 - old->pc10;
old->pkg_temp_c = new->pkg_temp_c;
- old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
+ /* flag an error when rc6 counter resets/wraps */
+ if (old->gfx_rc6_ms > new->gfx_rc6_ms)
+ old->gfx_rc6_ms = -1;
+ else
+ old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
+
old->gfx_mhz = new->gfx_mhz;
DELTA_WRAP32(new->energy_pkg, old->energy_pkg);