aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2015-09-26 00:12:38 -0400
committerLen Brown <len.brown@intel.com>2015-09-26 00:50:54 -0400
commita2b7b74945dbfe5d734eafe8aa52f9f1f8bc6931 (patch)
treebc3f7991cfef9bd9cf0d902fa6d5160edecb22ba /tools
parentb2b34dfe4d9aa4c468fc363b3b666974783ed1f9 (diff)
tools/power turbostat: SKL: Adjust for TSC difference from base frequency
On a Skylake with 1500MHz base frequency, the TSC runs at 1512MHz. This is because the TSC is no longer in the n*100 MHz BCLK domain, but is now in the m*24MHz crystal clock domain. (24 MHz * 63 = 1512 MHz) This adds error to several calculations in turbostat, unless the TSC sample sizes are adjusted for this difference. Note that calculations in the time domain are immune from this issue, as the timing sub-system has already calibrated the TSC against a known wall clock. AVG_MHz = APERF_delta/measurement_interval need no adjustment. APERF_delta is in the BCLK domain, and measurement_interval is in the time domain. TSC_MHz = TSC_delta/measurement_interval needs no adjustment -- as we really do want to report the actual measured TSC delta here, and measurement_interval is in the accurate time domain. %Busy = MPERF_delta/TSC_delta needs adjustment to use TSC_BCLK_DOMAIN_delta. TSC_BCLK_DOMAIN_delta = TSC_delta * base_hz / tsc_hz Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval need adjustment as above. No other metrics in turbostat need to be adjusted. Before: CPU Avg_MHz %Busy Bzy_MHz TSC_MHz - 550 24.84 2216 1512 0 2191 98.73 2219 1514 2 0 0.01 2130 1512 1 9 0.43 2016 1512 3 2 0.08 2016 1512 After: CPU Avg_MHz %Busy Bzy_MHz TSC_MHz - 550 25.05 2198 1512 0 2190 99.62 2199 1512 2 0 0.01 2152 1512 1 9 0.46 2000 1512 3 2 0.10 2000 1512 Note that in this example, the "Before" Bzy_MHz was reported as exceeding the 2200 max turbo rate. Also, even a pinned spin loop would not be reported as over 99% busy. Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/power/x86/turbostat/turbostat.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index d333c819fa1f..31d756b4ea78 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -74,6 +74,8 @@ unsigned int extra_delta_offset64;
74unsigned int aperf_mperf_multiplier = 1; 74unsigned int aperf_mperf_multiplier = 1;
75int do_smi; 75int do_smi;
76double bclk; 76double bclk;
77double base_hz;
78double tsc_tweak = 1.0;
77unsigned int show_pkg; 79unsigned int show_pkg;
78unsigned int show_core; 80unsigned int show_core;
79unsigned int show_cpu; 81unsigned int show_cpu;
@@ -503,7 +505,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
503 /* %Busy */ 505 /* %Busy */
504 if (has_aperf) { 506 if (has_aperf) {
505 if (!skip_c0) 507 if (!skip_c0)
506 outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc); 508 outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc/tsc_tweak);
507 else 509 else
508 outp += sprintf(outp, "********"); 510 outp += sprintf(outp, "********");
509 } 511 }
@@ -511,7 +513,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
511 /* Bzy_MHz */ 513 /* Bzy_MHz */
512 if (has_aperf) 514 if (has_aperf)
513 outp += sprintf(outp, "%8.0f", 515 outp += sprintf(outp, "%8.0f",
514 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); 516 1.0 * t->tsc * tsc_tweak / units * t->aperf / t->mperf / interval_float);
515 517
516 /* TSC_MHz */ 518 /* TSC_MHz */
517 outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); 519 outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float);
@@ -1152,6 +1154,19 @@ int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV,
1152int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1154int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1153int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1155int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1154 1156
1157
1158static void
1159calculate_tsc_tweak()
1160{
1161 unsigned long long msr;
1162 unsigned int base_ratio;
1163
1164 get_msr(base_cpu, MSR_NHM_PLATFORM_INFO, &msr);
1165 base_ratio = (msr >> 8) & 0xFF;
1166 base_hz = base_ratio * bclk * 1000000;
1167 tsc_tweak = base_hz / tsc_hz;
1168}
1169
1155static void 1170static void
1156dump_nhm_platform_info(void) 1171dump_nhm_platform_info(void)
1157{ 1172{
@@ -2773,6 +2788,9 @@ void process_cpuid()
2773 if (debug) 2788 if (debug)
2774 dump_cstate_pstate_config_info(); 2789 dump_cstate_pstate_config_info();
2775 2790
2791 if (has_skl_msrs(family, model))
2792 calculate_tsc_tweak();
2793
2776 return; 2794 return;
2777} 2795}
2778 2796