summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 25e51eb)
raw | patch | inline | side by side (parent: 25e51eb)
author | Vincent Brillault <git@lerya.net> | |
Thu, 12 Feb 2015 20:33:40 +0000 (21:33 +0100) | ||
committer | Vincent Brillault <git@lerya.net> | |
Sat, 28 Feb 2015 06:35:42 +0000 (07:35 +0100) |
Backport d7899447535929b3672442b7b42a09ae4e48fa91
from Len Brown <len.brown@intel.com>
Turbostat can be useful on systems that do not support invariant TSC,
so allow it to run on those systgems.
All arithmetic in turbostat using the TSC value is per-processsor,
so it does not depend on the TSC values being in sync acrosss
processors.
Turbostat uses cdtime() for the measurement interval
rather than using the TSC directly, so that key metric
is also immune from variable TSC.
Turbostat has a TSC sanity check gauge:
TSC_MHz = TSC_delta/interval
If this column is constant and is close to the processor
base frequency, then the TSC is behaving properly.
The other key turbostat columns are calculated this way:
Avg_Mhz = APERF_delta/interval
Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/interval
c0 = MPERF_delta/TSC_delta
This adaptation of the original commit has not been tested on any
old CPU. This patch also re-introduce the boolean "do_smi" as such
old CPUs don't have SMI.
from Len Brown <len.brown@intel.com>
Turbostat can be useful on systems that do not support invariant TSC,
so allow it to run on those systgems.
All arithmetic in turbostat using the TSC value is per-processsor,
so it does not depend on the TSC values being in sync acrosss
processors.
Turbostat uses cdtime() for the measurement interval
rather than using the TSC directly, so that key metric
is also immune from variable TSC.
Turbostat has a TSC sanity check gauge:
TSC_MHz = TSC_delta/interval
If this column is constant and is close to the processor
base frequency, then the TSC is behaving properly.
The other key turbostat columns are calculated this way:
Avg_Mhz = APERF_delta/interval
Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/interval
c0 = MPERF_delta/TSC_delta
This adaptation of the original commit has not been tested on any
old CPU. This patch also re-introduce the boolean "do_smi" as such
old CPUs don't have SMI.
src/turbostat.c | patch | blob | history |
diff --git a/src/turbostat.c b/src/turbostat.c
index 2f30206a6c9f4db54062447c6736161af5461fb6..4cd1e50096f76b8d26c7320b5bea09e8b9c0136f 100644 (file)
--- a/src/turbostat.c
+++ b/src/turbostat.c
*/
static unsigned int do_pkg_cstate;
+/*
+ * Boolean indicating if the processor supports 'I/O System-Management Interrupt counter'
+ */
+static _Bool do_smi;
+
/*
* Boolean indicating if the processor supports 'Digital temperature sensor'
* This feature enables the monitoring of the temperature of each core
READ_MSR(MSR_IA32_APERF, &t->aperf);
READ_MSR(MSR_IA32_MPERF, &t->mperf);
- READ_MSR(MSR_SMI_COUNT, &msr);
- t->smi_count = msr & 0xFFFFFFFF;
+ if (do_smi) {
+ READ_MSR(MSR_SMI_COUNT, &msr);
+ t->smi_count = msr & 0xFFFFFFFF;
+ }
/* collect core counters only for 1st thread in core */
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) {
@@ -525,7 +532,8 @@ delta_thread(struct thread_data *delta, const struct thread_data *new, const str
delta->mperf = 1; /* divide by 0 protection */
}
- delta->smi_count = new->smi_count - old->smi_count;
+ if (do_smi)
+ delta->smi_count = new->smi_count - old->smi_count;
return 0;
}
turbostat_submit("TSC", "gauge", name, 1.0 * t->tsc / 1000000 / interval_float);
/* SMI */
- turbostat_submit(NULL, "current", name, t->smi_count);
+ if (do_smi)
+ turbostat_submit(NULL, "current", name, t->smi_count);
/* submit per-core data only for 1st thread in core */
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
return -1;
}
- /*
- * CPUID(0x80000000):
- * - EAX: Maximum Input Value for Extended Function CPUID Information
- *
- * This allows us to verify if the CPUID(0x80000007) can be called
- *
- * This check is valid for both Intel and AMD.
- */
- max_level = ebx = ecx = edx = 0;
- __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx);
- if (max_level < 0x80000007) {
- ERROR("Turbostat plugin: Unsupported CPU (no invariant TSC, "
- " Maximum Extended Function: 0x%x)", max_level);
- return -1;
- }
-
- /*
- * CPUID(0x80000007):
- * - EDX:
- * + 8: Invariant TSC available if set
- *
- * This check is valid for both Intel and AMD
- */
- eax = ebx = ecx = edx = 0;
- __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
- if (!(edx & (1 << 8))) {
- ERROR("Turbostat plugin: Unsupported CPU (No invariant TSC)");
- return -1;
- }
-
/*
* CPUID(6):
* - EAX:
switch (model) {
/* Atom (partial) */
case 0x27:
+ do_smi = 0;
do_core_cstate = 0;
do_pkg_cstate = (1 << 2) | (1 << 4) | (1 << 6);
break;
/* Silvermont */
case 0x37: /* BYT */
case 0x4D: /* AVN */
+ do_smi = 1;
do_core_cstate = (1 << 1) | (1 << 6);
do_pkg_cstate = (1 << 6);
break;
case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
case 0x1F: /* Core i7 and i5 Processor - Nehalem */
case 0x2E: /* Nehalem-EX Xeon - Beckton */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6);
do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7);
break;
case 0x25: /* Westmere Client - Clarkdale, Arrandale */
case 0x2C: /* Westmere EP - Gulftown */
case 0x2F: /* Westmere-EX Xeon - Eagleton */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6);
do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7);
break;
/* Sandy Bridge */
case 0x2A: /* SNB */
case 0x2D: /* SNB Xeon */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
break;
/* Ivy Bridge */
case 0x3A: /* IVB */
case 0x3E: /* IVB Xeon */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
break;
case 0x3C: /* HSW */
case 0x3F: /* HSW */
case 0x46: /* HSW */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
break;
case 0x45: /* HSW */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10);
break;
/* Broadwel */
case 0x4F: /* BDW */
case 0x56: /* BDX-DE */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
break;
case 0x3D: /* BDW */
+ do_smi = 1;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10);
break;
default:
- ERROR("Turbostat plugin: Unsupported CPU (family: %#x,"
- " model: %#x)", family, model);
+ do_smi = 0;
+ do_core_cstate = 0;
+ do_pkg_cstate = 0;
+ break;
}
switch (model) {
case 0x2A: /* SNB */