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