aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2012-09-21 23:45:46 -0400
committerLen Brown <len.brown@intel.com>2012-09-26 18:17:21 -0400
commit2f32edf12c1eafc8e5b1b0337360993fde1b3565 (patch)
tree4064b83fc867a2fb1d745590fddfc323f66c19d1 /tools
parent130ff304f6d31484fc73bb337bc635cba1ffe04c (diff)
tools/power turbostat: add [-m MSR#] option
-m MSR# prints the specified MSR in 32-bit format -M MSR# prints the specified MSR in 64-bit format Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/power/x86/turbostat/turbostat.814
-rw-r--r--tools/power/x86/turbostat/turbostat.c68
2 files changed, 66 insertions, 16 deletions
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 74e44507dfe9..8e7b29af78f6 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -6,12 +6,14 @@ turbostat \- Report processor frequency and idle statistics
6.B turbostat 6.B turbostat
7.RB [ "\-s" ] 7.RB [ "\-s" ]
8.RB [ "\-v" ] 8.RB [ "\-v" ]
9.RB [ "\-m MSR#" ]
9.RB [ "\-M MSR#" ] 10.RB [ "\-M MSR#" ]
10.RB command 11.RB command
11.br 12.br
12.B turbostat 13.B turbostat
13.RB [ "\-s" ] 14.RB [ "\-s" ]
14.RB [ "\-v" ] 15.RB [ "\-v" ]
16.RB [ "\-m MSR#" ]
15.RB [ "\-M MSR#" ] 17.RB [ "\-M MSR#" ]
16.RB [ "\-i interval_sec" ] 18.RB [ "\-i interval_sec" ]
17.SH DESCRIPTION 19.SH DESCRIPTION
@@ -35,7 +37,10 @@ The \fB-p\fP option limits output to the 1st thread in each package.
35.PP 37.PP
36The \fB-v\fP option increases verbosity. 38The \fB-v\fP option increases verbosity.
37.PP 39.PP
38The \fB-M MSR#\fP option dumps the specified MSR, 40The \fB-m MSR#\fP option dumps the specified 32-bit MSR,
41in addition to the usual frequency and idle statistics.
42.PP
43The \fB-M MSR#\fP option dumps the specified 64-bit MSR,
39in addition to the usual frequency and idle statistics. 44in addition to the usual frequency and idle statistics.
40.PP 45.PP
41The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. 46The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
@@ -165,6 +170,13 @@ may work poorly on Linux-2.6.20 through 2.6.29,
165as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF 170as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
166in those kernels. 171in those kernels.
167 172
173If the TSC column does not make sense, then
174the other numbers will also make no sense.
175Turbostat is lightweight, and its data collection is not atomic.
176These issues are usually caused by an extremely short measurement
177interval (much less than 1 second), or system activity that prevents
178turbostat from being able to run on all CPUS to quickly collect data.
179
168The APERF, MPERF MSRs are defined to count non-halted cycles. 180The APERF, MPERF MSRs are defined to count non-halted cycles.
169Although it is not guaranteed by the architecture, turbostat assumes 181Although it is not guaranteed by the architecture, turbostat assumes
170that they count at TSC rate, which is true on all processors tested to date. 182that they count at TSC rate, which is true on all processors tested to date.
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 5ce88dd8c95a..946e9ab48edb 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -63,7 +63,8 @@ unsigned int has_invariant_tsc;
63unsigned int do_nehalem_platform_info; 63unsigned int do_nehalem_platform_info;
64unsigned int do_nehalem_turbo_ratio_limit; 64unsigned int do_nehalem_turbo_ratio_limit;
65unsigned int do_ivt_turbo_ratio_limit; 65unsigned int do_ivt_turbo_ratio_limit;
66unsigned int extra_msr_offset; 66unsigned int extra_msr_offset32;
67unsigned int extra_msr_offset64;
67double bclk; 68double bclk;
68unsigned int show_pkg; 69unsigned int show_pkg;
69unsigned int show_core; 70unsigned int show_core;
@@ -84,7 +85,8 @@ struct thread_data {
84 unsigned long long aperf; 85 unsigned long long aperf;
85 unsigned long long mperf; 86 unsigned long long mperf;
86 unsigned long long c1; /* derived */ 87 unsigned long long c1; /* derived */
87 unsigned long long extra_msr; 88 unsigned long long extra_msr64;
89 unsigned int extra_msr32;
88 unsigned int cpu_id; 90 unsigned int cpu_id;
89 unsigned int flags; 91 unsigned int flags;
90#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 92#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
@@ -206,6 +208,24 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
206 return 0; 208 return 0;
207} 209}
208 210
211/*
212 * Truncate the 8 bytes we read from /dev/cpu/.../msr
213 * to the 4 bytes requested
214 */
215
216int get_msr32(int cpu, off_t offset, unsigned int *msr)
217{
218 int retval;
219
220 unsigned long long msr64;
221
222 retval = get_msr(cpu, offset, &msr64);
223 *msr = (unsigned int) msr64;
224
225 return retval;
226}
227
228
209void print_header(void) 229void print_header(void)
210{ 230{
211 if (show_pkg) 231 if (show_pkg)
@@ -223,8 +243,10 @@ void print_header(void)
223 if (has_aperf) 243 if (has_aperf)
224 outp += sprintf(outp, " GHz"); 244 outp += sprintf(outp, " GHz");
225 outp += sprintf(outp, " TSC"); 245 outp += sprintf(outp, " TSC");
226 if (extra_msr_offset) 246 if (extra_msr_offset32)
227 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset); 247 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset32);
248 if (extra_msr_offset64)
249 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset64);
228 if (do_nhm_cstates) 250 if (do_nhm_cstates)
229 outp += sprintf(outp, " %%c1"); 251 outp += sprintf(outp, " %%c1");
230 if (do_nhm_cstates) 252 if (do_nhm_cstates)
@@ -256,8 +278,10 @@ int dump_counters(struct thread_data *t, struct core_data *c,
256 fprintf(stderr, "aperf: %016llX\n", t->aperf); 278 fprintf(stderr, "aperf: %016llX\n", t->aperf);
257 fprintf(stderr, "mperf: %016llX\n", t->mperf); 279 fprintf(stderr, "mperf: %016llX\n", t->mperf);
258 fprintf(stderr, "c1: %016llX\n", t->c1); 280 fprintf(stderr, "c1: %016llX\n", t->c1);
281 fprintf(stderr, "msr0x%x: %08X\n",
282 extra_msr_offset32, t->extra_msr32);
259 fprintf(stderr, "msr0x%x: %016llX\n", 283 fprintf(stderr, "msr0x%x: %016llX\n",
260 extra_msr_offset, t->extra_msr); 284 extra_msr_offset64, t->extra_msr64);
261 } 285 }
262 286
263 if (c) { 287 if (c) {
@@ -361,9 +385,13 @@ int format_counters(struct thread_data *t, struct core_data *c,
361 /* TSC */ 385 /* TSC */
362 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); 386 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
363 387
388 /* msr */
389 if (extra_msr_offset32)
390 outp += sprintf(outp, " 0x%08x", t->extra_msr32);
391
364 /* MSR */ 392 /* MSR */
365 if (extra_msr_offset) 393 if (extra_msr_offset64)
366 outp += sprintf(outp, " 0x%016llx", t->extra_msr); 394 outp += sprintf(outp, " 0x%016llx", t->extra_msr64);
367 395
368 if (do_nhm_cstates) { 396 if (do_nhm_cstates) {
369 if (!skip_c1) 397 if (!skip_c1)
@@ -506,9 +534,10 @@ delta_thread(struct thread_data *new, struct thread_data *old,
506 } 534 }
507 535
508 /* 536 /*
509 * for "extra msr", just copy the latest w/o subtracting 537 * Extra MSR is a snapshot, simply copy latest w/o subtracting
510 */ 538 */
511 old->extra_msr = new->extra_msr; 539 old->extra_msr32 = new->extra_msr32;
540 old->extra_msr64 = new->extra_msr64;
512} 541}
513 542
514int delta_cpu(struct thread_data *t, struct core_data *c, 543int delta_cpu(struct thread_data *t, struct core_data *c,
@@ -632,8 +661,12 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
632 return -4; 661 return -4;
633 } 662 }
634 663
635 if (extra_msr_offset) 664 if (extra_msr_offset32)
636 if (get_msr(cpu, extra_msr_offset, &t->extra_msr)) 665 if (get_msr32(cpu, extra_msr_offset32, &t->extra_msr32))
666 return -5;
667
668 if (extra_msr_offset64)
669 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
637 return -5; 670 return -5;
638 671
639 /* collect core counters only for 1st thread in core */ 672 /* collect core counters only for 1st thread in core */
@@ -1242,7 +1275,7 @@ void check_cpuid()
1242 1275
1243void usage() 1276void usage()
1244{ 1277{
1245 fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n", 1278 fprintf(stderr, "%s: [-v] [-m msr#] [-M MSR#] [-i interval_sec | command ...]\n",
1246 progname); 1279 progname);
1247 exit(1); 1280 exit(1);
1248} 1281}
@@ -1532,7 +1565,7 @@ void cmdline(int argc, char **argv)
1532 1565
1533 progname = argv[0]; 1566 progname = argv[0];
1534 1567
1535 while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) { 1568 while ((opt = getopt(argc, argv, "+cpsvi:m:M:")) != -1) {
1536 switch (opt) { 1569 switch (opt) {
1537 case 'c': 1570 case 'c':
1538 show_core_only++; 1571 show_core_only++;
@@ -1549,10 +1582,15 @@ void cmdline(int argc, char **argv)
1549 case 'i': 1582 case 'i':
1550 interval_sec = atoi(optarg); 1583 interval_sec = atoi(optarg);
1551 break; 1584 break;
1585 case 'm':
1586 sscanf(optarg, "%x", &extra_msr_offset32);
1587 if (verbose > 1)
1588 fprintf(stderr, "msr 0x%X\n", extra_msr_offset32);
1589 break;
1552 case 'M': 1590 case 'M':
1553 sscanf(optarg, "%x", &extra_msr_offset); 1591 sscanf(optarg, "%x", &extra_msr_offset64);
1554 if (verbose > 1) 1592 if (verbose > 1)
1555 fprintf(stderr, "MSR 0x%X\n", extra_msr_offset); 1593 fprintf(stderr, "MSR 0x%X\n", extra_msr_offset64);
1556 break; 1594 break;
1557 default: 1595 default:
1558 usage(); 1596 usage();