1 /* 2 * turbostat -- show CPU frequency and C-state residency 3 * on modern Intel turbo-capable processors. 4 * 5 * Copyright (c) 2013 Intel Corporation. 6 * Len Brown <len.brown@intel.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program; if not, write to the Free Software Foundation, Inc., 19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 20 */ 21 22 #define _GNU_SOURCE 23 #include MSRHEADER 24 #include INTEL_FAMILY_HEADER 25 #include <stdarg.h> 26 #include <stdio.h> 27 #include <err.h> 28 #include <unistd.h> 29 #include <sys/types.h> 30 #include <sys/wait.h> 31 #include <sys/stat.h> 32 #include <sys/resource.h> 33 #include <fcntl.h> 34 #include <signal.h> 35 #include <sys/time.h> 36 #include <stdlib.h> 37 #include <getopt.h> 38 #include <dirent.h> 39 #include <string.h> 40 #include <ctype.h> 41 #include <sched.h> 42 #include <time.h> 43 #include <cpuid.h> 44 #include <linux/capability.h> 45 #include <errno.h> 46 47 char *proc_stat = "/proc/stat"; 48 FILE *outf; 49 int *fd_percpu; 50 struct timespec interval_ts = {5, 0}; 51 unsigned int debug; 52 unsigned int rapl_joules; 53 unsigned int summary_only; 54 unsigned int dump_only; 55 unsigned int do_nhm_cstates; 56 unsigned int do_snb_cstates; 57 unsigned int do_knl_cstates; 58 unsigned int do_pc2; 59 unsigned int do_pc3; 60 unsigned int do_pc6; 61 unsigned int do_pc7; 62 unsigned int do_c8_c9_c10; 63 unsigned int do_skl_residency; 64 unsigned int do_slm_cstates; 65 unsigned int use_c1_residency_msr; 66 unsigned int has_aperf; 67 unsigned int has_epb; 68 unsigned int do_irtl_snb; 69 unsigned int do_irtl_hsw; 70 unsigned int units = 1000000; /* MHz etc */ 71 unsigned int genuine_intel; 72 unsigned int has_invariant_tsc; 73 unsigned int do_nhm_platform_info; 74 unsigned int aperf_mperf_multiplier = 1; 75 int do_irq = 1; 76 int do_smi; 77 double bclk; 78 double base_hz; 79 unsigned int has_base_hz; 80 double tsc_tweak = 1.0; 81 unsigned int show_pkg; 82 unsigned int show_core; 83 unsigned int show_cpu; 84 unsigned int show_pkg_only; 85 unsigned int show_core_only; 86 char *output_buffer, *outp; 87 unsigned int do_rapl; 88 unsigned int do_dts; 89 unsigned int do_ptm; 90 unsigned int do_gfx_rc6_ms; 91 unsigned long long gfx_cur_rc6_ms; 92 unsigned int do_gfx_mhz; 93 unsigned int gfx_cur_mhz; 94 unsigned int tcc_activation_temp; 95 unsigned int tcc_activation_temp_override; 96 double rapl_power_units, rapl_time_units; 97 double rapl_dram_energy_units, rapl_energy_units; 98 double rapl_joule_counter_range; 99 unsigned int do_core_perf_limit_reasons; 100 unsigned int do_gfx_perf_limit_reasons; 101 unsigned int do_ring_perf_limit_reasons; 102 unsigned int crystal_hz; 103 unsigned long long tsc_hz; 104 int base_cpu; 105 double discover_bclk(unsigned int family, unsigned int model); 106 unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ 107 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ 108 unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */ 109 unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */ 110 unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ 111 unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ 112 113 #define RAPL_PKG (1 << 0) 114 /* 0x610 MSR_PKG_POWER_LIMIT */ 115 /* 0x611 MSR_PKG_ENERGY_STATUS */ 116 #define RAPL_PKG_PERF_STATUS (1 << 1) 117 /* 0x613 MSR_PKG_PERF_STATUS */ 118 #define RAPL_PKG_POWER_INFO (1 << 2) 119 /* 0x614 MSR_PKG_POWER_INFO */ 120 121 #define RAPL_DRAM (1 << 3) 122 /* 0x618 MSR_DRAM_POWER_LIMIT */ 123 /* 0x619 MSR_DRAM_ENERGY_STATUS */ 124 #define RAPL_DRAM_PERF_STATUS (1 << 4) 125 /* 0x61b MSR_DRAM_PERF_STATUS */ 126 #define RAPL_DRAM_POWER_INFO (1 << 5) 127 /* 0x61c MSR_DRAM_POWER_INFO */ 128 129 #define RAPL_CORES_POWER_LIMIT (1 << 6) 130 /* 0x638 MSR_PP0_POWER_LIMIT */ 131 #define RAPL_CORE_POLICY (1 << 7) 132 /* 0x63a MSR_PP0_POLICY */ 133 134 #define RAPL_GFX (1 << 8) 135 /* 0x640 MSR_PP1_POWER_LIMIT */ 136 /* 0x641 MSR_PP1_ENERGY_STATUS */ 137 /* 0x642 MSR_PP1_POLICY */ 138 139 #define RAPL_CORES_ENERGY_STATUS (1 << 9) 140 /* 0x639 MSR_PP0_ENERGY_STATUS */ 141 #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT) 142 #define TJMAX_DEFAULT 100 143 144 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 145 146 /* 147 * buffer size used by sscanf() for added column names 148 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters 149 */ 150 #define NAME_BYTES 20 151 152 int backwards_count; 153 char *progname; 154 155 cpu_set_t *cpu_present_set, *cpu_affinity_set; 156 size_t cpu_present_setsize, cpu_affinity_setsize; 157 158 struct thread_data { 159 unsigned long long tsc; 160 unsigned long long aperf; 161 unsigned long long mperf; 162 unsigned long long c1; 163 unsigned int irq_count; 164 unsigned int smi_count; 165 unsigned int cpu_id; 166 unsigned int flags; 167 #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 168 #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 169 unsigned long long counter[1]; 170 } *thread_even, *thread_odd; 171 172 struct core_data { 173 unsigned long long c3; 174 unsigned long long c6; 175 unsigned long long c7; 176 unsigned int core_temp_c; 177 unsigned int core_id; 178 unsigned long long counter[1]; 179 } *core_even, *core_odd; 180 181 struct pkg_data { 182 unsigned long long pc2; 183 unsigned long long pc3; 184 unsigned long long pc6; 185 unsigned long long pc7; 186 unsigned long long pc8; 187 unsigned long long pc9; 188 unsigned long long pc10; 189 unsigned long long pkg_wtd_core_c0; 190 unsigned long long pkg_any_core_c0; 191 unsigned long long pkg_any_gfxe_c0; 192 unsigned long long pkg_both_core_gfxe_c0; 193 long long gfx_rc6_ms; 194 unsigned int gfx_mhz; 195 unsigned int package_id; 196 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */ 197 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */ 198 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */ 199 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */ 200 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */ 201 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */ 202 unsigned int pkg_temp_c; 203 unsigned long long counter[1]; 204 } *package_even, *package_odd; 205 206 #define ODD_COUNTERS thread_odd, core_odd, package_odd 207 #define EVEN_COUNTERS thread_even, core_even, package_even 208 209 #define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \ 210 (thread_base + (pkg_no) * topo.num_cores_per_pkg * \ 211 topo.num_threads_per_core + \ 212 (core_no) * topo.num_threads_per_core + (thread_no)) 213 #define GET_CORE(core_base, core_no, pkg_no) \ 214 (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no)) 215 #define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no) 216 217 enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE}; 218 enum counter_type {COUNTER_CYCLES, COUNTER_SECONDS}; 219 enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT}; 220 221 struct msr_counter { 222 unsigned int msr_num; 223 char name[NAME_BYTES]; 224 unsigned int width; 225 enum counter_type type; 226 enum counter_format format; 227 struct msr_counter *next; 228 }; 229 230 struct sys_counters { 231 unsigned int thread_counter_bytes; 232 unsigned int core_counter_bytes; 233 unsigned int package_counter_bytes; 234 struct msr_counter *tp; 235 struct msr_counter *cp; 236 struct msr_counter *pp; 237 } sys; 238 239 struct system_summary { 240 struct thread_data threads; 241 struct core_data cores; 242 struct pkg_data packages; 243 } average; 244 245 246 struct topo_params { 247 int num_packages; 248 int num_cpus; 249 int num_cores; 250 int max_cpu_num; 251 int num_cores_per_pkg; 252 int num_threads_per_core; 253 } topo; 254 255 struct timeval tv_even, tv_odd, tv_delta; 256 257 int *irq_column_2_cpu; /* /proc/interrupts column numbers */ 258 int *irqs_per_cpu; /* indexed by cpu_num */ 259 260 void setup_all_buffers(void); 261 262 int cpu_is_not_present(int cpu) 263 { 264 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); 265 } 266 /* 267 * run func(thread, core, package) in topology order 268 * skip non-present cpus 269 */ 270 271 int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *), 272 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base) 273 { 274 int retval, pkg_no, core_no, thread_no; 275 276 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { 277 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) { 278 for (thread_no = 0; thread_no < 279 topo.num_threads_per_core; ++thread_no) { 280 struct thread_data *t; 281 struct core_data *c; 282 struct pkg_data *p; 283 284 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no); 285 286 if (cpu_is_not_present(t->cpu_id)) 287 continue; 288 289 c = GET_CORE(core_base, core_no, pkg_no); 290 p = GET_PKG(pkg_base, pkg_no); 291 292 retval = func(t, c, p); 293 if (retval) 294 return retval; 295 } 296 } 297 } 298 return 0; 299 } 300 301 int cpu_migrate(int cpu) 302 { 303 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); 304 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); 305 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) 306 return -1; 307 else 308 return 0; 309 } 310 int get_msr_fd(int cpu) 311 { 312 char pathname[32]; 313 int fd; 314 315 fd = fd_percpu[cpu]; 316 317 if (fd) 318 return fd; 319 320 sprintf(pathname, "/dev/cpu/%d/msr", cpu); 321 fd = open(pathname, O_RDONLY); 322 if (fd < 0) 323 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname); 324 325 fd_percpu[cpu] = fd; 326 327 return fd; 328 } 329 330 int get_msr(int cpu, off_t offset, unsigned long long *msr) 331 { 332 ssize_t retval; 333 334 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); 335 336 if (retval != sizeof *msr) 337 err(-1, "msr %d offset 0x%llx read failed", cpu, (unsigned long long)offset); 338 339 return 0; 340 } 341 342 /* 343 * Example Format w/ field column widths: 344 * 345 * 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 346 * 12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678 347 */ 348 349 void print_header(void) 350 { 351 struct msr_counter *mp; 352 353 if (show_pkg) 354 outp += sprintf(outp, "\tPackage"); 355 if (show_core) 356 outp += sprintf(outp, "\tCore"); 357 if (show_cpu) 358 outp += sprintf(outp, "\tCPU"); 359 if (has_aperf) 360 outp += sprintf(outp, "\tAvg_MHz"); 361 if (has_aperf) 362 outp += sprintf(outp, "\tBusy%%"); 363 if (has_aperf) 364 outp += sprintf(outp, "\tBzy_MHz"); 365 outp += sprintf(outp, "\tTSC_MHz"); 366 367 if (!debug) 368 goto done; 369 370 if (do_irq) 371 outp += sprintf(outp, "\tIRQ"); 372 if (do_smi) 373 outp += sprintf(outp, "\tSMI"); 374 375 if (do_nhm_cstates) 376 outp += sprintf(outp, "\tCPU%%c1"); 377 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) 378 outp += sprintf(outp, "\tCPU%%c3"); 379 if (do_nhm_cstates) 380 outp += sprintf(outp, "\tCPU%%c6"); 381 if (do_snb_cstates) 382 outp += sprintf(outp, "\tCPU%%c7"); 383 384 for (mp = sys.tp; mp; mp = mp->next) { 385 if (mp->format == FORMAT_RAW) { 386 if (mp->width == 64) 387 outp += sprintf(outp, "\t%18.18s", mp->name); 388 else 389 outp += sprintf(outp, "\t%10.10s", mp->name); 390 } else { 391 outp += sprintf(outp, "\t%-7.7s", mp->name); 392 } 393 } 394 395 if (do_dts) 396 outp += sprintf(outp, "\tCoreTmp"); 397 398 for (mp = sys.cp; mp; mp = mp->next) { 399 if (mp->format == FORMAT_RAW) { 400 if (mp->width == 64) 401 outp += sprintf(outp, "\t%18.18s", mp->name); 402 else 403 outp += sprintf(outp, "\t%10.10s", mp->name); 404 } else { 405 outp += sprintf(outp, "\t%-7.7s", mp->name); 406 } 407 } 408 409 if (do_ptm) 410 outp += sprintf(outp, "\tPkgTmp"); 411 412 if (do_gfx_rc6_ms) 413 outp += sprintf(outp, "\tGFX%%rc6"); 414 415 if (do_gfx_mhz) 416 outp += sprintf(outp, "\tGFXMHz"); 417 418 if (do_skl_residency) { 419 outp += sprintf(outp, "\tTotl%%C0"); 420 outp += sprintf(outp, "\tAny%%C0"); 421 outp += sprintf(outp, "\tGFX%%C0"); 422 outp += sprintf(outp, "\tCPUGFX%%"); 423 } 424 425 if (do_pc2) 426 outp += sprintf(outp, "\tPkg%%pc2"); 427 if (do_pc3) 428 outp += sprintf(outp, "\tPkg%%pc3"); 429 if (do_pc6) 430 outp += sprintf(outp, "\tPkg%%pc6"); 431 if (do_pc7) 432 outp += sprintf(outp, "\tPkg%%pc7"); 433 if (do_c8_c9_c10) { 434 outp += sprintf(outp, "\tPkg%%pc8"); 435 outp += sprintf(outp, "\tPkg%%pc9"); 436 outp += sprintf(outp, "\tPk%%pc10"); 437 } 438 439 if (do_rapl && !rapl_joules) { 440 if (do_rapl & RAPL_PKG) 441 outp += sprintf(outp, "\tPkgWatt"); 442 if (do_rapl & RAPL_CORES_ENERGY_STATUS) 443 outp += sprintf(outp, "\tCorWatt"); 444 if (do_rapl & RAPL_GFX) 445 outp += sprintf(outp, "\tGFXWatt"); 446 if (do_rapl & RAPL_DRAM) 447 outp += sprintf(outp, "\tRAMWatt"); 448 if (do_rapl & RAPL_PKG_PERF_STATUS) 449 outp += sprintf(outp, "\tPKG_%%"); 450 if (do_rapl & RAPL_DRAM_PERF_STATUS) 451 outp += sprintf(outp, "\tRAM_%%"); 452 } else if (do_rapl && rapl_joules) { 453 if (do_rapl & RAPL_PKG) 454 outp += sprintf(outp, "\tPkg_J"); 455 if (do_rapl & RAPL_CORES_ENERGY_STATUS) 456 outp += sprintf(outp, "\tCor_J"); 457 if (do_rapl & RAPL_GFX) 458 outp += sprintf(outp, "\tGFX_J"); 459 if (do_rapl & RAPL_DRAM) 460 outp += sprintf(outp, "\tRAM_J"); 461 if (do_rapl & RAPL_PKG_PERF_STATUS) 462 outp += sprintf(outp, "\tPKG_%%"); 463 if (do_rapl & RAPL_DRAM_PERF_STATUS) 464 outp += sprintf(outp, "\tRAM_%%"); 465 } 466 for (mp = sys.pp; mp; mp = mp->next) { 467 if (mp->format == FORMAT_RAW) { 468 if (mp->width == 64) 469 outp += sprintf(outp, "\t%18.18s", mp->name); 470 else 471 outp += sprintf(outp, "\t%10.10s", mp->name); 472 } else { 473 outp += sprintf(outp, "\t%-7.7s", mp->name); 474 } 475 } 476 477 done: 478 outp += sprintf(outp, "\n"); 479 } 480 481 int dump_counters(struct thread_data *t, struct core_data *c, 482 struct pkg_data *p) 483 { 484 int i; 485 struct msr_counter *mp; 486 487 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p); 488 489 if (t) { 490 outp += sprintf(outp, "CPU: %d flags 0x%x\n", 491 t->cpu_id, t->flags); 492 outp += sprintf(outp, "TSC: %016llX\n", t->tsc); 493 outp += sprintf(outp, "aperf: %016llX\n", t->aperf); 494 outp += sprintf(outp, "mperf: %016llX\n", t->mperf); 495 outp += sprintf(outp, "c1: %016llX\n", t->c1); 496 497 if (do_irq) 498 outp += sprintf(outp, "IRQ: %08X\n", t->irq_count); 499 if (do_smi) 500 outp += sprintf(outp, "SMI: %08X\n", t->smi_count); 501 502 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 503 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n", 504 i, mp->msr_num, t->counter[i]); 505 } 506 } 507 508 if (c) { 509 outp += sprintf(outp, "core: %d\n", c->core_id); 510 outp += sprintf(outp, "c3: %016llX\n", c->c3); 511 outp += sprintf(outp, "c6: %016llX\n", c->c6); 512 outp += sprintf(outp, "c7: %016llX\n", c->c7); 513 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c); 514 515 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 516 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", 517 i, mp->msr_num, c->counter[i]); 518 } 519 } 520 521 if (p) { 522 outp += sprintf(outp, "package: %d\n", p->package_id); 523 524 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0); 525 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0); 526 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0); 527 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0); 528 529 outp += sprintf(outp, "pc2: %016llX\n", p->pc2); 530 if (do_pc3) 531 outp += sprintf(outp, "pc3: %016llX\n", p->pc3); 532 if (do_pc6) 533 outp += sprintf(outp, "pc6: %016llX\n", p->pc6); 534 if (do_pc7) 535 outp += sprintf(outp, "pc7: %016llX\n", p->pc7); 536 outp += sprintf(outp, "pc8: %016llX\n", p->pc8); 537 outp += sprintf(outp, "pc9: %016llX\n", p->pc9); 538 outp += sprintf(outp, "pc10: %016llX\n", p->pc10); 539 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg); 540 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores); 541 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx); 542 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram); 543 outp += sprintf(outp, "Throttle PKG: %0X\n", 544 p->rapl_pkg_perf_status); 545 outp += sprintf(outp, "Throttle RAM: %0X\n", 546 p->rapl_dram_perf_status); 547 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c); 548 549 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 550 outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n", 551 i, mp->msr_num, p->counter[i]); 552 } 553 } 554 555 outp += sprintf(outp, "\n"); 556 557 return 0; 558 } 559 560 /* 561 * column formatting convention & formats 562 */ 563 int format_counters(struct thread_data *t, struct core_data *c, 564 struct pkg_data *p) 565 { 566 double interval_float; 567 char *fmt8; 568 int i; 569 struct msr_counter *mp; 570 571 /* if showing only 1st thread in core and this isn't one, bail out */ 572 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 573 return 0; 574 575 /* if showing only 1st thread in pkg and this isn't one, bail out */ 576 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 577 return 0; 578 579 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; 580 581 /* topo columns, print blanks on 1st (average) line */ 582 if (t == &average.threads) { 583 if (show_pkg) 584 outp += sprintf(outp, "\t-"); 585 if (show_core) 586 outp += sprintf(outp, "\t-"); 587 if (show_cpu) 588 outp += sprintf(outp, "\t-"); 589 } else { 590 if (show_pkg) { 591 if (p) 592 outp += sprintf(outp, "\t%d", p->package_id); 593 else 594 outp += sprintf(outp, "\t-"); 595 } 596 if (show_core) { 597 if (c) 598 outp += sprintf(outp, "\t%d", c->core_id); 599 else 600 outp += sprintf(outp, "\t-"); 601 } 602 if (show_cpu) 603 outp += sprintf(outp, "\t%d", t->cpu_id); 604 } 605 606 /* Avg_MHz */ 607 if (has_aperf) 608 outp += sprintf(outp, "\t%.0f", 609 1.0 / units * t->aperf / interval_float); 610 611 /* Busy% */ 612 if (has_aperf) 613 outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/t->tsc/tsc_tweak); 614 615 /* Bzy_MHz */ 616 if (has_aperf) { 617 if (has_base_hz) 618 outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf); 619 else 620 outp += sprintf(outp, "\t%.0f", 621 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); 622 } 623 624 /* TSC_MHz */ 625 outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float); 626 627 if (!debug) 628 goto done; 629 630 /* IRQ */ 631 if (do_irq) 632 outp += sprintf(outp, "\t%d", t->irq_count); 633 634 /* SMI */ 635 if (do_smi) 636 outp += sprintf(outp, "\t%d", t->smi_count); 637 638 if (do_nhm_cstates) 639 outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/t->tsc); 640 641 /* print per-core data only for 1st thread in core */ 642 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 643 goto done; 644 645 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) 646 outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/t->tsc); 647 if (do_nhm_cstates) 648 outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/t->tsc); 649 if (do_snb_cstates) 650 outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/t->tsc); 651 652 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 653 if (mp->format == FORMAT_RAW) { 654 if (mp->width == 32) 655 outp += sprintf(outp, "\t0x%08lx", (unsigned long) t->counter[i]); 656 else 657 outp += sprintf(outp, "\t0x%016llx", t->counter[i]); 658 } else if (mp->format == FORMAT_DELTA) { 659 outp += sprintf(outp, "\t%8lld", t->counter[i]); 660 } else if (mp->format == FORMAT_PERCENT) { 661 outp += sprintf(outp, "\t%.2f", 100.0 * t->counter[i]/t->tsc); 662 } 663 } 664 665 666 if (do_dts) 667 outp += sprintf(outp, "\t%d", c->core_temp_c); 668 669 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 670 if (mp->format == FORMAT_RAW) { 671 if (mp->width == 32) 672 outp += sprintf(outp, "\t0x%08lx", (unsigned long) c->counter[i]); 673 else 674 outp += sprintf(outp, "\t0x%016llx", c->counter[i]); 675 } else if (mp->format == FORMAT_DELTA) { 676 outp += sprintf(outp, "\t%8lld", c->counter[i]); 677 } else if (mp->format == FORMAT_PERCENT) { 678 outp += sprintf(outp, "\t%.2f", 100.0 * c->counter[i]/t->tsc); 679 } 680 } 681 682 /* print per-package data only for 1st core in package */ 683 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 684 goto done; 685 686 /* PkgTmp */ 687 if (do_ptm) 688 outp += sprintf(outp, "\t%d", p->pkg_temp_c); 689 690 /* GFXrc6 */ 691 if (do_gfx_rc6_ms) { 692 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */ 693 outp += sprintf(outp, "\t**.**"); 694 } else { 695 outp += sprintf(outp, "\t%.2f", 696 p->gfx_rc6_ms / 10.0 / interval_float); 697 } 698 } 699 700 /* GFXMHz */ 701 if (do_gfx_mhz) 702 outp += sprintf(outp, "\t%d", p->gfx_mhz); 703 704 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */ 705 if (do_skl_residency) { 706 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc); 707 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/t->tsc); 708 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/t->tsc); 709 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/t->tsc); 710 } 711 712 if (do_pc2) 713 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/t->tsc); 714 if (do_pc3) 715 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/t->tsc); 716 if (do_pc6) 717 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/t->tsc); 718 if (do_pc7) 719 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/t->tsc); 720 if (do_c8_c9_c10) { 721 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/t->tsc); 722 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/t->tsc); 723 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/t->tsc); 724 } 725 726 /* 727 * If measurement interval exceeds minimum RAPL Joule Counter range, 728 * indicate that results are suspect by printing "**" in fraction place. 729 */ 730 if (interval_float < rapl_joule_counter_range) 731 fmt8 = "\t%.2f"; 732 else 733 fmt8 = "%6.0f**"; 734 735 if (do_rapl && !rapl_joules) { 736 if (do_rapl & RAPL_PKG) 737 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float); 738 if (do_rapl & RAPL_CORES_ENERGY_STATUS) 739 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float); 740 if (do_rapl & RAPL_GFX) 741 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float); 742 if (do_rapl & RAPL_DRAM) 743 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units / interval_float); 744 if (do_rapl & RAPL_PKG_PERF_STATUS) 745 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); 746 if (do_rapl & RAPL_DRAM_PERF_STATUS) 747 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); 748 } else if (do_rapl && rapl_joules) { 749 if (do_rapl & RAPL_PKG) 750 outp += sprintf(outp, fmt8, 751 p->energy_pkg * rapl_energy_units); 752 if (do_rapl & RAPL_CORES) 753 outp += sprintf(outp, fmt8, 754 p->energy_cores * rapl_energy_units); 755 if (do_rapl & RAPL_GFX) 756 outp += sprintf(outp, fmt8, 757 p->energy_gfx * rapl_energy_units); 758 if (do_rapl & RAPL_DRAM) 759 outp += sprintf(outp, fmt8, 760 p->energy_dram * rapl_dram_energy_units); 761 if (do_rapl & RAPL_PKG_PERF_STATUS) 762 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); 763 if (do_rapl & RAPL_DRAM_PERF_STATUS) 764 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); 765 } 766 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 767 if (mp->format == FORMAT_RAW) { 768 if (mp->width == 32) 769 outp += sprintf(outp, "\t0x%08lx", (unsigned long) p->counter[i]); 770 else 771 outp += sprintf(outp, "\t0x%016llx", p->counter[i]); 772 } else if (mp->format == FORMAT_DELTA) { 773 outp += sprintf(outp, "\t%8lld", p->counter[i]); 774 } else if (mp->format == FORMAT_PERCENT) { 775 outp += sprintf(outp, "\t%.2f", 100.0 * p->counter[i]/t->tsc); 776 } 777 } 778 779 done: 780 outp += sprintf(outp, "\n"); 781 782 return 0; 783 } 784 785 void flush_output_stdout(void) 786 { 787 FILE *filep; 788 789 if (outf == stderr) 790 filep = stdout; 791 else 792 filep = outf; 793 794 fputs(output_buffer, filep); 795 fflush(filep); 796 797 outp = output_buffer; 798 } 799 void flush_output_stderr(void) 800 { 801 fputs(output_buffer, outf); 802 fflush(outf); 803 outp = output_buffer; 804 } 805 void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) 806 { 807 static int printed; 808 809 if (!printed || !summary_only) 810 print_header(); 811 812 if (topo.num_cpus > 1) 813 format_counters(&average.threads, &average.cores, 814 &average.packages); 815 816 printed = 1; 817 818 if (summary_only) 819 return; 820 821 for_all_cpus(format_counters, t, c, p); 822 } 823 824 #define DELTA_WRAP32(new, old) \ 825 if (new > old) { \ 826 old = new - old; \ 827 } else { \ 828 old = 0x100000000 + new - old; \ 829 } 830 831 int 832 delta_package(struct pkg_data *new, struct pkg_data *old) 833 { 834 int i; 835 struct msr_counter *mp; 836 837 if (do_skl_residency) { 838 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0; 839 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0; 840 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0; 841 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0; 842 } 843 old->pc2 = new->pc2 - old->pc2; 844 if (do_pc3) 845 old->pc3 = new->pc3 - old->pc3; 846 if (do_pc6) 847 old->pc6 = new->pc6 - old->pc6; 848 if (do_pc7) 849 old->pc7 = new->pc7 - old->pc7; 850 old->pc8 = new->pc8 - old->pc8; 851 old->pc9 = new->pc9 - old->pc9; 852 old->pc10 = new->pc10 - old->pc10; 853 old->pkg_temp_c = new->pkg_temp_c; 854 855 /* flag an error when rc6 counter resets/wraps */ 856 if (old->gfx_rc6_ms > new->gfx_rc6_ms) 857 old->gfx_rc6_ms = -1; 858 else 859 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms; 860 861 old->gfx_mhz = new->gfx_mhz; 862 863 DELTA_WRAP32(new->energy_pkg, old->energy_pkg); 864 DELTA_WRAP32(new->energy_cores, old->energy_cores); 865 DELTA_WRAP32(new->energy_gfx, old->energy_gfx); 866 DELTA_WRAP32(new->energy_dram, old->energy_dram); 867 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status); 868 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status); 869 870 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 871 if (mp->format == FORMAT_RAW) 872 old->counter[i] = new->counter[i]; 873 else 874 old->counter[i] = new->counter[i] - old->counter[i]; 875 } 876 877 return 0; 878 } 879 880 void 881 delta_core(struct core_data *new, struct core_data *old) 882 { 883 int i; 884 struct msr_counter *mp; 885 886 old->c3 = new->c3 - old->c3; 887 old->c6 = new->c6 - old->c6; 888 old->c7 = new->c7 - old->c7; 889 old->core_temp_c = new->core_temp_c; 890 891 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 892 if (mp->format == FORMAT_RAW) 893 old->counter[i] = new->counter[i]; 894 else 895 old->counter[i] = new->counter[i] - old->counter[i]; 896 } 897 } 898 899 /* 900 * old = new - old 901 */ 902 int 903 delta_thread(struct thread_data *new, struct thread_data *old, 904 struct core_data *core_delta) 905 { 906 int i; 907 struct msr_counter *mp; 908 909 old->tsc = new->tsc - old->tsc; 910 911 /* check for TSC < 1 Mcycles over interval */ 912 if (old->tsc < (1000 * 1000)) 913 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n" 914 "You can disable all c-states by booting with \"idle=poll\"\n" 915 "or just the deep ones with \"processor.max_cstate=1\""); 916 917 old->c1 = new->c1 - old->c1; 918 919 if (has_aperf) { 920 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { 921 old->aperf = new->aperf - old->aperf; 922 old->mperf = new->mperf - old->mperf; 923 } else { 924 return -1; 925 } 926 } 927 928 929 if (use_c1_residency_msr) { 930 /* 931 * Some models have a dedicated C1 residency MSR, 932 * which should be more accurate than the derivation below. 933 */ 934 } else { 935 /* 936 * As counter collection is not atomic, 937 * it is possible for mperf's non-halted cycles + idle states 938 * to exceed TSC's all cycles: show c1 = 0% in that case. 939 */ 940 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc) 941 old->c1 = 0; 942 else { 943 /* normal case, derive c1 */ 944 old->c1 = old->tsc - old->mperf - core_delta->c3 945 - core_delta->c6 - core_delta->c7; 946 } 947 } 948 949 if (old->mperf == 0) { 950 if (debug > 1) 951 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id); 952 old->mperf = 1; /* divide by 0 protection */ 953 } 954 955 if (do_irq) 956 old->irq_count = new->irq_count - old->irq_count; 957 958 if (do_smi) 959 old->smi_count = new->smi_count - old->smi_count; 960 961 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 962 if (mp->format == FORMAT_RAW) 963 old->counter[i] = new->counter[i]; 964 else 965 old->counter[i] = new->counter[i] - old->counter[i]; 966 } 967 return 0; 968 } 969 970 int delta_cpu(struct thread_data *t, struct core_data *c, 971 struct pkg_data *p, struct thread_data *t2, 972 struct core_data *c2, struct pkg_data *p2) 973 { 974 int retval = 0; 975 976 /* calculate core delta only for 1st thread in core */ 977 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE) 978 delta_core(c, c2); 979 980 /* always calculate thread delta */ 981 retval = delta_thread(t, t2, c2); /* c2 is core delta */ 982 if (retval) 983 return retval; 984 985 /* calculate package delta only for 1st core in package */ 986 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE) 987 retval = delta_package(p, p2); 988 989 return retval; 990 } 991 992 void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) 993 { 994 int i; 995 struct msr_counter *mp; 996 997 t->tsc = 0; 998 t->aperf = 0; 999 t->mperf = 0; 1000 t->c1 = 0; 1001 1002 t->irq_count = 0; 1003 t->smi_count = 0; 1004 1005 /* tells format_counters to dump all fields from this set */ 1006 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE; 1007 1008 c->c3 = 0; 1009 c->c6 = 0; 1010 c->c7 = 0; 1011 c->core_temp_c = 0; 1012 1013 p->pkg_wtd_core_c0 = 0; 1014 p->pkg_any_core_c0 = 0; 1015 p->pkg_any_gfxe_c0 = 0; 1016 p->pkg_both_core_gfxe_c0 = 0; 1017 1018 p->pc2 = 0; 1019 if (do_pc3) 1020 p->pc3 = 0; 1021 if (do_pc6) 1022 p->pc6 = 0; 1023 if (do_pc7) 1024 p->pc7 = 0; 1025 p->pc8 = 0; 1026 p->pc9 = 0; 1027 p->pc10 = 0; 1028 1029 p->energy_pkg = 0; 1030 p->energy_dram = 0; 1031 p->energy_cores = 0; 1032 p->energy_gfx = 0; 1033 p->rapl_pkg_perf_status = 0; 1034 p->rapl_dram_perf_status = 0; 1035 p->pkg_temp_c = 0; 1036 1037 p->gfx_rc6_ms = 0; 1038 p->gfx_mhz = 0; 1039 1040 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) 1041 t->counter[i] = 0; 1042 1043 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) 1044 c->counter[i] = 0; 1045 1046 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) 1047 p->counter[i] = 0; 1048 } 1049 int sum_counters(struct thread_data *t, struct core_data *c, 1050 struct pkg_data *p) 1051 { 1052 int i; 1053 struct msr_counter *mp; 1054 1055 average.threads.tsc += t->tsc; 1056 average.threads.aperf += t->aperf; 1057 average.threads.mperf += t->mperf; 1058 average.threads.c1 += t->c1; 1059 1060 average.threads.irq_count += t->irq_count; 1061 average.threads.smi_count += t->smi_count; 1062 1063 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 1064 if (mp->format == FORMAT_RAW) 1065 continue; 1066 average.threads.counter[i] += t->counter[i]; 1067 } 1068 1069 /* sum per-core values only for 1st thread in core */ 1070 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 1071 return 0; 1072 1073 average.cores.c3 += c->c3; 1074 average.cores.c6 += c->c6; 1075 average.cores.c7 += c->c7; 1076 1077 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); 1078 1079 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 1080 if (mp->format == FORMAT_RAW) 1081 continue; 1082 average.cores.counter[i] += c->counter[i]; 1083 } 1084 1085 /* sum per-pkg values only for 1st core in pkg */ 1086 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 1087 return 0; 1088 1089 if (do_skl_residency) { 1090 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0; 1091 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0; 1092 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0; 1093 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0; 1094 } 1095 1096 average.packages.pc2 += p->pc2; 1097 if (do_pc3) 1098 average.packages.pc3 += p->pc3; 1099 if (do_pc6) 1100 average.packages.pc6 += p->pc6; 1101 if (do_pc7) 1102 average.packages.pc7 += p->pc7; 1103 average.packages.pc8 += p->pc8; 1104 average.packages.pc9 += p->pc9; 1105 average.packages.pc10 += p->pc10; 1106 1107 average.packages.energy_pkg += p->energy_pkg; 1108 average.packages.energy_dram += p->energy_dram; 1109 average.packages.energy_cores += p->energy_cores; 1110 average.packages.energy_gfx += p->energy_gfx; 1111 1112 average.packages.gfx_rc6_ms = p->gfx_rc6_ms; 1113 average.packages.gfx_mhz = p->gfx_mhz; 1114 1115 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c); 1116 1117 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status; 1118 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status; 1119 1120 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 1121 if (mp->format == FORMAT_RAW) 1122 continue; 1123 average.packages.counter[i] += p->counter[i]; 1124 } 1125 return 0; 1126 } 1127 /* 1128 * sum the counters for all cpus in the system 1129 * compute the weighted average 1130 */ 1131 void compute_average(struct thread_data *t, struct core_data *c, 1132 struct pkg_data *p) 1133 { 1134 int i; 1135 struct msr_counter *mp; 1136 1137 clear_counters(&average.threads, &average.cores, &average.packages); 1138 1139 for_all_cpus(sum_counters, t, c, p); 1140 1141 average.threads.tsc /= topo.num_cpus; 1142 average.threads.aperf /= topo.num_cpus; 1143 average.threads.mperf /= topo.num_cpus; 1144 average.threads.c1 /= topo.num_cpus; 1145 1146 average.cores.c3 /= topo.num_cores; 1147 average.cores.c6 /= topo.num_cores; 1148 average.cores.c7 /= topo.num_cores; 1149 1150 if (do_skl_residency) { 1151 average.packages.pkg_wtd_core_c0 /= topo.num_packages; 1152 average.packages.pkg_any_core_c0 /= topo.num_packages; 1153 average.packages.pkg_any_gfxe_c0 /= topo.num_packages; 1154 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages; 1155 } 1156 1157 average.packages.pc2 /= topo.num_packages; 1158 if (do_pc3) 1159 average.packages.pc3 /= topo.num_packages; 1160 if (do_pc6) 1161 average.packages.pc6 /= topo.num_packages; 1162 if (do_pc7) 1163 average.packages.pc7 /= topo.num_packages; 1164 1165 average.packages.pc8 /= topo.num_packages; 1166 average.packages.pc9 /= topo.num_packages; 1167 average.packages.pc10 /= topo.num_packages; 1168 1169 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 1170 if (mp->format == FORMAT_RAW) 1171 continue; 1172 average.threads.counter[i] /= topo.num_cpus; 1173 } 1174 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 1175 if (mp->format == FORMAT_RAW) 1176 continue; 1177 average.cores.counter[i] /= topo.num_cores; 1178 } 1179 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 1180 if (mp->format == FORMAT_RAW) 1181 continue; 1182 average.packages.counter[i] /= topo.num_packages; 1183 } 1184 } 1185 1186 static unsigned long long rdtsc(void) 1187 { 1188 unsigned int low, high; 1189 1190 asm volatile("rdtsc" : "=a" (low), "=d" (high)); 1191 1192 return low | ((unsigned long long)high) << 32; 1193 } 1194 1195 /* 1196 * get_counters(...) 1197 * migrate to cpu 1198 * acquire and record local counters for that cpu 1199 */ 1200 int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) 1201 { 1202 int cpu = t->cpu_id; 1203 unsigned long long msr; 1204 int aperf_mperf_retry_count = 0; 1205 struct msr_counter *mp; 1206 int i; 1207 1208 if (cpu_migrate(cpu)) { 1209 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 1210 return -1; 1211 } 1212 1213 retry: 1214 t->tsc = rdtsc(); /* we are running on local CPU of interest */ 1215 1216 if (has_aperf) { 1217 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time; 1218 1219 /* 1220 * The TSC, APERF and MPERF must be read together for 1221 * APERF/MPERF and MPERF/TSC to give accurate results. 1222 * 1223 * Unfortunately, APERF and MPERF are read by 1224 * individual system call, so delays may occur 1225 * between them. If the time to read them 1226 * varies by a large amount, we re-read them. 1227 */ 1228 1229 /* 1230 * This initial dummy APERF read has been seen to 1231 * reduce jitter in the subsequent reads. 1232 */ 1233 1234 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf)) 1235 return -3; 1236 1237 t->tsc = rdtsc(); /* re-read close to APERF */ 1238 1239 tsc_before = t->tsc; 1240 1241 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf)) 1242 return -3; 1243 1244 tsc_between = rdtsc(); 1245 1246 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf)) 1247 return -4; 1248 1249 tsc_after = rdtsc(); 1250 1251 aperf_time = tsc_between - tsc_before; 1252 mperf_time = tsc_after - tsc_between; 1253 1254 /* 1255 * If the system call latency to read APERF and MPERF 1256 * differ by more than 2x, then try again. 1257 */ 1258 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) { 1259 aperf_mperf_retry_count++; 1260 if (aperf_mperf_retry_count < 5) 1261 goto retry; 1262 else 1263 warnx("cpu%d jitter %lld %lld", 1264 cpu, aperf_time, mperf_time); 1265 } 1266 aperf_mperf_retry_count = 0; 1267 1268 t->aperf = t->aperf * aperf_mperf_multiplier; 1269 t->mperf = t->mperf * aperf_mperf_multiplier; 1270 } 1271 1272 if (do_irq) 1273 t->irq_count = irqs_per_cpu[cpu]; 1274 if (do_smi) { 1275 if (get_msr(cpu, MSR_SMI_COUNT, &msr)) 1276 return -5; 1277 t->smi_count = msr & 0xFFFFFFFF; 1278 } 1279 1280 if (use_c1_residency_msr) { 1281 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1)) 1282 return -6; 1283 } 1284 1285 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 1286 if (get_msr(cpu, mp->msr_num, &t->counter[i])) 1287 return -10; 1288 } 1289 1290 1291 /* collect core counters only for 1st thread in core */ 1292 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 1293 return 0; 1294 1295 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) { 1296 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) 1297 return -6; 1298 } 1299 1300 if (do_nhm_cstates && !do_knl_cstates) { 1301 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) 1302 return -7; 1303 } else if (do_knl_cstates) { 1304 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) 1305 return -7; 1306 } 1307 1308 if (do_snb_cstates) 1309 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7)) 1310 return -8; 1311 1312 if (do_dts) { 1313 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr)) 1314 return -9; 1315 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); 1316 } 1317 1318 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 1319 if (get_msr(cpu, mp->msr_num, &c->counter[i])) 1320 return -10; 1321 } 1322 1323 /* collect package counters only for 1st core in package */ 1324 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 1325 return 0; 1326 1327 if (do_skl_residency) { 1328 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0)) 1329 return -10; 1330 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0)) 1331 return -11; 1332 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0)) 1333 return -12; 1334 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0)) 1335 return -13; 1336 } 1337 if (do_pc3) 1338 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) 1339 return -9; 1340 if (do_pc6) 1341 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) 1342 return -10; 1343 if (do_pc2) 1344 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2)) 1345 return -11; 1346 if (do_pc7) 1347 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) 1348 return -12; 1349 if (do_c8_c9_c10) { 1350 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8)) 1351 return -13; 1352 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9)) 1353 return -13; 1354 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10)) 1355 return -13; 1356 } 1357 if (do_rapl & RAPL_PKG) { 1358 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr)) 1359 return -13; 1360 p->energy_pkg = msr & 0xFFFFFFFF; 1361 } 1362 if (do_rapl & RAPL_CORES_ENERGY_STATUS) { 1363 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr)) 1364 return -14; 1365 p->energy_cores = msr & 0xFFFFFFFF; 1366 } 1367 if (do_rapl & RAPL_DRAM) { 1368 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr)) 1369 return -15; 1370 p->energy_dram = msr & 0xFFFFFFFF; 1371 } 1372 if (do_rapl & RAPL_GFX) { 1373 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr)) 1374 return -16; 1375 p->energy_gfx = msr & 0xFFFFFFFF; 1376 } 1377 if (do_rapl & RAPL_PKG_PERF_STATUS) { 1378 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr)) 1379 return -16; 1380 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF; 1381 } 1382 if (do_rapl & RAPL_DRAM_PERF_STATUS) { 1383 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr)) 1384 return -16; 1385 p->rapl_dram_perf_status = msr & 0xFFFFFFFF; 1386 } 1387 if (do_ptm) { 1388 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) 1389 return -17; 1390 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); 1391 } 1392 1393 if (do_gfx_rc6_ms) 1394 p->gfx_rc6_ms = gfx_cur_rc6_ms; 1395 1396 if (do_gfx_mhz) 1397 p->gfx_mhz = gfx_cur_mhz; 1398 1399 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 1400 if (get_msr(cpu, mp->msr_num, &p->counter[i])) 1401 return -10; 1402 } 1403 1404 return 0; 1405 } 1406 1407 /* 1408 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit: 1409 * If you change the values, note they are used both in comparisons 1410 * (>= PCL__7) and to index pkg_cstate_limit_strings[]. 1411 */ 1412 1413 #define PCLUKN 0 /* Unknown */ 1414 #define PCLRSV 1 /* Reserved */ 1415 #define PCL__0 2 /* PC0 */ 1416 #define PCL__1 3 /* PC1 */ 1417 #define PCL__2 4 /* PC2 */ 1418 #define PCL__3 5 /* PC3 */ 1419 #define PCL__4 6 /* PC4 */ 1420 #define PCL__6 7 /* PC6 */ 1421 #define PCL_6N 8 /* PC6 No Retention */ 1422 #define PCL_6R 9 /* PC6 Retention */ 1423 #define PCL__7 10 /* PC7 */ 1424 #define PCL_7S 11 /* PC7 Shrink */ 1425 #define PCL__8 12 /* PC8 */ 1426 #define PCL__9 13 /* PC9 */ 1427 #define PCLUNL 14 /* Unlimited */ 1428 1429 int pkg_cstate_limit = PCLUKN; 1430 char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2", 1431 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"}; 1432 1433 int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1434 int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1435 int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1436 int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1437 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}; 1438 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}; 1439 int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1440 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}; 1441 1442 1443 static void 1444 calculate_tsc_tweak() 1445 { 1446 tsc_tweak = base_hz / tsc_hz; 1447 } 1448 1449 static void 1450 dump_nhm_platform_info(void) 1451 { 1452 unsigned long long msr; 1453 unsigned int ratio; 1454 1455 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr); 1456 1457 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr); 1458 1459 ratio = (msr >> 40) & 0xFF; 1460 fprintf(outf, "%d * %.0f = %.0f MHz max efficiency frequency\n", 1461 ratio, bclk, ratio * bclk); 1462 1463 ratio = (msr >> 8) & 0xFF; 1464 fprintf(outf, "%d * %.0f = %.0f MHz base frequency\n", 1465 ratio, bclk, ratio * bclk); 1466 1467 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr); 1468 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", 1469 base_cpu, msr, msr & 0x2 ? "EN" : "DIS"); 1470 1471 return; 1472 } 1473 1474 static void 1475 dump_hsw_turbo_ratio_limits(void) 1476 { 1477 unsigned long long msr; 1478 unsigned int ratio; 1479 1480 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr); 1481 1482 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr); 1483 1484 ratio = (msr >> 8) & 0xFF; 1485 if (ratio) 1486 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 18 active cores\n", 1487 ratio, bclk, ratio * bclk); 1488 1489 ratio = (msr >> 0) & 0xFF; 1490 if (ratio) 1491 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 17 active cores\n", 1492 ratio, bclk, ratio * bclk); 1493 return; 1494 } 1495 1496 static void 1497 dump_ivt_turbo_ratio_limits(void) 1498 { 1499 unsigned long long msr; 1500 unsigned int ratio; 1501 1502 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr); 1503 1504 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr); 1505 1506 ratio = (msr >> 56) & 0xFF; 1507 if (ratio) 1508 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 16 active cores\n", 1509 ratio, bclk, ratio * bclk); 1510 1511 ratio = (msr >> 48) & 0xFF; 1512 if (ratio) 1513 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 15 active cores\n", 1514 ratio, bclk, ratio * bclk); 1515 1516 ratio = (msr >> 40) & 0xFF; 1517 if (ratio) 1518 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 14 active cores\n", 1519 ratio, bclk, ratio * bclk); 1520 1521 ratio = (msr >> 32) & 0xFF; 1522 if (ratio) 1523 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 13 active cores\n", 1524 ratio, bclk, ratio * bclk); 1525 1526 ratio = (msr >> 24) & 0xFF; 1527 if (ratio) 1528 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 12 active cores\n", 1529 ratio, bclk, ratio * bclk); 1530 1531 ratio = (msr >> 16) & 0xFF; 1532 if (ratio) 1533 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 11 active cores\n", 1534 ratio, bclk, ratio * bclk); 1535 1536 ratio = (msr >> 8) & 0xFF; 1537 if (ratio) 1538 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 10 active cores\n", 1539 ratio, bclk, ratio * bclk); 1540 1541 ratio = (msr >> 0) & 0xFF; 1542 if (ratio) 1543 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 9 active cores\n", 1544 ratio, bclk, ratio * bclk); 1545 return; 1546 } 1547 1548 static void 1549 dump_nhm_turbo_ratio_limits(void) 1550 { 1551 unsigned long long msr; 1552 unsigned int ratio; 1553 1554 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr); 1555 1556 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr); 1557 1558 ratio = (msr >> 56) & 0xFF; 1559 if (ratio) 1560 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 8 active cores\n", 1561 ratio, bclk, ratio * bclk); 1562 1563 ratio = (msr >> 48) & 0xFF; 1564 if (ratio) 1565 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 7 active cores\n", 1566 ratio, bclk, ratio * bclk); 1567 1568 ratio = (msr >> 40) & 0xFF; 1569 if (ratio) 1570 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 6 active cores\n", 1571 ratio, bclk, ratio * bclk); 1572 1573 ratio = (msr >> 32) & 0xFF; 1574 if (ratio) 1575 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 5 active cores\n", 1576 ratio, bclk, ratio * bclk); 1577 1578 ratio = (msr >> 24) & 0xFF; 1579 if (ratio) 1580 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 4 active cores\n", 1581 ratio, bclk, ratio * bclk); 1582 1583 ratio = (msr >> 16) & 0xFF; 1584 if (ratio) 1585 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 3 active cores\n", 1586 ratio, bclk, ratio * bclk); 1587 1588 ratio = (msr >> 8) & 0xFF; 1589 if (ratio) 1590 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 2 active cores\n", 1591 ratio, bclk, ratio * bclk); 1592 1593 ratio = (msr >> 0) & 0xFF; 1594 if (ratio) 1595 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", 1596 ratio, bclk, ratio * bclk); 1597 return; 1598 } 1599 1600 static void 1601 dump_knl_turbo_ratio_limits(void) 1602 { 1603 const unsigned int buckets_no = 7; 1604 1605 unsigned long long msr; 1606 int delta_cores, delta_ratio; 1607 int i, b_nr; 1608 unsigned int cores[buckets_no]; 1609 unsigned int ratio[buckets_no]; 1610 1611 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr); 1612 1613 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", 1614 base_cpu, msr); 1615 1616 /** 1617 * Turbo encoding in KNL is as follows: 1618 * [0] -- Reserved 1619 * [7:1] -- Base value of number of active cores of bucket 1. 1620 * [15:8] -- Base value of freq ratio of bucket 1. 1621 * [20:16] -- +ve delta of number of active cores of bucket 2. 1622 * i.e. active cores of bucket 2 = 1623 * active cores of bucket 1 + delta 1624 * [23:21] -- Negative delta of freq ratio of bucket 2. 1625 * i.e. freq ratio of bucket 2 = 1626 * freq ratio of bucket 1 - delta 1627 * [28:24]-- +ve delta of number of active cores of bucket 3. 1628 * [31:29]-- -ve delta of freq ratio of bucket 3. 1629 * [36:32]-- +ve delta of number of active cores of bucket 4. 1630 * [39:37]-- -ve delta of freq ratio of bucket 4. 1631 * [44:40]-- +ve delta of number of active cores of bucket 5. 1632 * [47:45]-- -ve delta of freq ratio of bucket 5. 1633 * [52:48]-- +ve delta of number of active cores of bucket 6. 1634 * [55:53]-- -ve delta of freq ratio of bucket 6. 1635 * [60:56]-- +ve delta of number of active cores of bucket 7. 1636 * [63:61]-- -ve delta of freq ratio of bucket 7. 1637 */ 1638 1639 b_nr = 0; 1640 cores[b_nr] = (msr & 0xFF) >> 1; 1641 ratio[b_nr] = (msr >> 8) & 0xFF; 1642 1643 for (i = 16; i < 64; i += 8) { 1644 delta_cores = (msr >> i) & 0x1F; 1645 delta_ratio = (msr >> (i + 5)) & 0x7; 1646 1647 cores[b_nr + 1] = cores[b_nr] + delta_cores; 1648 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio; 1649 b_nr++; 1650 } 1651 1652 for (i = buckets_no - 1; i >= 0; i--) 1653 if (i > 0 ? ratio[i] != ratio[i - 1] : 1) 1654 fprintf(outf, 1655 "%d * %.0f = %.0f MHz max turbo %d active cores\n", 1656 ratio[i], bclk, ratio[i] * bclk, cores[i]); 1657 } 1658 1659 static void 1660 dump_nhm_cst_cfg(void) 1661 { 1662 unsigned long long msr; 1663 1664 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); 1665 1666 #define SNB_C1_AUTO_UNDEMOTE (1UL << 27) 1667 #define SNB_C3_AUTO_UNDEMOTE (1UL << 28) 1668 1669 fprintf(outf, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr); 1670 1671 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n", 1672 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "", 1673 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "", 1674 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "", 1675 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "", 1676 (msr & (1 << 15)) ? "" : "UN", 1677 (unsigned int)msr & 0xF, 1678 pkg_cstate_limit_strings[pkg_cstate_limit]); 1679 return; 1680 } 1681 1682 static void 1683 dump_config_tdp(void) 1684 { 1685 unsigned long long msr; 1686 1687 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr); 1688 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr); 1689 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF); 1690 1691 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr); 1692 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr); 1693 if (msr) { 1694 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF); 1695 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF); 1696 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF); 1697 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF); 1698 } 1699 fprintf(outf, ")\n"); 1700 1701 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr); 1702 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr); 1703 if (msr) { 1704 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF); 1705 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF); 1706 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF); 1707 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF); 1708 } 1709 fprintf(outf, ")\n"); 1710 1711 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr); 1712 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr); 1713 if ((msr) & 0x3) 1714 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3); 1715 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); 1716 fprintf(outf, ")\n"); 1717 1718 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); 1719 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); 1720 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF); 1721 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); 1722 fprintf(outf, ")\n"); 1723 } 1724 1725 unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 }; 1726 1727 void print_irtl(void) 1728 { 1729 unsigned long long msr; 1730 1731 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr); 1732 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr); 1733 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", 1734 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); 1735 1736 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr); 1737 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr); 1738 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", 1739 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); 1740 1741 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr); 1742 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr); 1743 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", 1744 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); 1745 1746 if (!do_irtl_hsw) 1747 return; 1748 1749 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr); 1750 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr); 1751 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", 1752 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); 1753 1754 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr); 1755 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr); 1756 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", 1757 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); 1758 1759 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr); 1760 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr); 1761 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", 1762 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); 1763 1764 } 1765 void free_fd_percpu(void) 1766 { 1767 int i; 1768 1769 for (i = 0; i < topo.max_cpu_num + 1; ++i) { 1770 if (fd_percpu[i] != 0) 1771 close(fd_percpu[i]); 1772 } 1773 1774 free(fd_percpu); 1775 } 1776 1777 void free_all_buffers(void) 1778 { 1779 CPU_FREE(cpu_present_set); 1780 cpu_present_set = NULL; 1781 cpu_present_setsize = 0; 1782 1783 CPU_FREE(cpu_affinity_set); 1784 cpu_affinity_set = NULL; 1785 cpu_affinity_setsize = 0; 1786 1787 free(thread_even); 1788 free(core_even); 1789 free(package_even); 1790 1791 thread_even = NULL; 1792 core_even = NULL; 1793 package_even = NULL; 1794 1795 free(thread_odd); 1796 free(core_odd); 1797 free(package_odd); 1798 1799 thread_odd = NULL; 1800 core_odd = NULL; 1801 package_odd = NULL; 1802 1803 free(output_buffer); 1804 output_buffer = NULL; 1805 outp = NULL; 1806 1807 free_fd_percpu(); 1808 1809 free(irq_column_2_cpu); 1810 free(irqs_per_cpu); 1811 } 1812 1813 /* 1814 * Open a file, and exit on failure 1815 */ 1816 FILE *fopen_or_die(const char *path, const char *mode) 1817 { 1818 FILE *filep = fopen(path, mode); 1819 if (!filep) 1820 err(1, "%s: open failed", path); 1821 return filep; 1822 } 1823 1824 /* 1825 * Parse a file containing a single int. 1826 */ 1827 int parse_int_file(const char *fmt, ...) 1828 { 1829 va_list args; 1830 char path[PATH_MAX]; 1831 FILE *filep; 1832 int value; 1833 1834 va_start(args, fmt); 1835 vsnprintf(path, sizeof(path), fmt, args); 1836 va_end(args); 1837 filep = fopen_or_die(path, "r"); 1838 if (fscanf(filep, "%d", &value) != 1) 1839 err(1, "%s: failed to parse number from file", path); 1840 fclose(filep); 1841 return value; 1842 } 1843 1844 /* 1845 * get_cpu_position_in_core(cpu) 1846 * return the position of the CPU among its HT siblings in the core 1847 * return -1 if the sibling is not in list 1848 */ 1849 int get_cpu_position_in_core(int cpu) 1850 { 1851 char path[64]; 1852 FILE *filep; 1853 int this_cpu; 1854 char character; 1855 int i; 1856 1857 sprintf(path, 1858 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", 1859 cpu); 1860 filep = fopen(path, "r"); 1861 if (filep == NULL) { 1862 perror(path); 1863 exit(1); 1864 } 1865 1866 for (i = 0; i < topo.num_threads_per_core; i++) { 1867 fscanf(filep, "%d", &this_cpu); 1868 if (this_cpu == cpu) { 1869 fclose(filep); 1870 return i; 1871 } 1872 1873 /* Account for no separator after last thread*/ 1874 if (i != (topo.num_threads_per_core - 1)) 1875 fscanf(filep, "%c", &character); 1876 } 1877 1878 fclose(filep); 1879 return -1; 1880 } 1881 1882 /* 1883 * cpu_is_first_core_in_package(cpu) 1884 * return 1 if given CPU is 1st core in package 1885 */ 1886 int cpu_is_first_core_in_package(int cpu) 1887 { 1888 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu); 1889 } 1890 1891 int get_physical_package_id(int cpu) 1892 { 1893 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); 1894 } 1895 1896 int get_core_id(int cpu) 1897 { 1898 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); 1899 } 1900 1901 int get_num_ht_siblings(int cpu) 1902 { 1903 char path[80]; 1904 FILE *filep; 1905 int sib1; 1906 int matches = 0; 1907 char character; 1908 char str[100]; 1909 char *ch; 1910 1911 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu); 1912 filep = fopen_or_die(path, "r"); 1913 1914 /* 1915 * file format: 1916 * A ',' separated or '-' separated set of numbers 1917 * (eg 1-2 or 1,3,4,5) 1918 */ 1919 fscanf(filep, "%d%c\n", &sib1, &character); 1920 fseek(filep, 0, SEEK_SET); 1921 fgets(str, 100, filep); 1922 ch = strchr(str, character); 1923 while (ch != NULL) { 1924 matches++; 1925 ch = strchr(ch+1, character); 1926 } 1927 1928 fclose(filep); 1929 return matches+1; 1930 } 1931 1932 /* 1933 * run func(thread, core, package) in topology order 1934 * skip non-present cpus 1935 */ 1936 1937 int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *, 1938 struct pkg_data *, struct thread_data *, struct core_data *, 1939 struct pkg_data *), struct thread_data *thread_base, 1940 struct core_data *core_base, struct pkg_data *pkg_base, 1941 struct thread_data *thread_base2, struct core_data *core_base2, 1942 struct pkg_data *pkg_base2) 1943 { 1944 int retval, pkg_no, core_no, thread_no; 1945 1946 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { 1947 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) { 1948 for (thread_no = 0; thread_no < 1949 topo.num_threads_per_core; ++thread_no) { 1950 struct thread_data *t, *t2; 1951 struct core_data *c, *c2; 1952 struct pkg_data *p, *p2; 1953 1954 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no); 1955 1956 if (cpu_is_not_present(t->cpu_id)) 1957 continue; 1958 1959 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no); 1960 1961 c = GET_CORE(core_base, core_no, pkg_no); 1962 c2 = GET_CORE(core_base2, core_no, pkg_no); 1963 1964 p = GET_PKG(pkg_base, pkg_no); 1965 p2 = GET_PKG(pkg_base2, pkg_no); 1966 1967 retval = func(t, c, p, t2, c2, p2); 1968 if (retval) 1969 return retval; 1970 } 1971 } 1972 } 1973 return 0; 1974 } 1975 1976 /* 1977 * run func(cpu) on every cpu in /proc/stat 1978 * return max_cpu number 1979 */ 1980 int for_all_proc_cpus(int (func)(int)) 1981 { 1982 FILE *fp; 1983 int cpu_num; 1984 int retval; 1985 1986 fp = fopen_or_die(proc_stat, "r"); 1987 1988 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n"); 1989 if (retval != 0) 1990 err(1, "%s: failed to parse format", proc_stat); 1991 1992 while (1) { 1993 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num); 1994 if (retval != 1) 1995 break; 1996 1997 retval = func(cpu_num); 1998 if (retval) { 1999 fclose(fp); 2000 return(retval); 2001 } 2002 } 2003 fclose(fp); 2004 return 0; 2005 } 2006 2007 void re_initialize(void) 2008 { 2009 free_all_buffers(); 2010 setup_all_buffers(); 2011 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus); 2012 } 2013 2014 2015 /* 2016 * count_cpus() 2017 * remember the last one seen, it will be the max 2018 */ 2019 int count_cpus(int cpu) 2020 { 2021 if (topo.max_cpu_num < cpu) 2022 topo.max_cpu_num = cpu; 2023 2024 topo.num_cpus += 1; 2025 return 0; 2026 } 2027 int mark_cpu_present(int cpu) 2028 { 2029 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set); 2030 return 0; 2031 } 2032 2033 /* 2034 * snapshot_proc_interrupts() 2035 * 2036 * read and record summary of /proc/interrupts 2037 * 2038 * return 1 if config change requires a restart, else return 0 2039 */ 2040 int snapshot_proc_interrupts(void) 2041 { 2042 static FILE *fp; 2043 int column, retval; 2044 2045 if (fp == NULL) 2046 fp = fopen_or_die("/proc/interrupts", "r"); 2047 else 2048 rewind(fp); 2049 2050 /* read 1st line of /proc/interrupts to get cpu* name for each column */ 2051 for (column = 0; column < topo.num_cpus; ++column) { 2052 int cpu_number; 2053 2054 retval = fscanf(fp, " CPU%d", &cpu_number); 2055 if (retval != 1) 2056 break; 2057 2058 if (cpu_number > topo.max_cpu_num) { 2059 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num); 2060 return 1; 2061 } 2062 2063 irq_column_2_cpu[column] = cpu_number; 2064 irqs_per_cpu[cpu_number] = 0; 2065 } 2066 2067 /* read /proc/interrupt count lines and sum up irqs per cpu */ 2068 while (1) { 2069 int column; 2070 char buf[64]; 2071 2072 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */ 2073 if (retval != 1) 2074 break; 2075 2076 /* read the count per cpu */ 2077 for (column = 0; column < topo.num_cpus; ++column) { 2078 2079 int cpu_number, irq_count; 2080 2081 retval = fscanf(fp, " %d", &irq_count); 2082 if (retval != 1) 2083 break; 2084 2085 cpu_number = irq_column_2_cpu[column]; 2086 irqs_per_cpu[cpu_number] += irq_count; 2087 2088 } 2089 2090 while (getc(fp) != '\n') 2091 ; /* flush interrupt description */ 2092 2093 } 2094 return 0; 2095 } 2096 /* 2097 * snapshot_gfx_rc6_ms() 2098 * 2099 * record snapshot of 2100 * /sys/class/drm/card0/power/rc6_residency_ms 2101 * 2102 * return 1 if config change requires a restart, else return 0 2103 */ 2104 int snapshot_gfx_rc6_ms(void) 2105 { 2106 FILE *fp; 2107 int retval; 2108 2109 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r"); 2110 2111 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms); 2112 if (retval != 1) 2113 err(1, "GFX rc6"); 2114 2115 fclose(fp); 2116 2117 return 0; 2118 } 2119 /* 2120 * snapshot_gfx_mhz() 2121 * 2122 * record snapshot of 2123 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz 2124 * 2125 * return 1 if config change requires a restart, else return 0 2126 */ 2127 int snapshot_gfx_mhz(void) 2128 { 2129 static FILE *fp; 2130 int retval; 2131 2132 if (fp == NULL) 2133 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r"); 2134 else 2135 rewind(fp); 2136 2137 retval = fscanf(fp, "%d", &gfx_cur_mhz); 2138 if (retval != 1) 2139 err(1, "GFX MHz"); 2140 2141 return 0; 2142 } 2143 2144 /* 2145 * snapshot /proc and /sys files 2146 * 2147 * return 1 if configuration restart needed, else return 0 2148 */ 2149 int snapshot_proc_sysfs_files(void) 2150 { 2151 if (snapshot_proc_interrupts()) 2152 return 1; 2153 2154 if (do_gfx_rc6_ms) 2155 snapshot_gfx_rc6_ms(); 2156 2157 if (do_gfx_mhz) 2158 snapshot_gfx_mhz(); 2159 2160 return 0; 2161 } 2162 2163 void turbostat_loop() 2164 { 2165 int retval; 2166 int restarted = 0; 2167 2168 restart: 2169 restarted++; 2170 2171 snapshot_proc_sysfs_files(); 2172 retval = for_all_cpus(get_counters, EVEN_COUNTERS); 2173 if (retval < -1) { 2174 exit(retval); 2175 } else if (retval == -1) { 2176 if (restarted > 1) { 2177 exit(retval); 2178 } 2179 re_initialize(); 2180 goto restart; 2181 } 2182 restarted = 0; 2183 gettimeofday(&tv_even, (struct timezone *)NULL); 2184 2185 while (1) { 2186 if (for_all_proc_cpus(cpu_is_not_present)) { 2187 re_initialize(); 2188 goto restart; 2189 } 2190 nanosleep(&interval_ts, NULL); 2191 if (snapshot_proc_sysfs_files()) 2192 goto restart; 2193 retval = for_all_cpus(get_counters, ODD_COUNTERS); 2194 if (retval < -1) { 2195 exit(retval); 2196 } else if (retval == -1) { 2197 re_initialize(); 2198 goto restart; 2199 } 2200 gettimeofday(&tv_odd, (struct timezone *)NULL); 2201 timersub(&tv_odd, &tv_even, &tv_delta); 2202 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) { 2203 re_initialize(); 2204 goto restart; 2205 } 2206 compute_average(EVEN_COUNTERS); 2207 format_all_counters(EVEN_COUNTERS); 2208 flush_output_stdout(); 2209 nanosleep(&interval_ts, NULL); 2210 if (snapshot_proc_sysfs_files()) 2211 goto restart; 2212 retval = for_all_cpus(get_counters, EVEN_COUNTERS); 2213 if (retval < -1) { 2214 exit(retval); 2215 } else if (retval == -1) { 2216 re_initialize(); 2217 goto restart; 2218 } 2219 gettimeofday(&tv_even, (struct timezone *)NULL); 2220 timersub(&tv_even, &tv_odd, &tv_delta); 2221 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) { 2222 re_initialize(); 2223 goto restart; 2224 } 2225 compute_average(ODD_COUNTERS); 2226 format_all_counters(ODD_COUNTERS); 2227 flush_output_stdout(); 2228 } 2229 } 2230 2231 void check_dev_msr() 2232 { 2233 struct stat sb; 2234 char pathname[32]; 2235 2236 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); 2237 if (stat(pathname, &sb)) 2238 if (system("/sbin/modprobe msr > /dev/null 2>&1")) 2239 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); 2240 } 2241 2242 void check_permissions() 2243 { 2244 struct __user_cap_header_struct cap_header_data; 2245 cap_user_header_t cap_header = &cap_header_data; 2246 struct __user_cap_data_struct cap_data_data; 2247 cap_user_data_t cap_data = &cap_data_data; 2248 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); 2249 int do_exit = 0; 2250 char pathname[32]; 2251 2252 /* check for CAP_SYS_RAWIO */ 2253 cap_header->pid = getpid(); 2254 cap_header->version = _LINUX_CAPABILITY_VERSION; 2255 if (capget(cap_header, cap_data) < 0) 2256 err(-6, "capget(2) failed"); 2257 2258 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { 2259 do_exit++; 2260 warnx("capget(CAP_SYS_RAWIO) failed," 2261 " try \"# setcap cap_sys_rawio=ep %s\"", progname); 2262 } 2263 2264 /* test file permissions */ 2265 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); 2266 if (euidaccess(pathname, R_OK)) { 2267 do_exit++; 2268 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr"); 2269 } 2270 2271 /* if all else fails, thell them to be root */ 2272 if (do_exit) 2273 if (getuid() != 0) 2274 warnx("... or simply run as root"); 2275 2276 if (do_exit) 2277 exit(-6); 2278 } 2279 2280 /* 2281 * NHM adds support for additional MSRs: 2282 * 2283 * MSR_SMI_COUNT 0x00000034 2284 * 2285 * MSR_PLATFORM_INFO 0x000000ce 2286 * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 2287 * 2288 * MSR_PKG_C3_RESIDENCY 0x000003f8 2289 * MSR_PKG_C6_RESIDENCY 0x000003f9 2290 * MSR_CORE_C3_RESIDENCY 0x000003fc 2291 * MSR_CORE_C6_RESIDENCY 0x000003fd 2292 * 2293 * Side effect: 2294 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL 2295 */ 2296 int probe_nhm_msrs(unsigned int family, unsigned int model) 2297 { 2298 unsigned long long msr; 2299 unsigned int base_ratio; 2300 int *pkg_cstate_limits; 2301 2302 if (!genuine_intel) 2303 return 0; 2304 2305 if (family != 6) 2306 return 0; 2307 2308 bclk = discover_bclk(family, model); 2309 2310 switch (model) { 2311 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ 2312 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ 2313 case 0x1F: /* Core i7 and i5 Processor - Nehalem */ 2314 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */ 2315 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */ 2316 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ 2317 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ 2318 pkg_cstate_limits = nhm_pkg_cstate_limits; 2319 break; 2320 case INTEL_FAM6_SANDYBRIDGE: /* SNB */ 2321 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */ 2322 case INTEL_FAM6_IVYBRIDGE: /* IVB */ 2323 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ 2324 pkg_cstate_limits = snb_pkg_cstate_limits; 2325 break; 2326 case INTEL_FAM6_HASWELL_CORE: /* HSW */ 2327 case INTEL_FAM6_HASWELL_X: /* HSX */ 2328 case INTEL_FAM6_HASWELL_ULT: /* HSW */ 2329 case INTEL_FAM6_HASWELL_GT3E: /* HSW */ 2330 case INTEL_FAM6_BROADWELL_CORE: /* BDW */ 2331 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ 2332 case INTEL_FAM6_BROADWELL_X: /* BDX */ 2333 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ 2334 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 2335 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 2336 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 2337 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 2338 pkg_cstate_limits = hsw_pkg_cstate_limits; 2339 break; 2340 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 2341 pkg_cstate_limits = skx_pkg_cstate_limits; 2342 break; 2343 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ 2344 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ 2345 pkg_cstate_limits = slv_pkg_cstate_limits; 2346 break; 2347 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */ 2348 pkg_cstate_limits = amt_pkg_cstate_limits; 2349 break; 2350 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */ 2351 case INTEL_FAM6_XEON_PHI_KNM: 2352 pkg_cstate_limits = phi_pkg_cstate_limits; 2353 break; 2354 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 2355 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 2356 pkg_cstate_limits = bxt_pkg_cstate_limits; 2357 break; 2358 default: 2359 return 0; 2360 } 2361 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); 2362 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; 2363 2364 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr); 2365 base_ratio = (msr >> 8) & 0xFF; 2366 2367 base_hz = base_ratio * bclk * 1000000; 2368 has_base_hz = 1; 2369 return 1; 2370 } 2371 int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) 2372 { 2373 switch (model) { 2374 /* Nehalem compatible, but do not include turbo-ratio limit support */ 2375 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ 2376 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ 2377 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */ 2378 case INTEL_FAM6_XEON_PHI_KNM: 2379 return 0; 2380 default: 2381 return 1; 2382 } 2383 } 2384 int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) 2385 { 2386 if (!genuine_intel) 2387 return 0; 2388 2389 if (family != 6) 2390 return 0; 2391 2392 switch (model) { 2393 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ 2394 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */ 2395 return 1; 2396 default: 2397 return 0; 2398 } 2399 } 2400 int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model) 2401 { 2402 if (!genuine_intel) 2403 return 0; 2404 2405 if (family != 6) 2406 return 0; 2407 2408 switch (model) { 2409 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */ 2410 return 1; 2411 default: 2412 return 0; 2413 } 2414 } 2415 2416 int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model) 2417 { 2418 if (!genuine_intel) 2419 return 0; 2420 2421 if (family != 6) 2422 return 0; 2423 2424 switch (model) { 2425 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ 2426 case INTEL_FAM6_XEON_PHI_KNM: 2427 return 1; 2428 default: 2429 return 0; 2430 } 2431 } 2432 int has_config_tdp(unsigned int family, unsigned int model) 2433 { 2434 if (!genuine_intel) 2435 return 0; 2436 2437 if (family != 6) 2438 return 0; 2439 2440 switch (model) { 2441 case INTEL_FAM6_IVYBRIDGE: /* IVB */ 2442 case INTEL_FAM6_HASWELL_CORE: /* HSW */ 2443 case INTEL_FAM6_HASWELL_X: /* HSX */ 2444 case INTEL_FAM6_HASWELL_ULT: /* HSW */ 2445 case INTEL_FAM6_HASWELL_GT3E: /* HSW */ 2446 case INTEL_FAM6_BROADWELL_CORE: /* BDW */ 2447 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ 2448 case INTEL_FAM6_BROADWELL_X: /* BDX */ 2449 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ 2450 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 2451 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 2452 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 2453 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 2454 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 2455 2456 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ 2457 case INTEL_FAM6_XEON_PHI_KNM: 2458 return 1; 2459 default: 2460 return 0; 2461 } 2462 } 2463 2464 static void 2465 dump_cstate_pstate_config_info(unsigned int family, unsigned int model) 2466 { 2467 if (!do_nhm_platform_info) 2468 return; 2469 2470 dump_nhm_platform_info(); 2471 2472 if (has_hsw_turbo_ratio_limit(family, model)) 2473 dump_hsw_turbo_ratio_limits(); 2474 2475 if (has_ivt_turbo_ratio_limit(family, model)) 2476 dump_ivt_turbo_ratio_limits(); 2477 2478 if (has_nhm_turbo_ratio_limit(family, model)) 2479 dump_nhm_turbo_ratio_limits(); 2480 2481 if (has_knl_turbo_ratio_limit(family, model)) 2482 dump_knl_turbo_ratio_limits(); 2483 2484 if (has_config_tdp(family, model)) 2485 dump_config_tdp(); 2486 2487 dump_nhm_cst_cfg(); 2488 } 2489 2490 2491 /* 2492 * print_epb() 2493 * Decode the ENERGY_PERF_BIAS MSR 2494 */ 2495 int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) 2496 { 2497 unsigned long long msr; 2498 char *epb_string; 2499 int cpu; 2500 2501 if (!has_epb) 2502 return 0; 2503 2504 cpu = t->cpu_id; 2505 2506 /* EPB is per-package */ 2507 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 2508 return 0; 2509 2510 if (cpu_migrate(cpu)) { 2511 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 2512 return -1; 2513 } 2514 2515 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr)) 2516 return 0; 2517 2518 switch (msr & 0xF) { 2519 case ENERGY_PERF_BIAS_PERFORMANCE: 2520 epb_string = "performance"; 2521 break; 2522 case ENERGY_PERF_BIAS_NORMAL: 2523 epb_string = "balanced"; 2524 break; 2525 case ENERGY_PERF_BIAS_POWERSAVE: 2526 epb_string = "powersave"; 2527 break; 2528 default: 2529 epb_string = "custom"; 2530 break; 2531 } 2532 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string); 2533 2534 return 0; 2535 } 2536 /* 2537 * print_hwp() 2538 * Decode the MSR_HWP_CAPABILITIES 2539 */ 2540 int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) 2541 { 2542 unsigned long long msr; 2543 int cpu; 2544 2545 if (!has_hwp) 2546 return 0; 2547 2548 cpu = t->cpu_id; 2549 2550 /* MSR_HWP_CAPABILITIES is per-package */ 2551 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 2552 return 0; 2553 2554 if (cpu_migrate(cpu)) { 2555 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 2556 return -1; 2557 } 2558 2559 if (get_msr(cpu, MSR_PM_ENABLE, &msr)) 2560 return 0; 2561 2562 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n", 2563 cpu, msr, (msr & (1 << 0)) ? "" : "No-"); 2564 2565 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */ 2566 if ((msr & (1 << 0)) == 0) 2567 return 0; 2568 2569 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr)) 2570 return 0; 2571 2572 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx " 2573 "(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n", 2574 cpu, msr, 2575 (unsigned int)HWP_HIGHEST_PERF(msr), 2576 (unsigned int)HWP_GUARANTEED_PERF(msr), 2577 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr), 2578 (unsigned int)HWP_LOWEST_PERF(msr)); 2579 2580 if (get_msr(cpu, MSR_HWP_REQUEST, &msr)) 2581 return 0; 2582 2583 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx " 2584 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n", 2585 cpu, msr, 2586 (unsigned int)(((msr) >> 0) & 0xff), 2587 (unsigned int)(((msr) >> 8) & 0xff), 2588 (unsigned int)(((msr) >> 16) & 0xff), 2589 (unsigned int)(((msr) >> 24) & 0xff), 2590 (unsigned int)(((msr) >> 32) & 0xff3), 2591 (unsigned int)(((msr) >> 42) & 0x1)); 2592 2593 if (has_hwp_pkg) { 2594 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr)) 2595 return 0; 2596 2597 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx " 2598 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n", 2599 cpu, msr, 2600 (unsigned int)(((msr) >> 0) & 0xff), 2601 (unsigned int)(((msr) >> 8) & 0xff), 2602 (unsigned int)(((msr) >> 16) & 0xff), 2603 (unsigned int)(((msr) >> 24) & 0xff), 2604 (unsigned int)(((msr) >> 32) & 0xff3)); 2605 } 2606 if (has_hwp_notify) { 2607 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr)) 2608 return 0; 2609 2610 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx " 2611 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n", 2612 cpu, msr, 2613 ((msr) & 0x1) ? "EN" : "Dis", 2614 ((msr) & 0x2) ? "EN" : "Dis"); 2615 } 2616 if (get_msr(cpu, MSR_HWP_STATUS, &msr)) 2617 return 0; 2618 2619 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx " 2620 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n", 2621 cpu, msr, 2622 ((msr) & 0x1) ? "" : "No-", 2623 ((msr) & 0x2) ? "" : "No-"); 2624 2625 return 0; 2626 } 2627 2628 /* 2629 * print_perf_limit() 2630 */ 2631 int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p) 2632 { 2633 unsigned long long msr; 2634 int cpu; 2635 2636 cpu = t->cpu_id; 2637 2638 /* per-package */ 2639 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 2640 return 0; 2641 2642 if (cpu_migrate(cpu)) { 2643 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 2644 return -1; 2645 } 2646 2647 if (do_core_perf_limit_reasons) { 2648 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr); 2649 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); 2650 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)", 2651 (msr & 1 << 15) ? "bit15, " : "", 2652 (msr & 1 << 14) ? "bit14, " : "", 2653 (msr & 1 << 13) ? "Transitions, " : "", 2654 (msr & 1 << 12) ? "MultiCoreTurbo, " : "", 2655 (msr & 1 << 11) ? "PkgPwrL2, " : "", 2656 (msr & 1 << 10) ? "PkgPwrL1, " : "", 2657 (msr & 1 << 9) ? "CorePwr, " : "", 2658 (msr & 1 << 8) ? "Amps, " : "", 2659 (msr & 1 << 6) ? "VR-Therm, " : "", 2660 (msr & 1 << 5) ? "Auto-HWP, " : "", 2661 (msr & 1 << 4) ? "Graphics, " : "", 2662 (msr & 1 << 2) ? "bit2, " : "", 2663 (msr & 1 << 1) ? "ThermStatus, " : "", 2664 (msr & 1 << 0) ? "PROCHOT, " : ""); 2665 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", 2666 (msr & 1 << 31) ? "bit31, " : "", 2667 (msr & 1 << 30) ? "bit30, " : "", 2668 (msr & 1 << 29) ? "Transitions, " : "", 2669 (msr & 1 << 28) ? "MultiCoreTurbo, " : "", 2670 (msr & 1 << 27) ? "PkgPwrL2, " : "", 2671 (msr & 1 << 26) ? "PkgPwrL1, " : "", 2672 (msr & 1 << 25) ? "CorePwr, " : "", 2673 (msr & 1 << 24) ? "Amps, " : "", 2674 (msr & 1 << 22) ? "VR-Therm, " : "", 2675 (msr & 1 << 21) ? "Auto-HWP, " : "", 2676 (msr & 1 << 20) ? "Graphics, " : "", 2677 (msr & 1 << 18) ? "bit18, " : "", 2678 (msr & 1 << 17) ? "ThermStatus, " : "", 2679 (msr & 1 << 16) ? "PROCHOT, " : ""); 2680 2681 } 2682 if (do_gfx_perf_limit_reasons) { 2683 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr); 2684 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); 2685 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)", 2686 (msr & 1 << 0) ? "PROCHOT, " : "", 2687 (msr & 1 << 1) ? "ThermStatus, " : "", 2688 (msr & 1 << 4) ? "Graphics, " : "", 2689 (msr & 1 << 6) ? "VR-Therm, " : "", 2690 (msr & 1 << 8) ? "Amps, " : "", 2691 (msr & 1 << 9) ? "GFXPwr, " : "", 2692 (msr & 1 << 10) ? "PkgPwrL1, " : "", 2693 (msr & 1 << 11) ? "PkgPwrL2, " : ""); 2694 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n", 2695 (msr & 1 << 16) ? "PROCHOT, " : "", 2696 (msr & 1 << 17) ? "ThermStatus, " : "", 2697 (msr & 1 << 20) ? "Graphics, " : "", 2698 (msr & 1 << 22) ? "VR-Therm, " : "", 2699 (msr & 1 << 24) ? "Amps, " : "", 2700 (msr & 1 << 25) ? "GFXPwr, " : "", 2701 (msr & 1 << 26) ? "PkgPwrL1, " : "", 2702 (msr & 1 << 27) ? "PkgPwrL2, " : ""); 2703 } 2704 if (do_ring_perf_limit_reasons) { 2705 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr); 2706 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr); 2707 fprintf(outf, " (Active: %s%s%s%s%s%s)", 2708 (msr & 1 << 0) ? "PROCHOT, " : "", 2709 (msr & 1 << 1) ? "ThermStatus, " : "", 2710 (msr & 1 << 6) ? "VR-Therm, " : "", 2711 (msr & 1 << 8) ? "Amps, " : "", 2712 (msr & 1 << 10) ? "PkgPwrL1, " : "", 2713 (msr & 1 << 11) ? "PkgPwrL2, " : ""); 2714 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n", 2715 (msr & 1 << 16) ? "PROCHOT, " : "", 2716 (msr & 1 << 17) ? "ThermStatus, " : "", 2717 (msr & 1 << 22) ? "VR-Therm, " : "", 2718 (msr & 1 << 24) ? "Amps, " : "", 2719 (msr & 1 << 26) ? "PkgPwrL1, " : "", 2720 (msr & 1 << 27) ? "PkgPwrL2, " : ""); 2721 } 2722 return 0; 2723 } 2724 2725 #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ 2726 #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ 2727 2728 double get_tdp(unsigned int model) 2729 { 2730 unsigned long long msr; 2731 2732 if (do_rapl & RAPL_PKG_POWER_INFO) 2733 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr)) 2734 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; 2735 2736 switch (model) { 2737 case INTEL_FAM6_ATOM_SILVERMONT1: 2738 case INTEL_FAM6_ATOM_SILVERMONT2: 2739 return 30.0; 2740 default: 2741 return 135.0; 2742 } 2743 } 2744 2745 /* 2746 * rapl_dram_energy_units_probe() 2747 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR. 2748 */ 2749 static double 2750 rapl_dram_energy_units_probe(int model, double rapl_energy_units) 2751 { 2752 /* only called for genuine_intel, family 6 */ 2753 2754 switch (model) { 2755 case INTEL_FAM6_HASWELL_X: /* HSX */ 2756 case INTEL_FAM6_BROADWELL_X: /* BDX */ 2757 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ 2758 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ 2759 case INTEL_FAM6_XEON_PHI_KNM: 2760 return (rapl_dram_energy_units = 15.3 / 1000000); 2761 default: 2762 return (rapl_energy_units); 2763 } 2764 } 2765 2766 2767 /* 2768 * rapl_probe() 2769 * 2770 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units 2771 */ 2772 void rapl_probe(unsigned int family, unsigned int model) 2773 { 2774 unsigned long long msr; 2775 unsigned int time_unit; 2776 double tdp; 2777 2778 if (!genuine_intel) 2779 return; 2780 2781 if (family != 6) 2782 return; 2783 2784 switch (model) { 2785 case INTEL_FAM6_SANDYBRIDGE: 2786 case INTEL_FAM6_IVYBRIDGE: 2787 case INTEL_FAM6_HASWELL_CORE: /* HSW */ 2788 case INTEL_FAM6_HASWELL_ULT: /* HSW */ 2789 case INTEL_FAM6_HASWELL_GT3E: /* HSW */ 2790 case INTEL_FAM6_BROADWELL_CORE: /* BDW */ 2791 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ 2792 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; 2793 break; 2794 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 2795 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO; 2796 break; 2797 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 2798 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 2799 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 2800 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 2801 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; 2802 break; 2803 case INTEL_FAM6_HASWELL_X: /* HSX */ 2804 case INTEL_FAM6_BROADWELL_X: /* BDX */ 2805 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ 2806 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 2807 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ 2808 case INTEL_FAM6_XEON_PHI_KNM: 2809 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; 2810 break; 2811 case INTEL_FAM6_SANDYBRIDGE_X: 2812 case INTEL_FAM6_IVYBRIDGE_X: 2813 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; 2814 break; 2815 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ 2816 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ 2817 do_rapl = RAPL_PKG | RAPL_CORES; 2818 break; 2819 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 2820 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; 2821 break; 2822 default: 2823 return; 2824 } 2825 2826 /* units on package 0, verify later other packages match */ 2827 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr)) 2828 return; 2829 2830 rapl_power_units = 1.0 / (1 << (msr & 0xF)); 2831 if (model == INTEL_FAM6_ATOM_SILVERMONT1) 2832 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000; 2833 else 2834 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); 2835 2836 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units); 2837 2838 time_unit = msr >> 16 & 0xF; 2839 if (time_unit == 0) 2840 time_unit = 0xA; 2841 2842 rapl_time_units = 1.0 / (1 << (time_unit)); 2843 2844 tdp = get_tdp(model); 2845 2846 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; 2847 if (debug) 2848 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); 2849 2850 return; 2851 } 2852 2853 void perf_limit_reasons_probe(unsigned int family, unsigned int model) 2854 { 2855 if (!genuine_intel) 2856 return; 2857 2858 if (family != 6) 2859 return; 2860 2861 switch (model) { 2862 case INTEL_FAM6_HASWELL_CORE: /* HSW */ 2863 case INTEL_FAM6_HASWELL_ULT: /* HSW */ 2864 case INTEL_FAM6_HASWELL_GT3E: /* HSW */ 2865 do_gfx_perf_limit_reasons = 1; 2866 case INTEL_FAM6_HASWELL_X: /* HSX */ 2867 do_core_perf_limit_reasons = 1; 2868 do_ring_perf_limit_reasons = 1; 2869 default: 2870 return; 2871 } 2872 } 2873 2874 int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p) 2875 { 2876 unsigned long long msr; 2877 unsigned int dts; 2878 int cpu; 2879 2880 if (!(do_dts || do_ptm)) 2881 return 0; 2882 2883 cpu = t->cpu_id; 2884 2885 /* DTS is per-core, no need to print for each thread */ 2886 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 2887 return 0; 2888 2889 if (cpu_migrate(cpu)) { 2890 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 2891 return -1; 2892 } 2893 2894 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) { 2895 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) 2896 return 0; 2897 2898 dts = (msr >> 16) & 0x7F; 2899 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n", 2900 cpu, msr, tcc_activation_temp - dts); 2901 2902 #ifdef THERM_DEBUG 2903 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr)) 2904 return 0; 2905 2906 dts = (msr >> 16) & 0x7F; 2907 dts2 = (msr >> 8) & 0x7F; 2908 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n", 2909 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2); 2910 #endif 2911 } 2912 2913 2914 if (do_dts) { 2915 unsigned int resolution; 2916 2917 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr)) 2918 return 0; 2919 2920 dts = (msr >> 16) & 0x7F; 2921 resolution = (msr >> 27) & 0xF; 2922 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n", 2923 cpu, msr, tcc_activation_temp - dts, resolution); 2924 2925 #ifdef THERM_DEBUG 2926 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr)) 2927 return 0; 2928 2929 dts = (msr >> 16) & 0x7F; 2930 dts2 = (msr >> 8) & 0x7F; 2931 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n", 2932 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2); 2933 #endif 2934 } 2935 2936 return 0; 2937 } 2938 2939 void print_power_limit_msr(int cpu, unsigned long long msr, char *label) 2940 { 2941 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n", 2942 cpu, label, 2943 ((msr >> 15) & 1) ? "EN" : "DIS", 2944 ((msr >> 0) & 0x7FFF) * rapl_power_units, 2945 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units, 2946 (((msr >> 16) & 1) ? "EN" : "DIS")); 2947 2948 return; 2949 } 2950 2951 int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) 2952 { 2953 unsigned long long msr; 2954 int cpu; 2955 2956 if (!do_rapl) 2957 return 0; 2958 2959 /* RAPL counters are per package, so print only for 1st thread/package */ 2960 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 2961 return 0; 2962 2963 cpu = t->cpu_id; 2964 if (cpu_migrate(cpu)) { 2965 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 2966 return -1; 2967 } 2968 2969 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) 2970 return -1; 2971 2972 if (debug) { 2973 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " 2974 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, 2975 rapl_power_units, rapl_energy_units, rapl_time_units); 2976 } 2977 if (do_rapl & RAPL_PKG_POWER_INFO) { 2978 2979 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) 2980 return -5; 2981 2982 2983 fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n", 2984 cpu, msr, 2985 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units, 2986 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units, 2987 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, 2988 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units); 2989 2990 } 2991 if (do_rapl & RAPL_PKG) { 2992 2993 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr)) 2994 return -9; 2995 2996 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n", 2997 cpu, msr, (msr >> 63) & 1 ? "": "UN"); 2998 2999 print_power_limit_msr(cpu, msr, "PKG Limit #1"); 3000 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n", 3001 cpu, 3002 ((msr >> 47) & 1) ? "EN" : "DIS", 3003 ((msr >> 32) & 0x7FFF) * rapl_power_units, 3004 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units, 3005 ((msr >> 48) & 1) ? "EN" : "DIS"); 3006 } 3007 3008 if (do_rapl & RAPL_DRAM_POWER_INFO) { 3009 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr)) 3010 return -6; 3011 3012 fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n", 3013 cpu, msr, 3014 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units, 3015 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units, 3016 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, 3017 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units); 3018 } 3019 if (do_rapl & RAPL_DRAM) { 3020 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr)) 3021 return -9; 3022 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n", 3023 cpu, msr, (msr >> 31) & 1 ? "": "UN"); 3024 3025 print_power_limit_msr(cpu, msr, "DRAM Limit"); 3026 } 3027 if (do_rapl & RAPL_CORE_POLICY) { 3028 if (debug) { 3029 if (get_msr(cpu, MSR_PP0_POLICY, &msr)) 3030 return -7; 3031 3032 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); 3033 } 3034 } 3035 if (do_rapl & RAPL_CORES_POWER_LIMIT) { 3036 if (debug) { 3037 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) 3038 return -9; 3039 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n", 3040 cpu, msr, (msr >> 31) & 1 ? "": "UN"); 3041 print_power_limit_msr(cpu, msr, "Cores Limit"); 3042 } 3043 } 3044 if (do_rapl & RAPL_GFX) { 3045 if (debug) { 3046 if (get_msr(cpu, MSR_PP1_POLICY, &msr)) 3047 return -8; 3048 3049 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF); 3050 3051 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr)) 3052 return -9; 3053 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n", 3054 cpu, msr, (msr >> 31) & 1 ? "": "UN"); 3055 print_power_limit_msr(cpu, msr, "GFX Limit"); 3056 } 3057 } 3058 return 0; 3059 } 3060 3061 /* 3062 * SNB adds support for additional MSRs: 3063 * 3064 * MSR_PKG_C7_RESIDENCY 0x000003fa 3065 * MSR_CORE_C7_RESIDENCY 0x000003fe 3066 * MSR_PKG_C2_RESIDENCY 0x0000060d 3067 */ 3068 3069 int has_snb_msrs(unsigned int family, unsigned int model) 3070 { 3071 if (!genuine_intel) 3072 return 0; 3073 3074 switch (model) { 3075 case INTEL_FAM6_SANDYBRIDGE: 3076 case INTEL_FAM6_SANDYBRIDGE_X: 3077 case INTEL_FAM6_IVYBRIDGE: /* IVB */ 3078 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ 3079 case INTEL_FAM6_HASWELL_CORE: /* HSW */ 3080 case INTEL_FAM6_HASWELL_X: /* HSW */ 3081 case INTEL_FAM6_HASWELL_ULT: /* HSW */ 3082 case INTEL_FAM6_HASWELL_GT3E: /* HSW */ 3083 case INTEL_FAM6_BROADWELL_CORE: /* BDW */ 3084 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ 3085 case INTEL_FAM6_BROADWELL_X: /* BDX */ 3086 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ 3087 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 3088 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 3089 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 3090 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3091 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 3092 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 3093 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 3094 return 1; 3095 } 3096 return 0; 3097 } 3098 3099 /* 3100 * HSW adds support for additional MSRs: 3101 * 3102 * MSR_PKG_C8_RESIDENCY 0x00000630 3103 * MSR_PKG_C9_RESIDENCY 0x00000631 3104 * MSR_PKG_C10_RESIDENCY 0x00000632 3105 * 3106 * MSR_PKGC8_IRTL 0x00000633 3107 * MSR_PKGC9_IRTL 0x00000634 3108 * MSR_PKGC10_IRTL 0x00000635 3109 * 3110 */ 3111 int has_hsw_msrs(unsigned int family, unsigned int model) 3112 { 3113 if (!genuine_intel) 3114 return 0; 3115 3116 switch (model) { 3117 case INTEL_FAM6_HASWELL_ULT: /* HSW */ 3118 case INTEL_FAM6_BROADWELL_CORE: /* BDW */ 3119 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 3120 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 3121 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 3122 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3123 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 3124 return 1; 3125 } 3126 return 0; 3127 } 3128 3129 /* 3130 * SKL adds support for additional MSRS: 3131 * 3132 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658 3133 * MSR_PKG_ANY_CORE_C0_RES 0x00000659 3134 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A 3135 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B 3136 */ 3137 int has_skl_msrs(unsigned int family, unsigned int model) 3138 { 3139 if (!genuine_intel) 3140 return 0; 3141 3142 switch (model) { 3143 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 3144 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 3145 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 3146 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3147 return 1; 3148 } 3149 return 0; 3150 } 3151 3152 3153 3154 int is_slm(unsigned int family, unsigned int model) 3155 { 3156 if (!genuine_intel) 3157 return 0; 3158 switch (model) { 3159 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ 3160 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ 3161 return 1; 3162 } 3163 return 0; 3164 } 3165 3166 int is_knl(unsigned int family, unsigned int model) 3167 { 3168 if (!genuine_intel) 3169 return 0; 3170 switch (model) { 3171 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ 3172 case INTEL_FAM6_XEON_PHI_KNM: 3173 return 1; 3174 } 3175 return 0; 3176 } 3177 3178 unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model) 3179 { 3180 if (is_knl(family, model)) 3181 return 1024; 3182 return 1; 3183 } 3184 3185 #define SLM_BCLK_FREQS 5 3186 double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0}; 3187 3188 double slm_bclk(void) 3189 { 3190 unsigned long long msr = 3; 3191 unsigned int i; 3192 double freq; 3193 3194 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr)) 3195 fprintf(outf, "SLM BCLK: unknown\n"); 3196 3197 i = msr & 0xf; 3198 if (i >= SLM_BCLK_FREQS) { 3199 fprintf(outf, "SLM BCLK[%d] invalid\n", i); 3200 i = 3; 3201 } 3202 freq = slm_freq_table[i]; 3203 3204 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq); 3205 3206 return freq; 3207 } 3208 3209 double discover_bclk(unsigned int family, unsigned int model) 3210 { 3211 if (has_snb_msrs(family, model) || is_knl(family, model)) 3212 return 100.00; 3213 else if (is_slm(family, model)) 3214 return slm_bclk(); 3215 else 3216 return 133.33; 3217 } 3218 3219 /* 3220 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where 3221 * the Thermal Control Circuit (TCC) activates. 3222 * This is usually equal to tjMax. 3223 * 3224 * Older processors do not have this MSR, so there we guess, 3225 * but also allow cmdline over-ride with -T. 3226 * 3227 * Several MSR temperature values are in units of degrees-C 3228 * below this value, including the Digital Thermal Sensor (DTS), 3229 * Package Thermal Management Sensor (PTM), and thermal event thresholds. 3230 */ 3231 int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p) 3232 { 3233 unsigned long long msr; 3234 unsigned int target_c_local; 3235 int cpu; 3236 3237 /* tcc_activation_temp is used only for dts or ptm */ 3238 if (!(do_dts || do_ptm)) 3239 return 0; 3240 3241 /* this is a per-package concept */ 3242 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 3243 return 0; 3244 3245 cpu = t->cpu_id; 3246 if (cpu_migrate(cpu)) { 3247 fprintf(outf, "Could not migrate to CPU %d\n", cpu); 3248 return -1; 3249 } 3250 3251 if (tcc_activation_temp_override != 0) { 3252 tcc_activation_temp = tcc_activation_temp_override; 3253 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n", 3254 cpu, tcc_activation_temp); 3255 return 0; 3256 } 3257 3258 /* Temperature Target MSR is Nehalem and newer only */ 3259 if (!do_nhm_platform_info) 3260 goto guess; 3261 3262 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr)) 3263 goto guess; 3264 3265 target_c_local = (msr >> 16) & 0xFF; 3266 3267 if (debug) 3268 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", 3269 cpu, msr, target_c_local); 3270 3271 if (!target_c_local) 3272 goto guess; 3273 3274 tcc_activation_temp = target_c_local; 3275 3276 return 0; 3277 3278 guess: 3279 tcc_activation_temp = TJMAX_DEFAULT; 3280 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n", 3281 cpu, tcc_activation_temp); 3282 3283 return 0; 3284 } 3285 3286 void decode_feature_control_msr(void) 3287 { 3288 unsigned long long msr; 3289 3290 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr)) 3291 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n", 3292 base_cpu, msr, 3293 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-", 3294 msr & (1 << 18) ? "SGX" : ""); 3295 } 3296 3297 void decode_misc_enable_msr(void) 3298 { 3299 unsigned long long msr; 3300 3301 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr)) 3302 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%s %s %s)\n", 3303 base_cpu, msr, 3304 msr & (1 << 3) ? "TCC" : "", 3305 msr & (1 << 16) ? "EIST" : "", 3306 msr & (1 << 18) ? "MONITOR" : ""); 3307 } 3308 3309 /* 3310 * Decode MSR_MISC_PWR_MGMT 3311 * 3312 * Decode the bits according to the Nehalem documentation 3313 * bit[0] seems to continue to have same meaning going forward 3314 * bit[1] less so... 3315 */ 3316 void decode_misc_pwr_mgmt_msr(void) 3317 { 3318 unsigned long long msr; 3319 3320 if (!do_nhm_platform_info) 3321 return; 3322 3323 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr)) 3324 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n", 3325 base_cpu, msr, 3326 msr & (1 << 0) ? "DIS" : "EN", 3327 msr & (1 << 1) ? "EN" : "DIS", 3328 msr & (1 << 8) ? "EN" : "DIS"); 3329 } 3330 3331 void process_cpuid() 3332 { 3333 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level; 3334 unsigned int fms, family, model, stepping; 3335 3336 eax = ebx = ecx = edx = 0; 3337 3338 __cpuid(0, max_level, ebx, ecx, edx); 3339 3340 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) 3341 genuine_intel = 1; 3342 3343 if (debug) 3344 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ", 3345 (char *)&ebx, (char *)&edx, (char *)&ecx); 3346 3347 __cpuid(1, fms, ebx, ecx, edx); 3348 family = (fms >> 8) & 0xf; 3349 model = (fms >> 4) & 0xf; 3350 stepping = fms & 0xf; 3351 if (family == 6 || family == 0xf) 3352 model += ((fms >> 16) & 0xf) << 4; 3353 3354 if (debug) { 3355 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", 3356 max_level, family, model, stepping, family, model, stepping); 3357 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n", 3358 ecx & (1 << 0) ? "SSE3" : "-", 3359 ecx & (1 << 3) ? "MONITOR" : "-", 3360 ecx & (1 << 6) ? "SMX" : "-", 3361 ecx & (1 << 7) ? "EIST" : "-", 3362 ecx & (1 << 8) ? "TM2" : "-", 3363 edx & (1 << 4) ? "TSC" : "-", 3364 edx & (1 << 5) ? "MSR" : "-", 3365 edx & (1 << 22) ? "ACPI-TM" : "-", 3366 edx & (1 << 29) ? "TM" : "-"); 3367 } 3368 3369 if (!(edx & (1 << 5))) 3370 errx(1, "CPUID: no MSR"); 3371 3372 /* 3373 * check max extended function levels of CPUID. 3374 * This is needed to check for invariant TSC. 3375 * This check is valid for both Intel and AMD. 3376 */ 3377 ebx = ecx = edx = 0; 3378 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx); 3379 3380 if (max_extended_level >= 0x80000007) { 3381 3382 /* 3383 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 3384 * this check is valid for both Intel and AMD 3385 */ 3386 __cpuid(0x80000007, eax, ebx, ecx, edx); 3387 has_invariant_tsc = edx & (1 << 8); 3388 } 3389 3390 /* 3391 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0 3392 * this check is valid for both Intel and AMD 3393 */ 3394 3395 __cpuid(0x6, eax, ebx, ecx, edx); 3396 has_aperf = ecx & (1 << 0); 3397 do_dts = eax & (1 << 0); 3398 do_ptm = eax & (1 << 6); 3399 has_hwp = eax & (1 << 7); 3400 has_hwp_notify = eax & (1 << 8); 3401 has_hwp_activity_window = eax & (1 << 9); 3402 has_hwp_epp = eax & (1 << 10); 3403 has_hwp_pkg = eax & (1 << 11); 3404 has_epb = ecx & (1 << 3); 3405 3406 if (debug) 3407 fprintf(outf, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sHWP, " 3408 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n", 3409 has_aperf ? "" : "No-", 3410 do_dts ? "" : "No-", 3411 do_ptm ? "" : "No-", 3412 has_hwp ? "" : "No-", 3413 has_hwp_notify ? "" : "No-", 3414 has_hwp_activity_window ? "" : "No-", 3415 has_hwp_epp ? "" : "No-", 3416 has_hwp_pkg ? "" : "No-", 3417 has_epb ? "" : "No-"); 3418 3419 if (debug) 3420 decode_misc_enable_msr(); 3421 3422 if (max_level >= 0x7 && debug) { 3423 int has_sgx; 3424 3425 ecx = 0; 3426 3427 __cpuid_count(0x7, 0, eax, ebx, ecx, edx); 3428 3429 has_sgx = ebx & (1 << 2); 3430 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-"); 3431 3432 if (has_sgx) 3433 decode_feature_control_msr(); 3434 } 3435 3436 if (max_level >= 0x15) { 3437 unsigned int eax_crystal; 3438 unsigned int ebx_tsc; 3439 3440 /* 3441 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz 3442 */ 3443 eax_crystal = ebx_tsc = crystal_hz = edx = 0; 3444 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx); 3445 3446 if (ebx_tsc != 0) { 3447 3448 if (debug && (ebx != 0)) 3449 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n", 3450 eax_crystal, ebx_tsc, crystal_hz); 3451 3452 if (crystal_hz == 0) 3453 switch(model) { 3454 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 3455 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 3456 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 3457 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3458 crystal_hz = 24000000; /* 24.0 MHz */ 3459 break; 3460 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 3461 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 3462 crystal_hz = 25000000; /* 25.0 MHz */ 3463 break; 3464 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 3465 crystal_hz = 19200000; /* 19.2 MHz */ 3466 break; 3467 default: 3468 crystal_hz = 0; 3469 } 3470 3471 if (crystal_hz) { 3472 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal; 3473 if (debug) 3474 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n", 3475 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal); 3476 } 3477 } 3478 } 3479 if (max_level >= 0x16) { 3480 unsigned int base_mhz, max_mhz, bus_mhz, edx; 3481 3482 /* 3483 * CPUID 16H Base MHz, Max MHz, Bus MHz 3484 */ 3485 base_mhz = max_mhz = bus_mhz = edx = 0; 3486 3487 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx); 3488 if (debug) 3489 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n", 3490 base_mhz, max_mhz, bus_mhz); 3491 } 3492 3493 if (has_aperf) 3494 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model); 3495 3496 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model); 3497 do_snb_cstates = has_snb_msrs(family, model); 3498 do_irtl_snb = has_snb_msrs(family, model); 3499 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2); 3500 do_pc3 = (pkg_cstate_limit >= PCL__3); 3501 do_pc6 = (pkg_cstate_limit >= PCL__6); 3502 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7); 3503 do_c8_c9_c10 = has_hsw_msrs(family, model); 3504 do_irtl_hsw = has_hsw_msrs(family, model); 3505 do_skl_residency = has_skl_msrs(family, model); 3506 do_slm_cstates = is_slm(family, model); 3507 do_knl_cstates = is_knl(family, model); 3508 3509 if (debug) 3510 decode_misc_pwr_mgmt_msr(); 3511 3512 rapl_probe(family, model); 3513 perf_limit_reasons_probe(family, model); 3514 3515 if (debug) 3516 dump_cstate_pstate_config_info(family, model); 3517 3518 if (has_skl_msrs(family, model)) 3519 calculate_tsc_tweak(); 3520 3521 do_gfx_rc6_ms = !access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK); 3522 3523 do_gfx_mhz = !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK); 3524 3525 return; 3526 } 3527 3528 void help() 3529 { 3530 fprintf(outf, 3531 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n" 3532 "\n" 3533 "Turbostat forks the specified COMMAND and prints statistics\n" 3534 "when COMMAND completes.\n" 3535 "If no COMMAND is specified, turbostat wakes every 5-seconds\n" 3536 "to print statistics, until interrupted.\n" 3537 "--add add a counter\n" 3538 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n" 3539 "--debug run in \"debug\" mode\n" 3540 "--interval sec Override default 5-second measurement interval\n" 3541 "--help print this help message\n" 3542 "--out file create or truncate \"file\" for all output\n" 3543 "--version print version information\n" 3544 "\n" 3545 "For more help, run \"man turbostat\"\n"); 3546 } 3547 3548 3549 /* 3550 * in /dev/cpu/ return success for names that are numbers 3551 * ie. filter out ".", "..", "microcode". 3552 */ 3553 int dir_filter(const struct dirent *dirp) 3554 { 3555 if (isdigit(dirp->d_name[0])) 3556 return 1; 3557 else 3558 return 0; 3559 } 3560 3561 int open_dev_cpu_msr(int dummy1) 3562 { 3563 return 0; 3564 } 3565 3566 void topology_probe() 3567 { 3568 int i; 3569 int max_core_id = 0; 3570 int max_package_id = 0; 3571 int max_siblings = 0; 3572 struct cpu_topology { 3573 int core_id; 3574 int physical_package_id; 3575 } *cpus; 3576 3577 /* Initialize num_cpus, max_cpu_num */ 3578 topo.num_cpus = 0; 3579 topo.max_cpu_num = 0; 3580 for_all_proc_cpus(count_cpus); 3581 if (!summary_only && topo.num_cpus > 1) 3582 show_cpu = 1; 3583 3584 if (debug > 1) 3585 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num); 3586 3587 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology)); 3588 if (cpus == NULL) 3589 err(1, "calloc cpus"); 3590 3591 /* 3592 * Allocate and initialize cpu_present_set 3593 */ 3594 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1)); 3595 if (cpu_present_set == NULL) 3596 err(3, "CPU_ALLOC"); 3597 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 3598 CPU_ZERO_S(cpu_present_setsize, cpu_present_set); 3599 for_all_proc_cpus(mark_cpu_present); 3600 3601 /* 3602 * Allocate and initialize cpu_affinity_set 3603 */ 3604 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1)); 3605 if (cpu_affinity_set == NULL) 3606 err(3, "CPU_ALLOC"); 3607 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 3608 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); 3609 3610 3611 /* 3612 * For online cpus 3613 * find max_core_id, max_package_id 3614 */ 3615 for (i = 0; i <= topo.max_cpu_num; ++i) { 3616 int siblings; 3617 3618 if (cpu_is_not_present(i)) { 3619 if (debug > 1) 3620 fprintf(outf, "cpu%d NOT PRESENT\n", i); 3621 continue; 3622 } 3623 cpus[i].core_id = get_core_id(i); 3624 if (cpus[i].core_id > max_core_id) 3625 max_core_id = cpus[i].core_id; 3626 3627 cpus[i].physical_package_id = get_physical_package_id(i); 3628 if (cpus[i].physical_package_id > max_package_id) 3629 max_package_id = cpus[i].physical_package_id; 3630 3631 siblings = get_num_ht_siblings(i); 3632 if (siblings > max_siblings) 3633 max_siblings = siblings; 3634 if (debug > 1) 3635 fprintf(outf, "cpu %d pkg %d core %d\n", 3636 i, cpus[i].physical_package_id, cpus[i].core_id); 3637 } 3638 topo.num_cores_per_pkg = max_core_id + 1; 3639 if (debug > 1) 3640 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", 3641 max_core_id, topo.num_cores_per_pkg); 3642 if (debug && !summary_only && topo.num_cores_per_pkg > 1) 3643 show_core = 1; 3644 3645 topo.num_packages = max_package_id + 1; 3646 if (debug > 1) 3647 fprintf(outf, "max_package_id %d, sizing for %d packages\n", 3648 max_package_id, topo.num_packages); 3649 if (debug && !summary_only && topo.num_packages > 1) 3650 show_pkg = 1; 3651 3652 topo.num_threads_per_core = max_siblings; 3653 if (debug > 1) 3654 fprintf(outf, "max_siblings %d\n", max_siblings); 3655 3656 free(cpus); 3657 } 3658 3659 void 3660 allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p) 3661 { 3662 int i; 3663 3664 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg * 3665 topo.num_packages, sizeof(struct thread_data) + sys.thread_counter_bytes); 3666 if (*t == NULL) 3667 goto error; 3668 3669 for (i = 0; i < topo.num_threads_per_core * 3670 topo.num_cores_per_pkg * topo.num_packages; i++) 3671 (*t)[i].cpu_id = -1; 3672 3673 *c = calloc(topo.num_cores_per_pkg * topo.num_packages, 3674 sizeof(struct core_data) + sys.core_counter_bytes); 3675 if (*c == NULL) 3676 goto error; 3677 3678 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++) 3679 (*c)[i].core_id = -1; 3680 3681 *p = calloc(topo.num_packages, sizeof(struct pkg_data) + sys.package_counter_bytes); 3682 if (*p == NULL) 3683 goto error; 3684 3685 for (i = 0; i < topo.num_packages; i++) 3686 (*p)[i].package_id = i; 3687 3688 return; 3689 error: 3690 err(1, "calloc counters"); 3691 } 3692 /* 3693 * init_counter() 3694 * 3695 * set cpu_id, core_num, pkg_num 3696 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE 3697 * 3698 * increment topo.num_cores when 1st core in pkg seen 3699 */ 3700 void init_counter(struct thread_data *thread_base, struct core_data *core_base, 3701 struct pkg_data *pkg_base, int thread_num, int core_num, 3702 int pkg_num, int cpu_id) 3703 { 3704 struct thread_data *t; 3705 struct core_data *c; 3706 struct pkg_data *p; 3707 3708 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num); 3709 c = GET_CORE(core_base, core_num, pkg_num); 3710 p = GET_PKG(pkg_base, pkg_num); 3711 3712 t->cpu_id = cpu_id; 3713 if (thread_num == 0) { 3714 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE; 3715 if (cpu_is_first_core_in_package(cpu_id)) 3716 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE; 3717 } 3718 3719 c->core_id = core_num; 3720 p->package_id = pkg_num; 3721 } 3722 3723 3724 int initialize_counters(int cpu_id) 3725 { 3726 int my_thread_id, my_core_id, my_package_id; 3727 3728 my_package_id = get_physical_package_id(cpu_id); 3729 my_core_id = get_core_id(cpu_id); 3730 my_thread_id = get_cpu_position_in_core(cpu_id); 3731 if (!my_thread_id) 3732 topo.num_cores++; 3733 3734 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id); 3735 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id); 3736 return 0; 3737 } 3738 3739 void allocate_output_buffer() 3740 { 3741 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024); 3742 outp = output_buffer; 3743 if (outp == NULL) 3744 err(-1, "calloc output buffer"); 3745 } 3746 void allocate_fd_percpu(void) 3747 { 3748 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int)); 3749 if (fd_percpu == NULL) 3750 err(-1, "calloc fd_percpu"); 3751 } 3752 void allocate_irq_buffers(void) 3753 { 3754 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int)); 3755 if (irq_column_2_cpu == NULL) 3756 err(-1, "calloc %d", topo.num_cpus); 3757 3758 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int)); 3759 if (irqs_per_cpu == NULL) 3760 err(-1, "calloc %d", topo.max_cpu_num + 1); 3761 } 3762 void setup_all_buffers(void) 3763 { 3764 topology_probe(); 3765 allocate_irq_buffers(); 3766 allocate_fd_percpu(); 3767 allocate_counters(&thread_even, &core_even, &package_even); 3768 allocate_counters(&thread_odd, &core_odd, &package_odd); 3769 allocate_output_buffer(); 3770 for_all_proc_cpus(initialize_counters); 3771 } 3772 3773 void set_base_cpu(void) 3774 { 3775 base_cpu = sched_getcpu(); 3776 if (base_cpu < 0) 3777 err(-ENODEV, "No valid cpus found"); 3778 3779 if (debug > 1) 3780 fprintf(outf, "base_cpu = %d\n", base_cpu); 3781 } 3782 3783 void turbostat_init() 3784 { 3785 setup_all_buffers(); 3786 set_base_cpu(); 3787 check_dev_msr(); 3788 check_permissions(); 3789 process_cpuid(); 3790 3791 3792 if (debug) 3793 for_all_cpus(print_hwp, ODD_COUNTERS); 3794 3795 if (debug) 3796 for_all_cpus(print_epb, ODD_COUNTERS); 3797 3798 if (debug) 3799 for_all_cpus(print_perf_limit, ODD_COUNTERS); 3800 3801 if (debug) 3802 for_all_cpus(print_rapl, ODD_COUNTERS); 3803 3804 for_all_cpus(set_temperature_target, ODD_COUNTERS); 3805 3806 if (debug) 3807 for_all_cpus(print_thermal, ODD_COUNTERS); 3808 3809 if (debug && do_irtl_snb) 3810 print_irtl(); 3811 } 3812 3813 int fork_it(char **argv) 3814 { 3815 pid_t child_pid; 3816 int status; 3817 3818 status = for_all_cpus(get_counters, EVEN_COUNTERS); 3819 if (status) 3820 exit(status); 3821 /* clear affinity side-effect of get_counters() */ 3822 sched_setaffinity(0, cpu_present_setsize, cpu_present_set); 3823 gettimeofday(&tv_even, (struct timezone *)NULL); 3824 3825 child_pid = fork(); 3826 if (!child_pid) { 3827 /* child */ 3828 execvp(argv[0], argv); 3829 } else { 3830 3831 /* parent */ 3832 if (child_pid == -1) 3833 err(1, "fork"); 3834 3835 signal(SIGINT, SIG_IGN); 3836 signal(SIGQUIT, SIG_IGN); 3837 if (waitpid(child_pid, &status, 0) == -1) 3838 err(status, "waitpid"); 3839 } 3840 /* 3841 * n.b. fork_it() does not check for errors from for_all_cpus() 3842 * because re-starting is problematic when forking 3843 */ 3844 for_all_cpus(get_counters, ODD_COUNTERS); 3845 gettimeofday(&tv_odd, (struct timezone *)NULL); 3846 timersub(&tv_odd, &tv_even, &tv_delta); 3847 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) 3848 fprintf(outf, "%s: Counter reset detected\n", progname); 3849 else { 3850 compute_average(EVEN_COUNTERS); 3851 format_all_counters(EVEN_COUNTERS); 3852 } 3853 3854 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); 3855 3856 flush_output_stderr(); 3857 3858 return status; 3859 } 3860 3861 int get_and_dump_counters(void) 3862 { 3863 int status; 3864 3865 status = for_all_cpus(get_counters, ODD_COUNTERS); 3866 if (status) 3867 return status; 3868 3869 status = for_all_cpus(dump_counters, ODD_COUNTERS); 3870 if (status) 3871 return status; 3872 3873 flush_output_stdout(); 3874 3875 return status; 3876 } 3877 3878 void print_version() { 3879 fprintf(outf, "turbostat version 4.16 24 Dec 2016" 3880 " - Len Brown <lenb@kernel.org>\n"); 3881 } 3882 3883 int add_counter(unsigned int msr_num, char *name, unsigned int width, 3884 enum counter_scope scope, enum counter_type type, 3885 enum counter_format format) 3886 { 3887 struct msr_counter *msrp; 3888 3889 msrp = calloc(1, sizeof(struct msr_counter)); 3890 if (msrp == NULL) { 3891 perror("calloc"); 3892 exit(1); 3893 } 3894 3895 msrp->msr_num = msr_num; 3896 strncpy(msrp->name, name, NAME_BYTES); 3897 msrp->width = width; 3898 msrp->type = type; 3899 msrp->format = format; 3900 3901 switch (scope) { 3902 3903 case SCOPE_CPU: 3904 sys.thread_counter_bytes += 64; 3905 msrp->next = sys.tp; 3906 sys.tp = msrp; 3907 sys.thread_counter_bytes += sizeof(unsigned long long); 3908 break; 3909 3910 case SCOPE_CORE: 3911 sys.core_counter_bytes += 64; 3912 msrp->next = sys.cp; 3913 sys.cp = msrp; 3914 sys.core_counter_bytes += sizeof(unsigned long long); 3915 break; 3916 3917 case SCOPE_PACKAGE: 3918 sys.package_counter_bytes += 64; 3919 msrp->next = sys.pp; 3920 sys.pp = msrp; 3921 sys.package_counter_bytes += sizeof(unsigned long long); 3922 break; 3923 } 3924 3925 return 0; 3926 } 3927 3928 void parse_add_command(char *add_command) 3929 { 3930 int msr_num = 0; 3931 char name_buffer[NAME_BYTES]; 3932 int width = 64; 3933 int fail = 0; 3934 enum counter_scope scope = SCOPE_CPU; 3935 enum counter_type type = COUNTER_CYCLES; 3936 enum counter_format format = FORMAT_DELTA; 3937 3938 while (add_command) { 3939 3940 if (sscanf(add_command, "msr0x%x", &msr_num) == 1) 3941 goto next; 3942 3943 if (sscanf(add_command, "msr%d", &msr_num) == 1) 3944 goto next; 3945 3946 if (sscanf(add_command, "u%d", &width) == 1) { 3947 if ((width == 32) || (width == 64)) 3948 goto next; 3949 width = 64; 3950 } 3951 if (!strncmp(add_command, "cpu", strlen("cpu"))) { 3952 scope = SCOPE_CPU; 3953 goto next; 3954 } 3955 if (!strncmp(add_command, "core", strlen("core"))) { 3956 scope = SCOPE_CORE; 3957 goto next; 3958 } 3959 if (!strncmp(add_command, "package", strlen("package"))) { 3960 scope = SCOPE_PACKAGE; 3961 goto next; 3962 } 3963 if (!strncmp(add_command, "cycles", strlen("cycles"))) { 3964 type = COUNTER_CYCLES; 3965 goto next; 3966 } 3967 if (!strncmp(add_command, "seconds", strlen("seconds"))) { 3968 type = COUNTER_SECONDS; 3969 goto next; 3970 } 3971 if (!strncmp(add_command, "raw", strlen("raw"))) { 3972 format = FORMAT_RAW; 3973 goto next; 3974 } 3975 if (!strncmp(add_command, "delta", strlen("delta"))) { 3976 format = FORMAT_DELTA; 3977 goto next; 3978 } 3979 if (!strncmp(add_command, "percent", strlen("percent"))) { 3980 format = FORMAT_PERCENT; 3981 goto next; 3982 } 3983 3984 if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) { /* 18 < NAME_BYTES */ 3985 char *eos; 3986 3987 eos = strchr(name_buffer, ','); 3988 if (eos) 3989 *eos = '\0'; 3990 goto next; 3991 } 3992 3993 next: 3994 add_command = strchr(add_command, ','); 3995 if (add_command) 3996 add_command++; 3997 3998 } 3999 if (msr_num == 0) { 4000 fprintf(stderr, "--add: (msrDDD | msr0xXXX) required\n"); 4001 fail++; 4002 } 4003 4004 /* generate default column header */ 4005 if (*name_buffer == '\0') { 4006 if (format == FORMAT_RAW) { 4007 if (width == 32) 4008 sprintf(name_buffer, "msr%d", msr_num); 4009 else 4010 sprintf(name_buffer, "MSR%d", msr_num); 4011 } else if (format == FORMAT_DELTA) { 4012 if (width == 32) 4013 sprintf(name_buffer, "cnt%d", msr_num); 4014 else 4015 sprintf(name_buffer, "CNT%d", msr_num); 4016 } else if (format == FORMAT_PERCENT) { 4017 if (width == 32) 4018 sprintf(name_buffer, "msr%d%%", msr_num); 4019 else 4020 sprintf(name_buffer, "MSR%d%%", msr_num); 4021 } 4022 } 4023 4024 if (add_counter(msr_num, name_buffer, width, scope, type, format)) 4025 fail++; 4026 4027 if (fail) { 4028 help(); 4029 exit(1); 4030 } 4031 } 4032 void cmdline(int argc, char **argv) 4033 { 4034 int opt; 4035 int option_index = 0; 4036 static struct option long_options[] = { 4037 {"add", required_argument, 0, 'a'}, 4038 {"Dump", no_argument, 0, 'D'}, 4039 {"debug", no_argument, 0, 'd'}, 4040 {"interval", required_argument, 0, 'i'}, 4041 {"help", no_argument, 0, 'h'}, 4042 {"Joules", no_argument, 0, 'J'}, 4043 {"out", required_argument, 0, 'o'}, 4044 {"Package", no_argument, 0, 'p'}, 4045 {"processor", no_argument, 0, 'p'}, 4046 {"Summary", no_argument, 0, 'S'}, 4047 {"TCC", required_argument, 0, 'T'}, 4048 {"version", no_argument, 0, 'v' }, 4049 {0, 0, 0, 0 } 4050 }; 4051 4052 progname = argv[0]; 4053 4054 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v", 4055 long_options, &option_index)) != -1) { 4056 switch (opt) { 4057 case 'a': 4058 parse_add_command(optarg); 4059 break; 4060 case 'D': 4061 dump_only++; 4062 break; 4063 case 'd': 4064 debug++; 4065 break; 4066 case 'h': 4067 default: 4068 help(); 4069 exit(1); 4070 case 'i': 4071 { 4072 double interval = strtod(optarg, NULL); 4073 4074 if (interval < 0.001) { 4075 fprintf(outf, "interval %f seconds is too small\n", 4076 interval); 4077 exit(2); 4078 } 4079 4080 interval_ts.tv_sec = interval; 4081 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000; 4082 } 4083 break; 4084 case 'J': 4085 rapl_joules++; 4086 break; 4087 case 'o': 4088 outf = fopen_or_die(optarg, "w"); 4089 break; 4090 case 'P': 4091 show_pkg_only++; 4092 break; 4093 case 'p': 4094 show_core_only++; 4095 break; 4096 case 'S': 4097 summary_only++; 4098 break; 4099 case 'T': 4100 tcc_activation_temp_override = atoi(optarg); 4101 break; 4102 case 'v': 4103 print_version(); 4104 exit(0); 4105 break; 4106 } 4107 } 4108 } 4109 4110 int main(int argc, char **argv) 4111 { 4112 outf = stderr; 4113 4114 cmdline(argc, argv); 4115 4116 if (debug) 4117 print_version(); 4118 4119 turbostat_init(); 4120 4121 /* dump counters and exit */ 4122 if (dump_only) 4123 return get_and_dump_counters(); 4124 4125 /* 4126 * if any params left, it must be a command to fork 4127 */ 4128 if (argc - optind) 4129 return fork_it(argv + optind); 4130 else 4131 turbostat_loop(); 4132 4133 return 0; 4134 } 4135