aboutsummaryrefslogtreecommitdiffstats
path: root/tools/power/x86/turbostat/turbostat.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2012-09-22 01:25:08 -0400
committerLen Brown <len.brown@intel.com>2012-09-27 22:04:56 -0400
commit8e180f3cb6b7510a3bdf14e16ce87c9f5d86f102 (patch)
tree2a7b3ac9789a47d1bfb9ccbb7a9a4fa31f91b61d /tools/power/x86/turbostat/turbostat.c
parent2f32edf12c1eafc8e5b1b0337360993fde1b3565 (diff)
tools/power turbostat: add [-d MSR#][-D MSR#] options to print counter deltas
# turbostat -d 0x34 is useful for printing the number of SMI's within an interval on Nehalem and newer processors. where # turbostat -m 0x34 will simply print out the total SMI count since reset. Suggested-by: Andi Kleen Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools/power/x86/turbostat/turbostat.c')
-rw-r--r--tools/power/x86/turbostat/turbostat.c95
1 files changed, 63 insertions, 32 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 946e9ab48edb..e38976c0b0a2 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -65,6 +65,8 @@ unsigned int do_nehalem_turbo_ratio_limit;
65unsigned int do_ivt_turbo_ratio_limit; 65unsigned int do_ivt_turbo_ratio_limit;
66unsigned int extra_msr_offset32; 66unsigned int extra_msr_offset32;
67unsigned int extra_msr_offset64; 67unsigned int extra_msr_offset64;
68unsigned int extra_delta_offset32;
69unsigned int extra_delta_offset64;
68double bclk; 70double bclk;
69unsigned int show_pkg; 71unsigned int show_pkg;
70unsigned int show_core; 72unsigned int show_core;
@@ -86,7 +88,9 @@ struct thread_data {
86 unsigned long long mperf; 88 unsigned long long mperf;
87 unsigned long long c1; /* derived */ 89 unsigned long long c1; /* derived */
88 unsigned long long extra_msr64; 90 unsigned long long extra_msr64;
89 unsigned int extra_msr32; 91 unsigned long long extra_delta64;
92 unsigned long long extra_msr32;
93 unsigned long long extra_delta32;
90 unsigned int cpu_id; 94 unsigned int cpu_id;
91 unsigned int flags; 95 unsigned int flags;
92#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 96#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
@@ -208,24 +212,6 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
208 return 0; 212 return 0;
209} 213}
210 214
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
229void print_header(void) 215void print_header(void)
230{ 216{
231 if (show_pkg) 217 if (show_pkg)
@@ -243,10 +229,14 @@ void print_header(void)
243 if (has_aperf) 229 if (has_aperf)
244 outp += sprintf(outp, " GHz"); 230 outp += sprintf(outp, " GHz");
245 outp += sprintf(outp, " TSC"); 231 outp += sprintf(outp, " TSC");
232 if (extra_delta_offset32)
233 outp += sprintf(outp, " delta 0x%03X", extra_delta_offset32);
234 if (extra_delta_offset64)
235 outp += sprintf(outp, " DELTA 0x%03X", extra_delta_offset64);
246 if (extra_msr_offset32) 236 if (extra_msr_offset32)
247 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset32); 237 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
248 if (extra_msr_offset64) 238 if (extra_msr_offset64)
249 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset64); 239 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
250 if (do_nhm_cstates) 240 if (do_nhm_cstates)
251 outp += sprintf(outp, " %%c1"); 241 outp += sprintf(outp, " %%c1");
252 if (do_nhm_cstates) 242 if (do_nhm_cstates)
@@ -278,7 +268,11 @@ int dump_counters(struct thread_data *t, struct core_data *c,
278 fprintf(stderr, "aperf: %016llX\n", t->aperf); 268 fprintf(stderr, "aperf: %016llX\n", t->aperf);
279 fprintf(stderr, "mperf: %016llX\n", t->mperf); 269 fprintf(stderr, "mperf: %016llX\n", t->mperf);
280 fprintf(stderr, "c1: %016llX\n", t->c1); 270 fprintf(stderr, "c1: %016llX\n", t->c1);
281 fprintf(stderr, "msr0x%x: %08X\n", 271 fprintf(stderr, "msr0x%x: %08llX\n",
272 extra_delta_offset32, t->extra_delta32);
273 fprintf(stderr, "msr0x%x: %016llX\n",
274 extra_delta_offset64, t->extra_delta64);
275 fprintf(stderr, "msr0x%x: %08llX\n",
282 extra_msr_offset32, t->extra_msr32); 276 extra_msr_offset32, t->extra_msr32);
283 fprintf(stderr, "msr0x%x: %016llX\n", 277 fprintf(stderr, "msr0x%x: %016llX\n",
284 extra_msr_offset64, t->extra_msr64); 278 extra_msr_offset64, t->extra_msr64);
@@ -385,9 +379,16 @@ int format_counters(struct thread_data *t, struct core_data *c,
385 /* TSC */ 379 /* TSC */
386 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); 380 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
387 381
382 /* delta */
383 if (extra_delta_offset32)
384 outp += sprintf(outp, " %11llu", t->extra_delta32);
385
386 /* DELTA */
387 if (extra_delta_offset64)
388 outp += sprintf(outp, " %11llu", t->extra_delta64);
388 /* msr */ 389 /* msr */
389 if (extra_msr_offset32) 390 if (extra_msr_offset32)
390 outp += sprintf(outp, " 0x%08x", t->extra_msr32); 391 outp += sprintf(outp, " 0x%08llx", t->extra_msr32);
391 392
392 /* MSR */ 393 /* MSR */
393 if (extra_msr_offset64) 394 if (extra_msr_offset64)
@@ -533,8 +534,13 @@ delta_thread(struct thread_data *new, struct thread_data *old,
533 old->mperf = 1; /* divide by 0 protection */ 534 old->mperf = 1; /* divide by 0 protection */
534 } 535 }
535 536
537 old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
538 old->extra_delta32 &= 0xFFFFFFFF;
539
540 old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
541
536 /* 542 /*
537 * Extra MSR is a snapshot, simply copy latest w/o subtracting 543 * Extra MSR is just a snapshot, simply copy latest w/o subtracting
538 */ 544 */
539 old->extra_msr32 = new->extra_msr32; 545 old->extra_msr32 = new->extra_msr32;
540 old->extra_msr64 = new->extra_msr64; 546 old->extra_msr64 = new->extra_msr64;
@@ -565,6 +571,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
565 t->mperf = 0; 571 t->mperf = 0;
566 t->c1 = 0; 572 t->c1 = 0;
567 573
574 t->extra_delta32 = 0;
575 t->extra_delta64 = 0;
576
568 /* tells format_counters to dump all fields from this set */ 577 /* tells format_counters to dump all fields from this set */
569 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE; 578 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
570 579
@@ -585,6 +594,9 @@ int sum_counters(struct thread_data *t, struct core_data *c,
585 average.threads.mperf += t->mperf; 594 average.threads.mperf += t->mperf;
586 average.threads.c1 += t->c1; 595 average.threads.c1 += t->c1;
587 596
597 average.threads.extra_delta32 += t->extra_delta32;
598 average.threads.extra_delta64 += t->extra_delta64;
599
588 /* sum per-core values only for 1st thread in core */ 600 /* sum per-core values only for 1st thread in core */
589 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 601 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
590 return 0; 602 return 0;
@@ -620,6 +632,11 @@ void compute_average(struct thread_data *t, struct core_data *c,
620 average.threads.mperf /= topo.num_cpus; 632 average.threads.mperf /= topo.num_cpus;
621 average.threads.c1 /= topo.num_cpus; 633 average.threads.c1 /= topo.num_cpus;
622 634
635 average.threads.extra_delta32 /= topo.num_cpus;
636 average.threads.extra_delta32 &= 0xFFFFFFFF;
637
638 average.threads.extra_delta64 /= topo.num_cpus;
639
623 average.cores.c3 /= topo.num_cores; 640 average.cores.c3 /= topo.num_cores;
624 average.cores.c6 /= topo.num_cores; 641 average.cores.c6 /= topo.num_cores;
625 average.cores.c7 /= topo.num_cores; 642 average.cores.c7 /= topo.num_cores;
@@ -661,10 +678,22 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
661 return -4; 678 return -4;
662 } 679 }
663 680
664 if (extra_msr_offset32) 681 if (extra_delta_offset32) {
665 if (get_msr32(cpu, extra_msr_offset32, &t->extra_msr32)) 682 if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
683 return -5;
684 t->extra_delta32 &= 0xFFFFFFFF;
685 }
686
687 if (extra_delta_offset64)
688 if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
666 return -5; 689 return -5;
667 690
691 if (extra_msr_offset32) {
692 if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
693 return -5;
694 t->extra_msr32 &= 0xFFFFFFFF;
695 }
696
668 if (extra_msr_offset64) 697 if (extra_msr_offset64)
669 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) 698 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
670 return -5; 699 return -5;
@@ -1275,7 +1304,7 @@ void check_cpuid()
1275 1304
1276void usage() 1305void usage()
1277{ 1306{
1278 fprintf(stderr, "%s: [-v] [-m msr#] [-M MSR#] [-i interval_sec | command ...]\n", 1307 fprintf(stderr, "%s: [-v][-d MSR#][-D MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
1279 progname); 1308 progname);
1280 exit(1); 1309 exit(1);
1281} 1310}
@@ -1565,7 +1594,7 @@ void cmdline(int argc, char **argv)
1565 1594
1566 progname = argv[0]; 1595 progname = argv[0];
1567 1596
1568 while ((opt = getopt(argc, argv, "+cpsvi:m:M:")) != -1) { 1597 while ((opt = getopt(argc, argv, "+cpsvid:D:m:M:")) != -1) {
1569 switch (opt) { 1598 switch (opt) {
1570 case 'c': 1599 case 'c':
1571 show_core_only++; 1600 show_core_only++;
@@ -1582,15 +1611,17 @@ void cmdline(int argc, char **argv)
1582 case 'i': 1611 case 'i':
1583 interval_sec = atoi(optarg); 1612 interval_sec = atoi(optarg);
1584 break; 1613 break;
1614 case 'd':
1615 sscanf(optarg, "%x", &extra_delta_offset32);
1616 break;
1617 case 'D':
1618 sscanf(optarg, "%x", &extra_delta_offset64);
1619 break;
1585 case 'm': 1620 case 'm':
1586 sscanf(optarg, "%x", &extra_msr_offset32); 1621 sscanf(optarg, "%x", &extra_msr_offset32);
1587 if (verbose > 1)
1588 fprintf(stderr, "msr 0x%X\n", extra_msr_offset32);
1589 break; 1622 break;
1590 case 'M': 1623 case 'M':
1591 sscanf(optarg, "%x", &extra_msr_offset64); 1624 sscanf(optarg, "%x", &extra_msr_offset64);
1592 if (verbose > 1)
1593 fprintf(stderr, "MSR 0x%X\n", extra_msr_offset64);
1594 break; 1625 break;
1595 default: 1626 default:
1596 usage(); 1627 usage();