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