From e975db5d528abf5c42adfc50a6b0384993b6280b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 6 Apr 2016 23:56:02 -0400 Subject: tools/power turbostat: tidy up output on Joule counter overflow The RAPL Joules counter is limited in capacity. Turbostat estimates how soon it can roll-over based on the max TDP of the processor -- which tells us the maximum increment rate. eg. RAPL: 2759 sec. Joule Counter Range, at 95 Watts So if a sample duration is longer than 2759 seconds on this system, '**' replace the decimal place in the display to indicate that the results may be suspect. But the display had an extra ' ' in this case, throwing off the columns. Also, the -J "Joules" option appended an extra "time" column to the display. While this may be useful, it printed the interval time, which may not be the accurate time per processor. Remove this column, which appeared only when using '-J', as we plan to add accurate per-cpu interval times in a future commit. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 3e199b508a96..a302a333c084 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -423,8 +423,6 @@ void print_header(void) outp += sprintf(outp, " PKG_%%"); if (do_rapl & RAPL_DRAM_PERF_STATUS) outp += sprintf(outp, " RAM_%%"); - outp += sprintf(outp, " time"); - } done: outp += sprintf(outp, "\n"); @@ -665,7 +663,7 @@ int format_counters(struct thread_data *t, struct core_data *c, if (interval_float < rapl_joule_counter_range) fmt8 = "%8.2f"; else - fmt8 = " %6.0f**"; + fmt8 = "%6.0f**"; if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) @@ -697,8 +695,6 @@ int format_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); if (do_rapl & RAPL_DRAM_PERF_STATUS) outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); - - outp += sprintf(outp, fmt8, interval_float); } done: outp += sprintf(outp, "\n"); -- cgit v1.2.3-59-g8ed1b From ba3dec99fc99fbe5a08d6c37f06feeb4d4bcb921 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 22 Apr 2016 20:31:46 -0400 Subject: tools/power turbostat: Gracefully handle ACPI S3 turbostat gives valid results across suspend to idle, aka freeze, whether invoked in interval mode, or in command mode. Indeed, this can be used to measure suspend to idle: turbostat echo freeze > /sys/power/state But this does not work across suspend to ACPI S3, because the processor counters, including the TSC, are reset on resume. Further, when turbostat detects a problem, it does't forgive the hardware, and interval mode will print *'s from there on out. Instead, upon detecting counters going backwards, simply reset and start over. Interval mode across ACPI S3: (observe TSC going backwards) root@sharkbay:/home/lenb/turbostat-src# ./turbostat -M 0x10 CPU Avg_MHz Busy% Bzy_MHz TSC_MHz MSR 0x010 - 1 0.06 858 2294 0x0000000000000000 0 0 0.06 847 2294 0x0000002a254b98ac 1 1 0.06 878 2294 0x0000002a254efa3a 2 1 0.07 843 2294 0x0000002a2551df65 3 0 0.05 863 2294 0x0000002a2553fea2 turbostat: re-initialized with num_cpus 4 CPU Avg_MHz Busy% Bzy_MHz TSC_MHz MSR 0x010 - 2 0.20 849 2294 0x0000000000000000 0 2 0.26 856 2294 0x0000000449abb60d 1 2 0.20 844 2294 0x0000000449b087ec 2 2 0.21 850 2294 0x0000000449b35d5d 3 1 0.12 839 2294 0x0000000449b5fd5a ^C Command mode across ACPI S3: root@sharkbay:/home/lenb/turbostat-src# ./turbostat -M 0x10 sleep 10 ./turbostat: Counter reset detected 14.196299 sec Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 77 ++++++++++++++++------------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index a302a333c084..c0dade0c1921 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -51,8 +51,6 @@ unsigned int debug; unsigned int rapl_joules; unsigned int summary_only; unsigned int dump_only; -unsigned int skip_c0; -unsigned int skip_c1; unsigned int do_nhm_cstates; unsigned int do_snb_cstates; unsigned int do_knl_cstates; @@ -145,7 +143,6 @@ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) -int aperf_mperf_unstable; int backwards_count; char *progname; @@ -546,12 +543,8 @@ int format_counters(struct thread_data *t, struct core_data *c, 1.0 / units * t->aperf / interval_float); /* Busy% */ - if (has_aperf) { - if (!skip_c0) - outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc/tsc_tweak); - else - outp += sprintf(outp, "********"); - } + if (has_aperf) + outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc/tsc_tweak); /* Bzy_MHz */ if (has_aperf) { @@ -591,12 +584,8 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_smi) outp += sprintf(outp, "%8d", t->smi_count); - if (do_nhm_cstates) { - if (!skip_c1) - outp += sprintf(outp, "%8.2f", 100.0 * t->c1/t->tsc); - else - outp += sprintf(outp, "********"); - } + if (do_nhm_cstates) + outp += sprintf(outp, "%8.2f", 100.0 * t->c1/t->tsc); /* print per-core data only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) @@ -622,8 +611,8 @@ int format_counters(struct thread_data *t, struct core_data *c, /* GFXrc6 */ if (do_gfx_rc6_ms) { - if (p->gfx_rc6_ms == -1) { /* detect counter reset */ - outp += sprintf(outp, " ***.**"); + if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */ + outp += sprintf(outp, " **.**"); } else { outp += sprintf(outp, "%8.2f", p->gfx_rc6_ms / 10.0 / interval_float); @@ -748,7 +737,7 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_ old = 0x100000000 + new - old; \ } -void +int delta_package(struct pkg_data *new, struct pkg_data *old) { @@ -784,6 +773,8 @@ delta_package(struct pkg_data *new, struct pkg_data *old) DELTA_WRAP32(new->energy_dram, old->energy_dram); DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status); DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status); + + return 0; } void @@ -798,7 +789,7 @@ delta_core(struct core_data *new, struct core_data *old) /* * old = new - old */ -void +int delta_thread(struct thread_data *new, struct thread_data *old, struct core_data *core_delta) { @@ -817,20 +808,7 @@ delta_thread(struct thread_data *new, struct thread_data *old, old->aperf = new->aperf - old->aperf; old->mperf = new->mperf - old->mperf; } else { - - if (!aperf_mperf_unstable) { - fprintf(outf, "%s: APERF or MPERF went backwards *\n", progname); - fprintf(outf, "* Frequency results do not cover entire interval *\n"); - fprintf(outf, "* fix this by running Linux-2.6.30 or later *\n"); - - aperf_mperf_unstable = 1; - } - /* - * mperf delta is likely a huge "positive" number - * can not use it for calculating c0 time - */ - skip_c0 = 1; - skip_c1 = 1; + return -1; } } @@ -877,24 +855,30 @@ delta_thread(struct thread_data *new, struct thread_data *old, if (do_smi) old->smi_count = new->smi_count - old->smi_count; + + return 0; } int delta_cpu(struct thread_data *t, struct core_data *c, struct pkg_data *p, struct thread_data *t2, struct core_data *c2, struct pkg_data *p2) { + int retval = 0; + /* calculate core delta only for 1st thread in core */ if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE) delta_core(c, c2); /* always calculate thread delta */ - delta_thread(t, t2, c2); /* c2 is core delta */ + retval = delta_thread(t, t2, c2); /* c2 is core delta */ + if (retval) + return retval; /* calculate package delta only for 1st core in package */ if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE) - delta_package(p, p2); + retval = delta_package(p, p2); - return 0; + return retval; } void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) @@ -2067,7 +2051,10 @@ restart: } gettimeofday(&tv_odd, (struct timezone *)NULL); timersub(&tv_odd, &tv_even, &tv_delta); - for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS); + if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) { + re_initialize(); + goto restart; + } compute_average(EVEN_COUNTERS); format_all_counters(EVEN_COUNTERS); flush_output_stdout(); @@ -2083,7 +2070,10 @@ restart: } gettimeofday(&tv_even, (struct timezone *)NULL); timersub(&tv_even, &tv_odd, &tv_delta); - for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS); + if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) { + re_initialize(); + goto restart; + } compute_average(ODD_COUNTERS); format_all_counters(ODD_COUNTERS); flush_output_stdout(); @@ -3693,9 +3683,12 @@ int fork_it(char **argv) for_all_cpus(get_counters, ODD_COUNTERS); gettimeofday(&tv_odd, (struct timezone *)NULL); timersub(&tv_odd, &tv_even, &tv_delta); - for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS); - compute_average(EVEN_COUNTERS); - format_all_counters(EVEN_COUNTERS); + if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) + fprintf(outf, "%s: Counter reset detected\n", progname); + else { + compute_average(EVEN_COUNTERS); + format_all_counters(EVEN_COUNTERS); + } fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); @@ -3722,7 +3715,7 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(outf, "turbostat version 4.12 5 Apr 2016" + fprintf(outf, "turbostat version 4.13 22 Apr 2016" " - Len Brown \n"); } -- cgit v1.2.3-59-g8ed1b From 3d109de23c93e9196c370fd729fbd7ecf7371701 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 22 Apr 2016 23:24:27 -0400 Subject: tools/power turbostat: switch to tab delimited output Switch to tab-delimited output from fixed-width columns to make it simpler to import into spreadsheets. As the fixed width columnns were 8-spaces wide, the output on the screen should not change. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 170 +++++++++++++++++----------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index c0dade0c1921..be50892f27aa 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -323,103 +323,103 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) void print_header(void) { if (show_pkg) - outp += sprintf(outp, " Package"); + outp += sprintf(outp, "\tPackage"); if (show_core) - outp += sprintf(outp, " Core"); + outp += sprintf(outp, "\tCore"); if (show_cpu) - outp += sprintf(outp, " CPU"); + outp += sprintf(outp, "\tCPU"); if (has_aperf) - outp += sprintf(outp, " Avg_MHz"); + outp += sprintf(outp, "\tAvg_MHz"); if (has_aperf) - outp += sprintf(outp, " Busy%%"); + outp += sprintf(outp, "\tBusy%%"); if (has_aperf) - outp += sprintf(outp, " Bzy_MHz"); - outp += sprintf(outp, " TSC_MHz"); + outp += sprintf(outp, "\tBzy_MHz"); + outp += sprintf(outp, "\tTSC_MHz"); if (extra_delta_offset32) - outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); + outp += sprintf(outp, "\tcount 0x%03X", extra_delta_offset32); if (extra_delta_offset64) - outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); + outp += sprintf(outp, "\tCOUNT 0x%03X", extra_delta_offset64); if (extra_msr_offset32) - outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); + outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset32); if (extra_msr_offset64) - outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); + outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset64); if (!debug) goto done; if (do_irq) - outp += sprintf(outp, " IRQ"); + outp += sprintf(outp, "\tIRQ"); if (do_smi) - outp += sprintf(outp, " SMI"); + outp += sprintf(outp, "\tSMI"); if (do_nhm_cstates) - outp += sprintf(outp, " CPU%%c1"); + outp += sprintf(outp, "\tCPU%%c1"); if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) - outp += sprintf(outp, " CPU%%c3"); + outp += sprintf(outp, "\tCPU%%c3"); if (do_nhm_cstates) - outp += sprintf(outp, " CPU%%c6"); + outp += sprintf(outp, "\tCPU%%c6"); if (do_snb_cstates) - outp += sprintf(outp, " CPU%%c7"); + outp += sprintf(outp, "\tCPU%%c7"); if (do_dts) - outp += sprintf(outp, " CoreTmp"); + outp += sprintf(outp, "\tCoreTmp"); if (do_ptm) - outp += sprintf(outp, " PkgTmp"); + outp += sprintf(outp, "\tPkgTmp"); if (do_gfx_rc6_ms) - outp += sprintf(outp, " GFX%%rc6"); + outp += sprintf(outp, "\tGFX%%rc6"); if (do_gfx_mhz) - outp += sprintf(outp, " GFXMHz"); + outp += sprintf(outp, "\tGFXMHz"); if (do_skl_residency) { - outp += sprintf(outp, " Totl%%C0"); - outp += sprintf(outp, " Any%%C0"); - outp += sprintf(outp, " GFX%%C0"); - outp += sprintf(outp, " CPUGFX%%"); + outp += sprintf(outp, "\tTotl%%C0"); + outp += sprintf(outp, "\tAny%%C0"); + outp += sprintf(outp, "\tGFX%%C0"); + outp += sprintf(outp, "\tCPUGFX%%"); } if (do_pc2) - outp += sprintf(outp, " Pkg%%pc2"); + outp += sprintf(outp, "\tPkg%%pc2"); if (do_pc3) - outp += sprintf(outp, " Pkg%%pc3"); + outp += sprintf(outp, "\tPkg%%pc3"); if (do_pc6) - outp += sprintf(outp, " Pkg%%pc6"); + outp += sprintf(outp, "\tPkg%%pc6"); if (do_pc7) - outp += sprintf(outp, " Pkg%%pc7"); + outp += sprintf(outp, "\tPkg%%pc7"); if (do_c8_c9_c10) { - outp += sprintf(outp, " Pkg%%pc8"); - outp += sprintf(outp, " Pkg%%pc9"); - outp += sprintf(outp, " Pk%%pc10"); + outp += sprintf(outp, "\tPkg%%pc8"); + outp += sprintf(outp, "\tPkg%%pc9"); + outp += sprintf(outp, "\tPk%%pc10"); } if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, " PkgWatt"); + outp += sprintf(outp, "\tPkgWatt"); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, " CorWatt"); + outp += sprintf(outp, "\tCorWatt"); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, " GFXWatt"); + outp += sprintf(outp, "\tGFXWatt"); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, " RAMWatt"); + outp += sprintf(outp, "\tRAMWatt"); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, " PKG_%%"); + outp += sprintf(outp, "\tPKG_%%"); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, " RAM_%%"); + outp += sprintf(outp, "\tRAM_%%"); } else if (do_rapl && rapl_joules) { if (do_rapl & RAPL_PKG) - outp += sprintf(outp, " Pkg_J"); + outp += sprintf(outp, "\tPkg_J"); if (do_rapl & RAPL_CORES) - outp += sprintf(outp, " Cor_J"); + outp += sprintf(outp, "\tCor_J"); if (do_rapl & RAPL_GFX) - outp += sprintf(outp, " GFX_J"); + outp += sprintf(outp, "\tGFX_J"); if (do_rapl & RAPL_DRAM) - outp += sprintf(outp, " RAM_J"); + outp += sprintf(outp, "\tRAM_J"); if (do_rapl & RAPL_PKG_PERF_STATUS) - outp += sprintf(outp, " PKG_%%"); + outp += sprintf(outp, "\tPKG_%%"); if (do_rapl & RAPL_DRAM_PERF_STATUS) - outp += sprintf(outp, " RAM_%%"); + outp += sprintf(outp, "\tRAM_%%"); } done: outp += sprintf(outp, "\n"); @@ -515,91 +515,91 @@ int format_counters(struct thread_data *t, struct core_data *c, /* topo columns, print blanks on 1st (average) line */ if (t == &average.threads) { if (show_pkg) - outp += sprintf(outp, " -"); + outp += sprintf(outp, "\t-"); if (show_core) - outp += sprintf(outp, " -"); + outp += sprintf(outp, "\t-"); if (show_cpu) - outp += sprintf(outp, " -"); + outp += sprintf(outp, "\t-"); } else { if (show_pkg) { if (p) - outp += sprintf(outp, "%8d", p->package_id); + outp += sprintf(outp, "\t%d", p->package_id); else - outp += sprintf(outp, " -"); + outp += sprintf(outp, "\t-"); } if (show_core) { if (c) - outp += sprintf(outp, "%8d", c->core_id); + outp += sprintf(outp, "\t%d", c->core_id); else - outp += sprintf(outp, " -"); + outp += sprintf(outp, "\t-"); } if (show_cpu) - outp += sprintf(outp, "%8d", t->cpu_id); + outp += sprintf(outp, "\t%d", t->cpu_id); } /* Avg_MHz */ if (has_aperf) - outp += sprintf(outp, "%8.0f", + outp += sprintf(outp, "\t%.0f", 1.0 / units * t->aperf / interval_float); /* Busy% */ if (has_aperf) - outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc/tsc_tweak); + outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/t->tsc/tsc_tweak); /* Bzy_MHz */ if (has_aperf) { if (has_base_hz) - outp += sprintf(outp, "%8.0f", base_hz / units * t->aperf / t->mperf); + outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf); else - outp += sprintf(outp, "%8.0f", + outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); } /* TSC_MHz */ - outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); + outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float); /* delta */ if (extra_delta_offset32) - outp += sprintf(outp, " %11llu", t->extra_delta32); + outp += sprintf(outp, "\t%11llu", t->extra_delta32); /* DELTA */ if (extra_delta_offset64) - outp += sprintf(outp, " %11llu", t->extra_delta64); + outp += sprintf(outp, "\t%11llu", t->extra_delta64); /* msr */ if (extra_msr_offset32) - outp += sprintf(outp, " 0x%08llx", t->extra_msr32); + outp += sprintf(outp, "\t0x%08llx", t->extra_msr32); /* MSR */ if (extra_msr_offset64) - outp += sprintf(outp, " 0x%016llx", t->extra_msr64); + outp += sprintf(outp, "\t0x%016llx", t->extra_msr64); if (!debug) goto done; /* IRQ */ if (do_irq) - outp += sprintf(outp, "%8d", t->irq_count); + outp += sprintf(outp, "\t%d", t->irq_count); /* SMI */ if (do_smi) - outp += sprintf(outp, "%8d", t->smi_count); + outp += sprintf(outp, "\t%d", t->smi_count); if (do_nhm_cstates) - outp += sprintf(outp, "%8.2f", 100.0 * t->c1/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/t->tsc); /* print per-core data only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) goto done; if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) - outp += sprintf(outp, "%8.2f", 100.0 * c->c3/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/t->tsc); if (do_nhm_cstates) - outp += sprintf(outp, "%8.2f", 100.0 * c->c6/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/t->tsc); if (do_snb_cstates) - outp += sprintf(outp, "%8.2f", 100.0 * c->c7/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/t->tsc); if (do_dts) - outp += sprintf(outp, "%8d", c->core_temp_c); + outp += sprintf(outp, "\t%d", c->core_temp_c); /* print per-package data only for 1st core in package */ if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) @@ -607,42 +607,42 @@ int format_counters(struct thread_data *t, struct core_data *c, /* PkgTmp */ if (do_ptm) - outp += sprintf(outp, "%8d", p->pkg_temp_c); + outp += sprintf(outp, "\t%d", p->pkg_temp_c); /* GFXrc6 */ if (do_gfx_rc6_ms) { if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */ - outp += sprintf(outp, " **.**"); + outp += sprintf(outp, "\t**.**"); } else { - outp += sprintf(outp, "%8.2f", + outp += sprintf(outp, "\t%.2f", p->gfx_rc6_ms / 10.0 / interval_float); } } /* GFXMHz */ if (do_gfx_mhz) - outp += sprintf(outp, "%8d", p->gfx_mhz); + outp += sprintf(outp, "\t%d", p->gfx_mhz); /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */ if (do_skl_residency) { - outp += sprintf(outp, "%8.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc); - outp += sprintf(outp, "%8.2f", 100.0 * p->pkg_any_core_c0/t->tsc); - outp += sprintf(outp, "%8.2f", 100.0 * p->pkg_any_gfxe_c0/t->tsc); - outp += sprintf(outp, "%8.2f", 100.0 * p->pkg_both_core_gfxe_c0/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/t->tsc); } if (do_pc2) - outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/t->tsc); if (do_pc3) - outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/t->tsc); if (do_pc6) - outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/t->tsc); if (do_pc7) - outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/t->tsc); if (do_c8_c9_c10) { - outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc); - outp += sprintf(outp, "%8.2f", 100.0 * p->pc9/t->tsc); - outp += sprintf(outp, "%8.2f", 100.0 * p->pc10/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/t->tsc); + outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/t->tsc); } /* @@ -650,7 +650,7 @@ int format_counters(struct thread_data *t, struct core_data *c, * indicate that results are suspect by printing "**" in fraction place. */ if (interval_float < rapl_joule_counter_range) - fmt8 = "%8.2f"; + fmt8 = "\t%.2f"; else fmt8 = "%6.0f**"; @@ -3715,7 +3715,7 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(outf, "turbostat version 4.13 22 Apr 2016" + fprintf(outf, "turbostat version 4.14 22 Apr 2016" " - Len Brown \n"); } -- cgit v1.2.3-59-g8ed1b From 01a67adfc5d73d24e999d9cf65b5b8a6687187b8 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 22 Apr 2016 11:13:23 +0300 Subject: tools/power turbostat: Allocate correct amount of fd and irq entries The tool uses topo.max_cpu_num to determine number of entries needed for fd_percpu[] and irqs_per_cpu[]. For example on a system with 4 CPUs topo.max_cpu_num is 3 so we get too small array for holding per-CPU items. Fix this to use right number of entries, which is topo.max_cpu_num + 1. Signed-off-by: Mika Westerberg Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index be50892f27aa..741fefa2f07e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1618,7 +1618,7 @@ void free_fd_percpu(void) { int i; - for (i = 0; i < topo.max_cpu_num; ++i) { + for (i = 0; i < topo.max_cpu_num + 1; ++i) { if (fd_percpu[i] != 0) close(fd_percpu[i]); } @@ -3584,7 +3584,7 @@ void allocate_output_buffer() } void allocate_fd_percpu(void) { - fd_percpu = calloc(topo.max_cpu_num, sizeof(int)); + fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int)); if (fd_percpu == NULL) err(-1, "calloc fd_percpu"); } @@ -3594,9 +3594,9 @@ void allocate_irq_buffers(void) if (irq_column_2_cpu == NULL) err(-1, "calloc %d", topo.num_cpus); - irqs_per_cpu = calloc(topo.max_cpu_num, sizeof(int)); + irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int)); if (irqs_per_cpu == NULL) - err(-1, "calloc %d", topo.max_cpu_num); + err(-1, "calloc %d", topo.max_cpu_num + 1); } void setup_all_buffers(void) { -- cgit v1.2.3-59-g8ed1b From 0a91e551527a7b931d36f4822b97e70536bd2bb3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 25 Apr 2016 13:03:15 +0100 Subject: tools/power turbostat: fix error case overflow read of slm_freq_table[] When i >= SLM_BCLK_FREQS, the frequency read from the slm_freq_table is off the end of the array because msr is set to 3 rather than the actual array index i. Set i to 3 rather than msr to fix this. Signed-off-by: Colin Ian King Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 741fefa2f07e..12a6eea2d6ae 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3036,7 +3036,7 @@ double slm_bclk(void) i = msr & 0xf; if (i >= SLM_BCLK_FREQS) { fprintf(outf, "SLM BCLK[%d] invalid\n", i); - msr = 3; + i = 3; } freq = slm_freq_table[i]; -- cgit v1.2.3-59-g8ed1b From 9148494c59f53bb6c9233df07447777dc533db33 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Thu, 16 Jun 2016 09:48:20 -0700 Subject: tools/power/turbostat: split core MSR support into status + limit Some CPUs may not have PP0/Core domain power limit MSRs. We should still allow its domain energy status to be used. This patch splits PP0/Core RAPL into two separate flags for power limit and energy status such that energy status can continue to be reported without power limit. Without this patch, turbostat will not be able to use the remaining RAPL features if some PL MSRs are not present. Signed-off-by: Jacob Pan Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 12a6eea2d6ae..3a80f949e5ba 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -129,9 +129,8 @@ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ #define RAPL_DRAM_POWER_INFO (1 << 5) /* 0x61c MSR_DRAM_POWER_INFO */ -#define RAPL_CORES (1 << 6) +#define RAPL_CORES_POWER_LIMIT (1 << 6) /* 0x638 MSR_PP0_POWER_LIMIT */ - /* 0x639 MSR_PP0_ENERGY_STATUS */ #define RAPL_CORE_POLICY (1 << 7) /* 0x63a MSR_PP0_POLICY */ @@ -139,6 +138,10 @@ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ /* 0x640 MSR_PP1_POWER_LIMIT */ /* 0x641 MSR_PP1_ENERGY_STATUS */ /* 0x642 MSR_PP1_POLICY */ + +#define RAPL_CORES_ENERGY_STATUS (1 << 9) + /* 0x639 MSR_PP0_ENERGY_STATUS */ +#define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) #define TJMAX_DEFAULT 100 #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -397,7 +400,7 @@ void print_header(void) if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) outp += sprintf(outp, "\tPkgWatt"); - if (do_rapl & RAPL_CORES) + if (do_rapl & RAPL_CORES_ENERGY_STATUS) outp += sprintf(outp, "\tCorWatt"); if (do_rapl & RAPL_GFX) outp += sprintf(outp, "\tGFXWatt"); @@ -410,7 +413,7 @@ void print_header(void) } else if (do_rapl && rapl_joules) { if (do_rapl & RAPL_PKG) outp += sprintf(outp, "\tPkg_J"); - if (do_rapl & RAPL_CORES) + if (do_rapl & RAPL_CORES_ENERGY_STATUS) outp += sprintf(outp, "\tCor_J"); if (do_rapl & RAPL_GFX) outp += sprintf(outp, "\tGFX_J"); @@ -657,7 +660,7 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_rapl && !rapl_joules) { if (do_rapl & RAPL_PKG) outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float); - if (do_rapl & RAPL_CORES) + if (do_rapl & RAPL_CORES_ENERGY_STATUS) outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float); if (do_rapl & RAPL_GFX) outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float); @@ -1217,7 +1220,7 @@ retry: return -13; p->energy_pkg = msr & 0xFFFFFFFF; } - if (do_rapl & RAPL_CORES) { + if (do_rapl & RAPL_CORES_ENERGY_STATUS) { if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr)) return -14; p->energy_cores = msr & 0xFFFFFFFF; @@ -2657,7 +2660,7 @@ void rapl_probe(unsigned int family, unsigned int model) break; case 0x37: /* BYT */ case 0x4D: /* AVN */ - do_rapl = RAPL_PKG | RAPL_CORES ; + do_rapl = RAPL_PKG | RAPL_CORES; break; default: return; @@ -2872,9 +2875,8 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); } } - if (do_rapl & RAPL_CORES) { + if (do_rapl & RAPL_CORES_POWER_LIMIT) { if (debug) { - if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) return -9; fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n", -- cgit v1.2.3-59-g8ed1b From 2c48c990ea330ae8079488fdf1d156620c6f9d0c Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Thu, 16 Jun 2016 09:48:21 -0700 Subject: tools/power/turbostat: Add Denverton support Denverton is an Atom based micro server which shares the same Goldmont architecture as Broxton. The available C-states on Denverton is a subset of Broxton with only C1, C1e, and C6. Signed-off-by: Jacob Pan Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 3a80f949e5ba..16ccada7e439 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2204,6 +2204,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) pkg_cstate_limits = phi_pkg_cstate_limits; break; case 0x5C: /* BXT */ + case 0x5F: /* DNV */ pkg_cstate_limits = bxt_pkg_cstate_limits; break; default: @@ -3301,6 +3302,7 @@ void process_cpuid() crystal_hz = 25000000; /* 25.0 MHz */ break; case 0x5C: /* BXT */ + case 0x5F: /* DNV */ crystal_hz = 19200000; /* 19.2 MHz */ break; default: -- cgit v1.2.3-59-g8ed1b From 0f64490978ef9ed4debe33bf0dbf25e80659f7f7 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Thu, 16 Jun 2016 09:48:22 -0700 Subject: tools/power/turbostat: Add Denverton RAPL support The Denverton CPU RAPL supports package, core, and DRAM domains. Signed-off-by: Jacob Pan Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 16ccada7e439..70a6699c528c 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2663,6 +2663,9 @@ void rapl_probe(unsigned int family, unsigned int model) case 0x4D: /* AVN */ do_rapl = RAPL_PKG | RAPL_CORES; break; + case 0x5f: /* DNV */ + do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS; + break; default: return; } -- cgit v1.2.3-59-g8ed1b From 869ce69e1e8ae7e6fa4a1a90887e5f94eac653eb Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 16 Jun 2016 23:22:37 -0400 Subject: tools/power turbostat: use intel-family.h model strings All except for model 1F, a Nehalem, which is currently incorrectly indentified as a Westmere in that new header. Signed-off-by: Len Brown --- tools/power/x86/turbostat/Makefile | 1 + tools/power/x86/turbostat/turbostat.c | 249 +++++++++++++++++----------------- 2 files changed, 126 insertions(+), 124 deletions(-) diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index 8561e7ddca59..8792ad8dbf83 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile @@ -10,6 +10,7 @@ endif turbostat : turbostat.c CFLAGS += -Wall CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' +CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' %: %.c @mkdir -p $(BUILD_OUTPUT) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 70a6699c528c..2056c148c684 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -21,6 +21,7 @@ #define _GNU_SOURCE #include MSRHEADER +#include INTEL_FAMILY_HEADER #include #include #include @@ -2163,48 +2164,48 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) bclk = discover_bclk(family, model); switch (model) { - case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ - case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ + case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ + case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ case 0x1F: /* Core i7 and i5 Processor - Nehalem */ - case 0x25: /* Westmere Client - Clarkdale, Arrandale */ - case 0x2C: /* Westmere EP - Gulftown */ - case 0x2E: /* Nehalem-EX Xeon - Beckton */ - case 0x2F: /* Westmere-EX Xeon - Eagleton */ + case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */ + case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */ + case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ + case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ pkg_cstate_limits = nhm_pkg_cstate_limits; break; - case 0x2A: /* SNB */ - case 0x2D: /* SNB Xeon */ - case 0x3A: /* IVB */ - case 0x3E: /* IVB Xeon */ + case INTEL_FAM6_SANDYBRIDGE: /* SNB */ + case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */ + case INTEL_FAM6_IVYBRIDGE: /* IVB */ + case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ pkg_cstate_limits = snb_pkg_cstate_limits; break; - case 0x3C: /* HSW */ - case 0x3F: /* HSX */ - case 0x45: /* HSW */ - case 0x46: /* HSW */ - case 0x3D: /* BDW */ - case 0x47: /* BDW */ - case 0x4F: /* BDX */ - case 0x56: /* BDX-DE */ - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ - case 0x55: /* SKX */ + case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_X: /* HSX */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_X: /* BDX */ + case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ + case INTEL_FAM6_SKYLAKE_X: /* SKX */ pkg_cstate_limits = hsw_pkg_cstate_limits; break; - case 0x37: /* BYT */ - case 0x4D: /* AVN */ + case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ + case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ pkg_cstate_limits = slv_pkg_cstate_limits; break; - case 0x4C: /* AMT */ + case INTEL_FAM6_ATOM_AIRMONT: /* AMT */ pkg_cstate_limits = amt_pkg_cstate_limits; break; - case 0x57: /* PHI */ + case INTEL_FAM6_XEON_PHI_KNL: /* PHI */ pkg_cstate_limits = phi_pkg_cstate_limits; break; - case 0x5C: /* BXT */ - case 0x5F: /* DNV */ + case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ + case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ pkg_cstate_limits = bxt_pkg_cstate_limits; break; default: @@ -2224,9 +2225,9 @@ int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) { switch (model) { /* Nehalem compatible, but do not include turbo-ratio limit support */ - case 0x2E: /* Nehalem-EX Xeon - Beckton */ - case 0x2F: /* Westmere-EX Xeon - Eagleton */ - case 0x57: /* PHI - Knights Landing (different MSR definition) */ + case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ + case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ + case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */ return 0; default: return 1; @@ -2241,8 +2242,8 @@ int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x3E: /* IVB Xeon */ - case 0x3F: /* HSW Xeon */ + case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ + case INTEL_FAM6_HASWELL_X: /* HSW Xeon */ return 1; default: return 0; @@ -2257,7 +2258,7 @@ int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x3F: /* HSW Xeon */ + case INTEL_FAM6_HASWELL_X: /* HSW Xeon */ return 1; default: return 0; @@ -2273,7 +2274,7 @@ int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x57: /* Knights Landing */ + case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ return 1; default: return 0; @@ -2288,22 +2289,22 @@ int has_config_tdp(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x3A: /* IVB */ - case 0x3C: /* HSW */ - case 0x3F: /* HSX */ - case 0x45: /* HSW */ - case 0x46: /* HSW */ - case 0x3D: /* BDW */ - case 0x47: /* BDW */ - case 0x4F: /* BDX */ - case 0x56: /* BDX-DE */ - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ - case 0x55: /* SKX */ - - case 0x57: /* Knights Landing */ + case INTEL_FAM6_IVYBRIDGE: /* IVB */ + case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_X: /* HSX */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_X: /* BDX */ + case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ + case INTEL_FAM6_SKYLAKE_X: /* SKX */ + + case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ return 1; default: return 0; @@ -2583,8 +2584,8 @@ double get_tdp(unsigned int model) return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; switch (model) { - case 0x37: - case 0x4D: + case INTEL_FAM6_ATOM_SILVERMONT1: + case INTEL_FAM6_ATOM_SILVERMONT2: return 30.0; default: return 135.0; @@ -2601,10 +2602,10 @@ rapl_dram_energy_units_probe(int model, double rapl_energy_units) /* only called for genuine_intel, family 6 */ switch (model) { - case 0x3F: /* HSX */ - case 0x4F: /* BDX */ - case 0x56: /* BDX-DE */ - case 0x57: /* KNL */ + case INTEL_FAM6_HASWELL_X: /* HSX */ + case INTEL_FAM6_BROADWELL_X: /* BDX */ + case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ return (rapl_dram_energy_units = 15.3 / 1000000); default: return (rapl_energy_units); @@ -2630,40 +2631,40 @@ void rapl_probe(unsigned int family, unsigned int model) return; switch (model) { - case 0x2A: - case 0x3A: - case 0x3C: /* HSW */ - case 0x45: /* HSW */ - case 0x46: /* HSW */ - case 0x3D: /* BDW */ - case 0x47: /* BDW */ + case INTEL_FAM6_SANDYBRIDGE: + case INTEL_FAM6_IVYBRIDGE: + case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; break; - case 0x5C: /* BXT */ + case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO; break; - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; break; - case 0x3F: /* HSX */ - case 0x4F: /* BDX */ - case 0x56: /* BDX-DE */ - case 0x55: /* SKX */ - case 0x57: /* KNL */ + case INTEL_FAM6_HASWELL_X: /* HSX */ + case INTEL_FAM6_BROADWELL_X: /* BDX */ + case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + case INTEL_FAM6_SKYLAKE_X: /* SKX */ + case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; break; - case 0x2D: - case 0x3E: + case INTEL_FAM6_SANDYBRIDGE_X: + case INTEL_FAM6_IVYBRIDGE_X: do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO; break; - case 0x37: /* BYT */ - case 0x4D: /* AVN */ + case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ + case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ do_rapl = RAPL_PKG | RAPL_CORES; break; - case 0x5f: /* DNV */ + case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS; break; default: @@ -2675,7 +2676,7 @@ void rapl_probe(unsigned int family, unsigned int model) return; rapl_power_units = 1.0 / (1 << (msr & 0xF)); - if (model == 0x37) + if (model == INTEL_FAM6_ATOM_SILVERMONT1) rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000; else rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); @@ -2706,11 +2707,11 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) return; switch (model) { - case 0x3C: /* HSW */ - case 0x45: /* HSW */ - case 0x46: /* HSW */ + case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_HASWELL_GT3E: /* HSW */ do_gfx_perf_limit_reasons = 1; - case 0x3F: /* HSX */ + case INTEL_FAM6_HASWELL_X: /* HSX */ do_core_perf_limit_reasons = 1; do_ring_perf_limit_reasons = 1; default: @@ -2919,24 +2920,24 @@ int has_snb_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x2A: - case 0x2D: - case 0x3A: /* IVB */ - case 0x3E: /* IVB Xeon */ - case 0x3C: /* HSW */ - case 0x3F: /* HSW */ - case 0x45: /* HSW */ - case 0x46: /* HSW */ - case 0x3D: /* BDW */ - case 0x47: /* BDW */ - case 0x4F: /* BDX */ - case 0x56: /* BDX-DE */ - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ - case 0x55: /* SKX */ - case 0x5C: /* BXT */ + case INTEL_FAM6_SANDYBRIDGE: + case INTEL_FAM6_SANDYBRIDGE_X: + case INTEL_FAM6_IVYBRIDGE: /* IVB */ + case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ + case INTEL_FAM6_HASWELL_CORE: /* HSW */ + case INTEL_FAM6_HASWELL_X: /* HSW */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_HASWELL_GT3E: /* HSW */ + case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ + case INTEL_FAM6_BROADWELL_X: /* BDX */ + case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ + case INTEL_FAM6_SKYLAKE_X: /* SKX */ + case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ return 1; } return 0; @@ -2960,13 +2961,13 @@ int has_hsw_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x45: /* HSW */ - case 0x3D: /* BDW */ - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ - case 0x5C: /* BXT */ + case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_BROADWELL_CORE: /* BDW */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ + case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ return 1; } return 0; @@ -2986,10 +2987,10 @@ int has_skl_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ return 1; } return 0; @@ -3002,8 +3003,8 @@ int is_slm(unsigned int family, unsigned int model) if (!genuine_intel) return 0; switch (model) { - case 0x37: /* BYT */ - case 0x4D: /* AVN */ + case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ + case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ return 1; } return 0; @@ -3014,7 +3015,7 @@ int is_knl(unsigned int family, unsigned int model) if (!genuine_intel) return 0; switch (model) { - case 0x57: /* KNL */ + case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ return 1; } return 0; @@ -3295,17 +3296,17 @@ void process_cpuid() if (crystal_hz == 0) switch(model) { - case 0x4E: /* SKL */ - case 0x5E: /* SKL */ - case 0x8E: /* KBL */ - case 0x9E: /* KBL */ + case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ + case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ + case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ + case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ crystal_hz = 24000000; /* 24.0 MHz */ break; - case 0x55: /* SKX */ + case INTEL_FAM6_SKYLAKE_X: /* SKX */ crystal_hz = 25000000; /* 25.0 MHz */ break; - case 0x5C: /* BXT */ - case 0x5F: /* DNV */ + case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ + case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ crystal_hz = 19200000; /* 19.2 MHz */ break; default: -- cgit v1.2.3-59-g8ed1b From 5bbac26eae35065a9b2a5279118daad14f88eae9 Mon Sep 17 00:00:00 2001 From: Xiaolong Wang Date: Fri, 30 Sep 2016 17:53:40 +0800 Subject: tools/power turbostat: fix Denverton BCLK Add Denverton to the group of SandyBridge and later processors, to let the bclk be recognized as 100MHz rather than 133MHz, then avoid the wrong value of the frequencies based on it, including Bzy_MHz, max efficiency freuency, base frequency, and turbo mode frequencies. Signed-off-by: Xiaolong Wang Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 2056c148c684..89c31e90a85e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2938,6 +2938,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ + case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ return 1; } return 0; -- cgit v1.2.3-59-g8ed1b From ddadb8adea76e6168c55850f2066e441880fb3d5 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 11 Nov 2016 14:29:48 -0800 Subject: tools/power turbostat: Display HWP OOB status Display if the HWP is enabled in OOB (Out of band) mode. Signed-off-by: Srinivas Pandruvada Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 89c31e90a85e..83d1fb9750aa 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3168,10 +3168,11 @@ void decode_misc_pwr_mgmt_msr(void) return; if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr)) - fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB)\n", + fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n", base_cpu, msr, msr & (1 << 0) ? "DIS" : "EN", - msr & (1 << 1) ? "EN" : "DIS"); + msr & (1 << 1) ? "EN" : "DIS", + msr & (1 << 8) ? "EN" : "DIS"); } void process_cpuid() -- cgit v1.2.3-59-g8ed1b From 005c82d64d1aa49290a39573019f73b5088beeff Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Dec 2016 01:35:38 -0500 Subject: tools/power turbostat: Support Knights Mill (KNM) Original-author: Piotr Luc Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 83d1fb9750aa..a54ca3775521 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -2202,6 +2202,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) pkg_cstate_limits = amt_pkg_cstate_limits; break; case INTEL_FAM6_XEON_PHI_KNL: /* PHI */ + case INTEL_FAM6_XEON_PHI_KNM: pkg_cstate_limits = phi_pkg_cstate_limits; break; case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ @@ -2228,6 +2229,7 @@ int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */ + case INTEL_FAM6_XEON_PHI_KNM: return 0; default: return 1; @@ -2275,6 +2277,7 @@ int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ + case INTEL_FAM6_XEON_PHI_KNM: return 1; default: return 0; @@ -2305,6 +2308,7 @@ int has_config_tdp(unsigned int family, unsigned int model) case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ + case INTEL_FAM6_XEON_PHI_KNM: return 1; default: return 0; @@ -2606,6 +2610,7 @@ rapl_dram_energy_units_probe(int model, double rapl_energy_units) case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ + case INTEL_FAM6_XEON_PHI_KNM: return (rapl_dram_energy_units = 15.3 / 1000000); default: return (rapl_energy_units); @@ -2654,6 +2659,7 @@ void rapl_probe(unsigned int family, unsigned int model) case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ + case INTEL_FAM6_XEON_PHI_KNM: do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; break; case INTEL_FAM6_SANDYBRIDGE_X: @@ -3017,6 +3023,7 @@ int is_knl(unsigned int family, unsigned int model) return 0; switch (model) { case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ + case INTEL_FAM6_XEON_PHI_KNM: return 1; } return 0; -- cgit v1.2.3-59-g8ed1b From d8ebb442264de62d5d0157adb8f0df96e831b3d3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Dec 2016 20:27:46 -0500 Subject: tools/power turbostat: fix SKX PKG_CSTATE_LIMIT decoding SKX has fewer package C-states than previous generations, and so the decoding of PKG_CSTATE_LIMIT has changed. This changes the line ending with pkg-cstate-limit=XXX: pcYYY Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index a54ca3775521..10ae4ffe137c 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1294,6 +1294,7 @@ int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, int 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}; int 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}; int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; +int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; static void @@ -2191,9 +2192,11 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ - case INTEL_FAM6_SKYLAKE_X: /* SKX */ pkg_cstate_limits = hsw_pkg_cstate_limits; break; + case INTEL_FAM6_SKYLAKE_X: /* SKX */ + pkg_cstate_limits = skx_pkg_cstate_limits; + break; case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ pkg_cstate_limits = slv_pkg_cstate_limits; -- cgit v1.2.3-59-g8ed1b From 5cc6323c797687d7193fef6deec589c23f16289a Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Dec 2016 21:14:38 -0500 Subject: tools/power turbostat: line up headers when -M is used The -M option adds an 18-column item, and the header needs to be wide enough to keep the header aligned with the columns. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 10ae4ffe137c..cfdb574ea302 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -345,7 +345,7 @@ void print_header(void) if (extra_delta_offset64) outp += sprintf(outp, "\tCOUNT 0x%03X", extra_delta_offset64); if (extra_msr_offset32) - outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset32); + outp += sprintf(outp, "\t MSR 0x%03X", extra_msr_offset32); if (extra_msr_offset64) outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset64); -- cgit v1.2.3-59-g8ed1b From 7268d407ad4c49fbd521fb2e2f675a447bfef472 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Dec 2016 23:10:39 -0500 Subject: tools/power turbostat: Denverton uses a 25 MHz crystal, not 19.2 MHz This changes only the TSC frequency decoding line seen with --debug old: TSC: 1382 MHz (19200000 Hz * 216 / 3 / 1000000) new: TSC: 1800 MHz (25000000 Hz * 216 / 3 / 1000000) Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index cfdb574ea302..3708386531f2 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3315,10 +3315,10 @@ void process_cpuid() crystal_hz = 24000000; /* 24.0 MHz */ break; case INTEL_FAM6_SKYLAKE_X: /* SKX */ + case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ crystal_hz = 25000000; /* 25.0 MHz */ break; case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ - case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ crystal_hz = 19200000; /* 19.2 MHz */ break; default: -- cgit v1.2.3-59-g8ed1b From 388e9c8134be6bbc3751ba7072f5fa9bc8ecbe01 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 22 Dec 2016 23:57:55 -0500 Subject: tools/power turbostat: Make extensible via the --add parameter Create the "--add" parameter. This can be used to teach an existing turbostat binary about any number of any type of counter. turbostat(8) details the syntax for --add. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.8 | 22 ++ tools/power/x86/turbostat/turbostat.c | 396 +++++++++++++++++++++++++++++++++- 2 files changed, 409 insertions(+), 9 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 492e84fbebfa..39f7daeb6fbd 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -25,6 +25,28 @@ Some information is not available on older processors. .SS Options Options can be specified with a single or double '-', and only as much of the option name as necessary to disambiguate it from others is necessary. Note that options are case-sensitive. +.PP +\fB--add attributes\fP add column with counter having specified 'attributes'. The 'location' attribute is required, all others are optional. +.nf + location: {\fBmsrDDD\fP | \fBmsr0xXXX\fP} + msrDDD is a decimal offset, eg. msr16 + msr0xXXX is a hex offset, eg. msr0x10 + + scope: {\fBcpu\fP | \fBcore\fP | \fBpackage\fP} + sample and print the counter for every cpu, core, or package. + default: cpu + + size: {\fBu32\fP | \fBu64\fP } + MSRs are read as 64-bits, u32 truncates the displayed value to 32-bits. + default: u64 + + format: {\fBraw\fP | \fBdelta\fP | \fBpercent\fP} + 'raw' shows the MSR contents in hex. + 'delta' shows the difference in values during the measurement interval. + 'percent' shows the delta as a percentage of the cycles elapsed. + default: delta +.fi +.PP \fB--Counter MSR#\fP shows the delta of the specified 64-bit MSR counter. .PP \fB--counter MSR#\fP shows the delta of the specified 32-bit MSR counter. diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 3708386531f2..4490a776bbae 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -147,6 +147,12 @@ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) +/* + * buffer size used by sscanf() for added column names + * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters + */ +#define NAME_BYTES 20 + int backwards_count; char *progname; @@ -168,6 +174,7 @@ struct thread_data { unsigned int flags; #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 + unsigned long long counter[1]; } *thread_even, *thread_odd; struct core_data { @@ -176,6 +183,7 @@ struct core_data { unsigned long long c7; unsigned int core_temp_c; unsigned int core_id; + unsigned long long counter[1]; } *core_even, *core_odd; struct pkg_data { @@ -200,7 +208,7 @@ struct pkg_data { unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */ unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */ unsigned int pkg_temp_c; - + unsigned long long counter[1]; } *package_even, *package_odd; #define ODD_COUNTERS thread_odd, core_odd, package_odd @@ -214,11 +222,33 @@ struct pkg_data { (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no)) #define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no) +enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE}; +enum counter_type {COUNTER_CYCLES, COUNTER_SECONDS}; +enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT}; + +struct msr_counter { + unsigned int msr_num; + char name[NAME_BYTES]; + unsigned int width; + enum counter_type type; + enum counter_format format; + struct msr_counter *next; +}; + +struct sys_counters { + unsigned int thread_counter_bytes; + unsigned int core_counter_bytes; + unsigned int package_counter_bytes; + struct msr_counter *tp; + struct msr_counter *cp; + struct msr_counter *pp; +} sys; + struct system_summary { struct thread_data threads; struct core_data cores; struct pkg_data packages; -} sum, average; +} average; struct topo_params { @@ -320,12 +350,14 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) /* * Example Format w/ field column widths: * - * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz IRQ SMI Busy% CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp GFXMHz Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt + * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz IRQ SMI Busy% CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 ThreadC CoreTmp CoreCnt PkgTmp GFXMHz Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt PkgCnt * 12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678 */ void print_header(void) { + struct msr_counter *mp; + if (show_pkg) outp += sprintf(outp, "\tPackage"); if (show_core) @@ -366,8 +398,31 @@ void print_header(void) if (do_snb_cstates) outp += sprintf(outp, "\tCPU%%c7"); + for (mp = sys.tp; mp; mp = mp->next) { + if (mp->format == FORMAT_RAW) { + if (mp->width == 64) + outp += sprintf(outp, "\t%18.18s", mp->name); + else + outp += sprintf(outp, "\t%10.10s", mp->name); + } else { + outp += sprintf(outp, "\t%-7.7s", mp->name); + } + } + if (do_dts) outp += sprintf(outp, "\tCoreTmp"); + + for (mp = sys.cp; mp; mp = mp->next) { + if (mp->format == FORMAT_RAW) { + if (mp->width == 64) + outp += sprintf(outp, "\t%18.18s", mp->name); + else + outp += sprintf(outp, "\t%10.10s", mp->name); + } else { + outp += sprintf(outp, "\t%-7.7s", mp->name); + } + } + if (do_ptm) outp += sprintf(outp, "\tPkgTmp"); @@ -425,13 +480,27 @@ void print_header(void) if (do_rapl & RAPL_DRAM_PERF_STATUS) outp += sprintf(outp, "\tRAM_%%"); } - done: + for (mp = sys.pp; mp; mp = mp->next) { + if (mp->format == FORMAT_RAW) { + if (mp->width == 64) + outp += sprintf(outp, "\t%18.18s", mp->name); + else + outp += sprintf(outp, "\t%10.10s", mp->name); + } else { + outp += sprintf(outp, "\t%-7.7s", mp->name); + } + } + +done: outp += sprintf(outp, "\n"); } int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) { + int i; + struct msr_counter *mp; + outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p); if (t) { @@ -453,6 +522,11 @@ int dump_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, "IRQ: %08X\n", t->irq_count); if (do_smi) outp += sprintf(outp, "SMI: %08X\n", t->smi_count); + + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n", + i, mp->msr_num, t->counter[i]); + } } if (c) { @@ -461,6 +535,11 @@ int dump_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, "c6: %016llX\n", c->c6); outp += sprintf(outp, "c7: %016llX\n", c->c7); outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); + + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { + outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", + i, mp->msr_num, c->counter[i]); + } } if (p) { @@ -490,6 +569,11 @@ int dump_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, "Throttle RAM: %0X\n", p->rapl_dram_perf_status); outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c); + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { + outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n", + i, mp->msr_num, p->counter[i]); + } } outp += sprintf(outp, "\n"); @@ -505,6 +589,8 @@ int format_counters(struct thread_data *t, struct core_data *c, { double interval_float; char *fmt8; + int i; + struct msr_counter *mp; /* if showing only 1st thread in core and this isn't one, bail out */ if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) @@ -602,9 +688,36 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_snb_cstates) outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/t->tsc); + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += sprintf(outp, "\t0x%08lx", (unsigned long) t->counter[i]); + else + outp += sprintf(outp, "\t0x%016llx", t->counter[i]); + } else if (mp->format == FORMAT_DELTA) { + outp += sprintf(outp, "\t%8lld", t->counter[i]); + } else if (mp->format == FORMAT_PERCENT) { + outp += sprintf(outp, "\t%.2f", 100.0 * t->counter[i]/t->tsc); + } + } + + if (do_dts) outp += sprintf(outp, "\t%d", c->core_temp_c); + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += sprintf(outp, "\t0x%08lx", (unsigned long) c->counter[i]); + else + outp += sprintf(outp, "\t0x%016llx", c->counter[i]); + } else if (mp->format == FORMAT_DELTA) { + outp += sprintf(outp, "\t%8lld", c->counter[i]); + } else if (mp->format == FORMAT_PERCENT) { + outp += sprintf(outp, "\t%.2f", 100.0 * c->counter[i]/t->tsc); + } + } + /* print per-package data only for 1st core in package */ if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) goto done; @@ -689,6 +802,19 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_rapl & RAPL_DRAM_PERF_STATUS) outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); } + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += sprintf(outp, "\t0x%08lx", (unsigned long) p->counter[i]); + else + outp += sprintf(outp, "\t0x%016llx", p->counter[i]); + } else if (mp->format == FORMAT_DELTA) { + outp += sprintf(outp, "\t%8lld", p->counter[i]); + } else if (mp->format == FORMAT_PERCENT) { + outp += sprintf(outp, "\t%.2f", 100.0 * p->counter[i]/t->tsc); + } + } + done: outp += sprintf(outp, "\n"); @@ -744,6 +870,8 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_ int delta_package(struct pkg_data *new, struct pkg_data *old) { + int i; + struct msr_counter *mp; if (do_skl_residency) { old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0; @@ -778,16 +906,33 @@ delta_package(struct pkg_data *new, struct pkg_data *old) DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status); DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status); + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + old->counter[i] = new->counter[i]; + else + old->counter[i] = new->counter[i] - old->counter[i]; + } + return 0; } void delta_core(struct core_data *new, struct core_data *old) { + int i; + struct msr_counter *mp; + old->c3 = new->c3 - old->c3; old->c6 = new->c6 - old->c6; old->c7 = new->c7 - old->c7; old->core_temp_c = new->core_temp_c; + + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + old->counter[i] = new->counter[i]; + else + old->counter[i] = new->counter[i] - old->counter[i]; + } } /* @@ -797,6 +942,9 @@ int delta_thread(struct thread_data *new, struct thread_data *old, struct core_data *core_delta) { + int i; + struct msr_counter *mp; + old->tsc = new->tsc - old->tsc; /* check for TSC < 1 Mcycles over interval */ @@ -860,6 +1008,12 @@ delta_thread(struct thread_data *new, struct thread_data *old, if (do_smi) old->smi_count = new->smi_count - old->smi_count; + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + old->counter[i] = new->counter[i]; + else + old->counter[i] = new->counter[i] - old->counter[i]; + } return 0; } @@ -887,6 +1041,9 @@ int delta_cpu(struct thread_data *t, struct core_data *c, void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) { + int i; + struct msr_counter *mp; + t->tsc = 0; t->aperf = 0; t->mperf = 0; @@ -932,10 +1089,22 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data p->gfx_rc6_ms = 0; p->gfx_mhz = 0; + + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) + t->counter[i] = 0; + + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) + c->counter[i] = 0; + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) + p->counter[i] = 0; } int sum_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) { + int i; + struct msr_counter *mp; + average.threads.tsc += t->tsc; average.threads.aperf += t->aperf; average.threads.mperf += t->mperf; @@ -947,6 +1116,12 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.threads.irq_count += t->irq_count; average.threads.smi_count += t->smi_count; + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + continue; + average.threads.counter[i] += t->counter[i]; + } + /* sum per-core values only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) return 0; @@ -957,6 +1132,12 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + continue; + average.cores.counter[i] += c->counter[i]; + } + /* sum per-pkg values only for 1st core in pkg */ if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) return 0; @@ -991,6 +1172,12 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status; average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status; + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + continue; + average.packages.counter[i] += p->counter[i]; + } return 0; } /* @@ -1000,6 +1187,9 @@ int sum_counters(struct thread_data *t, struct core_data *c, void compute_average(struct thread_data *t, struct core_data *c, struct pkg_data *p) { + int i; + struct msr_counter *mp; + clear_counters(&average.threads, &average.cores, &average.packages); for_all_cpus(sum_counters, t, c, p); @@ -1036,6 +1226,22 @@ void compute_average(struct thread_data *t, struct core_data *c, average.packages.pc8 /= topo.num_packages; average.packages.pc9 /= topo.num_packages; average.packages.pc10 /= topo.num_packages; + + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + continue; + average.threads.counter[i] /= topo.num_cpus; + } + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + continue; + average.cores.counter[i] /= topo.num_cores; + } + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { + if (mp->format == FORMAT_RAW) + continue; + average.packages.counter[i] /= topo.num_packages; + } } static unsigned long long rdtsc(void) @@ -1057,6 +1263,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) int cpu = t->cpu_id; unsigned long long msr; int aperf_mperf_retry_count = 0; + struct msr_counter *mp; + int i; if (cpu_migrate(cpu)) { fprintf(outf, "Could not migrate to CPU %d\n", cpu); @@ -1154,6 +1362,12 @@ retry: return -6; } + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { + if (get_msr(cpu, mp->msr_num, &t->counter[i])) + return -10; + } + + /* collect core counters only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) return 0; @@ -1181,6 +1395,10 @@ retry: c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); } + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { + if (get_msr(cpu, mp->msr_num, &c->counter[i])) + return -10; + } /* collect package counters only for 1st core in package */ if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) @@ -1258,6 +1476,11 @@ retry: if (do_gfx_mhz) p->gfx_mhz = gfx_cur_mhz; + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { + if (get_msr(cpu, mp->msr_num, &p->counter[i])) + return -10; + } + return 0; } @@ -2740,7 +2963,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p cpu = t->cpu_id; /* DTS is per-core, no need to print for each thread */ - if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) + if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) return 0; if (cpu_migrate(cpu)) { @@ -3391,6 +3614,8 @@ void help() "when COMMAND completes.\n" "If no COMMAND is specified, turbostat wakes every 5-seconds\n" "to print statistics, until interrupted.\n" + "--add add a counter\n" + " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n" "--debug run in \"debug\" mode\n" "--interval sec Override default 5-second measurement interval\n" "--help print this help message\n" @@ -3521,7 +3746,7 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data int i; *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg * - topo.num_packages, sizeof(struct thread_data)); + topo.num_packages, sizeof(struct thread_data) + sys.thread_counter_bytes); if (*t == NULL) goto error; @@ -3530,14 +3755,14 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data (*t)[i].cpu_id = -1; *c = calloc(topo.num_cores_per_pkg * topo.num_packages, - sizeof(struct core_data)); + sizeof(struct core_data) + sys.core_counter_bytes); if (*c == NULL) goto error; for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++) (*c)[i].core_id = -1; - *p = calloc(topo.num_packages, sizeof(struct pkg_data)); + *p = calloc(topo.num_packages, sizeof(struct pkg_data) + sys.package_counter_bytes); if (*p == NULL) goto error; @@ -3735,15 +3960,165 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(outf, "turbostat version 4.14 22 Apr 2016" + fprintf(outf, "turbostat version 4.15 21 Dec 2016" " - Len Brown \n"); } +int add_counter(unsigned int msr_num, char *name, unsigned int width, + enum counter_scope scope, enum counter_type type, + enum counter_format format) +{ + struct msr_counter *msrp; + + msrp = calloc(1, sizeof(struct msr_counter)); + if (msrp == NULL) { + perror("calloc"); + exit(1); + } + + msrp->msr_num = msr_num; + strncpy(msrp->name, name, NAME_BYTES); + msrp->width = width; + msrp->type = type; + msrp->format = format; + + switch (scope) { + + case SCOPE_CPU: + sys.thread_counter_bytes += 64; + msrp->next = sys.tp; + sys.tp = msrp; + sys.thread_counter_bytes += sizeof(unsigned long long); + break; + + case SCOPE_CORE: + sys.core_counter_bytes += 64; + msrp->next = sys.cp; + sys.cp = msrp; + sys.core_counter_bytes += sizeof(unsigned long long); + break; + + case SCOPE_PACKAGE: + sys.package_counter_bytes += 64; + msrp->next = sys.pp; + sys.pp = msrp; + sys.package_counter_bytes += sizeof(unsigned long long); + break; + } + + return 0; +} + +void parse_add_command(char *add_command) +{ + int msr_num = 0; + char name_buffer[NAME_BYTES]; + int width = 64; + int fail = 0; + enum counter_scope scope = SCOPE_CPU; + enum counter_type type = COUNTER_CYCLES; + enum counter_format format = FORMAT_DELTA; + + while (add_command) { + + if (sscanf(add_command, "msr0x%x", &msr_num) == 1) + goto next; + + if (sscanf(add_command, "msr%d", &msr_num) == 1) + goto next; + + if (sscanf(add_command, "u%d", &width) == 1) { + if ((width == 32) || (width == 64)) + goto next; + width = 64; + } + if (!strncmp(add_command, "cpu", strlen("cpu"))) { + scope = SCOPE_CPU; + goto next; + } + if (!strncmp(add_command, "core", strlen("core"))) { + scope = SCOPE_CORE; + goto next; + } + if (!strncmp(add_command, "package", strlen("package"))) { + scope = SCOPE_PACKAGE; + goto next; + } + if (!strncmp(add_command, "cycles", strlen("cycles"))) { + type = COUNTER_CYCLES; + goto next; + } + if (!strncmp(add_command, "seconds", strlen("seconds"))) { + type = COUNTER_SECONDS; + goto next; + } + if (!strncmp(add_command, "raw", strlen("raw"))) { + format = FORMAT_RAW; + goto next; + } + if (!strncmp(add_command, "delta", strlen("delta"))) { + format = FORMAT_DELTA; + goto next; + } + if (!strncmp(add_command, "percent", strlen("percent"))) { + format = FORMAT_PERCENT; + goto next; + } + + if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) { /* 18 < NAME_BYTES */ + char *eos; + + eos = strchr(name_buffer, ','); + if (eos) + *eos = '\0'; + goto next; + } + +next: + add_command = strchr(add_command, ','); + if (add_command) + add_command++; + + } + if (msr_num == 0) { + fprintf(stderr, "--add: (msrDDD | msr0xXXX) required\n"); + fail++; + } + + /* generate default column header */ + if (*name_buffer == '\0') { + if (format == FORMAT_RAW) { + if (width == 32) + sprintf(name_buffer, "msr%d", msr_num); + else + sprintf(name_buffer, "MSR%d", msr_num); + } else if (format == FORMAT_DELTA) { + if (width == 32) + sprintf(name_buffer, "cnt%d", msr_num); + else + sprintf(name_buffer, "CNT%d", msr_num); + } else if (format == FORMAT_PERCENT) { + if (width == 32) + sprintf(name_buffer, "msr%d%%", msr_num); + else + sprintf(name_buffer, "MSR%d%%", msr_num); + } + } + + if (add_counter(msr_num, name_buffer, width, scope, type, format)) + fail++; + + if (fail) { + help(); + exit(1); + } +} void cmdline(int argc, char **argv) { int opt; int option_index = 0; static struct option long_options[] = { + {"add", required_argument, 0, 'a'}, {"Counter", required_argument, 0, 'C'}, {"counter", required_argument, 0, 'c'}, {"Dump", no_argument, 0, 'D'}, @@ -3767,6 +4142,9 @@ void cmdline(int argc, char **argv) while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v", long_options, &option_index)) != -1) { switch (opt) { + case 'a': + parse_add_command(optarg); + break; case 'C': sscanf(optarg, "%x", &extra_delta_offset64); break; -- cgit v1.2.3-59-g8ed1b From 6886fee4d7a3afaf905a8e0bec62dc8fdc39878d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 24 Dec 2016 15:18:37 -0500 Subject: tools/power turbostat: remove obsolete -M, -m, -C, -c options The new --add option has replaced the -M, -m, -C, -c options Eg. -M 0x10 is now --add msr0x10,raw -m 0x10 is now --add msr0x10,raw,u32 -C 0x10 is now --add msr0x10,delta -c 0x10 is now --add msr0x10,delta,u32 The --add option can be repeated to add any number of counters, while the previous options were limited to adding one of each type. In addition, the --add option can accept a column label, and can also display a counter as a percentage of elapsed cycles. Eg. --add msr0x3fe,core,percent,MY_CC3 Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.8 | 8 --- tools/power/x86/turbostat/turbostat.c | 104 +--------------------------------- 2 files changed, 2 insertions(+), 110 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 39f7daeb6fbd..03cb639b292e 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -47,10 +47,6 @@ name as necessary to disambiguate it from others is necessary. Note that option default: delta .fi .PP -\fB--Counter MSR#\fP shows the delta of the specified 64-bit MSR counter. -.PP -\fB--counter MSR#\fP shows the delta of the specified 32-bit MSR counter. -.PP \fB--Dump\fP displays the raw counter values. .PP \fB--debug\fP displays additional system configuration information. Invoking this parameter @@ -65,10 +61,6 @@ The file is truncated if it already exists, and it is created if it does not exi .PP \fB--Joules\fP displays energy in Joules, rather than dividing Joules by time to print power in Watts. .PP -\fB--MSR MSR#\fP shows the specified 64-bit MSR value. -.PP -\fB--msr MSR#\fP shows the specified 32-bit MSR value. -.PP \fB--Package\fP limits output to the system summary plus the 1st thread in each Package. .PP \fB--processor\fP limits output to the system summary plus the 1st thread in each processor of each package. Ie. it skips hyper-threaded siblings. diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 4490a776bbae..f13f61b065c6 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -71,10 +71,6 @@ unsigned int units = 1000000; /* MHz etc */ unsigned int genuine_intel; unsigned int has_invariant_tsc; unsigned int do_nhm_platform_info; -unsigned int extra_msr_offset32; -unsigned int extra_msr_offset64; -unsigned int extra_delta_offset32; -unsigned int extra_delta_offset64; unsigned int aperf_mperf_multiplier = 1; int do_irq = 1; int do_smi; @@ -164,10 +160,6 @@ struct thread_data { unsigned long long aperf; unsigned long long mperf; unsigned long long c1; - unsigned long long extra_msr64; - unsigned long long extra_delta64; - unsigned long long extra_msr32; - unsigned long long extra_delta32; unsigned int irq_count; unsigned int smi_count; unsigned int cpu_id; @@ -372,15 +364,6 @@ void print_header(void) outp += sprintf(outp, "\tBzy_MHz"); outp += sprintf(outp, "\tTSC_MHz"); - if (extra_delta_offset32) - outp += sprintf(outp, "\tcount 0x%03X", extra_delta_offset32); - if (extra_delta_offset64) - outp += sprintf(outp, "\tCOUNT 0x%03X", extra_delta_offset64); - if (extra_msr_offset32) - outp += sprintf(outp, "\t MSR 0x%03X", extra_msr_offset32); - if (extra_msr_offset64) - outp += sprintf(outp, "\tMSR 0x%03X", extra_msr_offset64); - if (!debug) goto done; @@ -510,14 +493,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, "aperf: %016llX\n", t->aperf); outp += sprintf(outp, "mperf: %016llX\n", t->mperf); outp += sprintf(outp, "c1: %016llX\n", t->c1); - outp += sprintf(outp, "msr0x%x: %08llX\n", - extra_delta_offset32, t->extra_delta32); - outp += sprintf(outp, "msr0x%x: %016llX\n", - extra_delta_offset64, t->extra_delta64); - outp += sprintf(outp, "msr0x%x: %08llX\n", - extra_msr_offset32, t->extra_msr32); - outp += sprintf(outp, "msr0x%x: %016llX\n", - extra_msr_offset64, t->extra_msr64); + if (do_irq) outp += sprintf(outp, "IRQ: %08X\n", t->irq_count); if (do_smi) @@ -648,21 +624,6 @@ int format_counters(struct thread_data *t, struct core_data *c, /* TSC_MHz */ outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float); - /* delta */ - if (extra_delta_offset32) - outp += sprintf(outp, "\t%11llu", t->extra_delta32); - - /* DELTA */ - if (extra_delta_offset64) - outp += sprintf(outp, "\t%11llu", t->extra_delta64); - /* msr */ - if (extra_msr_offset32) - outp += sprintf(outp, "\t0x%08llx", t->extra_msr32); - - /* MSR */ - if (extra_msr_offset64) - outp += sprintf(outp, "\t0x%016llx", t->extra_msr64); - if (!debug) goto done; @@ -991,17 +952,6 @@ delta_thread(struct thread_data *new, struct thread_data *old, old->mperf = 1; /* divide by 0 protection */ } - old->extra_delta32 = new->extra_delta32 - old->extra_delta32; - old->extra_delta32 &= 0xFFFFFFFF; - - old->extra_delta64 = new->extra_delta64 - old->extra_delta64; - - /* - * Extra MSR is just a snapshot, simply copy latest w/o subtracting - */ - old->extra_msr32 = new->extra_msr32; - old->extra_msr64 = new->extra_msr64; - if (do_irq) old->irq_count = new->irq_count - old->irq_count; @@ -1049,9 +999,6 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data t->mperf = 0; t->c1 = 0; - t->extra_delta32 = 0; - t->extra_delta64 = 0; - t->irq_count = 0; t->smi_count = 0; @@ -1110,9 +1057,6 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.threads.mperf += t->mperf; average.threads.c1 += t->c1; - average.threads.extra_delta32 += t->extra_delta32; - average.threads.extra_delta64 += t->extra_delta64; - average.threads.irq_count += t->irq_count; average.threads.smi_count += t->smi_count; @@ -1199,11 +1143,6 @@ void compute_average(struct thread_data *t, struct core_data *c, average.threads.mperf /= topo.num_cpus; average.threads.c1 /= topo.num_cpus; - average.threads.extra_delta32 /= topo.num_cpus; - average.threads.extra_delta32 &= 0xFFFFFFFF; - - average.threads.extra_delta64 /= topo.num_cpus; - average.cores.c3 /= topo.num_cores; average.cores.c6 /= topo.num_cores; average.cores.c7 /= topo.num_cores; @@ -1337,25 +1276,6 @@ retry: return -5; t->smi_count = msr & 0xFFFFFFFF; } - if (extra_delta_offset32) { - if (get_msr(cpu, extra_delta_offset32, &msr)) - return -5; - t->extra_delta32 = msr & 0xFFFFFFFF; - } - - if (extra_delta_offset64) - if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64)) - return -5; - - if (extra_msr_offset32) { - if (get_msr(cpu, extra_msr_offset32, &msr)) - return -5; - t->extra_msr32 = msr & 0xFFFFFFFF; - } - - if (extra_msr_offset64) - if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) - return -5; if (use_c1_residency_msr) { if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1)) @@ -3619,11 +3539,7 @@ void help() "--debug run in \"debug\" mode\n" "--interval sec Override default 5-second measurement interval\n" "--help print this help message\n" - "--counter msr print 32-bit counter at address \"msr\"\n" - "--Counter msr print 64-bit Counter at address \"msr\"\n" "--out file create or truncate \"file\" for all output\n" - "--msr msr print 32-bit value at address \"msr\"\n" - "--MSR msr print 64-bit Value at address \"msr\"\n" "--version print version information\n" "\n" "For more help, run \"man turbostat\"\n"); @@ -3960,7 +3876,7 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(outf, "turbostat version 4.15 21 Dec 2016" + fprintf(outf, "turbostat version 4.16 24 Dec 2016" " - Len Brown \n"); } @@ -4119,15 +4035,11 @@ void cmdline(int argc, char **argv) int option_index = 0; static struct option long_options[] = { {"add", required_argument, 0, 'a'}, - {"Counter", required_argument, 0, 'C'}, - {"counter", required_argument, 0, 'c'}, {"Dump", no_argument, 0, 'D'}, {"debug", no_argument, 0, 'd'}, {"interval", required_argument, 0, 'i'}, {"help", no_argument, 0, 'h'}, {"Joules", no_argument, 0, 'J'}, - {"MSR", required_argument, 0, 'M'}, - {"msr", required_argument, 0, 'm'}, {"out", required_argument, 0, 'o'}, {"Package", no_argument, 0, 'p'}, {"processor", no_argument, 0, 'p'}, @@ -4145,12 +4057,6 @@ void cmdline(int argc, char **argv) case 'a': parse_add_command(optarg); break; - case 'C': - sscanf(optarg, "%x", &extra_delta_offset64); - break; - case 'c': - sscanf(optarg, "%x", &extra_delta_offset32); - break; case 'D': dump_only++; break; @@ -4178,12 +4084,6 @@ void cmdline(int argc, char **argv) case 'J': rapl_joules++; break; - case 'M': - sscanf(optarg, "%x", &extra_msr_offset64); - break; - case 'm': - sscanf(optarg, "%x", &extra_msr_offset32); - break; case 'o': outf = fopen_or_die(optarg, "w"); break; -- cgit v1.2.3-59-g8ed1b