aboutsummaryrefslogtreecommitdiffstats
path: root/tools/power
diff options
context:
space:
mode:
Diffstat (limited to 'tools/power')
-rw-r--r--tools/power/x86/turbostat/turbostat.868
-rw-r--r--tools/power/x86/turbostat/turbostat.c344
2 files changed, 254 insertions, 158 deletions
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 9b950699e63d..feea7ad9500b 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -9,7 +9,7 @@ turbostat \- Report processor frequency and idle statistics
9.br 9.br
10.B turbostat 10.B turbostat
11.RB [ Options ] 11.RB [ Options ]
12.RB [ "\-i interval_sec" ] 12.RB [ "\--interval seconds" ]
13.SH DESCRIPTION 13.SH DESCRIPTION
14\fBturbostat \fP reports processor topology, frequency, 14\fBturbostat \fP reports processor topology, frequency,
15idle power-state statistics, temperature and power on X86 processors. 15idle power-state statistics, temperature and power on X86 processors.
@@ -18,31 +18,41 @@ The first method is to supply a
18\fBcommand\fP, which is forked and statistics are printed 18\fBcommand\fP, which is forked and statistics are printed
19upon its completion. 19upon its completion.
20The second method is to omit the command, 20The second method is to omit the command,
21and turbodstat will print statistics every 5 seconds. 21and turbostat displays statistics every 5 seconds.
22The 5-second interval can changed using the -i option. 22The 5-second interval can be changed using the --interval option.
23 23
24Some information is not availalbe on older processors. 24Some information is not available on older processors.
25.SS Options 25.SS Options
26The \fB-p\fP option limits output to the 1st thread in 1st core of each package. 26\fB--Counter MSR#\fP shows the delta of the specified 64-bit MSR counter.
27.PP 27.PP
28The \fB-P\fP option limits output to the 1st thread in each Package. 28\fB--counter MSR#\fP shows the delta of the specified 32-bit MSR counter.
29.PP 29.PP
30The \fB-S\fP option limits output to a 1-line System Summary for each interval. 30\fB--Dump\fP displays the raw counter values.
31.PP 31.PP
32The \fB-v\fP option increases verbosity. 32\fB--debug\fP displays additional system configuration information. Invoking this parameter
33more than once may also enable internal turbostat debug information.
33.PP 34.PP
34The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter. 35\fB--interval seconds\fP overrides the default 5-second measurement interval.
35.PP 36.PP
36The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter. 37\fB--help\fP displays usage for the most common parameters.
37.PP 38.PP
38The \fB-m MSR#\fP option includes the the specified 32-bit MSR value. 39\fB--Joules\fP displays energy in Joules, rather than dividing Joules by time to print power in Watts.
39.PP 40.PP
40The \fB-M MSR#\fP option includes the the specified 64-bit MSR value. 41\fB--MSR MSR#\fP shows the specified 64-bit MSR value.
41.PP 42.PP
42The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. 43\fB--msr MSR#\fP shows the specified 32-bit MSR value.
43The default is 5 seconds.
44.PP 44.PP
45The \fBcommand\fP parameter forks \fBcommand\fP and upon its exit, 45\fB--Package\fP limits output to the system summary plus the 1st thread in each Package.
46.PP
47\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.
48.PP
49\fB--Summary\fP limits output to a 1-line System Summary for each interval.
50.PP
51\fB--TCC temperature\fP sets the Thermal Control Circuit temperature for systems which do not export that value. This is used for making sense of the Digital Thermal Sensor outputs, as they return degrees Celsius below the TCC activation temperature.
52.PP
53\fB--version\fP displays the version.
54.PP
55The \fBcommand\fP parameter forks \fBcommand\fP, and upon its exit,
46displays the statistics gathered since it was forked. 56displays the statistics gathered since it was forked.
47.PP 57.PP
48.SH FIELD DESCRIPTIONS 58.SH FIELD DESCRIPTIONS
@@ -52,7 +62,7 @@ displays the statistics gathered since it was forked.
52\fBCPU\fP Linux CPU (logical processor) number. 62\fBCPU\fP Linux CPU (logical processor) number.
53Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology. 63Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology.
54\fBAVG_MHz\fP number of cycles executed divided by time elapsed. 64\fBAVG_MHz\fP number of cycles executed divided by time elapsed.
55\fB%Buzy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state. 65\fB%Busy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
56\fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state). 66\fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state).
57\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval. 67\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval.
58\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. 68\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states.
@@ -68,7 +78,7 @@ Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading T
68.fi 78.fi
69.PP 79.PP
70.SH EXAMPLE 80.SH EXAMPLE
71Without any parameters, turbostat prints out counters ever 5 seconds. 81Without any parameters, turbostat displays statistics ever 5 seconds.
72(override interval with "-i sec" option, or specify a command 82(override interval with "-i sec" option, or specify a command
73for turbostat to fork). 83for turbostat to fork).
74 84
@@ -91,19 +101,19 @@ Subsequent rows show per-CPU statistics.
91 3 3 3 0.20 1596 3492 0 0.44 0.00 99.37 0.00 23 101 3 3 3 0.20 1596 3492 0 0.44 0.00 99.37 0.00 23
92 3 7 5 0.31 1596 3492 0 0.33 102 3 7 5 0.31 1596 3492 0 0.33
93.fi 103.fi
94.SH VERBOSE EXAMPLE 104.SH DEBUG EXAMPLE
95The "-v" option adds verbosity to the output: 105The "--debug" option prints additional system information before measurements:
96 106
97.nf 107.nf
98[root@ivy]# turbostat -v 108turbostat version 4.0 10-Feb, 2015 - Len Brown <lenb@kernel.org>
99turbostat v3.0 November 23, 2012 - Len Brown <lenb@kernel.org>
100CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3a:9 (6:58:9) 109CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3a:9 (6:58:9)
101CPUID(6): APERF, DTS, PTM, EPB 110CPUID(6): APERF, DTS, PTM, EPB
102RAPL: 851 sec. Joule Counter Range 111RAPL: 851 sec. Joule Counter Range, at 77 Watts
103cpu0: MSR_NHM_PLATFORM_INFO: 0x81010f0012300 112cpu0: MSR_NHM_PLATFORM_INFO: 0x81010f0012300
10416 * 100 = 1600 MHz max efficiency 11316 * 100 = 1600 MHz max efficiency
10535 * 100 = 3500 MHz TSC frequency 11435 * 100 = 3500 MHz TSC frequency
106cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6-noret) 115cpu0: MSR_IA32_POWER_CTL: 0x0014005d (C1E auto-promotion: DISabled)
116cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6n)
107cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727 117cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
10837 * 100 = 3700 MHz max turbo 4 active cores 11837 * 100 = 3700 MHz max turbo 4 active cores
10938 * 100 = 3800 MHz max turbo 3 active cores 11938 * 100 = 3800 MHz max turbo 3 active cores
@@ -112,9 +122,9 @@ cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
112cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced) 122cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced)
113cpu0: MSR_RAPL_POWER_UNIT: 0x000a1003 (0.125000 Watts, 0.000015 Joules, 0.000977 sec.) 123cpu0: MSR_RAPL_POWER_UNIT: 0x000a1003 (0.125000 Watts, 0.000015 Joules, 0.000977 sec.)
114cpu0: MSR_PKG_POWER_INFO: 0x01e00268 (77 W TDP, RAPL 60 - 0 W, 0.000000 sec.) 124cpu0: MSR_PKG_POWER_INFO: 0x01e00268 (77 W TDP, RAPL 60 - 0 W, 0.000000 sec.)
115cpu0: MSR_PKG_POWER_LIMIT: 0x830000148268 (UNlocked) 125cpu0: MSR_PKG_POWER_LIMIT: 0x30000148268 (UNlocked)
116cpu0: PKG Limit #1: ENabled (77.000000 Watts, 1.000000 sec, clamp DISabled) 126cpu0: PKG Limit #1: ENabled (77.000000 Watts, 1.000000 sec, clamp DISabled)
117cpu0: PKG Limit #2: ENabled (96.000000 Watts, 0.000977* sec, clamp DISabled) 127cpu0: PKG Limit #2: DISabled (96.000000 Watts, 0.000977* sec, clamp DISabled)
118cpu0: MSR_PP0_POLICY: 0 128cpu0: MSR_PP0_POLICY: 0
119cpu0: MSR_PP0_POWER_LIMIT: 0x00000000 (UNlocked) 129cpu0: MSR_PP0_POWER_LIMIT: 0x00000000 (UNlocked)
120cpu0: Cores Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled) 130cpu0: Cores Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
@@ -123,9 +133,9 @@ cpu0: MSR_PP1_POWER_LIMIT: 0x00000000 (UNlocked)
123cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled) 133cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
124cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00691400 (105 C) 134cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00691400 (105 C)
125cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x884e0000 (27 C) 135cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x884e0000 (27 C)
126cpu0: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1) 136cpu0: MSR_IA32_THERM_STATUS: 0x88580000 (17 C +/- 1)
127cpu1: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1) 137cpu1: MSR_IA32_THERM_STATUS: 0x885a0000 (15 C +/- 1)
128cpu2: MSR_IA32_THERM_STATUS: 0x88540000 (21 C +/- 1) 138cpu2: MSR_IA32_THERM_STATUS: 0x88570000 (18 C +/- 1)
129cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1) 139cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1)
130 ... 140 ...
131.fi 141.fi
@@ -195,7 +205,7 @@ in those kernels.
195 205
196AVG_MHz = APERF_delta/measurement_interval. This is the actual 206AVG_MHz = APERF_delta/measurement_interval. This is the actual
197number of elapsed cycles divided by the entire sample interval -- 207number of elapsed cycles divided by the entire sample interval --
198including idle time. Note that this calculation is resiliant 208including idle time. Note that this calculation is resilient
199to systems lacking a non-stop TSC. 209to systems lacking a non-stop TSC.
200 210
201TSC_MHz = TSC_delta/measurement_interval. 211TSC_MHz = TSC_delta/measurement_interval.
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index a02c02f25e88..2d089cac8580 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -33,6 +33,7 @@
33#include <signal.h> 33#include <signal.h>
34#include <sys/time.h> 34#include <sys/time.h>
35#include <stdlib.h> 35#include <stdlib.h>
36#include <getopt.h>
36#include <dirent.h> 37#include <dirent.h>
37#include <string.h> 38#include <string.h>
38#include <ctype.h> 39#include <ctype.h>
@@ -42,17 +43,19 @@
42#include <errno.h> 43#include <errno.h>
43 44
44char *proc_stat = "/proc/stat"; 45char *proc_stat = "/proc/stat";
45unsigned int interval_sec = 5; /* set with -i interval_sec */ 46unsigned int interval_sec = 5;
46unsigned int verbose; /* set with -v */ 47unsigned int debug;
47unsigned int rapl_verbose; /* set with -R */ 48unsigned int rapl_joules;
48unsigned int rapl_joules; /* set with -J */ 49unsigned int summary_only;
49unsigned int thermal_verbose; /* set with -T */ 50unsigned int dump_only;
50unsigned int summary_only; /* set with -S */
51unsigned int dump_only; /* set with -s */
52unsigned int skip_c0; 51unsigned int skip_c0;
53unsigned int skip_c1; 52unsigned int skip_c1;
54unsigned int do_nhm_cstates; 53unsigned int do_nhm_cstates;
55unsigned int do_snb_cstates; 54unsigned int do_snb_cstates;
55unsigned int do_pc2;
56unsigned int do_pc3;
57unsigned int do_pc6;
58unsigned int do_pc7;
56unsigned int do_c8_c9_c10; 59unsigned int do_c8_c9_c10;
57unsigned int do_slm_cstates; 60unsigned int do_slm_cstates;
58unsigned int use_c1_residency_msr; 61unsigned int use_c1_residency_msr;
@@ -313,13 +316,13 @@ void print_header(void)
313 if (do_ptm) 316 if (do_ptm)
314 outp += sprintf(outp, " PkgTmp"); 317 outp += sprintf(outp, " PkgTmp");
315 318
316 if (do_snb_cstates) 319 if (do_pc2)
317 outp += sprintf(outp, " Pkg%%pc2"); 320 outp += sprintf(outp, " Pkg%%pc2");
318 if (do_nhm_cstates && !do_slm_cstates) 321 if (do_pc3)
319 outp += sprintf(outp, " Pkg%%pc3"); 322 outp += sprintf(outp, " Pkg%%pc3");
320 if (do_nhm_cstates && !do_slm_cstates) 323 if (do_pc6)
321 outp += sprintf(outp, " Pkg%%pc6"); 324 outp += sprintf(outp, " Pkg%%pc6");
322 if (do_snb_cstates) 325 if (do_pc7)
323 outp += sprintf(outp, " Pkg%%pc7"); 326 outp += sprintf(outp, " Pkg%%pc7");
324 if (do_c8_c9_c10) { 327 if (do_c8_c9_c10) {
325 outp += sprintf(outp, " Pkg%%pc8"); 328 outp += sprintf(outp, " Pkg%%pc8");
@@ -394,9 +397,12 @@ int dump_counters(struct thread_data *t, struct core_data *c,
394 if (p) { 397 if (p) {
395 outp += sprintf(outp, "package: %d\n", p->package_id); 398 outp += sprintf(outp, "package: %d\n", p->package_id);
396 outp += sprintf(outp, "pc2: %016llX\n", p->pc2); 399 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
397 outp += sprintf(outp, "pc3: %016llX\n", p->pc3); 400 if (do_pc3)
398 outp += sprintf(outp, "pc6: %016llX\n", p->pc6); 401 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
399 outp += sprintf(outp, "pc7: %016llX\n", p->pc7); 402 if (do_pc6)
403 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
404 if (do_pc7)
405 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
400 outp += sprintf(outp, "pc8: %016llX\n", p->pc8); 406 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
401 outp += sprintf(outp, "pc9: %016llX\n", p->pc9); 407 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
402 outp += sprintf(outp, "pc10: %016llX\n", p->pc10); 408 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
@@ -528,13 +534,13 @@ int format_counters(struct thread_data *t, struct core_data *c,
528 if (do_ptm) 534 if (do_ptm)
529 outp += sprintf(outp, "%8d", p->pkg_temp_c); 535 outp += sprintf(outp, "%8d", p->pkg_temp_c);
530 536
531 if (do_snb_cstates) 537 if (do_pc2)
532 outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc); 538 outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc);
533 if (do_nhm_cstates && !do_slm_cstates) 539 if (do_pc3)
534 outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc); 540 outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc);
535 if (do_nhm_cstates && !do_slm_cstates) 541 if (do_pc6)
536 outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc); 542 outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc);
537 if (do_snb_cstates) 543 if (do_pc7)
538 outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc); 544 outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc);
539 if (do_c8_c9_c10) { 545 if (do_c8_c9_c10) {
540 outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc); 546 outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc);
@@ -631,9 +637,12 @@ void
631delta_package(struct pkg_data *new, struct pkg_data *old) 637delta_package(struct pkg_data *new, struct pkg_data *old)
632{ 638{
633 old->pc2 = new->pc2 - old->pc2; 639 old->pc2 = new->pc2 - old->pc2;
634 old->pc3 = new->pc3 - old->pc3; 640 if (do_pc3)
635 old->pc6 = new->pc6 - old->pc6; 641 old->pc3 = new->pc3 - old->pc3;
636 old->pc7 = new->pc7 - old->pc7; 642 if (do_pc6)
643 old->pc6 = new->pc6 - old->pc6;
644 if (do_pc7)
645 old->pc7 = new->pc7 - old->pc7;
637 old->pc8 = new->pc8 - old->pc8; 646 old->pc8 = new->pc8 - old->pc8;
638 old->pc9 = new->pc9 - old->pc9; 647 old->pc9 = new->pc9 - old->pc9;
639 old->pc10 = new->pc10 - old->pc10; 648 old->pc10 = new->pc10 - old->pc10;
@@ -717,7 +726,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
717 } 726 }
718 727
719 if (old->mperf == 0) { 728 if (old->mperf == 0) {
720 if (verbose > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id); 729 if (debug > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
721 old->mperf = 1; /* divide by 0 protection */ 730 old->mperf = 1; /* divide by 0 protection */
722 } 731 }
723 732
@@ -774,9 +783,12 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
774 c->core_temp_c = 0; 783 c->core_temp_c = 0;
775 784
776 p->pc2 = 0; 785 p->pc2 = 0;
777 p->pc3 = 0; 786 if (do_pc3)
778 p->pc6 = 0; 787 p->pc3 = 0;
779 p->pc7 = 0; 788 if (do_pc6)
789 p->pc6 = 0;
790 if (do_pc7)
791 p->pc7 = 0;
780 p->pc8 = 0; 792 p->pc8 = 0;
781 p->pc9 = 0; 793 p->pc9 = 0;
782 p->pc10 = 0; 794 p->pc10 = 0;
@@ -815,9 +827,12 @@ int sum_counters(struct thread_data *t, struct core_data *c,
815 return 0; 827 return 0;
816 828
817 average.packages.pc2 += p->pc2; 829 average.packages.pc2 += p->pc2;
818 average.packages.pc3 += p->pc3; 830 if (do_pc3)
819 average.packages.pc6 += p->pc6; 831 average.packages.pc3 += p->pc3;
820 average.packages.pc7 += p->pc7; 832 if (do_pc6)
833 average.packages.pc6 += p->pc6;
834 if (do_pc7)
835 average.packages.pc7 += p->pc7;
821 average.packages.pc8 += p->pc8; 836 average.packages.pc8 += p->pc8;
822 average.packages.pc9 += p->pc9; 837 average.packages.pc9 += p->pc9;
823 average.packages.pc10 += p->pc10; 838 average.packages.pc10 += p->pc10;
@@ -859,9 +874,12 @@ void compute_average(struct thread_data *t, struct core_data *c,
859 average.cores.c7 /= topo.num_cores; 874 average.cores.c7 /= topo.num_cores;
860 875
861 average.packages.pc2 /= topo.num_packages; 876 average.packages.pc2 /= topo.num_packages;
862 average.packages.pc3 /= topo.num_packages; 877 if (do_pc3)
863 average.packages.pc6 /= topo.num_packages; 878 average.packages.pc3 /= topo.num_packages;
864 average.packages.pc7 /= topo.num_packages; 879 if (do_pc6)
880 average.packages.pc6 /= topo.num_packages;
881 if (do_pc7)
882 average.packages.pc7 /= topo.num_packages;
865 883
866 average.packages.pc8 /= topo.num_packages; 884 average.packages.pc8 /= topo.num_packages;
867 average.packages.pc9 /= topo.num_packages; 885 average.packages.pc9 /= topo.num_packages;
@@ -961,18 +979,18 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
961 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 979 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
962 return 0; 980 return 0;
963 981
964 if (do_nhm_cstates && !do_slm_cstates) { 982 if (do_pc3)
965 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) 983 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
966 return -9; 984 return -9;
985 if (do_pc6)
967 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) 986 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
968 return -10; 987 return -10;
969 } 988 if (do_pc2)
970 if (do_snb_cstates) {
971 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2)) 989 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
972 return -11; 990 return -11;
991 if (do_pc7)
973 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) 992 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
974 return -12; 993 return -12;
975 }
976 if (do_c8_c9_c10) { 994 if (do_c8_c9_c10) {
977 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8)) 995 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
978 return -13; 996 return -13;
@@ -1019,6 +1037,37 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1019 return 0; 1037 return 0;
1020} 1038}
1021 1039
1040/*
1041 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1042 * If you change the values, note they are used both in comparisons
1043 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1044 */
1045
1046#define PCLUKN 0 /* Unknown */
1047#define PCLRSV 1 /* Reserved */
1048#define PCL__0 2 /* PC0 */
1049#define PCL__1 3 /* PC1 */
1050#define PCL__2 4 /* PC2 */
1051#define PCL__3 5 /* PC3 */
1052#define PCL__4 6 /* PC4 */
1053#define PCL__6 7 /* PC6 */
1054#define PCL_6N 8 /* PC6 No Retention */
1055#define PCL_6R 9 /* PC6 Retention */
1056#define PCL__7 10 /* PC7 */
1057#define PCL_7S 11 /* PC7 Shrink */
1058#define PCLUNL 12 /* Unlimited */
1059
1060int pkg_cstate_limit = PCLUKN;
1061char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
1062 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "unlimited"};
1063
1064int nhm_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL};
1065int snb_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL};
1066int hsw_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCLRSV, PCLUNL};
1067int slv_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7};
1068int amt_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
1069int phi_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL};
1070
1022void print_verbose_header(void) 1071void print_verbose_header(void)
1023{ 1072{
1024 unsigned long long msr; 1073 unsigned long long msr;
@@ -1098,44 +1147,14 @@ print_nhm_turbo_ratio_limits:
1098 1147
1099 fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr); 1148 fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr);
1100 1149
1101 fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: ", 1150 fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
1102 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "", 1151 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1103 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "", 1152 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1104 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "", 1153 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1105 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "", 1154 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1106 (msr & (1 << 15)) ? "" : "UN", 1155 (msr & (1 << 15)) ? "" : "UN",
1107 (unsigned int)msr & 7); 1156 (unsigned int)msr & 7,
1108 1157 pkg_cstate_limit_strings[pkg_cstate_limit]);
1109
1110 switch(msr & 0x7) {
1111 case 0:
1112 fprintf(stderr, do_slm_cstates ? "no pkg states" : "pc0");
1113 break;
1114 case 1:
1115 fprintf(stderr, do_slm_cstates ? "no pkg states" : do_snb_cstates ? "pc2" : "pc0");
1116 break;
1117 case 2:
1118 fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc6-noret" : "pc3");
1119 break;
1120 case 3:
1121 fprintf(stderr, do_slm_cstates ? "invalid" : "pc6");
1122 break;
1123 case 4:
1124 fprintf(stderr, do_slm_cstates ? "pc4" : "pc7");
1125 break;
1126 case 5:
1127 fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc7s" : "invalid");
1128 break;
1129 case 6:
1130 fprintf(stderr, do_slm_cstates ? "pc6" : "invalid");
1131 break;
1132 case 7:
1133 fprintf(stderr, do_slm_cstates ? "pc7" : "unlimited");
1134 break;
1135 default:
1136 fprintf(stderr, "invalid");
1137 }
1138 fprintf(stderr, ")\n");
1139 1158
1140 if (!do_nhm_turbo_ratio_limit) 1159 if (!do_nhm_turbo_ratio_limit)
1141 return; 1160 return;
@@ -1516,9 +1535,14 @@ void check_permissions()
1516 * MSR_CORE_C3_RESIDENCY 0x000003fc 1535 * MSR_CORE_C3_RESIDENCY 0x000003fc
1517 * MSR_CORE_C6_RESIDENCY 0x000003fd 1536 * MSR_CORE_C6_RESIDENCY 0x000003fd
1518 * 1537 *
1538 * Side effect:
1539 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL
1519 */ 1540 */
1520int has_nhm_msrs(unsigned int family, unsigned int model) 1541int probe_nhm_msrs(unsigned int family, unsigned int model)
1521{ 1542{
1543 unsigned long long msr;
1544 int *pkg_cstate_limits;
1545
1522 if (!genuine_intel) 1546 if (!genuine_intel)
1523 return 0; 1547 return 0;
1524 1548
@@ -1531,31 +1555,47 @@ int has_nhm_msrs(unsigned int family, unsigned int model)
1531 case 0x1F: /* Core i7 and i5 Processor - Nehalem */ 1555 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
1532 case 0x25: /* Westmere Client - Clarkdale, Arrandale */ 1556 case 0x25: /* Westmere Client - Clarkdale, Arrandale */
1533 case 0x2C: /* Westmere EP - Gulftown */ 1557 case 0x2C: /* Westmere EP - Gulftown */
1558 case 0x2E: /* Nehalem-EX Xeon - Beckton */
1559 case 0x2F: /* Westmere-EX Xeon - Eagleton */
1560 pkg_cstate_limits = nhm_pkg_cstate_limits;
1561 break;
1534 case 0x2A: /* SNB */ 1562 case 0x2A: /* SNB */
1535 case 0x2D: /* SNB Xeon */ 1563 case 0x2D: /* SNB Xeon */
1536 case 0x3A: /* IVB */ 1564 case 0x3A: /* IVB */
1537 case 0x3E: /* IVB Xeon */ 1565 case 0x3E: /* IVB Xeon */
1566 pkg_cstate_limits = snb_pkg_cstate_limits;
1567 break;
1538 case 0x3C: /* HSW */ 1568 case 0x3C: /* HSW */
1539 case 0x3F: /* HSX */ 1569 case 0x3F: /* HSX */
1540 case 0x45: /* HSW */ 1570 case 0x45: /* HSW */
1541 case 0x46: /* HSW */ 1571 case 0x46: /* HSW */
1542 case 0x37: /* BYT */
1543 case 0x4D: /* AVN */
1544 case 0x3D: /* BDW */ 1572 case 0x3D: /* BDW */
1573 case 0x47: /* BDW */
1545 case 0x4F: /* BDX */ 1574 case 0x4F: /* BDX */
1546 case 0x56: /* BDX-DE */ 1575 case 0x56: /* BDX-DE */
1547 case 0x2E: /* Nehalem-EX Xeon - Beckton */ 1576 pkg_cstate_limits = hsw_pkg_cstate_limits;
1548 case 0x2F: /* Westmere-EX Xeon - Eagleton */ 1577 break;
1549 return 1; 1578 case 0x37: /* BYT */
1579 case 0x4D: /* AVN */
1580 pkg_cstate_limits = slv_pkg_cstate_limits;
1581 break;
1582 case 0x4C: /* AMT */
1583 pkg_cstate_limits = amt_pkg_cstate_limits;
1584 break;
1585 case 0x57: /* PHI */
1586 pkg_cstate_limits = phi_pkg_cstate_limits;
1587 break;
1550 default: 1588 default:
1551 return 0; 1589 return 0;
1552 } 1590 }
1591 get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
1592
1593 pkg_cstate_limit = pkg_cstate_limits[msr & 0x7];
1594
1595 return 1;
1553} 1596}
1554int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) 1597int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
1555{ 1598{
1556 if (!has_nhm_msrs(family, model))
1557 return 0;
1558
1559 switch (model) { 1599 switch (model) {
1560 /* Nehalem compatible, but do not include turbo-ratio limit support */ 1600 /* Nehalem compatible, but do not include turbo-ratio limit support */
1561 case 0x2E: /* Nehalem-EX Xeon - Beckton */ 1601 case 0x2E: /* Nehalem-EX Xeon - Beckton */
@@ -1769,6 +1809,7 @@ void rapl_probe(unsigned int family, unsigned int model)
1769 case 0x45: /* HSW */ 1809 case 0x45: /* HSW */
1770 case 0x46: /* HSW */ 1810 case 0x46: /* HSW */
1771 case 0x3D: /* BDW */ 1811 case 0x3D: /* BDW */
1812 case 0x47: /* BDW */
1772 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; 1813 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
1773 break; 1814 break;
1774 case 0x3F: /* HSX */ 1815 case 0x3F: /* HSX */
@@ -1807,7 +1848,7 @@ void rapl_probe(unsigned int family, unsigned int model)
1807 tdp = get_tdp(model); 1848 tdp = get_tdp(model);
1808 1849
1809 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; 1850 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
1810 if (verbose) 1851 if (debug)
1811 fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); 1852 fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
1812 1853
1813 return; 1854 return;
@@ -1932,7 +1973,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1932 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) 1973 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
1933 return -1; 1974 return -1;
1934 1975
1935 if (verbose) { 1976 if (debug) {
1936 fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " 1977 fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
1937 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, 1978 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
1938 rapl_power_units, rapl_energy_units, rapl_time_units); 1979 rapl_power_units, rapl_energy_units, rapl_time_units);
@@ -1989,7 +2030,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1989 print_power_limit_msr(cpu, msr, "DRAM Limit"); 2030 print_power_limit_msr(cpu, msr, "DRAM Limit");
1990 } 2031 }
1991 if (do_rapl & RAPL_CORE_POLICY) { 2032 if (do_rapl & RAPL_CORE_POLICY) {
1992 if (verbose) { 2033 if (debug) {
1993 if (get_msr(cpu, MSR_PP0_POLICY, &msr)) 2034 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
1994 return -7; 2035 return -7;
1995 2036
@@ -1997,7 +2038,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1997 } 2038 }
1998 } 2039 }
1999 if (do_rapl & RAPL_CORES) { 2040 if (do_rapl & RAPL_CORES) {
2000 if (verbose) { 2041 if (debug) {
2001 2042
2002 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) 2043 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
2003 return -9; 2044 return -9;
@@ -2007,7 +2048,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2007 } 2048 }
2008 } 2049 }
2009 if (do_rapl & RAPL_GFX) { 2050 if (do_rapl & RAPL_GFX) {
2010 if (verbose) { 2051 if (debug) {
2011 if (get_msr(cpu, MSR_PP1_POLICY, &msr)) 2052 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
2012 return -8; 2053 return -8;
2013 2054
@@ -2046,6 +2087,7 @@ int has_snb_msrs(unsigned int family, unsigned int model)
2046 case 0x45: /* HSW */ 2087 case 0x45: /* HSW */
2047 case 0x46: /* HSW */ 2088 case 0x46: /* HSW */
2048 case 0x3D: /* BDW */ 2089 case 0x3D: /* BDW */
2090 case 0x47: /* BDW */
2049 case 0x4F: /* BDX */ 2091 case 0x4F: /* BDX */
2050 case 0x56: /* BDX-DE */ 2092 case 0x56: /* BDX-DE */
2051 return 1; 2093 return 1;
@@ -2168,7 +2210,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
2168 2210
2169 target_c_local = (msr >> 16) & 0xFF; 2211 target_c_local = (msr >> 16) & 0xFF;
2170 2212
2171 if (verbose) 2213 if (debug)
2172 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", 2214 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
2173 cpu, msr, target_c_local); 2215 cpu, msr, target_c_local);
2174 2216
@@ -2198,7 +2240,7 @@ void check_cpuid()
2198 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) 2240 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
2199 genuine_intel = 1; 2241 genuine_intel = 1;
2200 2242
2201 if (verbose) 2243 if (debug)
2202 fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", 2244 fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
2203 (char *)&ebx, (char *)&edx, (char *)&ecx); 2245 (char *)&ebx, (char *)&edx, (char *)&ecx);
2204 2246
@@ -2209,7 +2251,7 @@ void check_cpuid()
2209 if (family == 6 || family == 0xf) 2251 if (family == 6 || family == 0xf)
2210 model += ((fms >> 16) & 0xf) << 4; 2252 model += ((fms >> 16) & 0xf) << 4;
2211 2253
2212 if (verbose) 2254 if (debug)
2213 fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", 2255 fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
2214 max_level, family, model, stepping, family, model, stepping); 2256 max_level, family, model, stepping, family, model, stepping);
2215 2257
@@ -2245,20 +2287,24 @@ void check_cpuid()
2245 do_ptm = eax & (1 << 6); 2287 do_ptm = eax & (1 << 6);
2246 has_epb = ecx & (1 << 3); 2288 has_epb = ecx & (1 << 3);
2247 2289
2248 if (verbose) 2290 if (debug)
2249 fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n", 2291 fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n",
2250 has_aperf ? "" : "No ", 2292 has_aperf ? "" : "No ",
2251 do_dts ? "" : "No ", 2293 do_dts ? "" : "No ",
2252 do_ptm ? "" : "No ", 2294 do_ptm ? "" : "No ",
2253 has_epb ? "" : "No "); 2295 has_epb ? "" : "No ");
2254 2296
2255 do_nhm_platform_info = do_nhm_cstates = do_smi = has_nhm_msrs(family, model); 2297 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
2256 do_snb_cstates = has_snb_msrs(family, model); 2298 do_snb_cstates = has_snb_msrs(family, model);
2299 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
2300 do_pc3 = (pkg_cstate_limit >= PCL__3);
2301 do_pc6 = (pkg_cstate_limit >= PCL__6);
2302 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
2257 do_c8_c9_c10 = has_hsw_msrs(family, model); 2303 do_c8_c9_c10 = has_hsw_msrs(family, model);
2258 do_slm_cstates = is_slm(family, model); 2304 do_slm_cstates = is_slm(family, model);
2259 bclk = discover_bclk(family, model); 2305 bclk = discover_bclk(family, model);
2260 2306
2261 do_nhm_turbo_ratio_limit = has_nhm_turbo_ratio_limit(family, model); 2307 do_nhm_turbo_ratio_limit = do_nhm_platform_info && has_nhm_turbo_ratio_limit(family, model);
2262 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); 2308 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
2263 rapl_probe(family, model); 2309 rapl_probe(family, model);
2264 perf_limit_reasons_probe(family, model); 2310 perf_limit_reasons_probe(family, model);
@@ -2267,10 +2313,25 @@ void check_cpuid()
2267} 2313}
2268 2314
2269 2315
2270void usage() 2316void help()
2271{ 2317{
2272 errx(1, "%s: [-v][-R][-T][-p|-P|-S][-c MSR#][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n", 2318 fprintf(stderr,
2273 progname); 2319 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
2320 "\n"
2321 "Turbostat forks the specified COMMAND and prints statistics\n"
2322 "when COMMAND completes.\n"
2323 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
2324 "to print statistics, until interrupted.\n"
2325 "--debug run in \"debug\" mode\n"
2326 "--interval sec Override default 5-second measurement interval\n"
2327 "--help print this help message\n"
2328 "--counter msr print 32-bit counter at address \"msr\"\n"
2329 "--Counter msr print 64-bit Counter at address \"msr\"\n"
2330 "--msr msr print 32-bit value at address \"msr\"\n"
2331 "--MSR msr print 64-bit Value at address \"msr\"\n"
2332 "--version print version information\n"
2333 "\n"
2334 "For more help, run \"man turbostat\"\n");
2274} 2335}
2275 2336
2276 2337
@@ -2309,7 +2370,7 @@ void topology_probe()
2309 if (!summary_only && topo.num_cpus > 1) 2370 if (!summary_only && topo.num_cpus > 1)
2310 show_cpu = 1; 2371 show_cpu = 1;
2311 2372
2312 if (verbose > 1) 2373 if (debug > 1)
2313 fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num); 2374 fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
2314 2375
2315 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology)); 2376 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
@@ -2344,7 +2405,7 @@ void topology_probe()
2344 int siblings; 2405 int siblings;
2345 2406
2346 if (cpu_is_not_present(i)) { 2407 if (cpu_is_not_present(i)) {
2347 if (verbose > 1) 2408 if (debug > 1)
2348 fprintf(stderr, "cpu%d NOT PRESENT\n", i); 2409 fprintf(stderr, "cpu%d NOT PRESENT\n", i);
2349 continue; 2410 continue;
2350 } 2411 }
@@ -2359,26 +2420,26 @@ void topology_probe()
2359 siblings = get_num_ht_siblings(i); 2420 siblings = get_num_ht_siblings(i);
2360 if (siblings > max_siblings) 2421 if (siblings > max_siblings)
2361 max_siblings = siblings; 2422 max_siblings = siblings;
2362 if (verbose > 1) 2423 if (debug > 1)
2363 fprintf(stderr, "cpu %d pkg %d core %d\n", 2424 fprintf(stderr, "cpu %d pkg %d core %d\n",
2364 i, cpus[i].physical_package_id, cpus[i].core_id); 2425 i, cpus[i].physical_package_id, cpus[i].core_id);
2365 } 2426 }
2366 topo.num_cores_per_pkg = max_core_id + 1; 2427 topo.num_cores_per_pkg = max_core_id + 1;
2367 if (verbose > 1) 2428 if (debug > 1)
2368 fprintf(stderr, "max_core_id %d, sizing for %d cores per package\n", 2429 fprintf(stderr, "max_core_id %d, sizing for %d cores per package\n",
2369 max_core_id, topo.num_cores_per_pkg); 2430 max_core_id, topo.num_cores_per_pkg);
2370 if (!summary_only && topo.num_cores_per_pkg > 1) 2431 if (!summary_only && topo.num_cores_per_pkg > 1)
2371 show_core = 1; 2432 show_core = 1;
2372 2433
2373 topo.num_packages = max_package_id + 1; 2434 topo.num_packages = max_package_id + 1;
2374 if (verbose > 1) 2435 if (debug > 1)
2375 fprintf(stderr, "max_package_id %d, sizing for %d packages\n", 2436 fprintf(stderr, "max_package_id %d, sizing for %d packages\n",
2376 max_package_id, topo.num_packages); 2437 max_package_id, topo.num_packages);
2377 if (!summary_only && topo.num_packages > 1) 2438 if (!summary_only && topo.num_packages > 1)
2378 show_pkg = 1; 2439 show_pkg = 1;
2379 2440
2380 topo.num_threads_per_core = max_siblings; 2441 topo.num_threads_per_core = max_siblings;
2381 if (verbose > 1) 2442 if (debug > 1)
2382 fprintf(stderr, "max_siblings %d\n", max_siblings); 2443 fprintf(stderr, "max_siblings %d\n", max_siblings);
2383 2444
2384 free(cpus); 2445 free(cpus);
@@ -2493,21 +2554,21 @@ void turbostat_init()
2493 2554
2494 setup_all_buffers(); 2555 setup_all_buffers();
2495 2556
2496 if (verbose) 2557 if (debug)
2497 print_verbose_header(); 2558 print_verbose_header();
2498 2559
2499 if (verbose) 2560 if (debug)
2500 for_all_cpus(print_epb, ODD_COUNTERS); 2561 for_all_cpus(print_epb, ODD_COUNTERS);
2501 2562
2502 if (verbose) 2563 if (debug)
2503 for_all_cpus(print_perf_limit, ODD_COUNTERS); 2564 for_all_cpus(print_perf_limit, ODD_COUNTERS);
2504 2565
2505 if (verbose) 2566 if (debug)
2506 for_all_cpus(print_rapl, ODD_COUNTERS); 2567 for_all_cpus(print_rapl, ODD_COUNTERS);
2507 2568
2508 for_all_cpus(set_temperature_target, ODD_COUNTERS); 2569 for_all_cpus(set_temperature_target, ODD_COUNTERS);
2509 2570
2510 if (verbose) 2571 if (debug)
2511 for_all_cpus(print_thermal, ODD_COUNTERS); 2572 for_all_cpus(print_thermal, ODD_COUNTERS);
2512} 2573}
2513 2574
@@ -2572,56 +2633,82 @@ int get_and_dump_counters(void)
2572 return status; 2633 return status;
2573} 2634}
2574 2635
2636void print_version() {
2637 fprintf(stderr, "turbostat version 4.1 10-Feb, 2015"
2638 " - Len Brown <lenb@kernel.org>\n");
2639}
2640
2575void cmdline(int argc, char **argv) 2641void cmdline(int argc, char **argv)
2576{ 2642{
2577 int opt; 2643 int opt;
2644 int option_index = 0;
2645 static struct option long_options[] = {
2646 {"Counter", required_argument, 0, 'C'},
2647 {"counter", required_argument, 0, 'c'},
2648 {"Dump", no_argument, 0, 'D'},
2649 {"debug", no_argument, 0, 'd'},
2650 {"interval", required_argument, 0, 'i'},
2651 {"help", no_argument, 0, 'h'},
2652 {"Joules", no_argument, 0, 'J'},
2653 {"MSR", required_argument, 0, 'M'},
2654 {"msr", required_argument, 0, 'm'},
2655 {"Package", no_argument, 0, 'p'},
2656 {"processor", no_argument, 0, 'p'},
2657 {"Summary", no_argument, 0, 'S'},
2658 {"TCC", required_argument, 0, 'T'},
2659 {"version", no_argument, 0, 'v' },
2660 {0, 0, 0, 0 }
2661 };
2578 2662
2579 progname = argv[0]; 2663 progname = argv[0];
2580 2664
2581 while ((opt = getopt(argc, argv, "+pPsSvi:c:C:m:M:RJT:")) != -1) { 2665 while ((opt = getopt_long_only(argc, argv, "C:c:Ddhi:JM:m:PpST:v",
2666 long_options, &option_index)) != -1) {
2582 switch (opt) { 2667 switch (opt) {
2583 case 'p': 2668 case 'C':
2584 show_core_only++; 2669 sscanf(optarg, "%x", &extra_delta_offset64);
2585 break; 2670 break;
2586 case 'P': 2671 case 'c':
2587 show_pkg_only++; 2672 sscanf(optarg, "%x", &extra_delta_offset32);
2588 break; 2673 break;
2589 case 's': 2674 case 'D':
2590 dump_only++; 2675 dump_only++;
2591 break; 2676 break;
2592 case 'S': 2677 case 'd':
2593 summary_only++; 2678 debug++;
2594 break;
2595 case 'v':
2596 verbose++;
2597 break; 2679 break;
2680 case 'h':
2681 default:
2682 help();
2683 exit(1);
2598 case 'i': 2684 case 'i':
2599 interval_sec = atoi(optarg); 2685 interval_sec = atoi(optarg);
2600 break; 2686 break;
2601 case 'c': 2687 case 'J':
2602 sscanf(optarg, "%x", &extra_delta_offset32); 2688 rapl_joules++;
2603 break; 2689 break;
2604 case 'C': 2690 case 'M':
2605 sscanf(optarg, "%x", &extra_delta_offset64); 2691 sscanf(optarg, "%x", &extra_msr_offset64);
2606 break; 2692 break;
2607 case 'm': 2693 case 'm':
2608 sscanf(optarg, "%x", &extra_msr_offset32); 2694 sscanf(optarg, "%x", &extra_msr_offset32);
2609 break; 2695 break;
2610 case 'M': 2696 case 'P':
2611 sscanf(optarg, "%x", &extra_msr_offset64); 2697 show_pkg_only++;
2612 break; 2698 break;
2613 case 'R': 2699 case 'p':
2614 rapl_verbose++; 2700 show_core_only++;
2701 break;
2702 case 'S':
2703 summary_only++;
2615 break; 2704 break;
2616 case 'T': 2705 case 'T':
2617 tcc_activation_temp_override = atoi(optarg); 2706 tcc_activation_temp_override = atoi(optarg);
2618 break; 2707 break;
2619 case 'J': 2708 case 'v':
2620 rapl_joules++; 2709 print_version();
2710 exit(0);
2621 break; 2711 break;
2622
2623 default:
2624 usage();
2625 } 2712 }
2626 } 2713 }
2627} 2714}
@@ -2630,9 +2717,8 @@ int main(int argc, char **argv)
2630{ 2717{
2631 cmdline(argc, argv); 2718 cmdline(argc, argv);
2632 2719
2633 if (verbose) 2720 if (debug)
2634 fprintf(stderr, "turbostat v3.9 23-Jan, 2015" 2721 print_version();
2635 " - Len Brown <lenb@kernel.org>\n");
2636 2722
2637 turbostat_init(); 2723 turbostat_init();
2638 2724