aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/power/x86/turbostat/.gitignore1
-rw-r--r--tools/power/x86/turbostat/Makefile2
-rw-r--r--tools/power/x86/turbostat/turbostat.c441
3 files changed, 244 insertions, 200 deletions
diff --git a/tools/power/x86/turbostat/.gitignore b/tools/power/x86/turbostat/.gitignore
new file mode 100644
index 000000000000..7521370d3568
--- /dev/null
+++ b/tools/power/x86/turbostat/.gitignore
@@ -0,0 +1 @@
turbostat
diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile
index f09641da40d4..d1b3a361e526 100644
--- a/tools/power/x86/turbostat/Makefile
+++ b/tools/power/x86/turbostat/Makefile
@@ -5,7 +5,7 @@ DESTDIR :=
5 5
6turbostat : turbostat.c 6turbostat : turbostat.c
7CFLAGS += -Wall 7CFLAGS += -Wall
8CFLAGS += -I../../../../arch/x86/include/uapi/ 8CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/uapi/asm/msr-index.h"'
9 9
10%: %.c 10%: %.c
11 @mkdir -p $(BUILD_OUTPUT) 11 @mkdir -p $(BUILD_OUTPUT)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 9d77f13c2d25..77eb130168da 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -20,8 +20,10 @@
20 */ 20 */
21 21
22#define _GNU_SOURCE 22#define _GNU_SOURCE
23#include <asm/msr.h> 23#include MSRHEADER
24#include <stdarg.h>
24#include <stdio.h> 25#include <stdio.h>
26#include <err.h>
25#include <unistd.h> 27#include <unistd.h>
26#include <sys/types.h> 28#include <sys/types.h>
27#include <sys/wait.h> 29#include <sys/wait.h>
@@ -35,13 +37,16 @@
35#include <string.h> 37#include <string.h>
36#include <ctype.h> 38#include <ctype.h>
37#include <sched.h> 39#include <sched.h>
40#include <cpuid.h>
38 41
39char *proc_stat = "/proc/stat"; 42char *proc_stat = "/proc/stat";
40unsigned int interval_sec = 5; /* set with -i interval_sec */ 43unsigned int interval_sec = 5; /* set with -i interval_sec */
41unsigned int verbose; /* set with -v */ 44unsigned int verbose; /* set with -v */
42unsigned int rapl_verbose; /* set with -R */ 45unsigned int rapl_verbose; /* set with -R */
46unsigned int rapl_joules; /* set with -J */
43unsigned int thermal_verbose; /* set with -T */ 47unsigned int thermal_verbose; /* set with -T */
44unsigned int summary_only; /* set with -s */ 48unsigned int summary_only; /* set with -S */
49unsigned int dump_only; /* set with -s */
45unsigned int skip_c0; 50unsigned int skip_c0;
46unsigned int skip_c1; 51unsigned int skip_c1;
47unsigned int do_nhm_cstates; 52unsigned int do_nhm_cstates;
@@ -77,14 +82,32 @@ unsigned int tcc_activation_temp_override;
77double rapl_power_units, rapl_energy_units, rapl_time_units; 82double rapl_power_units, rapl_energy_units, rapl_time_units;
78double rapl_joule_counter_range; 83double rapl_joule_counter_range;
79 84
80#define RAPL_PKG (1 << 0) 85#define RAPL_PKG (1 << 0)
81#define RAPL_CORES (1 << 1) 86 /* 0x610 MSR_PKG_POWER_LIMIT */
82#define RAPL_GFX (1 << 2) 87 /* 0x611 MSR_PKG_ENERGY_STATUS */
83#define RAPL_DRAM (1 << 3) 88#define RAPL_PKG_PERF_STATUS (1 << 1)
84#define RAPL_PKG_PERF_STATUS (1 << 4) 89 /* 0x613 MSR_PKG_PERF_STATUS */
85#define RAPL_DRAM_PERF_STATUS (1 << 5) 90#define RAPL_PKG_POWER_INFO (1 << 2)
86#define RAPL_PKG_POWER_INFO (1 << 6) 91 /* 0x614 MSR_PKG_POWER_INFO */
87#define RAPL_CORE_POLICY (1 << 7) 92
93#define RAPL_DRAM (1 << 3)
94 /* 0x618 MSR_DRAM_POWER_LIMIT */
95 /* 0x619 MSR_DRAM_ENERGY_STATUS */
96 /* 0x61c MSR_DRAM_POWER_INFO */
97#define RAPL_DRAM_PERF_STATUS (1 << 4)
98 /* 0x61b MSR_DRAM_PERF_STATUS */
99
100#define RAPL_CORES (1 << 5)
101 /* 0x638 MSR_PP0_POWER_LIMIT */
102 /* 0x639 MSR_PP0_ENERGY_STATUS */
103#define RAPL_CORE_POLICY (1 << 6)
104 /* 0x63a MSR_PP0_POLICY */
105
106
107#define RAPL_GFX (1 << 7)
108 /* 0x640 MSR_PP1_POWER_LIMIT */
109 /* 0x641 MSR_PP1_ENERGY_STATUS */
110 /* 0x642 MSR_PP1_POLICY */
88#define TJMAX_DEFAULT 100 111#define TJMAX_DEFAULT 100
89 112
90#define MAX(a, b) ((a) > (b) ? (a) : (b)) 113#define MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -234,7 +257,7 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
234 close(fd); 257 close(fd);
235 258
236 if (retval != sizeof *msr) { 259 if (retval != sizeof *msr) {
237 fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset); 260 fprintf(stderr, "%s offset 0x%llx read failed\n", pathname, (unsigned long long)offset);
238 return -1; 261 return -1;
239 } 262 }
240 263
@@ -296,70 +319,92 @@ void print_header(void)
296 outp += sprintf(outp, " %%pc10"); 319 outp += sprintf(outp, " %%pc10");
297 } 320 }
298 321
299 if (do_rapl & RAPL_PKG) 322 if (do_rapl && !rapl_joules) {
300 outp += sprintf(outp, " Pkg_W"); 323 if (do_rapl & RAPL_PKG)
301 if (do_rapl & RAPL_CORES) 324 outp += sprintf(outp, " Pkg_W");
302 outp += sprintf(outp, " Cor_W"); 325 if (do_rapl & RAPL_CORES)
303 if (do_rapl & RAPL_GFX) 326 outp += sprintf(outp, " Cor_W");
304 outp += sprintf(outp, " GFX_W"); 327 if (do_rapl & RAPL_GFX)
305 if (do_rapl & RAPL_DRAM) 328 outp += sprintf(outp, " GFX_W");
306 outp += sprintf(outp, " RAM_W"); 329 if (do_rapl & RAPL_DRAM)
307 if (do_rapl & RAPL_PKG_PERF_STATUS) 330 outp += sprintf(outp, " RAM_W");
308 outp += sprintf(outp, " PKG_%%"); 331 if (do_rapl & RAPL_PKG_PERF_STATUS)
309 if (do_rapl & RAPL_DRAM_PERF_STATUS) 332 outp += sprintf(outp, " PKG_%%");
310 outp += sprintf(outp, " RAM_%%"); 333 if (do_rapl & RAPL_DRAM_PERF_STATUS)
334 outp += sprintf(outp, " RAM_%%");
335 } else {
336 if (do_rapl & RAPL_PKG)
337 outp += sprintf(outp, " Pkg_J");
338 if (do_rapl & RAPL_CORES)
339 outp += sprintf(outp, " Cor_J");
340 if (do_rapl & RAPL_GFX)
341 outp += sprintf(outp, " GFX_J");
342 if (do_rapl & RAPL_DRAM)
343 outp += sprintf(outp, " RAM_W");
344 if (do_rapl & RAPL_PKG_PERF_STATUS)
345 outp += sprintf(outp, " PKG_%%");
346 if (do_rapl & RAPL_DRAM_PERF_STATUS)
347 outp += sprintf(outp, " RAM_%%");
348 outp += sprintf(outp, " time");
311 349
350 }
312 outp += sprintf(outp, "\n"); 351 outp += sprintf(outp, "\n");
313} 352}
314 353
315int dump_counters(struct thread_data *t, struct core_data *c, 354int dump_counters(struct thread_data *t, struct core_data *c,
316 struct pkg_data *p) 355 struct pkg_data *p)
317{ 356{
318 fprintf(stderr, "t %p, c %p, p %p\n", t, c, p); 357 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
319 358
320 if (t) { 359 if (t) {
321 fprintf(stderr, "CPU: %d flags 0x%x\n", t->cpu_id, t->flags); 360 outp += sprintf(outp, "CPU: %d flags 0x%x\n",
322 fprintf(stderr, "TSC: %016llX\n", t->tsc); 361 t->cpu_id, t->flags);
323 fprintf(stderr, "aperf: %016llX\n", t->aperf); 362 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
324 fprintf(stderr, "mperf: %016llX\n", t->mperf); 363 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
325 fprintf(stderr, "c1: %016llX\n", t->c1); 364 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
326 fprintf(stderr, "msr0x%x: %08llX\n", 365 outp += sprintf(outp, "c1: %016llX\n", t->c1);
366 outp += sprintf(outp, "msr0x%x: %08llX\n",
327 extra_delta_offset32, t->extra_delta32); 367 extra_delta_offset32, t->extra_delta32);
328 fprintf(stderr, "msr0x%x: %016llX\n", 368 outp += sprintf(outp, "msr0x%x: %016llX\n",
329 extra_delta_offset64, t->extra_delta64); 369 extra_delta_offset64, t->extra_delta64);
330 fprintf(stderr, "msr0x%x: %08llX\n", 370 outp += sprintf(outp, "msr0x%x: %08llX\n",
331 extra_msr_offset32, t->extra_msr32); 371 extra_msr_offset32, t->extra_msr32);
332 fprintf(stderr, "msr0x%x: %016llX\n", 372 outp += sprintf(outp, "msr0x%x: %016llX\n",
333 extra_msr_offset64, t->extra_msr64); 373 extra_msr_offset64, t->extra_msr64);
334 if (do_smi) 374 if (do_smi)
335 fprintf(stderr, "SMI: %08X\n", t->smi_count); 375 outp += sprintf(outp, "SMI: %08X\n", t->smi_count);
336 } 376 }
337 377
338 if (c) { 378 if (c) {
339 fprintf(stderr, "core: %d\n", c->core_id); 379 outp += sprintf(outp, "core: %d\n", c->core_id);
340 fprintf(stderr, "c3: %016llX\n", c->c3); 380 outp += sprintf(outp, "c3: %016llX\n", c->c3);
341 fprintf(stderr, "c6: %016llX\n", c->c6); 381 outp += sprintf(outp, "c6: %016llX\n", c->c6);
342 fprintf(stderr, "c7: %016llX\n", c->c7); 382 outp += sprintf(outp, "c7: %016llX\n", c->c7);
343 fprintf(stderr, "DTS: %dC\n", c->core_temp_c); 383 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
344 } 384 }
345 385
346 if (p) { 386 if (p) {
347 fprintf(stderr, "package: %d\n", p->package_id); 387 outp += sprintf(outp, "package: %d\n", p->package_id);
348 fprintf(stderr, "pc2: %016llX\n", p->pc2); 388 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
349 fprintf(stderr, "pc3: %016llX\n", p->pc3); 389 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
350 fprintf(stderr, "pc6: %016llX\n", p->pc6); 390 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
351 fprintf(stderr, "pc7: %016llX\n", p->pc7); 391 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
352 fprintf(stderr, "pc8: %016llX\n", p->pc8); 392 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
353 fprintf(stderr, "pc9: %016llX\n", p->pc9); 393 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
354 fprintf(stderr, "pc10: %016llX\n", p->pc10); 394 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
355 fprintf(stderr, "Joules PKG: %0X\n", p->energy_pkg); 395 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
356 fprintf(stderr, "Joules COR: %0X\n", p->energy_cores); 396 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores);
357 fprintf(stderr, "Joules GFX: %0X\n", p->energy_gfx); 397 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx);
358 fprintf(stderr, "Joules RAM: %0X\n", p->energy_dram); 398 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram);
359 fprintf(stderr, "Throttle PKG: %0X\n", p->rapl_pkg_perf_status); 399 outp += sprintf(outp, "Throttle PKG: %0X\n",
360 fprintf(stderr, "Throttle RAM: %0X\n", p->rapl_dram_perf_status); 400 p->rapl_pkg_perf_status);
361 fprintf(stderr, "PTM: %dC\n", p->pkg_temp_c); 401 outp += sprintf(outp, "Throttle RAM: %0X\n",
402 p->rapl_dram_perf_status);
403 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
362 } 404 }
405
406 outp += sprintf(outp, "\n");
407
363 return 0; 408 return 0;
364} 409}
365 410
@@ -527,19 +572,39 @@ int format_counters(struct thread_data *t, struct core_data *c,
527 fmt6 = " %4.0f**"; 572 fmt6 = " %4.0f**";
528 } 573 }
529 574
530 if (do_rapl & RAPL_PKG) 575 if (do_rapl && !rapl_joules) {
531 outp += sprintf(outp, fmt6, p->energy_pkg * rapl_energy_units / interval_float); 576 if (do_rapl & RAPL_PKG)
532 if (do_rapl & RAPL_CORES) 577 outp += sprintf(outp, fmt6, p->energy_pkg * rapl_energy_units / interval_float);
533 outp += sprintf(outp, fmt6, p->energy_cores * rapl_energy_units / interval_float); 578 if (do_rapl & RAPL_CORES)
534 if (do_rapl & RAPL_GFX) 579 outp += sprintf(outp, fmt6, p->energy_cores * rapl_energy_units / interval_float);
535 outp += sprintf(outp, fmt5, p->energy_gfx * rapl_energy_units / interval_float); 580 if (do_rapl & RAPL_GFX)
536 if (do_rapl & RAPL_DRAM) 581 outp += sprintf(outp, fmt5, p->energy_gfx * rapl_energy_units / interval_float);
537 outp += sprintf(outp, fmt5, p->energy_dram * rapl_energy_units / interval_float); 582 if (do_rapl & RAPL_DRAM)
538 if (do_rapl & RAPL_PKG_PERF_STATUS ) 583 outp += sprintf(outp, fmt5, p->energy_dram * rapl_energy_units / interval_float);
539 outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); 584 if (do_rapl & RAPL_PKG_PERF_STATUS)
540 if (do_rapl & RAPL_DRAM_PERF_STATUS ) 585 outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
541 outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); 586 if (do_rapl & RAPL_DRAM_PERF_STATUS)
587 outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
588 } else {
589 if (do_rapl & RAPL_PKG)
590 outp += sprintf(outp, fmt6,
591 p->energy_pkg * rapl_energy_units);
592 if (do_rapl & RAPL_CORES)
593 outp += sprintf(outp, fmt6,
594 p->energy_cores * rapl_energy_units);
595 if (do_rapl & RAPL_GFX)
596 outp += sprintf(outp, fmt5,
597 p->energy_gfx * rapl_energy_units);
598 if (do_rapl & RAPL_DRAM)
599 outp += sprintf(outp, fmt5,
600 p->energy_dram * rapl_energy_units);
601 if (do_rapl & RAPL_PKG_PERF_STATUS)
602 outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
603 if (do_rapl & RAPL_DRAM_PERF_STATUS)
604 outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
605 outp += sprintf(outp, fmt5, interval_float);
542 606
607 }
543done: 608done:
544 outp += sprintf(outp, "\n"); 609 outp += sprintf(outp, "\n");
545 610
@@ -622,12 +687,10 @@ delta_thread(struct thread_data *new, struct thread_data *old,
622 old->tsc = new->tsc - old->tsc; 687 old->tsc = new->tsc - old->tsc;
623 688
624 /* check for TSC < 1 Mcycles over interval */ 689 /* check for TSC < 1 Mcycles over interval */
625 if (old->tsc < (1000 * 1000)) { 690 if (old->tsc < (1000 * 1000))
626 fprintf(stderr, "Insanely slow TSC rate, TSC stops in idle?\n"); 691 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
627 fprintf(stderr, "You can disable all c-states by booting with \"idle=poll\"\n"); 692 "You can disable all c-states by booting with \"idle=poll\"\n"
628 fprintf(stderr, "or just the deep ones with \"processor.max_cstate=1\"\n"); 693 "or just the deep ones with \"processor.max_cstate=1\"");
629 exit(-3);
630 }
631 694
632 old->c1 = new->c1 - old->c1; 695 old->c1 = new->c1 - old->c1;
633 696
@@ -1173,24 +1236,43 @@ void free_all_buffers(void)
1173} 1236}
1174 1237
1175/* 1238/*
1239 * Open a file, and exit on failure
1240 */
1241FILE *fopen_or_die(const char *path, const char *mode)
1242{
1243 FILE *filep = fopen(path, "r");
1244 if (!filep)
1245 err(1, "%s: open failed", path);
1246 return filep;
1247}
1248
1249/*
1250 * Parse a file containing a single int.
1251 */
1252int parse_int_file(const char *fmt, ...)
1253{
1254 va_list args;
1255 char path[PATH_MAX];
1256 FILE *filep;
1257 int value;
1258
1259 va_start(args, fmt);
1260 vsnprintf(path, sizeof(path), fmt, args);
1261 va_end(args);
1262 filep = fopen_or_die(path, "r");
1263 if (fscanf(filep, "%d", &value) != 1)
1264 err(1, "%s: failed to parse number from file", path);
1265 fclose(filep);
1266 return value;
1267}
1268
1269/*
1176 * cpu_is_first_sibling_in_core(cpu) 1270 * cpu_is_first_sibling_in_core(cpu)
1177 * return 1 if given CPU is 1st HT sibling in the core 1271 * return 1 if given CPU is 1st HT sibling in the core
1178 */ 1272 */
1179int cpu_is_first_sibling_in_core(int cpu) 1273int cpu_is_first_sibling_in_core(int cpu)
1180{ 1274{
1181 char path[64]; 1275 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
1182 FILE *filep;
1183 int first_cpu;
1184
1185 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
1186 filep = fopen(path, "r");
1187 if (filep == NULL) {
1188 perror(path);
1189 exit(1);
1190 }
1191 fscanf(filep, "%d", &first_cpu);
1192 fclose(filep);
1193 return (cpu == first_cpu);
1194} 1276}
1195 1277
1196/* 1278/*
@@ -1199,53 +1281,17 @@ int cpu_is_first_sibling_in_core(int cpu)
1199 */ 1281 */
1200int cpu_is_first_core_in_package(int cpu) 1282int cpu_is_first_core_in_package(int cpu)
1201{ 1283{
1202 char path[64]; 1284 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
1203 FILE *filep;
1204 int first_cpu;
1205
1206 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
1207 filep = fopen(path, "r");
1208 if (filep == NULL) {
1209 perror(path);
1210 exit(1);
1211 }
1212 fscanf(filep, "%d", &first_cpu);
1213 fclose(filep);
1214 return (cpu == first_cpu);
1215} 1285}
1216 1286
1217int get_physical_package_id(int cpu) 1287int get_physical_package_id(int cpu)
1218{ 1288{
1219 char path[80]; 1289 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
1220 FILE *filep;
1221 int pkg;
1222
1223 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
1224 filep = fopen(path, "r");
1225 if (filep == NULL) {
1226 perror(path);
1227 exit(1);
1228 }
1229 fscanf(filep, "%d", &pkg);
1230 fclose(filep);
1231 return pkg;
1232} 1290}
1233 1291
1234int get_core_id(int cpu) 1292int get_core_id(int cpu)
1235{ 1293{
1236 char path[80]; 1294 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
1237 FILE *filep;
1238 int core;
1239
1240 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
1241 filep = fopen(path, "r");
1242 if (filep == NULL) {
1243 perror(path);
1244 exit(1);
1245 }
1246 fscanf(filep, "%d", &core);
1247 fclose(filep);
1248 return core;
1249} 1295}
1250 1296
1251int get_num_ht_siblings(int cpu) 1297int get_num_ht_siblings(int cpu)
@@ -1257,11 +1303,7 @@ int get_num_ht_siblings(int cpu)
1257 char character; 1303 char character;
1258 1304
1259 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); 1305 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
1260 filep = fopen(path, "r"); 1306 filep = fopen_or_die(path, "r");
1261 if (filep == NULL) {
1262 perror(path);
1263 exit(1);
1264 }
1265 /* 1307 /*
1266 * file format: 1308 * file format:
1267 * if a pair of number with a character between: 2 siblings (eg. 1-2, or 1,4) 1309 * if a pair of number with a character between: 2 siblings (eg. 1-2, or 1,4)
@@ -1331,17 +1373,11 @@ int for_all_proc_cpus(int (func)(int))
1331 int cpu_num; 1373 int cpu_num;
1332 int retval; 1374 int retval;
1333 1375
1334 fp = fopen(proc_stat, "r"); 1376 fp = fopen_or_die(proc_stat, "r");
1335 if (fp == NULL) {
1336 perror(proc_stat);
1337 exit(1);
1338 }
1339 1377
1340 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n"); 1378 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
1341 if (retval != 0) { 1379 if (retval != 0)
1342 perror("/proc/stat format"); 1380 err(1, "%s: failed to parse format", proc_stat);
1343 exit(1);
1344 }
1345 1381
1346 while (1) { 1382 while (1) {
1347 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num); 1383 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
@@ -1445,19 +1481,15 @@ void check_dev_msr()
1445{ 1481{
1446 struct stat sb; 1482 struct stat sb;
1447 1483
1448 if (stat("/dev/cpu/0/msr", &sb)) { 1484 if (stat("/dev/cpu/0/msr", &sb))
1449 fprintf(stderr, "no /dev/cpu/0/msr\n"); 1485 err(-5, "no /dev/cpu/0/msr\n"
1450 fprintf(stderr, "Try \"# modprobe msr\"\n"); 1486 "Try \"# modprobe msr\"");
1451 exit(-5);
1452 }
1453} 1487}
1454 1488
1455void check_super_user() 1489void check_super_user()
1456{ 1490{
1457 if (getuid() != 0) { 1491 if (getuid() != 0)
1458 fprintf(stderr, "must be root\n"); 1492 errx(-6, "must be root");
1459 exit(-6);
1460 }
1461} 1493}
1462 1494
1463int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) 1495int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
@@ -1479,7 +1511,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
1479 case 0x3A: /* IVB */ 1511 case 0x3A: /* IVB */
1480 case 0x3E: /* IVB Xeon */ 1512 case 0x3E: /* IVB Xeon */
1481 case 0x3C: /* HSW */ 1513 case 0x3C: /* HSW */
1482 case 0x3F: /* HSW */ 1514 case 0x3F: /* HSX */
1483 case 0x45: /* HSW */ 1515 case 0x45: /* HSW */
1484 case 0x46: /* HSW */ 1516 case 0x46: /* HSW */
1485 case 0x37: /* BYT */ 1517 case 0x37: /* BYT */
@@ -1595,11 +1627,13 @@ void rapl_probe(unsigned int family, unsigned int model)
1595 case 0x2A: 1627 case 0x2A:
1596 case 0x3A: 1628 case 0x3A:
1597 case 0x3C: /* HSW */ 1629 case 0x3C: /* HSW */
1598 case 0x3F: /* HSW */
1599 case 0x45: /* HSW */ 1630 case 0x45: /* HSW */
1600 case 0x46: /* HSW */ 1631 case 0x46: /* HSW */
1601 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; 1632 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
1602 break; 1633 break;
1634 case 0x3F: /* HSX */
1635 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
1636 break;
1603 case 0x2D: 1637 case 0x2D:
1604 case 0x3E: 1638 case 0x3E:
1605 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO; 1639 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO;
@@ -1978,7 +2012,7 @@ void check_cpuid()
1978 2012
1979 eax = ebx = ecx = edx = 0; 2013 eax = ebx = ecx = edx = 0;
1980 2014
1981 asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0)); 2015 __get_cpuid(0, &max_level, &ebx, &ecx, &edx);
1982 2016
1983 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) 2017 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
1984 genuine_intel = 1; 2018 genuine_intel = 1;
@@ -1987,7 +2021,7 @@ void check_cpuid()
1987 fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", 2021 fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
1988 (char *)&ebx, (char *)&edx, (char *)&ecx); 2022 (char *)&ebx, (char *)&edx, (char *)&ecx);
1989 2023
1990 asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx"); 2024 __get_cpuid(1, &fms, &ebx, &ecx, &edx);
1991 family = (fms >> 8) & 0xf; 2025 family = (fms >> 8) & 0xf;
1992 model = (fms >> 4) & 0xf; 2026 model = (fms >> 4) & 0xf;
1993 stepping = fms & 0xf; 2027 stepping = fms & 0xf;
@@ -1998,10 +2032,8 @@ void check_cpuid()
1998 fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", 2032 fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
1999 max_level, family, model, stepping, family, model, stepping); 2033 max_level, family, model, stepping, family, model, stepping);
2000 2034
2001 if (!(edx & (1 << 5))) { 2035 if (!(edx & (1 << 5)))
2002 fprintf(stderr, "CPUID: no MSR\n"); 2036 errx(1, "CPUID: no MSR");
2003 exit(1);
2004 }
2005 2037
2006 /* 2038 /*
2007 * check max extended function levels of CPUID. 2039 * check max extended function levels of CPUID.
@@ -2009,31 +2041,27 @@ void check_cpuid()
2009 * This check is valid for both Intel and AMD. 2041 * This check is valid for both Intel and AMD.
2010 */ 2042 */
2011 ebx = ecx = edx = 0; 2043 ebx = ecx = edx = 0;
2012 asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000000)); 2044 __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx);
2013 2045
2014 if (max_level < 0x80000007) { 2046 if (max_level < 0x80000007)
2015 fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level); 2047 errx(1, "CPUID: no invariant TSC (max_level 0x%x)", max_level);
2016 exit(1);
2017 }
2018 2048
2019 /* 2049 /*
2020 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 2050 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
2021 * this check is valid for both Intel and AMD 2051 * this check is valid for both Intel and AMD
2022 */ 2052 */
2023 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); 2053 __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
2024 has_invariant_tsc = edx & (1 << 8); 2054 has_invariant_tsc = edx & (1 << 8);
2025 2055
2026 if (!has_invariant_tsc) { 2056 if (!has_invariant_tsc)
2027 fprintf(stderr, "No invariant TSC\n"); 2057 errx(1, "No invariant TSC");
2028 exit(1);
2029 }
2030 2058
2031 /* 2059 /*
2032 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0 2060 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
2033 * this check is valid for both Intel and AMD 2061 * this check is valid for both Intel and AMD
2034 */ 2062 */
2035 2063
2036 asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); 2064 __get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
2037 has_aperf = ecx & (1 << 0); 2065 has_aperf = ecx & (1 << 0);
2038 do_dts = eax & (1 << 0); 2066 do_dts = eax & (1 << 0);
2039 do_ptm = eax & (1 << 6); 2067 do_ptm = eax & (1 << 6);
@@ -2047,7 +2075,7 @@ void check_cpuid()
2047 has_epb ? ", EPB": ""); 2075 has_epb ? ", EPB": "");
2048 2076
2049 if (!has_aperf) 2077 if (!has_aperf)
2050 exit(-1); 2078 errx(-1, "No APERF");
2051 2079
2052 do_nehalem_platform_info = genuine_intel && has_invariant_tsc; 2080 do_nehalem_platform_info = genuine_intel && has_invariant_tsc;
2053 do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ 2081 do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */
@@ -2067,9 +2095,8 @@ void check_cpuid()
2067 2095
2068void usage() 2096void usage()
2069{ 2097{
2070 fprintf(stderr, "%s: [-v][-R][-T][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n", 2098 errx(1, "%s: [-v][-R][-T][-p|-P|-S][-c MSR#][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
2071 progname); 2099 progname);
2072 exit(1);
2073} 2100}
2074 2101
2075 2102
@@ -2112,19 +2139,15 @@ void topology_probe()
2112 fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num); 2139 fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
2113 2140
2114 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology)); 2141 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
2115 if (cpus == NULL) { 2142 if (cpus == NULL)
2116 perror("calloc cpus"); 2143 err(1, "calloc cpus");
2117 exit(1);
2118 }
2119 2144
2120 /* 2145 /*
2121 * Allocate and initialize cpu_present_set 2146 * Allocate and initialize cpu_present_set
2122 */ 2147 */
2123 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1)); 2148 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
2124 if (cpu_present_set == NULL) { 2149 if (cpu_present_set == NULL)
2125 perror("CPU_ALLOC"); 2150 err(3, "CPU_ALLOC");
2126 exit(3);
2127 }
2128 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 2151 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
2129 CPU_ZERO_S(cpu_present_setsize, cpu_present_set); 2152 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
2130 for_all_proc_cpus(mark_cpu_present); 2153 for_all_proc_cpus(mark_cpu_present);
@@ -2133,10 +2156,8 @@ void topology_probe()
2133 * Allocate and initialize cpu_affinity_set 2156 * Allocate and initialize cpu_affinity_set
2134 */ 2157 */
2135 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1)); 2158 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
2136 if (cpu_affinity_set == NULL) { 2159 if (cpu_affinity_set == NULL)
2137 perror("CPU_ALLOC"); 2160 err(3, "CPU_ALLOC");
2138 exit(3);
2139 }
2140 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 2161 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
2141 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); 2162 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
2142 2163
@@ -2220,8 +2241,7 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data
2220 2241
2221 return; 2242 return;
2222error: 2243error:
2223 perror("calloc counters"); 2244 err(1, "calloc counters");
2224 exit(1);
2225} 2245}
2226/* 2246/*
2227 * init_counter() 2247 * init_counter()
@@ -2276,12 +2296,10 @@ int initialize_counters(int cpu_id)
2276 2296
2277void allocate_output_buffer() 2297void allocate_output_buffer()
2278{ 2298{
2279 output_buffer = calloc(1, (1 + topo.num_cpus) * 256); 2299 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
2280 outp = output_buffer; 2300 outp = output_buffer;
2281 if (outp == NULL) { 2301 if (outp == NULL)
2282 perror("calloc"); 2302 err(-1, "calloc output buffer");
2283 exit(-1);
2284 }
2285} 2303}
2286 2304
2287void setup_all_buffers(void) 2305void setup_all_buffers(void)
@@ -2292,6 +2310,7 @@ void setup_all_buffers(void)
2292 allocate_output_buffer(); 2310 allocate_output_buffer();
2293 for_all_proc_cpus(initialize_counters); 2311 for_all_proc_cpus(initialize_counters);
2294} 2312}
2313
2295void turbostat_init() 2314void turbostat_init()
2296{ 2315{
2297 check_cpuid(); 2316 check_cpuid();
@@ -2335,17 +2354,13 @@ int fork_it(char **argv)
2335 } else { 2354 } else {
2336 2355
2337 /* parent */ 2356 /* parent */
2338 if (child_pid == -1) { 2357 if (child_pid == -1)
2339 perror("fork"); 2358 err(1, "fork");
2340 exit(1);
2341 }
2342 2359
2343 signal(SIGINT, SIG_IGN); 2360 signal(SIGINT, SIG_IGN);
2344 signal(SIGQUIT, SIG_IGN); 2361 signal(SIGQUIT, SIG_IGN);
2345 if (waitpid(child_pid, &status, 0) == -1) { 2362 if (waitpid(child_pid, &status, 0) == -1)
2346 perror("wait"); 2363 err(status, "waitpid");
2347 exit(status);
2348 }
2349 } 2364 }
2350 /* 2365 /*
2351 * n.b. fork_it() does not check for errors from for_all_cpus() 2366 * n.b. fork_it() does not check for errors from for_all_cpus()
@@ -2364,13 +2379,30 @@ int fork_it(char **argv)
2364 return status; 2379 return status;
2365} 2380}
2366 2381
2382int get_and_dump_counters(void)
2383{
2384 int status;
2385
2386 status = for_all_cpus(get_counters, ODD_COUNTERS);
2387 if (status)
2388 return status;
2389
2390 status = for_all_cpus(dump_counters, ODD_COUNTERS);
2391 if (status)
2392 return status;
2393
2394 flush_stdout();
2395
2396 return status;
2397}
2398
2367void cmdline(int argc, char **argv) 2399void cmdline(int argc, char **argv)
2368{ 2400{
2369 int opt; 2401 int opt;
2370 2402
2371 progname = argv[0]; 2403 progname = argv[0];
2372 2404
2373 while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:RT:")) != -1) { 2405 while ((opt = getopt(argc, argv, "+pPsSvi:c:C:m:M:RJT:")) != -1) {
2374 switch (opt) { 2406 switch (opt) {
2375 case 'p': 2407 case 'p':
2376 show_core_only++; 2408 show_core_only++;
@@ -2378,6 +2410,9 @@ void cmdline(int argc, char **argv)
2378 case 'P': 2410 case 'P':
2379 show_pkg_only++; 2411 show_pkg_only++;
2380 break; 2412 break;
2413 case 's':
2414 dump_only++;
2415 break;
2381 case 'S': 2416 case 'S':
2382 summary_only++; 2417 summary_only++;
2383 break; 2418 break;
@@ -2405,6 +2440,10 @@ void cmdline(int argc, char **argv)
2405 case 'T': 2440 case 'T':
2406 tcc_activation_temp_override = atoi(optarg); 2441 tcc_activation_temp_override = atoi(optarg);
2407 break; 2442 break;
2443 case 'J':
2444 rapl_joules++;
2445 break;
2446
2408 default: 2447 default:
2409 usage(); 2448 usage();
2410 } 2449 }
@@ -2416,11 +2455,15 @@ int main(int argc, char **argv)
2416 cmdline(argc, argv); 2455 cmdline(argc, argv);
2417 2456
2418 if (verbose) 2457 if (verbose)
2419 fprintf(stderr, "turbostat v3.5 April 26, 2013" 2458 fprintf(stderr, "turbostat v3.6 Dec 2, 2013"
2420 " - Len Brown <lenb@kernel.org>\n"); 2459 " - Len Brown <lenb@kernel.org>\n");
2421 2460
2422 turbostat_init(); 2461 turbostat_init();
2423 2462
2463 /* dump counters and exit */
2464 if (dump_only)
2465 return get_and_dump_counters();
2466
2424 /* 2467 /*
2425 * if any params left, it must be a command to fork 2468 * if any params left, it must be a command to fork
2426 */ 2469 */