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