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