1 // SPDX-License-Identifier: GPL-2.0-only
3 * turbostat -- show CPU frequency and C-state residency
4 * on modern Intel and AMD processors.
6 * Copyright (c) 2013 Intel Corporation.
7 * Len Brown <len.brown@intel.com>
12 #include INTEL_FAMILY_HEADER
17 #include <sys/types.h>
20 #include <sys/select.h>
21 #include <sys/resource.h>
33 #include <sys/capability.h>
37 char *proc_stat
= "/proc/stat";
40 struct timeval interval_tv
= {5, 0};
41 struct timespec interval_ts
= {5, 0};
42 unsigned int num_iterations
;
46 unsigned int sums_need_wide_columns
;
47 unsigned int rapl_joules
;
48 unsigned int summary_only
;
49 unsigned int list_header_only
;
50 unsigned int dump_only
;
51 unsigned int do_snb_cstates
;
52 unsigned int do_knl_cstates
;
53 unsigned int do_slm_cstates
;
54 unsigned int use_c1_residency_msr
;
55 unsigned int has_aperf
;
57 unsigned int do_irtl_snb
;
58 unsigned int do_irtl_hsw
;
59 unsigned int units
= 1000000; /* MHz etc */
60 unsigned int genuine_intel
;
61 unsigned int authentic_amd
;
62 unsigned int hygon_genuine
;
63 unsigned int max_level
, max_extended_level
;
64 unsigned int has_invariant_tsc
;
65 unsigned int do_nhm_platform_info
;
66 unsigned int no_MSR_MISC_PWR_MGMT
;
67 unsigned int aperf_mperf_multiplier
= 1;
70 unsigned int has_base_hz
;
71 double tsc_tweak
= 1.0;
72 unsigned int show_pkg_only
;
73 unsigned int show_core_only
;
74 char *output_buffer
, *outp
;
78 unsigned long long gfx_cur_rc6_ms
;
79 unsigned long long cpuidle_cur_cpu_lpi_us
;
80 unsigned long long cpuidle_cur_sys_lpi_us
;
81 unsigned int gfx_cur_mhz
;
82 unsigned int gfx_act_mhz
;
83 unsigned int tcc_activation_temp
;
84 unsigned int tcc_activation_temp_override
;
85 double rapl_power_units
, rapl_time_units
;
86 double rapl_dram_energy_units
, rapl_energy_units
;
87 double rapl_joule_counter_range
;
88 unsigned int do_core_perf_limit_reasons
;
89 unsigned int has_automatic_cstate_conversion
;
90 unsigned int do_gfx_perf_limit_reasons
;
91 unsigned int do_ring_perf_limit_reasons
;
92 unsigned int crystal_hz
;
93 unsigned long long tsc_hz
;
95 double discover_bclk(unsigned int family
, unsigned int model
);
96 unsigned int has_hwp
; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
97 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
98 unsigned int has_hwp_notify
; /* IA32_HWP_INTERRUPT */
99 unsigned int has_hwp_activity_window
; /* IA32_HWP_REQUEST[bits 41:32] */
100 unsigned int has_hwp_epp
; /* IA32_HWP_REQUEST[bits 31:24] */
101 unsigned int has_hwp_pkg
; /* IA32_HWP_REQUEST_PKG */
102 unsigned int has_misc_feature_control
;
103 unsigned int first_counter_read
= 1;
106 #define RAPL_PKG (1 << 0)
107 /* 0x610 MSR_PKG_POWER_LIMIT */
108 /* 0x611 MSR_PKG_ENERGY_STATUS */
109 #define RAPL_PKG_PERF_STATUS (1 << 1)
110 /* 0x613 MSR_PKG_PERF_STATUS */
111 #define RAPL_PKG_POWER_INFO (1 << 2)
112 /* 0x614 MSR_PKG_POWER_INFO */
114 #define RAPL_DRAM (1 << 3)
115 /* 0x618 MSR_DRAM_POWER_LIMIT */
116 /* 0x619 MSR_DRAM_ENERGY_STATUS */
117 #define RAPL_DRAM_PERF_STATUS (1 << 4)
118 /* 0x61b MSR_DRAM_PERF_STATUS */
119 #define RAPL_DRAM_POWER_INFO (1 << 5)
120 /* 0x61c MSR_DRAM_POWER_INFO */
122 #define RAPL_CORES_POWER_LIMIT (1 << 6)
123 /* 0x638 MSR_PP0_POWER_LIMIT */
124 #define RAPL_CORE_POLICY (1 << 7)
125 /* 0x63a MSR_PP0_POLICY */
127 #define RAPL_GFX (1 << 8)
128 /* 0x640 MSR_PP1_POWER_LIMIT */
129 /* 0x641 MSR_PP1_ENERGY_STATUS */
130 /* 0x642 MSR_PP1_POLICY */
132 #define RAPL_CORES_ENERGY_STATUS (1 << 9)
133 /* 0x639 MSR_PP0_ENERGY_STATUS */
134 #define RAPL_PER_CORE_ENERGY (1 << 10)
135 /* Indicates cores energy collection is per-core,
136 * not per-package. */
137 #define RAPL_AMD_F17H (1 << 11)
138 /* 0xc0010299 MSR_RAPL_PWR_UNIT */
139 /* 0xc001029a MSR_CORE_ENERGY_STAT */
140 /* 0xc001029b MSR_PKG_ENERGY_STAT */
141 #define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
142 #define TJMAX_DEFAULT 100
144 /* MSRs that are not yet in the kernel-provided header. */
145 #define MSR_RAPL_PWR_UNIT 0xc0010299
146 #define MSR_CORE_ENERGY_STAT 0xc001029a
147 #define MSR_PKG_ENERGY_STAT 0xc001029b
149 #define MAX(a, b) ((a) > (b) ? (a) : (b))
152 * buffer size used by sscanf() for added column names
153 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
155 #define NAME_BYTES 20
156 #define PATH_BYTES 128
161 #define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
162 cpu_set_t
*cpu_present_set
, *cpu_affinity_set
, *cpu_subset
;
163 size_t cpu_present_setsize
, cpu_affinity_setsize
, cpu_subset_size
;
164 #define MAX_ADDED_COUNTERS 8
165 #define MAX_ADDED_THREAD_COUNTERS 24
166 #define BITMASK_SIZE 32
169 struct timeval tv_begin
;
170 struct timeval tv_end
;
171 struct timeval tv_delta
;
172 unsigned long long tsc
;
173 unsigned long long aperf
;
174 unsigned long long mperf
;
175 unsigned long long c1
;
176 unsigned long long irq_count
;
177 unsigned int smi_count
;
179 unsigned int apic_id
;
180 unsigned int x2apic_id
;
182 #define CPU_IS_FIRST_THREAD_IN_CORE 0x2
183 #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
184 unsigned long long counter
[MAX_ADDED_THREAD_COUNTERS
];
185 } *thread_even
, *thread_odd
;
188 unsigned long long c3
;
189 unsigned long long c6
;
190 unsigned long long c7
;
191 unsigned long long mc6_us
; /* duplicate as per-core for now, even though per module */
192 unsigned int core_temp_c
;
193 unsigned int core_energy
; /* MSR_CORE_ENERGY_STAT */
194 unsigned int core_id
;
195 unsigned long long counter
[MAX_ADDED_COUNTERS
];
196 } *core_even
, *core_odd
;
199 unsigned long long pc2
;
200 unsigned long long pc3
;
201 unsigned long long pc6
;
202 unsigned long long pc7
;
203 unsigned long long pc8
;
204 unsigned long long pc9
;
205 unsigned long long pc10
;
206 unsigned long long cpu_lpi
;
207 unsigned long long sys_lpi
;
208 unsigned long long pkg_wtd_core_c0
;
209 unsigned long long pkg_any_core_c0
;
210 unsigned long long pkg_any_gfxe_c0
;
211 unsigned long long pkg_both_core_gfxe_c0
;
212 long long gfx_rc6_ms
;
213 unsigned int gfx_mhz
;
214 unsigned int gfx_act_mhz
;
215 unsigned int package_id
;
216 unsigned long long energy_pkg
; /* MSR_PKG_ENERGY_STATUS */
217 unsigned long long energy_dram
; /* MSR_DRAM_ENERGY_STATUS */
218 unsigned long long energy_cores
; /* MSR_PP0_ENERGY_STATUS */
219 unsigned long long energy_gfx
; /* MSR_PP1_ENERGY_STATUS */
220 unsigned long long rapl_pkg_perf_status
; /* MSR_PKG_PERF_STATUS */
221 unsigned long long rapl_dram_perf_status
; /* MSR_DRAM_PERF_STATUS */
222 unsigned int pkg_temp_c
;
223 unsigned long long counter
[MAX_ADDED_COUNTERS
];
224 } *package_even
, *package_odd
;
226 #define ODD_COUNTERS thread_odd, core_odd, package_odd
227 #define EVEN_COUNTERS thread_even, core_even, package_even
229 #define GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no) \
232 topo.nodes_per_pkg * topo.cores_per_node * topo.threads_per_core) + \
233 ((node_no) * topo.cores_per_node * topo.threads_per_core) + \
234 ((core_no) * topo.threads_per_core) + \
237 #define GET_CORE(core_base, core_no, node_no, pkg_no) \
239 ((pkg_no) * topo.nodes_per_pkg * topo.cores_per_node) + \
240 ((node_no) * topo.cores_per_node) + \
244 #define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
246 enum counter_scope
{SCOPE_CPU
, SCOPE_CORE
, SCOPE_PACKAGE
};
247 enum counter_type
{COUNTER_ITEMS
, COUNTER_CYCLES
, COUNTER_SECONDS
, COUNTER_USEC
};
248 enum counter_format
{FORMAT_RAW
, FORMAT_DELTA
, FORMAT_PERCENT
};
251 unsigned int msr_num
;
252 char name
[NAME_BYTES
];
253 char path
[PATH_BYTES
];
255 enum counter_type type
;
256 enum counter_format format
;
257 struct msr_counter
*next
;
259 #define FLAGS_HIDE (1 << 0)
260 #define FLAGS_SHOW (1 << 1)
261 #define SYSFS_PERCPU (1 << 1)
265 * The accumulated sum of MSR is defined as a monotonic
266 * increasing MSR, it will be accumulated periodically,
267 * despite its register's bit width.
279 int get_msr_sum(int cpu
, off_t offset
, unsigned long long *msr
);
281 struct msr_sum_array
{
282 /* get_msr_sum() = sum + (get_msr() - last) */
284 /*The accumulated MSR value is updated by the timer*/
285 unsigned long long sum
;
286 /*The MSR footprint recorded in last timer*/
287 unsigned long long last
;
288 } entries
[IDX_COUNT
];
291 /* The percpu MSR sum array.*/
292 struct msr_sum_array
*per_cpu_msr_sum
;
294 int idx_to_offset(int idx
)
300 offset
= MSR_PKG_ENERGY_STATUS
;
302 case IDX_DRAM_ENERGY
:
303 offset
= MSR_DRAM_ENERGY_STATUS
;
306 offset
= MSR_PP0_ENERGY_STATUS
;
309 offset
= MSR_PP1_ENERGY_STATUS
;
312 offset
= MSR_PKG_PERF_STATUS
;
315 offset
= MSR_DRAM_PERF_STATUS
;
323 int offset_to_idx(int offset
)
328 case MSR_PKG_ENERGY_STATUS
:
329 idx
= IDX_PKG_ENERGY
;
331 case MSR_DRAM_ENERGY_STATUS
:
332 idx
= IDX_DRAM_ENERGY
;
334 case MSR_PP0_ENERGY_STATUS
:
335 idx
= IDX_PP0_ENERGY
;
337 case MSR_PP1_ENERGY_STATUS
:
338 idx
= IDX_PP1_ENERGY
;
340 case MSR_PKG_PERF_STATUS
:
343 case MSR_DRAM_PERF_STATUS
:
352 int idx_valid(int idx
)
356 return do_rapl
& RAPL_PKG
;
357 case IDX_DRAM_ENERGY
:
358 return do_rapl
& RAPL_DRAM
;
360 return do_rapl
& RAPL_CORES_ENERGY_STATUS
;
362 return do_rapl
& RAPL_GFX
;
364 return do_rapl
& RAPL_PKG_PERF_STATUS
;
366 return do_rapl
& RAPL_DRAM_PERF_STATUS
;
371 struct sys_counters
{
372 unsigned int added_thread_counters
;
373 unsigned int added_core_counters
;
374 unsigned int added_package_counters
;
375 struct msr_counter
*tp
;
376 struct msr_counter
*cp
;
377 struct msr_counter
*pp
;
380 struct system_summary
{
381 struct thread_data threads
;
382 struct core_data cores
;
383 struct pkg_data packages
;
386 struct cpu_topology
{
387 int physical_package_id
;
390 int physical_node_id
;
391 int logical_node_id
; /* 0-based count within the package */
392 int physical_core_id
;
394 cpu_set_t
*put_ids
; /* Processing Unit/Thread IDs */
406 int threads_per_core
;
409 struct timeval tv_even
, tv_odd
, tv_delta
;
411 int *irq_column_2_cpu
; /* /proc/interrupts column numbers */
412 int *irqs_per_cpu
; /* indexed by cpu_num */
414 void setup_all_buffers(void);
417 char *sys_lpi_file_sysfs
= "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us";
418 char *sys_lpi_file_debugfs
= "/sys/kernel/debug/pmc_core/slp_s0_residency_usec";
420 int cpu_is_not_present(int cpu
)
422 return !CPU_ISSET_S(cpu
, cpu_present_setsize
, cpu_present_set
);
425 * run func(thread, core, package) in topology order
426 * skip non-present cpus
429 int for_all_cpus(int (func
)(struct thread_data
*, struct core_data
*, struct pkg_data
*),
430 struct thread_data
*thread_base
, struct core_data
*core_base
, struct pkg_data
*pkg_base
)
432 int retval
, pkg_no
, core_no
, thread_no
, node_no
;
434 for (pkg_no
= 0; pkg_no
< topo
.num_packages
; ++pkg_no
) {
435 for (node_no
= 0; node_no
< topo
.nodes_per_pkg
; node_no
++) {
436 for (core_no
= 0; core_no
< topo
.cores_per_node
; ++core_no
) {
437 for (thread_no
= 0; thread_no
<
438 topo
.threads_per_core
; ++thread_no
) {
439 struct thread_data
*t
;
443 t
= GET_THREAD(thread_base
, thread_no
,
447 if (cpu_is_not_present(t
->cpu_id
))
450 c
= GET_CORE(core_base
, core_no
,
452 p
= GET_PKG(pkg_base
, pkg_no
);
454 retval
= func(t
, c
, p
);
464 int cpu_migrate(int cpu
)
466 CPU_ZERO_S(cpu_affinity_setsize
, cpu_affinity_set
);
467 CPU_SET_S(cpu
, cpu_affinity_setsize
, cpu_affinity_set
);
468 if (sched_setaffinity(0, cpu_affinity_setsize
, cpu_affinity_set
) == -1)
473 int get_msr_fd(int cpu
)
483 sprintf(pathname
, "/dev/cpu/%d/msr", cpu
);
484 fd
= open(pathname
, O_RDONLY
);
486 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname
);
493 int get_msr(int cpu
, off_t offset
, unsigned long long *msr
)
497 retval
= pread(get_msr_fd(cpu
), msr
, sizeof(*msr
), offset
);
499 if (retval
!= sizeof *msr
)
500 err(-1, "cpu%d: msr offset 0x%llx read failed", cpu
, (unsigned long long)offset
);
506 * This list matches the column headers, except
507 * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time
508 * 2. Core and CPU are moved to the end, we can't have strings that contain them
509 * matching on them for --show and --hide.
511 struct msr_counter bic
[] = {
513 { 0x0, "Time_Of_Day_Seconds" },
521 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA
, NULL
},
566 #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
567 #define BIC_USEC (1ULL << 0)
568 #define BIC_TOD (1ULL << 1)
569 #define BIC_Package (1ULL << 2)
570 #define BIC_Node (1ULL << 3)
571 #define BIC_Avg_MHz (1ULL << 4)
572 #define BIC_Busy (1ULL << 5)
573 #define BIC_Bzy_MHz (1ULL << 6)
574 #define BIC_TSC_MHz (1ULL << 7)
575 #define BIC_IRQ (1ULL << 8)
576 #define BIC_SMI (1ULL << 9)
577 #define BIC_sysfs (1ULL << 10)
578 #define BIC_CPU_c1 (1ULL << 11)
579 #define BIC_CPU_c3 (1ULL << 12)
580 #define BIC_CPU_c6 (1ULL << 13)
581 #define BIC_CPU_c7 (1ULL << 14)
582 #define BIC_ThreadC (1ULL << 15)
583 #define BIC_CoreTmp (1ULL << 16)
584 #define BIC_CoreCnt (1ULL << 17)
585 #define BIC_PkgTmp (1ULL << 18)
586 #define BIC_GFX_rc6 (1ULL << 19)
587 #define BIC_GFXMHz (1ULL << 20)
588 #define BIC_Pkgpc2 (1ULL << 21)
589 #define BIC_Pkgpc3 (1ULL << 22)
590 #define BIC_Pkgpc6 (1ULL << 23)
591 #define BIC_Pkgpc7 (1ULL << 24)
592 #define BIC_Pkgpc8 (1ULL << 25)
593 #define BIC_Pkgpc9 (1ULL << 26)
594 #define BIC_Pkgpc10 (1ULL << 27)
595 #define BIC_CPU_LPI (1ULL << 28)
596 #define BIC_SYS_LPI (1ULL << 29)
597 #define BIC_PkgWatt (1ULL << 30)
598 #define BIC_CorWatt (1ULL << 31)
599 #define BIC_GFXWatt (1ULL << 32)
600 #define BIC_PkgCnt (1ULL << 33)
601 #define BIC_RAMWatt (1ULL << 34)
602 #define BIC_PKG__ (1ULL << 35)
603 #define BIC_RAM__ (1ULL << 36)
604 #define BIC_Pkg_J (1ULL << 37)
605 #define BIC_Cor_J (1ULL << 38)
606 #define BIC_GFX_J (1ULL << 39)
607 #define BIC_RAM_J (1ULL << 40)
608 #define BIC_Mod_c6 (1ULL << 41)
609 #define BIC_Totl_c0 (1ULL << 42)
610 #define BIC_Any_c0 (1ULL << 43)
611 #define BIC_GFX_c0 (1ULL << 44)
612 #define BIC_CPUGFX (1ULL << 45)
613 #define BIC_Core (1ULL << 46)
614 #define BIC_CPU (1ULL << 47)
615 #define BIC_APIC (1ULL << 48)
616 #define BIC_X2APIC (1ULL << 49)
617 #define BIC_Die (1ULL << 50)
618 #define BIC_GFXACTMHz (1ULL << 51)
620 #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
622 unsigned long long bic_enabled
= (0xFFFFFFFFFFFFFFFFULL
& ~BIC_DISABLED_BY_DEFAULT
);
623 unsigned long long bic_present
= BIC_USEC
| BIC_TOD
| BIC_sysfs
| BIC_APIC
| BIC_X2APIC
;
625 #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
626 #define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
627 #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
628 #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
629 #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
632 #define MAX_DEFERRED 16
633 char *deferred_skip_names
[MAX_DEFERRED
];
634 int deferred_skip_index
;
637 * HIDE_LIST - hide this list of counters, show the rest [default]
638 * SHOW_LIST - show this list of counters, hide the rest
640 enum show_hide_mode
{ SHOW_LIST
, HIDE_LIST
} global_show_hide_mode
= HIDE_LIST
;
645 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
647 "Turbostat forks the specified COMMAND and prints statistics\n"
648 "when COMMAND completes.\n"
649 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
650 "to print statistics, until interrupted.\n"
651 " -a, --add add a counter\n"
652 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
653 " -c, --cpu cpu-set limit output to summary plus cpu-set:\n"
654 " {core | package | j,k,l..m,n-p }\n"
655 " -d, --debug displays usec, Time_Of_Day_Seconds and more debugging\n"
656 " -D, --Dump displays the raw counter values\n"
657 " -e, --enable [all | column]\n"
658 " shows all or the specified disabled column\n"
659 " -H, --hide [column|column,column,...]\n"
660 " hide the specified column(s)\n"
661 " -i, --interval sec.subsec\n"
662 " Override default 5-second measurement interval\n"
663 " -J, --Joules displays energy in Joules instead of Watts\n"
664 " -l, --list list column headers only\n"
665 " -n, --num_iterations num\n"
666 " number of the measurement iterations\n"
668 " create or truncate \"file\" for all output\n"
669 " -q, --quiet skip decoding system configuration header\n"
670 " -s, --show [column|column,column,...]\n"
671 " show only the specified column(s)\n"
673 " limits output to 1-line system summary per interval\n"
674 " -T, --TCC temperature\n"
675 " sets the Thermal Control Circuit temperature in\n"
677 " -h, --help print this help message\n"
678 " -v, --version print version information\n"
680 "For more help, run \"man turbostat\"\n");
685 * for all the strings in comma separate name_list,
686 * set the approprate bit in return value.
688 unsigned long long bic_lookup(char *name_list
, enum show_hide_mode mode
)
691 unsigned long long retval
= 0;
696 comma
= strchr(name_list
, ',');
701 if (!strcmp(name_list
, "all"))
704 for (i
= 0; i
< MAX_BIC
; ++i
) {
705 if (!strcmp(name_list
, bic
[i
].name
)) {
706 retval
|= (1ULL << i
);
711 if (mode
== SHOW_LIST
) {
712 fprintf(stderr
, "Invalid counter name: %s\n", name_list
);
715 deferred_skip_names
[deferred_skip_index
++] = name_list
;
717 fprintf(stderr
, "deferred \"%s\"\n", name_list
);
718 if (deferred_skip_index
>= MAX_DEFERRED
) {
719 fprintf(stderr
, "More than max %d un-recognized --skip options '%s'\n",
720 MAX_DEFERRED
, name_list
);
735 void print_header(char *delim
)
737 struct msr_counter
*mp
;
740 if (DO_BIC(BIC_USEC
))
741 outp
+= sprintf(outp
, "%susec", (printed
++ ? delim
: ""));
743 outp
+= sprintf(outp
, "%sTime_Of_Day_Seconds", (printed
++ ? delim
: ""));
744 if (DO_BIC(BIC_Package
))
745 outp
+= sprintf(outp
, "%sPackage", (printed
++ ? delim
: ""));
747 outp
+= sprintf(outp
, "%sDie", (printed
++ ? delim
: ""));
748 if (DO_BIC(BIC_Node
))
749 outp
+= sprintf(outp
, "%sNode", (printed
++ ? delim
: ""));
750 if (DO_BIC(BIC_Core
))
751 outp
+= sprintf(outp
, "%sCore", (printed
++ ? delim
: ""));
753 outp
+= sprintf(outp
, "%sCPU", (printed
++ ? delim
: ""));
754 if (DO_BIC(BIC_APIC
))
755 outp
+= sprintf(outp
, "%sAPIC", (printed
++ ? delim
: ""));
756 if (DO_BIC(BIC_X2APIC
))
757 outp
+= sprintf(outp
, "%sX2APIC", (printed
++ ? delim
: ""));
758 if (DO_BIC(BIC_Avg_MHz
))
759 outp
+= sprintf(outp
, "%sAvg_MHz", (printed
++ ? delim
: ""));
760 if (DO_BIC(BIC_Busy
))
761 outp
+= sprintf(outp
, "%sBusy%%", (printed
++ ? delim
: ""));
762 if (DO_BIC(BIC_Bzy_MHz
))
763 outp
+= sprintf(outp
, "%sBzy_MHz", (printed
++ ? delim
: ""));
764 if (DO_BIC(BIC_TSC_MHz
))
765 outp
+= sprintf(outp
, "%sTSC_MHz", (printed
++ ? delim
: ""));
767 if (DO_BIC(BIC_IRQ
)) {
768 if (sums_need_wide_columns
)
769 outp
+= sprintf(outp
, "%s IRQ", (printed
++ ? delim
: ""));
771 outp
+= sprintf(outp
, "%sIRQ", (printed
++ ? delim
: ""));
775 outp
+= sprintf(outp
, "%sSMI", (printed
++ ? delim
: ""));
777 for (mp
= sys
.tp
; mp
; mp
= mp
->next
) {
779 if (mp
->format
== FORMAT_RAW
) {
781 outp
+= sprintf(outp
, "%s%18.18s", (printed
++ ? delim
: ""), mp
->name
);
783 outp
+= sprintf(outp
, "%s%10.10s", (printed
++ ? delim
: ""), mp
->name
);
785 if ((mp
->type
== COUNTER_ITEMS
) && sums_need_wide_columns
)
786 outp
+= sprintf(outp
, "%s%8s", (printed
++ ? delim
: ""), mp
->name
);
788 outp
+= sprintf(outp
, "%s%s", (printed
++ ? delim
: ""), mp
->name
);
792 if (DO_BIC(BIC_CPU_c1
))
793 outp
+= sprintf(outp
, "%sCPU%%c1", (printed
++ ? delim
: ""));
794 if (DO_BIC(BIC_CPU_c3
))
795 outp
+= sprintf(outp
, "%sCPU%%c3", (printed
++ ? delim
: ""));
796 if (DO_BIC(BIC_CPU_c6
))
797 outp
+= sprintf(outp
, "%sCPU%%c6", (printed
++ ? delim
: ""));
798 if (DO_BIC(BIC_CPU_c7
))
799 outp
+= sprintf(outp
, "%sCPU%%c7", (printed
++ ? delim
: ""));
801 if (DO_BIC(BIC_Mod_c6
))
802 outp
+= sprintf(outp
, "%sMod%%c6", (printed
++ ? delim
: ""));
804 if (DO_BIC(BIC_CoreTmp
))
805 outp
+= sprintf(outp
, "%sCoreTmp", (printed
++ ? delim
: ""));
807 if (do_rapl
&& !rapl_joules
) {
808 if (DO_BIC(BIC_CorWatt
) && (do_rapl
& RAPL_PER_CORE_ENERGY
))
809 outp
+= sprintf(outp
, "%sCorWatt", (printed
++ ? delim
: ""));
810 } else if (do_rapl
&& rapl_joules
) {
811 if (DO_BIC(BIC_Cor_J
) && (do_rapl
& RAPL_PER_CORE_ENERGY
))
812 outp
+= sprintf(outp
, "%sCor_J", (printed
++ ? delim
: ""));
815 for (mp
= sys
.cp
; mp
; mp
= mp
->next
) {
816 if (mp
->format
== FORMAT_RAW
) {
818 outp
+= sprintf(outp
, "%s%18.18s", delim
, mp
->name
);
820 outp
+= sprintf(outp
, "%s%10.10s", delim
, mp
->name
);
822 if ((mp
->type
== COUNTER_ITEMS
) && sums_need_wide_columns
)
823 outp
+= sprintf(outp
, "%s%8s", delim
, mp
->name
);
825 outp
+= sprintf(outp
, "%s%s", delim
, mp
->name
);
829 if (DO_BIC(BIC_PkgTmp
))
830 outp
+= sprintf(outp
, "%sPkgTmp", (printed
++ ? delim
: ""));
832 if (DO_BIC(BIC_GFX_rc6
))
833 outp
+= sprintf(outp
, "%sGFX%%rc6", (printed
++ ? delim
: ""));
835 if (DO_BIC(BIC_GFXMHz
))
836 outp
+= sprintf(outp
, "%sGFXMHz", (printed
++ ? delim
: ""));
838 if (DO_BIC(BIC_GFXACTMHz
))
839 outp
+= sprintf(outp
, "%sGFXAMHz", (printed
++ ? delim
: ""));
841 if (DO_BIC(BIC_Totl_c0
))
842 outp
+= sprintf(outp
, "%sTotl%%C0", (printed
++ ? delim
: ""));
843 if (DO_BIC(BIC_Any_c0
))
844 outp
+= sprintf(outp
, "%sAny%%C0", (printed
++ ? delim
: ""));
845 if (DO_BIC(BIC_GFX_c0
))
846 outp
+= sprintf(outp
, "%sGFX%%C0", (printed
++ ? delim
: ""));
847 if (DO_BIC(BIC_CPUGFX
))
848 outp
+= sprintf(outp
, "%sCPUGFX%%", (printed
++ ? delim
: ""));
850 if (DO_BIC(BIC_Pkgpc2
))
851 outp
+= sprintf(outp
, "%sPkg%%pc2", (printed
++ ? delim
: ""));
852 if (DO_BIC(BIC_Pkgpc3
))
853 outp
+= sprintf(outp
, "%sPkg%%pc3", (printed
++ ? delim
: ""));
854 if (DO_BIC(BIC_Pkgpc6
))
855 outp
+= sprintf(outp
, "%sPkg%%pc6", (printed
++ ? delim
: ""));
856 if (DO_BIC(BIC_Pkgpc7
))
857 outp
+= sprintf(outp
, "%sPkg%%pc7", (printed
++ ? delim
: ""));
858 if (DO_BIC(BIC_Pkgpc8
))
859 outp
+= sprintf(outp
, "%sPkg%%pc8", (printed
++ ? delim
: ""));
860 if (DO_BIC(BIC_Pkgpc9
))
861 outp
+= sprintf(outp
, "%sPkg%%pc9", (printed
++ ? delim
: ""));
862 if (DO_BIC(BIC_Pkgpc10
))
863 outp
+= sprintf(outp
, "%sPk%%pc10", (printed
++ ? delim
: ""));
864 if (DO_BIC(BIC_CPU_LPI
))
865 outp
+= sprintf(outp
, "%sCPU%%LPI", (printed
++ ? delim
: ""));
866 if (DO_BIC(BIC_SYS_LPI
))
867 outp
+= sprintf(outp
, "%sSYS%%LPI", (printed
++ ? delim
: ""));
869 if (do_rapl
&& !rapl_joules
) {
870 if (DO_BIC(BIC_PkgWatt
))
871 outp
+= sprintf(outp
, "%sPkgWatt", (printed
++ ? delim
: ""));
872 if (DO_BIC(BIC_CorWatt
) && !(do_rapl
& RAPL_PER_CORE_ENERGY
))
873 outp
+= sprintf(outp
, "%sCorWatt", (printed
++ ? delim
: ""));
874 if (DO_BIC(BIC_GFXWatt
))
875 outp
+= sprintf(outp
, "%sGFXWatt", (printed
++ ? delim
: ""));
876 if (DO_BIC(BIC_RAMWatt
))
877 outp
+= sprintf(outp
, "%sRAMWatt", (printed
++ ? delim
: ""));
878 if (DO_BIC(BIC_PKG__
))
879 outp
+= sprintf(outp
, "%sPKG_%%", (printed
++ ? delim
: ""));
880 if (DO_BIC(BIC_RAM__
))
881 outp
+= sprintf(outp
, "%sRAM_%%", (printed
++ ? delim
: ""));
882 } else if (do_rapl
&& rapl_joules
) {
883 if (DO_BIC(BIC_Pkg_J
))
884 outp
+= sprintf(outp
, "%sPkg_J", (printed
++ ? delim
: ""));
885 if (DO_BIC(BIC_Cor_J
) && !(do_rapl
& RAPL_PER_CORE_ENERGY
))
886 outp
+= sprintf(outp
, "%sCor_J", (printed
++ ? delim
: ""));
887 if (DO_BIC(BIC_GFX_J
))
888 outp
+= sprintf(outp
, "%sGFX_J", (printed
++ ? delim
: ""));
889 if (DO_BIC(BIC_RAM_J
))
890 outp
+= sprintf(outp
, "%sRAM_J", (printed
++ ? delim
: ""));
891 if (DO_BIC(BIC_PKG__
))
892 outp
+= sprintf(outp
, "%sPKG_%%", (printed
++ ? delim
: ""));
893 if (DO_BIC(BIC_RAM__
))
894 outp
+= sprintf(outp
, "%sRAM_%%", (printed
++ ? delim
: ""));
896 for (mp
= sys
.pp
; mp
; mp
= mp
->next
) {
897 if (mp
->format
== FORMAT_RAW
) {
899 outp
+= sprintf(outp
, "%s%18.18s", delim
, mp
->name
);
901 outp
+= sprintf(outp
, "%s%10.10s", delim
, mp
->name
);
903 if ((mp
->type
== COUNTER_ITEMS
) && sums_need_wide_columns
)
904 outp
+= sprintf(outp
, "%s%8s", delim
, mp
->name
);
906 outp
+= sprintf(outp
, "%s%s", delim
, mp
->name
);
910 outp
+= sprintf(outp
, "\n");
913 int dump_counters(struct thread_data
*t
, struct core_data
*c
,
917 struct msr_counter
*mp
;
919 outp
+= sprintf(outp
, "t %p, c %p, p %p\n", t
, c
, p
);
922 outp
+= sprintf(outp
, "CPU: %d flags 0x%x\n",
923 t
->cpu_id
, t
->flags
);
924 outp
+= sprintf(outp
, "TSC: %016llX\n", t
->tsc
);
925 outp
+= sprintf(outp
, "aperf: %016llX\n", t
->aperf
);
926 outp
+= sprintf(outp
, "mperf: %016llX\n", t
->mperf
);
927 outp
+= sprintf(outp
, "c1: %016llX\n", t
->c1
);
930 outp
+= sprintf(outp
, "IRQ: %lld\n", t
->irq_count
);
932 outp
+= sprintf(outp
, "SMI: %d\n", t
->smi_count
);
934 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
) {
935 outp
+= sprintf(outp
, "tADDED [%d] msr0x%x: %08llX\n",
936 i
, mp
->msr_num
, t
->counter
[i
]);
941 outp
+= sprintf(outp
, "core: %d\n", c
->core_id
);
942 outp
+= sprintf(outp
, "c3: %016llX\n", c
->c3
);
943 outp
+= sprintf(outp
, "c6: %016llX\n", c
->c6
);
944 outp
+= sprintf(outp
, "c7: %016llX\n", c
->c7
);
945 outp
+= sprintf(outp
, "DTS: %dC\n", c
->core_temp_c
);
946 outp
+= sprintf(outp
, "Joules: %0X\n", c
->core_energy
);
948 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
) {
949 outp
+= sprintf(outp
, "cADDED [%d] msr0x%x: %08llX\n",
950 i
, mp
->msr_num
, c
->counter
[i
]);
952 outp
+= sprintf(outp
, "mc6_us: %016llX\n", c
->mc6_us
);
956 outp
+= sprintf(outp
, "package: %d\n", p
->package_id
);
958 outp
+= sprintf(outp
, "Weighted cores: %016llX\n", p
->pkg_wtd_core_c0
);
959 outp
+= sprintf(outp
, "Any cores: %016llX\n", p
->pkg_any_core_c0
);
960 outp
+= sprintf(outp
, "Any GFX: %016llX\n", p
->pkg_any_gfxe_c0
);
961 outp
+= sprintf(outp
, "CPU + GFX: %016llX\n", p
->pkg_both_core_gfxe_c0
);
963 outp
+= sprintf(outp
, "pc2: %016llX\n", p
->pc2
);
964 if (DO_BIC(BIC_Pkgpc3
))
965 outp
+= sprintf(outp
, "pc3: %016llX\n", p
->pc3
);
966 if (DO_BIC(BIC_Pkgpc6
))
967 outp
+= sprintf(outp
, "pc6: %016llX\n", p
->pc6
);
968 if (DO_BIC(BIC_Pkgpc7
))
969 outp
+= sprintf(outp
, "pc7: %016llX\n", p
->pc7
);
970 outp
+= sprintf(outp
, "pc8: %016llX\n", p
->pc8
);
971 outp
+= sprintf(outp
, "pc9: %016llX\n", p
->pc9
);
972 outp
+= sprintf(outp
, "pc10: %016llX\n", p
->pc10
);
973 outp
+= sprintf(outp
, "cpu_lpi: %016llX\n", p
->cpu_lpi
);
974 outp
+= sprintf(outp
, "sys_lpi: %016llX\n", p
->sys_lpi
);
975 outp
+= sprintf(outp
, "Joules PKG: %0llX\n", p
->energy_pkg
);
976 outp
+= sprintf(outp
, "Joules COR: %0llX\n", p
->energy_cores
);
977 outp
+= sprintf(outp
, "Joules GFX: %0llX\n", p
->energy_gfx
);
978 outp
+= sprintf(outp
, "Joules RAM: %0llX\n", p
->energy_dram
);
979 outp
+= sprintf(outp
, "Throttle PKG: %0llX\n",
980 p
->rapl_pkg_perf_status
);
981 outp
+= sprintf(outp
, "Throttle RAM: %0llX\n",
982 p
->rapl_dram_perf_status
);
983 outp
+= sprintf(outp
, "PTM: %dC\n", p
->pkg_temp_c
);
985 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
) {
986 outp
+= sprintf(outp
, "pADDED [%d] msr0x%x: %08llX\n",
987 i
, mp
->msr_num
, p
->counter
[i
]);
991 outp
+= sprintf(outp
, "\n");
997 * column formatting convention & formats
999 int format_counters(struct thread_data
*t
, struct core_data
*c
,
1002 double interval_float
, tsc
;
1005 struct msr_counter
*mp
;
1009 /* if showing only 1st thread in core and this isn't one, bail out */
1010 if (show_core_only
&& !(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
))
1013 /* if showing only 1st thread in pkg and this isn't one, bail out */
1014 if (show_pkg_only
&& !(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
1017 /*if not summary line and --cpu is used */
1018 if ((t
!= &average
.threads
) &&
1019 (cpu_subset
&& !CPU_ISSET_S(t
->cpu_id
, cpu_subset_size
, cpu_subset
)))
1022 if (DO_BIC(BIC_USEC
)) {
1023 /* on each row, print how many usec each timestamp took to gather */
1026 timersub(&t
->tv_end
, &t
->tv_begin
, &tv
);
1027 outp
+= sprintf(outp
, "%5ld\t", tv
.tv_sec
* 1000000 + tv
.tv_usec
);
1030 /* Time_Of_Day_Seconds: on each row, print sec.usec last timestamp taken */
1031 if (DO_BIC(BIC_TOD
))
1032 outp
+= sprintf(outp
, "%10ld.%06ld\t", t
->tv_end
.tv_sec
, t
->tv_end
.tv_usec
);
1034 interval_float
= t
->tv_delta
.tv_sec
+ t
->tv_delta
.tv_usec
/1000000.0;
1036 tsc
= t
->tsc
* tsc_tweak
;
1038 /* topo columns, print blanks on 1st (average) line */
1039 if (t
== &average
.threads
) {
1040 if (DO_BIC(BIC_Package
))
1041 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1042 if (DO_BIC(BIC_Die
))
1043 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1044 if (DO_BIC(BIC_Node
))
1045 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1046 if (DO_BIC(BIC_Core
))
1047 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1048 if (DO_BIC(BIC_CPU
))
1049 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1050 if (DO_BIC(BIC_APIC
))
1051 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1052 if (DO_BIC(BIC_X2APIC
))
1053 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1055 if (DO_BIC(BIC_Package
)) {
1057 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), p
->package_id
);
1059 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1061 if (DO_BIC(BIC_Die
)) {
1063 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), cpus
[t
->cpu_id
].die_id
);
1065 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1067 if (DO_BIC(BIC_Node
)) {
1069 outp
+= sprintf(outp
, "%s%d",
1070 (printed
++ ? delim
: ""),
1071 cpus
[t
->cpu_id
].physical_node_id
);
1073 outp
+= sprintf(outp
, "%s-",
1074 (printed
++ ? delim
: ""));
1076 if (DO_BIC(BIC_Core
)) {
1078 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), c
->core_id
);
1080 outp
+= sprintf(outp
, "%s-", (printed
++ ? delim
: ""));
1082 if (DO_BIC(BIC_CPU
))
1083 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), t
->cpu_id
);
1084 if (DO_BIC(BIC_APIC
))
1085 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), t
->apic_id
);
1086 if (DO_BIC(BIC_X2APIC
))
1087 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), t
->x2apic_id
);
1090 if (DO_BIC(BIC_Avg_MHz
))
1091 outp
+= sprintf(outp
, "%s%.0f", (printed
++ ? delim
: ""),
1092 1.0 / units
* t
->aperf
/ interval_float
);
1094 if (DO_BIC(BIC_Busy
))
1095 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * t
->mperf
/tsc
);
1097 if (DO_BIC(BIC_Bzy_MHz
)) {
1099 outp
+= sprintf(outp
, "%s%.0f", (printed
++ ? delim
: ""), base_hz
/ units
* t
->aperf
/ t
->mperf
);
1101 outp
+= sprintf(outp
, "%s%.0f", (printed
++ ? delim
: ""),
1102 tsc
/ units
* t
->aperf
/ t
->mperf
/ interval_float
);
1105 if (DO_BIC(BIC_TSC_MHz
))
1106 outp
+= sprintf(outp
, "%s%.0f", (printed
++ ? delim
: ""), 1.0 * t
->tsc
/units
/interval_float
);
1109 if (DO_BIC(BIC_IRQ
)) {
1110 if (sums_need_wide_columns
)
1111 outp
+= sprintf(outp
, "%s%8lld", (printed
++ ? delim
: ""), t
->irq_count
);
1113 outp
+= sprintf(outp
, "%s%lld", (printed
++ ? delim
: ""), t
->irq_count
);
1117 if (DO_BIC(BIC_SMI
))
1118 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), t
->smi_count
);
1120 /* Added counters */
1121 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
) {
1122 if (mp
->format
== FORMAT_RAW
) {
1123 if (mp
->width
== 32)
1124 outp
+= sprintf(outp
, "%s0x%08x", (printed
++ ? delim
: ""), (unsigned int) t
->counter
[i
]);
1126 outp
+= sprintf(outp
, "%s0x%016llx", (printed
++ ? delim
: ""), t
->counter
[i
]);
1127 } else if (mp
->format
== FORMAT_DELTA
) {
1128 if ((mp
->type
== COUNTER_ITEMS
) && sums_need_wide_columns
)
1129 outp
+= sprintf(outp
, "%s%8lld", (printed
++ ? delim
: ""), t
->counter
[i
]);
1131 outp
+= sprintf(outp
, "%s%lld", (printed
++ ? delim
: ""), t
->counter
[i
]);
1132 } else if (mp
->format
== FORMAT_PERCENT
) {
1133 if (mp
->type
== COUNTER_USEC
)
1134 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), t
->counter
[i
]/interval_float
/10000);
1136 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * t
->counter
[i
]/tsc
);
1141 if (DO_BIC(BIC_CPU_c1
))
1142 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * t
->c1
/tsc
);
1145 /* print per-core data only for 1st thread in core */
1146 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
))
1149 if (DO_BIC(BIC_CPU_c3
))
1150 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * c
->c3
/tsc
);
1151 if (DO_BIC(BIC_CPU_c6
))
1152 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * c
->c6
/tsc
);
1153 if (DO_BIC(BIC_CPU_c7
))
1154 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * c
->c7
/tsc
);
1157 if (DO_BIC(BIC_Mod_c6
))
1158 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * c
->mc6_us
/ tsc
);
1160 if (DO_BIC(BIC_CoreTmp
))
1161 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), c
->core_temp_c
);
1163 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
) {
1164 if (mp
->format
== FORMAT_RAW
) {
1165 if (mp
->width
== 32)
1166 outp
+= sprintf(outp
, "%s0x%08x", (printed
++ ? delim
: ""), (unsigned int) c
->counter
[i
]);
1168 outp
+= sprintf(outp
, "%s0x%016llx", (printed
++ ? delim
: ""), c
->counter
[i
]);
1169 } else if (mp
->format
== FORMAT_DELTA
) {
1170 if ((mp
->type
== COUNTER_ITEMS
) && sums_need_wide_columns
)
1171 outp
+= sprintf(outp
, "%s%8lld", (printed
++ ? delim
: ""), c
->counter
[i
]);
1173 outp
+= sprintf(outp
, "%s%lld", (printed
++ ? delim
: ""), c
->counter
[i
]);
1174 } else if (mp
->format
== FORMAT_PERCENT
) {
1175 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * c
->counter
[i
]/tsc
);
1181 if (DO_BIC(BIC_CorWatt
) && (do_rapl
& RAPL_PER_CORE_ENERGY
))
1182 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), c
->core_energy
* rapl_energy_units
/ interval_float
);
1183 if (DO_BIC(BIC_Cor_J
) && (do_rapl
& RAPL_PER_CORE_ENERGY
))
1184 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), c
->core_energy
* rapl_energy_units
);
1186 /* print per-package data only for 1st core in package */
1187 if (!(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
1191 if (DO_BIC(BIC_PkgTmp
))
1192 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), p
->pkg_temp_c
);
1195 if (DO_BIC(BIC_GFX_rc6
)) {
1196 if (p
->gfx_rc6_ms
== -1) { /* detect GFX counter reset */
1197 outp
+= sprintf(outp
, "%s**.**", (printed
++ ? delim
: ""));
1199 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""),
1200 p
->gfx_rc6_ms
/ 10.0 / interval_float
);
1205 if (DO_BIC(BIC_GFXMHz
))
1206 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), p
->gfx_mhz
);
1209 if (DO_BIC(BIC_GFXACTMHz
))
1210 outp
+= sprintf(outp
, "%s%d", (printed
++ ? delim
: ""), p
->gfx_act_mhz
);
1212 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
1213 if (DO_BIC(BIC_Totl_c0
))
1214 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pkg_wtd_core_c0
/tsc
);
1215 if (DO_BIC(BIC_Any_c0
))
1216 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pkg_any_core_c0
/tsc
);
1217 if (DO_BIC(BIC_GFX_c0
))
1218 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pkg_any_gfxe_c0
/tsc
);
1219 if (DO_BIC(BIC_CPUGFX
))
1220 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pkg_both_core_gfxe_c0
/tsc
);
1222 if (DO_BIC(BIC_Pkgpc2
))
1223 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc2
/tsc
);
1224 if (DO_BIC(BIC_Pkgpc3
))
1225 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc3
/tsc
);
1226 if (DO_BIC(BIC_Pkgpc6
))
1227 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc6
/tsc
);
1228 if (DO_BIC(BIC_Pkgpc7
))
1229 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc7
/tsc
);
1230 if (DO_BIC(BIC_Pkgpc8
))
1231 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc8
/tsc
);
1232 if (DO_BIC(BIC_Pkgpc9
))
1233 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc9
/tsc
);
1234 if (DO_BIC(BIC_Pkgpc10
))
1235 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->pc10
/tsc
);
1237 if (DO_BIC(BIC_CPU_LPI
))
1238 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->cpu_lpi
/ 1000000.0 / interval_float
);
1239 if (DO_BIC(BIC_SYS_LPI
))
1240 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->sys_lpi
/ 1000000.0 / interval_float
);
1242 if (DO_BIC(BIC_PkgWatt
))
1243 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_pkg
* rapl_energy_units
/ interval_float
);
1244 if (DO_BIC(BIC_CorWatt
) && !(do_rapl
& RAPL_PER_CORE_ENERGY
))
1245 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_cores
* rapl_energy_units
/ interval_float
);
1246 if (DO_BIC(BIC_GFXWatt
))
1247 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_gfx
* rapl_energy_units
/ interval_float
);
1248 if (DO_BIC(BIC_RAMWatt
))
1249 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_dram
* rapl_dram_energy_units
/ interval_float
);
1250 if (DO_BIC(BIC_Pkg_J
))
1251 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_pkg
* rapl_energy_units
);
1252 if (DO_BIC(BIC_Cor_J
) && !(do_rapl
& RAPL_PER_CORE_ENERGY
))
1253 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_cores
* rapl_energy_units
);
1254 if (DO_BIC(BIC_GFX_J
))
1255 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_gfx
* rapl_energy_units
);
1256 if (DO_BIC(BIC_RAM_J
))
1257 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), p
->energy_dram
* rapl_dram_energy_units
);
1258 if (DO_BIC(BIC_PKG__
))
1259 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), 100.0 * p
->rapl_pkg_perf_status
* rapl_time_units
/ interval_float
);
1260 if (DO_BIC(BIC_RAM__
))
1261 outp
+= sprintf(outp
, fmt8
, (printed
++ ? delim
: ""), 100.0 * p
->rapl_dram_perf_status
* rapl_time_units
/ interval_float
);
1263 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
) {
1264 if (mp
->format
== FORMAT_RAW
) {
1265 if (mp
->width
== 32)
1266 outp
+= sprintf(outp
, "%s0x%08x", (printed
++ ? delim
: ""), (unsigned int) p
->counter
[i
]);
1268 outp
+= sprintf(outp
, "%s0x%016llx", (printed
++ ? delim
: ""), p
->counter
[i
]);
1269 } else if (mp
->format
== FORMAT_DELTA
) {
1270 if ((mp
->type
== COUNTER_ITEMS
) && sums_need_wide_columns
)
1271 outp
+= sprintf(outp
, "%s%8lld", (printed
++ ? delim
: ""), p
->counter
[i
]);
1273 outp
+= sprintf(outp
, "%s%lld", (printed
++ ? delim
: ""), p
->counter
[i
]);
1274 } else if (mp
->format
== FORMAT_PERCENT
) {
1275 outp
+= sprintf(outp
, "%s%.2f", (printed
++ ? delim
: ""), 100.0 * p
->counter
[i
]/tsc
);
1280 if (*(outp
- 1) != '\n')
1281 outp
+= sprintf(outp
, "\n");
1286 void flush_output_stdout(void)
1295 fputs(output_buffer
, filep
);
1298 outp
= output_buffer
;
1300 void flush_output_stderr(void)
1302 fputs(output_buffer
, outf
);
1304 outp
= output_buffer
;
1306 void format_all_counters(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
1310 if (!printed
|| !summary_only
)
1313 format_counters(&average
.threads
, &average
.cores
, &average
.packages
);
1320 for_all_cpus(format_counters
, t
, c
, p
);
1323 #define DELTA_WRAP32(new, old) \
1324 old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32);
1327 delta_package(struct pkg_data
*new, struct pkg_data
*old
)
1330 struct msr_counter
*mp
;
1333 if (DO_BIC(BIC_Totl_c0
))
1334 old
->pkg_wtd_core_c0
= new->pkg_wtd_core_c0
- old
->pkg_wtd_core_c0
;
1335 if (DO_BIC(BIC_Any_c0
))
1336 old
->pkg_any_core_c0
= new->pkg_any_core_c0
- old
->pkg_any_core_c0
;
1337 if (DO_BIC(BIC_GFX_c0
))
1338 old
->pkg_any_gfxe_c0
= new->pkg_any_gfxe_c0
- old
->pkg_any_gfxe_c0
;
1339 if (DO_BIC(BIC_CPUGFX
))
1340 old
->pkg_both_core_gfxe_c0
= new->pkg_both_core_gfxe_c0
- old
->pkg_both_core_gfxe_c0
;
1342 old
->pc2
= new->pc2
- old
->pc2
;
1343 if (DO_BIC(BIC_Pkgpc3
))
1344 old
->pc3
= new->pc3
- old
->pc3
;
1345 if (DO_BIC(BIC_Pkgpc6
))
1346 old
->pc6
= new->pc6
- old
->pc6
;
1347 if (DO_BIC(BIC_Pkgpc7
))
1348 old
->pc7
= new->pc7
- old
->pc7
;
1349 old
->pc8
= new->pc8
- old
->pc8
;
1350 old
->pc9
= new->pc9
- old
->pc9
;
1351 old
->pc10
= new->pc10
- old
->pc10
;
1352 old
->cpu_lpi
= new->cpu_lpi
- old
->cpu_lpi
;
1353 old
->sys_lpi
= new->sys_lpi
- old
->sys_lpi
;
1354 old
->pkg_temp_c
= new->pkg_temp_c
;
1356 /* flag an error when rc6 counter resets/wraps */
1357 if (old
->gfx_rc6_ms
> new->gfx_rc6_ms
)
1358 old
->gfx_rc6_ms
= -1;
1360 old
->gfx_rc6_ms
= new->gfx_rc6_ms
- old
->gfx_rc6_ms
;
1362 old
->gfx_mhz
= new->gfx_mhz
;
1363 old
->gfx_act_mhz
= new->gfx_act_mhz
;
1365 old
->energy_pkg
= new->energy_pkg
- old
->energy_pkg
;
1366 old
->energy_cores
= new->energy_cores
- old
->energy_cores
;
1367 old
->energy_gfx
= new->energy_gfx
- old
->energy_gfx
;
1368 old
->energy_dram
= new->energy_dram
- old
->energy_dram
;
1369 old
->rapl_pkg_perf_status
= new->rapl_pkg_perf_status
- old
->rapl_pkg_perf_status
;
1370 old
->rapl_dram_perf_status
= new->rapl_dram_perf_status
- old
->rapl_dram_perf_status
;
1372 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
) {
1373 if (mp
->format
== FORMAT_RAW
)
1374 old
->counter
[i
] = new->counter
[i
];
1376 old
->counter
[i
] = new->counter
[i
] - old
->counter
[i
];
1383 delta_core(struct core_data
*new, struct core_data
*old
)
1386 struct msr_counter
*mp
;
1388 old
->c3
= new->c3
- old
->c3
;
1389 old
->c6
= new->c6
- old
->c6
;
1390 old
->c7
= new->c7
- old
->c7
;
1391 old
->core_temp_c
= new->core_temp_c
;
1392 old
->mc6_us
= new->mc6_us
- old
->mc6_us
;
1394 DELTA_WRAP32(new->core_energy
, old
->core_energy
);
1396 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
) {
1397 if (mp
->format
== FORMAT_RAW
)
1398 old
->counter
[i
] = new->counter
[i
];
1400 old
->counter
[i
] = new->counter
[i
] - old
->counter
[i
];
1404 int soft_c1_residency_display(int bic
)
1406 if (!DO_BIC(BIC_CPU_c1
) || use_c1_residency_msr
)
1409 return DO_BIC_READ(bic
);
1416 delta_thread(struct thread_data
*new, struct thread_data
*old
,
1417 struct core_data
*core_delta
)
1420 struct msr_counter
*mp
;
1422 /* we run cpuid just the 1st time, copy the results */
1423 if (DO_BIC(BIC_APIC
))
1424 new->apic_id
= old
->apic_id
;
1425 if (DO_BIC(BIC_X2APIC
))
1426 new->x2apic_id
= old
->x2apic_id
;
1429 * the timestamps from start of measurement interval are in "old"
1430 * the timestamp from end of measurement interval are in "new"
1431 * over-write old w/ new so we can print end of interval values
1434 timersub(&new->tv_begin
, &old
->tv_begin
, &old
->tv_delta
);
1435 old
->tv_begin
= new->tv_begin
;
1436 old
->tv_end
= new->tv_end
;
1438 old
->tsc
= new->tsc
- old
->tsc
;
1440 /* check for TSC < 1 Mcycles over interval */
1441 if (old
->tsc
< (1000 * 1000))
1442 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
1443 "You can disable all c-states by booting with \"idle=poll\"\n"
1444 "or just the deep ones with \"processor.max_cstate=1\"");
1446 old
->c1
= new->c1
- old
->c1
;
1448 if (DO_BIC(BIC_Avg_MHz
) || DO_BIC(BIC_Busy
) || DO_BIC(BIC_Bzy_MHz
) ||
1449 soft_c1_residency_display(BIC_Avg_MHz
)) {
1450 if ((new->aperf
> old
->aperf
) && (new->mperf
> old
->mperf
)) {
1451 old
->aperf
= new->aperf
- old
->aperf
;
1452 old
->mperf
= new->mperf
- old
->mperf
;
1459 if (use_c1_residency_msr
) {
1461 * Some models have a dedicated C1 residency MSR,
1462 * which should be more accurate than the derivation below.
1466 * As counter collection is not atomic,
1467 * it is possible for mperf's non-halted cycles + idle states
1468 * to exceed TSC's all cycles: show c1 = 0% in that case.
1470 if ((old
->mperf
+ core_delta
->c3
+ core_delta
->c6
+ core_delta
->c7
) > (old
->tsc
* tsc_tweak
))
1473 /* normal case, derive c1 */
1474 old
->c1
= (old
->tsc
* tsc_tweak
) - old
->mperf
- core_delta
->c3
1475 - core_delta
->c6
- core_delta
->c7
;
1479 if (old
->mperf
== 0) {
1481 fprintf(outf
, "cpu%d MPERF 0!\n", old
->cpu_id
);
1482 old
->mperf
= 1; /* divide by 0 protection */
1485 if (DO_BIC(BIC_IRQ
))
1486 old
->irq_count
= new->irq_count
- old
->irq_count
;
1488 if (DO_BIC(BIC_SMI
))
1489 old
->smi_count
= new->smi_count
- old
->smi_count
;
1491 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
) {
1492 if (mp
->format
== FORMAT_RAW
)
1493 old
->counter
[i
] = new->counter
[i
];
1495 old
->counter
[i
] = new->counter
[i
] - old
->counter
[i
];
1500 int delta_cpu(struct thread_data
*t
, struct core_data
*c
,
1501 struct pkg_data
*p
, struct thread_data
*t2
,
1502 struct core_data
*c2
, struct pkg_data
*p2
)
1506 /* calculate core delta only for 1st thread in core */
1507 if (t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
)
1510 /* always calculate thread delta */
1511 retval
= delta_thread(t
, t2
, c2
); /* c2 is core delta */
1515 /* calculate package delta only for 1st core in package */
1516 if (t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
)
1517 retval
= delta_package(p
, p2
);
1522 void clear_counters(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
1525 struct msr_counter
*mp
;
1527 t
->tv_begin
.tv_sec
= 0;
1528 t
->tv_begin
.tv_usec
= 0;
1529 t
->tv_end
.tv_sec
= 0;
1530 t
->tv_end
.tv_usec
= 0;
1531 t
->tv_delta
.tv_sec
= 0;
1532 t
->tv_delta
.tv_usec
= 0;
1542 /* tells format_counters to dump all fields from this set */
1543 t
->flags
= CPU_IS_FIRST_THREAD_IN_CORE
| CPU_IS_FIRST_CORE_IN_PACKAGE
;
1552 p
->pkg_wtd_core_c0
= 0;
1553 p
->pkg_any_core_c0
= 0;
1554 p
->pkg_any_gfxe_c0
= 0;
1555 p
->pkg_both_core_gfxe_c0
= 0;
1558 if (DO_BIC(BIC_Pkgpc3
))
1560 if (DO_BIC(BIC_Pkgpc6
))
1562 if (DO_BIC(BIC_Pkgpc7
))
1572 p
->energy_cores
= 0;
1574 p
->rapl_pkg_perf_status
= 0;
1575 p
->rapl_dram_perf_status
= 0;
1581 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
)
1584 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
)
1587 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
)
1590 int sum_counters(struct thread_data
*t
, struct core_data
*c
,
1594 struct msr_counter
*mp
;
1596 /* copy un-changing apic_id's */
1597 if (DO_BIC(BIC_APIC
))
1598 average
.threads
.apic_id
= t
->apic_id
;
1599 if (DO_BIC(BIC_X2APIC
))
1600 average
.threads
.x2apic_id
= t
->x2apic_id
;
1602 /* remember first tv_begin */
1603 if (average
.threads
.tv_begin
.tv_sec
== 0)
1604 average
.threads
.tv_begin
= t
->tv_begin
;
1606 /* remember last tv_end */
1607 average
.threads
.tv_end
= t
->tv_end
;
1609 average
.threads
.tsc
+= t
->tsc
;
1610 average
.threads
.aperf
+= t
->aperf
;
1611 average
.threads
.mperf
+= t
->mperf
;
1612 average
.threads
.c1
+= t
->c1
;
1614 average
.threads
.irq_count
+= t
->irq_count
;
1615 average
.threads
.smi_count
+= t
->smi_count
;
1617 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
) {
1618 if (mp
->format
== FORMAT_RAW
)
1620 average
.threads
.counter
[i
] += t
->counter
[i
];
1623 /* sum per-core values only for 1st thread in core */
1624 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
))
1627 average
.cores
.c3
+= c
->c3
;
1628 average
.cores
.c6
+= c
->c6
;
1629 average
.cores
.c7
+= c
->c7
;
1630 average
.cores
.mc6_us
+= c
->mc6_us
;
1632 average
.cores
.core_temp_c
= MAX(average
.cores
.core_temp_c
, c
->core_temp_c
);
1634 average
.cores
.core_energy
+= c
->core_energy
;
1636 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
) {
1637 if (mp
->format
== FORMAT_RAW
)
1639 average
.cores
.counter
[i
] += c
->counter
[i
];
1642 /* sum per-pkg values only for 1st core in pkg */
1643 if (!(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
1646 if (DO_BIC(BIC_Totl_c0
))
1647 average
.packages
.pkg_wtd_core_c0
+= p
->pkg_wtd_core_c0
;
1648 if (DO_BIC(BIC_Any_c0
))
1649 average
.packages
.pkg_any_core_c0
+= p
->pkg_any_core_c0
;
1650 if (DO_BIC(BIC_GFX_c0
))
1651 average
.packages
.pkg_any_gfxe_c0
+= p
->pkg_any_gfxe_c0
;
1652 if (DO_BIC(BIC_CPUGFX
))
1653 average
.packages
.pkg_both_core_gfxe_c0
+= p
->pkg_both_core_gfxe_c0
;
1655 average
.packages
.pc2
+= p
->pc2
;
1656 if (DO_BIC(BIC_Pkgpc3
))
1657 average
.packages
.pc3
+= p
->pc3
;
1658 if (DO_BIC(BIC_Pkgpc6
))
1659 average
.packages
.pc6
+= p
->pc6
;
1660 if (DO_BIC(BIC_Pkgpc7
))
1661 average
.packages
.pc7
+= p
->pc7
;
1662 average
.packages
.pc8
+= p
->pc8
;
1663 average
.packages
.pc9
+= p
->pc9
;
1664 average
.packages
.pc10
+= p
->pc10
;
1666 average
.packages
.cpu_lpi
= p
->cpu_lpi
;
1667 average
.packages
.sys_lpi
= p
->sys_lpi
;
1669 average
.packages
.energy_pkg
+= p
->energy_pkg
;
1670 average
.packages
.energy_dram
+= p
->energy_dram
;
1671 average
.packages
.energy_cores
+= p
->energy_cores
;
1672 average
.packages
.energy_gfx
+= p
->energy_gfx
;
1674 average
.packages
.gfx_rc6_ms
= p
->gfx_rc6_ms
;
1675 average
.packages
.gfx_mhz
= p
->gfx_mhz
;
1676 average
.packages
.gfx_act_mhz
= p
->gfx_act_mhz
;
1678 average
.packages
.pkg_temp_c
= MAX(average
.packages
.pkg_temp_c
, p
->pkg_temp_c
);
1680 average
.packages
.rapl_pkg_perf_status
+= p
->rapl_pkg_perf_status
;
1681 average
.packages
.rapl_dram_perf_status
+= p
->rapl_dram_perf_status
;
1683 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
) {
1684 if (mp
->format
== FORMAT_RAW
)
1686 average
.packages
.counter
[i
] += p
->counter
[i
];
1691 * sum the counters for all cpus in the system
1692 * compute the weighted average
1694 void compute_average(struct thread_data
*t
, struct core_data
*c
,
1698 struct msr_counter
*mp
;
1700 clear_counters(&average
.threads
, &average
.cores
, &average
.packages
);
1702 for_all_cpus(sum_counters
, t
, c
, p
);
1704 /* Use the global time delta for the average. */
1705 average
.threads
.tv_delta
= tv_delta
;
1707 average
.threads
.tsc
/= topo
.num_cpus
;
1708 average
.threads
.aperf
/= topo
.num_cpus
;
1709 average
.threads
.mperf
/= topo
.num_cpus
;
1710 average
.threads
.c1
/= topo
.num_cpus
;
1712 if (average
.threads
.irq_count
> 9999999)
1713 sums_need_wide_columns
= 1;
1715 average
.cores
.c3
/= topo
.num_cores
;
1716 average
.cores
.c6
/= topo
.num_cores
;
1717 average
.cores
.c7
/= topo
.num_cores
;
1718 average
.cores
.mc6_us
/= topo
.num_cores
;
1720 if (DO_BIC(BIC_Totl_c0
))
1721 average
.packages
.pkg_wtd_core_c0
/= topo
.num_packages
;
1722 if (DO_BIC(BIC_Any_c0
))
1723 average
.packages
.pkg_any_core_c0
/= topo
.num_packages
;
1724 if (DO_BIC(BIC_GFX_c0
))
1725 average
.packages
.pkg_any_gfxe_c0
/= topo
.num_packages
;
1726 if (DO_BIC(BIC_CPUGFX
))
1727 average
.packages
.pkg_both_core_gfxe_c0
/= topo
.num_packages
;
1729 average
.packages
.pc2
/= topo
.num_packages
;
1730 if (DO_BIC(BIC_Pkgpc3
))
1731 average
.packages
.pc3
/= topo
.num_packages
;
1732 if (DO_BIC(BIC_Pkgpc6
))
1733 average
.packages
.pc6
/= topo
.num_packages
;
1734 if (DO_BIC(BIC_Pkgpc7
))
1735 average
.packages
.pc7
/= topo
.num_packages
;
1737 average
.packages
.pc8
/= topo
.num_packages
;
1738 average
.packages
.pc9
/= topo
.num_packages
;
1739 average
.packages
.pc10
/= topo
.num_packages
;
1741 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
) {
1742 if (mp
->format
== FORMAT_RAW
)
1744 if (mp
->type
== COUNTER_ITEMS
) {
1745 if (average
.threads
.counter
[i
] > 9999999)
1746 sums_need_wide_columns
= 1;
1749 average
.threads
.counter
[i
] /= topo
.num_cpus
;
1751 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
) {
1752 if (mp
->format
== FORMAT_RAW
)
1754 if (mp
->type
== COUNTER_ITEMS
) {
1755 if (average
.cores
.counter
[i
] > 9999999)
1756 sums_need_wide_columns
= 1;
1758 average
.cores
.counter
[i
] /= topo
.num_cores
;
1760 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
) {
1761 if (mp
->format
== FORMAT_RAW
)
1763 if (mp
->type
== COUNTER_ITEMS
) {
1764 if (average
.packages
.counter
[i
] > 9999999)
1765 sums_need_wide_columns
= 1;
1767 average
.packages
.counter
[i
] /= topo
.num_packages
;
1771 static unsigned long long rdtsc(void)
1773 unsigned int low
, high
;
1775 asm volatile("rdtsc" : "=a" (low
), "=d" (high
));
1777 return low
| ((unsigned long long)high
) << 32;
1781 * Open a file, and exit on failure
1783 FILE *fopen_or_die(const char *path
, const char *mode
)
1785 FILE *filep
= fopen(path
, mode
);
1788 err(1, "%s: open failed", path
);
1792 * snapshot_sysfs_counter()
1794 * return snapshot of given counter
1796 unsigned long long snapshot_sysfs_counter(char *path
)
1800 unsigned long long counter
;
1802 fp
= fopen_or_die(path
, "r");
1804 retval
= fscanf(fp
, "%lld", &counter
);
1806 err(1, "snapshot_sysfs_counter(%s)", path
);
1813 int get_mp(int cpu
, struct msr_counter
*mp
, unsigned long long *counterp
)
1815 if (mp
->msr_num
!= 0) {
1816 if (get_msr(cpu
, mp
->msr_num
, counterp
))
1819 char path
[128 + PATH_BYTES
];
1821 if (mp
->flags
& SYSFS_PERCPU
) {
1822 sprintf(path
, "/sys/devices/system/cpu/cpu%d/%s",
1825 *counterp
= snapshot_sysfs_counter(path
);
1827 *counterp
= snapshot_sysfs_counter(mp
->path
);
1834 int get_epb(int cpu
)
1836 char path
[128 + PATH_BYTES
];
1840 sprintf(path
, "/sys/devices/system/cpu/cpu%d/power/energy_perf_bias", cpu
);
1842 fp
= fopen_or_die(path
, "r");
1844 ret
= fscanf(fp
, "%d", &epb
);
1846 err(1, "%s(%s)", __func__
, path
);
1853 void get_apic_id(struct thread_data
*t
)
1855 unsigned int eax
, ebx
, ecx
, edx
;
1857 if (DO_BIC(BIC_APIC
)) {
1858 eax
= ebx
= ecx
= edx
= 0;
1859 __cpuid(1, eax
, ebx
, ecx
, edx
);
1861 t
->apic_id
= (ebx
>> 24) & 0xff;
1864 if (!DO_BIC(BIC_X2APIC
))
1867 if (authentic_amd
|| hygon_genuine
) {
1868 unsigned int topology_extensions
;
1870 if (max_extended_level
< 0x8000001e)
1873 eax
= ebx
= ecx
= edx
= 0;
1874 __cpuid(0x80000001, eax
, ebx
, ecx
, edx
);
1875 topology_extensions
= ecx
& (1 << 22);
1877 if (topology_extensions
== 0)
1880 eax
= ebx
= ecx
= edx
= 0;
1881 __cpuid(0x8000001e, eax
, ebx
, ecx
, edx
);
1890 if (max_level
< 0xb)
1894 __cpuid(0xb, eax
, ebx
, ecx
, edx
);
1897 if (debug
&& (t
->apic_id
!= (t
->x2apic_id
& 0xff)))
1898 fprintf(outf
, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n",
1899 t
->cpu_id
, t
->apic_id
, t
->x2apic_id
);
1905 * acquire and record local counters for that cpu
1907 int get_counters(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
1909 int cpu
= t
->cpu_id
;
1910 unsigned long long msr
;
1911 int aperf_mperf_retry_count
= 0;
1912 struct msr_counter
*mp
;
1915 if (cpu_migrate(cpu
)) {
1916 fprintf(outf
, "get_counters: Could not migrate to CPU %d\n", cpu
);
1920 gettimeofday(&t
->tv_begin
, (struct timezone
*)NULL
);
1922 if (first_counter_read
)
1925 t
->tsc
= rdtsc(); /* we are running on local CPU of interest */
1927 if (DO_BIC(BIC_Avg_MHz
) || DO_BIC(BIC_Busy
) || DO_BIC(BIC_Bzy_MHz
) ||
1928 soft_c1_residency_display(BIC_Avg_MHz
)) {
1929 unsigned long long tsc_before
, tsc_between
, tsc_after
, aperf_time
, mperf_time
;
1932 * The TSC, APERF and MPERF must be read together for
1933 * APERF/MPERF and MPERF/TSC to give accurate results.
1935 * Unfortunately, APERF and MPERF are read by
1936 * individual system call, so delays may occur
1937 * between them. If the time to read them
1938 * varies by a large amount, we re-read them.
1942 * This initial dummy APERF read has been seen to
1943 * reduce jitter in the subsequent reads.
1946 if (get_msr(cpu
, MSR_IA32_APERF
, &t
->aperf
))
1949 t
->tsc
= rdtsc(); /* re-read close to APERF */
1951 tsc_before
= t
->tsc
;
1953 if (get_msr(cpu
, MSR_IA32_APERF
, &t
->aperf
))
1956 tsc_between
= rdtsc();
1958 if (get_msr(cpu
, MSR_IA32_MPERF
, &t
->mperf
))
1961 tsc_after
= rdtsc();
1963 aperf_time
= tsc_between
- tsc_before
;
1964 mperf_time
= tsc_after
- tsc_between
;
1967 * If the system call latency to read APERF and MPERF
1968 * differ by more than 2x, then try again.
1970 if ((aperf_time
> (2 * mperf_time
)) || (mperf_time
> (2 * aperf_time
))) {
1971 aperf_mperf_retry_count
++;
1972 if (aperf_mperf_retry_count
< 5)
1975 warnx("cpu%d jitter %lld %lld",
1976 cpu
, aperf_time
, mperf_time
);
1978 aperf_mperf_retry_count
= 0;
1980 t
->aperf
= t
->aperf
* aperf_mperf_multiplier
;
1981 t
->mperf
= t
->mperf
* aperf_mperf_multiplier
;
1984 if (DO_BIC(BIC_IRQ
))
1985 t
->irq_count
= irqs_per_cpu
[cpu
];
1986 if (DO_BIC(BIC_SMI
)) {
1987 if (get_msr(cpu
, MSR_SMI_COUNT
, &msr
))
1989 t
->smi_count
= msr
& 0xFFFFFFFF;
1991 if (DO_BIC(BIC_CPU_c1
) && use_c1_residency_msr
) {
1992 if (get_msr(cpu
, MSR_CORE_C1_RES
, &t
->c1
))
1996 for (i
= 0, mp
= sys
.tp
; mp
; i
++, mp
= mp
->next
) {
1997 if (get_mp(cpu
, mp
, &t
->counter
[i
]))
2001 /* collect core counters only for 1st thread in core */
2002 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
))
2005 if (DO_BIC(BIC_CPU_c3
) || soft_c1_residency_display(BIC_CPU_c3
)) {
2006 if (get_msr(cpu
, MSR_CORE_C3_RESIDENCY
, &c
->c3
))
2010 if ((DO_BIC(BIC_CPU_c6
) || soft_c1_residency_display(BIC_CPU_c6
)) && !do_knl_cstates
) {
2011 if (get_msr(cpu
, MSR_CORE_C6_RESIDENCY
, &c
->c6
))
2013 } else if (do_knl_cstates
|| soft_c1_residency_display(BIC_CPU_c6
)) {
2014 if (get_msr(cpu
, MSR_KNL_CORE_C6_RESIDENCY
, &c
->c6
))
2018 if (DO_BIC(BIC_CPU_c7
) || soft_c1_residency_display(BIC_CPU_c7
))
2019 if (get_msr(cpu
, MSR_CORE_C7_RESIDENCY
, &c
->c7
))
2022 if (DO_BIC(BIC_Mod_c6
))
2023 if (get_msr(cpu
, MSR_MODULE_C6_RES_MS
, &c
->mc6_us
))
2026 if (DO_BIC(BIC_CoreTmp
)) {
2027 if (get_msr(cpu
, MSR_IA32_THERM_STATUS
, &msr
))
2029 c
->core_temp_c
= tcc_activation_temp
- ((msr
>> 16) & 0x7F);
2032 if (do_rapl
& RAPL_AMD_F17H
) {
2033 if (get_msr(cpu
, MSR_CORE_ENERGY_STAT
, &msr
))
2035 c
->core_energy
= msr
& 0xFFFFFFFF;
2038 for (i
= 0, mp
= sys
.cp
; mp
; i
++, mp
= mp
->next
) {
2039 if (get_mp(cpu
, mp
, &c
->counter
[i
]))
2043 /* collect package counters only for 1st core in package */
2044 if (!(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
2047 if (DO_BIC(BIC_Totl_c0
)) {
2048 if (get_msr(cpu
, MSR_PKG_WEIGHTED_CORE_C0_RES
, &p
->pkg_wtd_core_c0
))
2051 if (DO_BIC(BIC_Any_c0
)) {
2052 if (get_msr(cpu
, MSR_PKG_ANY_CORE_C0_RES
, &p
->pkg_any_core_c0
))
2055 if (DO_BIC(BIC_GFX_c0
)) {
2056 if (get_msr(cpu
, MSR_PKG_ANY_GFXE_C0_RES
, &p
->pkg_any_gfxe_c0
))
2059 if (DO_BIC(BIC_CPUGFX
)) {
2060 if (get_msr(cpu
, MSR_PKG_BOTH_CORE_GFXE_C0_RES
, &p
->pkg_both_core_gfxe_c0
))
2063 if (DO_BIC(BIC_Pkgpc3
))
2064 if (get_msr(cpu
, MSR_PKG_C3_RESIDENCY
, &p
->pc3
))
2066 if (DO_BIC(BIC_Pkgpc6
)) {
2067 if (do_slm_cstates
) {
2068 if (get_msr(cpu
, MSR_ATOM_PKG_C6_RESIDENCY
, &p
->pc6
))
2071 if (get_msr(cpu
, MSR_PKG_C6_RESIDENCY
, &p
->pc6
))
2076 if (DO_BIC(BIC_Pkgpc2
))
2077 if (get_msr(cpu
, MSR_PKG_C2_RESIDENCY
, &p
->pc2
))
2079 if (DO_BIC(BIC_Pkgpc7
))
2080 if (get_msr(cpu
, MSR_PKG_C7_RESIDENCY
, &p
->pc7
))
2082 if (DO_BIC(BIC_Pkgpc8
))
2083 if (get_msr(cpu
, MSR_PKG_C8_RESIDENCY
, &p
->pc8
))
2085 if (DO_BIC(BIC_Pkgpc9
))
2086 if (get_msr(cpu
, MSR_PKG_C9_RESIDENCY
, &p
->pc9
))
2088 if (DO_BIC(BIC_Pkgpc10
))
2089 if (get_msr(cpu
, MSR_PKG_C10_RESIDENCY
, &p
->pc10
))
2092 if (DO_BIC(BIC_CPU_LPI
))
2093 p
->cpu_lpi
= cpuidle_cur_cpu_lpi_us
;
2094 if (DO_BIC(BIC_SYS_LPI
))
2095 p
->sys_lpi
= cpuidle_cur_sys_lpi_us
;
2097 if (do_rapl
& RAPL_PKG
) {
2098 if (get_msr_sum(cpu
, MSR_PKG_ENERGY_STATUS
, &msr
))
2100 p
->energy_pkg
= msr
;
2102 if (do_rapl
& RAPL_CORES_ENERGY_STATUS
) {
2103 if (get_msr_sum(cpu
, MSR_PP0_ENERGY_STATUS
, &msr
))
2105 p
->energy_cores
= msr
;
2107 if (do_rapl
& RAPL_DRAM
) {
2108 if (get_msr_sum(cpu
, MSR_DRAM_ENERGY_STATUS
, &msr
))
2110 p
->energy_dram
= msr
;
2112 if (do_rapl
& RAPL_GFX
) {
2113 if (get_msr_sum(cpu
, MSR_PP1_ENERGY_STATUS
, &msr
))
2115 p
->energy_gfx
= msr
;
2117 if (do_rapl
& RAPL_PKG_PERF_STATUS
) {
2118 if (get_msr_sum(cpu
, MSR_PKG_PERF_STATUS
, &msr
))
2120 p
->rapl_pkg_perf_status
= msr
;
2122 if (do_rapl
& RAPL_DRAM_PERF_STATUS
) {
2123 if (get_msr_sum(cpu
, MSR_DRAM_PERF_STATUS
, &msr
))
2125 p
->rapl_dram_perf_status
= msr
;
2127 if (do_rapl
& RAPL_AMD_F17H
) {
2128 if (get_msr_sum(cpu
, MSR_PKG_ENERGY_STAT
, &msr
))
2130 p
->energy_pkg
= msr
;
2132 if (DO_BIC(BIC_PkgTmp
)) {
2133 if (get_msr(cpu
, MSR_IA32_PACKAGE_THERM_STATUS
, &msr
))
2135 p
->pkg_temp_c
= tcc_activation_temp
- ((msr
>> 16) & 0x7F);
2138 if (DO_BIC(BIC_GFX_rc6
))
2139 p
->gfx_rc6_ms
= gfx_cur_rc6_ms
;
2141 if (DO_BIC(BIC_GFXMHz
))
2142 p
->gfx_mhz
= gfx_cur_mhz
;
2144 if (DO_BIC(BIC_GFXACTMHz
))
2145 p
->gfx_act_mhz
= gfx_act_mhz
;
2147 for (i
= 0, mp
= sys
.pp
; mp
; i
++, mp
= mp
->next
) {
2148 if (get_mp(cpu
, mp
, &p
->counter
[i
]))
2152 gettimeofday(&t
->tv_end
, (struct timezone
*)NULL
);
2158 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
2159 * If you change the values, note they are used both in comparisons
2160 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
2163 #define PCLUKN 0 /* Unknown */
2164 #define PCLRSV 1 /* Reserved */
2165 #define PCL__0 2 /* PC0 */
2166 #define PCL__1 3 /* PC1 */
2167 #define PCL__2 4 /* PC2 */
2168 #define PCL__3 5 /* PC3 */
2169 #define PCL__4 6 /* PC4 */
2170 #define PCL__6 7 /* PC6 */
2171 #define PCL_6N 8 /* PC6 No Retention */
2172 #define PCL_6R 9 /* PC6 Retention */
2173 #define PCL__7 10 /* PC7 */
2174 #define PCL_7S 11 /* PC7 Shrink */
2175 #define PCL__8 12 /* PC8 */
2176 #define PCL__9 13 /* PC9 */
2177 #define PCL_10 14 /* PC10 */
2178 #define PCLUNL 15 /* Unlimited */
2180 int pkg_cstate_limit
= PCLUKN
;
2181 char *pkg_cstate_limit_strings
[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
2182 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"};
2184 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
};
2185 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
};
2186 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
};
2187 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
, PCL__6
, PCL__7
};
2188 int amt_pkg_cstate_limits
[16] = {PCLUNL
, PCL__1
, PCL__2
, PCLRSV
, PCLRSV
, PCLRSV
, PCL__6
, PCL__7
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
};
2189 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
};
2190 int glm_pkg_cstate_limits
[16] = {PCLUNL
, PCL__1
, PCL__3
, PCL__6
, PCL__7
, PCL_7S
, PCL__8
, PCL__9
, PCL_10
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
};
2191 int skx_pkg_cstate_limits
[16] = {PCL__0
, PCL__2
, PCL_6N
, PCL_6R
, PCLRSV
, PCLRSV
, PCLRSV
, PCLUNL
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
, PCLRSV
};
2195 calculate_tsc_tweak()
2197 tsc_tweak
= base_hz
/ tsc_hz
;
2201 dump_nhm_platform_info(void)
2203 unsigned long long msr
;
2206 get_msr(base_cpu
, MSR_PLATFORM_INFO
, &msr
);
2208 fprintf(outf
, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu
, msr
);
2210 ratio
= (msr
>> 40) & 0xFF;
2211 fprintf(outf
, "%d * %.1f = %.1f MHz max efficiency frequency\n",
2212 ratio
, bclk
, ratio
* bclk
);
2214 ratio
= (msr
>> 8) & 0xFF;
2215 fprintf(outf
, "%d * %.1f = %.1f MHz base frequency\n",
2216 ratio
, bclk
, ratio
* bclk
);
2218 get_msr(base_cpu
, MSR_IA32_POWER_CTL
, &msr
);
2219 fprintf(outf
, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
2220 base_cpu
, msr
, msr
& 0x2 ? "EN" : "DIS");
2226 dump_hsw_turbo_ratio_limits(void)
2228 unsigned long long msr
;
2231 get_msr(base_cpu
, MSR_TURBO_RATIO_LIMIT2
, &msr
);
2233 fprintf(outf
, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu
, msr
);
2235 ratio
= (msr
>> 8) & 0xFF;
2237 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 18 active cores\n",
2238 ratio
, bclk
, ratio
* bclk
);
2240 ratio
= (msr
>> 0) & 0xFF;
2242 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 17 active cores\n",
2243 ratio
, bclk
, ratio
* bclk
);
2248 dump_ivt_turbo_ratio_limits(void)
2250 unsigned long long msr
;
2253 get_msr(base_cpu
, MSR_TURBO_RATIO_LIMIT1
, &msr
);
2255 fprintf(outf
, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu
, msr
);
2257 ratio
= (msr
>> 56) & 0xFF;
2259 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 16 active cores\n",
2260 ratio
, bclk
, ratio
* bclk
);
2262 ratio
= (msr
>> 48) & 0xFF;
2264 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 15 active cores\n",
2265 ratio
, bclk
, ratio
* bclk
);
2267 ratio
= (msr
>> 40) & 0xFF;
2269 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 14 active cores\n",
2270 ratio
, bclk
, ratio
* bclk
);
2272 ratio
= (msr
>> 32) & 0xFF;
2274 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 13 active cores\n",
2275 ratio
, bclk
, ratio
* bclk
);
2277 ratio
= (msr
>> 24) & 0xFF;
2279 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 12 active cores\n",
2280 ratio
, bclk
, ratio
* bclk
);
2282 ratio
= (msr
>> 16) & 0xFF;
2284 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 11 active cores\n",
2285 ratio
, bclk
, ratio
* bclk
);
2287 ratio
= (msr
>> 8) & 0xFF;
2289 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 10 active cores\n",
2290 ratio
, bclk
, ratio
* bclk
);
2292 ratio
= (msr
>> 0) & 0xFF;
2294 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 9 active cores\n",
2295 ratio
, bclk
, ratio
* bclk
);
2298 int has_turbo_ratio_group_limits(int family
, int model
)
2305 case INTEL_FAM6_ATOM_GOLDMONT
:
2306 case INTEL_FAM6_SKYLAKE_X
:
2307 case INTEL_FAM6_ATOM_GOLDMONT_D
:
2308 case INTEL_FAM6_ATOM_TREMONT_D
:
2315 dump_turbo_ratio_limits(int family
, int model
)
2317 unsigned long long msr
, core_counts
;
2318 unsigned int ratio
, group_size
;
2320 get_msr(base_cpu
, MSR_TURBO_RATIO_LIMIT
, &msr
);
2321 fprintf(outf
, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu
, msr
);
2323 if (has_turbo_ratio_group_limits(family
, model
)) {
2324 get_msr(base_cpu
, MSR_TURBO_RATIO_LIMIT1
, &core_counts
);
2325 fprintf(outf
, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu
, core_counts
);
2327 core_counts
= 0x0807060504030201;
2330 ratio
= (msr
>> 56) & 0xFF;
2331 group_size
= (core_counts
>> 56) & 0xFF;
2333 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2334 ratio
, bclk
, ratio
* bclk
, group_size
);
2336 ratio
= (msr
>> 48) & 0xFF;
2337 group_size
= (core_counts
>> 48) & 0xFF;
2339 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2340 ratio
, bclk
, ratio
* bclk
, group_size
);
2342 ratio
= (msr
>> 40) & 0xFF;
2343 group_size
= (core_counts
>> 40) & 0xFF;
2345 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2346 ratio
, bclk
, ratio
* bclk
, group_size
);
2348 ratio
= (msr
>> 32) & 0xFF;
2349 group_size
= (core_counts
>> 32) & 0xFF;
2351 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2352 ratio
, bclk
, ratio
* bclk
, group_size
);
2354 ratio
= (msr
>> 24) & 0xFF;
2355 group_size
= (core_counts
>> 24) & 0xFF;
2357 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2358 ratio
, bclk
, ratio
* bclk
, group_size
);
2360 ratio
= (msr
>> 16) & 0xFF;
2361 group_size
= (core_counts
>> 16) & 0xFF;
2363 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2364 ratio
, bclk
, ratio
* bclk
, group_size
);
2366 ratio
= (msr
>> 8) & 0xFF;
2367 group_size
= (core_counts
>> 8) & 0xFF;
2369 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2370 ratio
, bclk
, ratio
* bclk
, group_size
);
2372 ratio
= (msr
>> 0) & 0xFF;
2373 group_size
= (core_counts
>> 0) & 0xFF;
2375 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2376 ratio
, bclk
, ratio
* bclk
, group_size
);
2381 dump_atom_turbo_ratio_limits(void)
2383 unsigned long long msr
;
2386 get_msr(base_cpu
, MSR_ATOM_CORE_RATIOS
, &msr
);
2387 fprintf(outf
, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu
, msr
& 0xFFFFFFFF);
2389 ratio
= (msr
>> 0) & 0x3F;
2391 fprintf(outf
, "%d * %.1f = %.1f MHz minimum operating frequency\n",
2392 ratio
, bclk
, ratio
* bclk
);
2394 ratio
= (msr
>> 8) & 0x3F;
2396 fprintf(outf
, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n",
2397 ratio
, bclk
, ratio
* bclk
);
2399 ratio
= (msr
>> 16) & 0x3F;
2401 fprintf(outf
, "%d * %.1f = %.1f MHz base frequency\n",
2402 ratio
, bclk
, ratio
* bclk
);
2404 get_msr(base_cpu
, MSR_ATOM_CORE_TURBO_RATIOS
, &msr
);
2405 fprintf(outf
, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu
, msr
& 0xFFFFFFFF);
2407 ratio
= (msr
>> 24) & 0x3F;
2409 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 4 active cores\n",
2410 ratio
, bclk
, ratio
* bclk
);
2412 ratio
= (msr
>> 16) & 0x3F;
2414 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 3 active cores\n",
2415 ratio
, bclk
, ratio
* bclk
);
2417 ratio
= (msr
>> 8) & 0x3F;
2419 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 2 active cores\n",
2420 ratio
, bclk
, ratio
* bclk
);
2422 ratio
= (msr
>> 0) & 0x3F;
2424 fprintf(outf
, "%d * %.1f = %.1f MHz max turbo 1 active core\n",
2425 ratio
, bclk
, ratio
* bclk
);
2429 dump_knl_turbo_ratio_limits(void)
2431 const unsigned int buckets_no
= 7;
2433 unsigned long long msr
;
2434 int delta_cores
, delta_ratio
;
2436 unsigned int cores
[buckets_no
];
2437 unsigned int ratio
[buckets_no
];
2439 get_msr(base_cpu
, MSR_TURBO_RATIO_LIMIT
, &msr
);
2441 fprintf(outf
, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
2445 * Turbo encoding in KNL is as follows:
2447 * [7:1] -- Base value of number of active cores of bucket 1.
2448 * [15:8] -- Base value of freq ratio of bucket 1.
2449 * [20:16] -- +ve delta of number of active cores of bucket 2.
2450 * i.e. active cores of bucket 2 =
2451 * active cores of bucket 1 + delta
2452 * [23:21] -- Negative delta of freq ratio of bucket 2.
2453 * i.e. freq ratio of bucket 2 =
2454 * freq ratio of bucket 1 - delta
2455 * [28:24]-- +ve delta of number of active cores of bucket 3.
2456 * [31:29]-- -ve delta of freq ratio of bucket 3.
2457 * [36:32]-- +ve delta of number of active cores of bucket 4.
2458 * [39:37]-- -ve delta of freq ratio of bucket 4.
2459 * [44:40]-- +ve delta of number of active cores of bucket 5.
2460 * [47:45]-- -ve delta of freq ratio of bucket 5.
2461 * [52:48]-- +ve delta of number of active cores of bucket 6.
2462 * [55:53]-- -ve delta of freq ratio of bucket 6.
2463 * [60:56]-- +ve delta of number of active cores of bucket 7.
2464 * [63:61]-- -ve delta of freq ratio of bucket 7.
2468 cores
[b_nr
] = (msr
& 0xFF) >> 1;
2469 ratio
[b_nr
] = (msr
>> 8) & 0xFF;
2471 for (i
= 16; i
< 64; i
+= 8) {
2472 delta_cores
= (msr
>> i
) & 0x1F;
2473 delta_ratio
= (msr
>> (i
+ 5)) & 0x7;
2475 cores
[b_nr
+ 1] = cores
[b_nr
] + delta_cores
;
2476 ratio
[b_nr
+ 1] = ratio
[b_nr
] - delta_ratio
;
2480 for (i
= buckets_no
- 1; i
>= 0; i
--)
2481 if (i
> 0 ? ratio
[i
] != ratio
[i
- 1] : 1)
2483 "%d * %.1f = %.1f MHz max turbo %d active cores\n",
2484 ratio
[i
], bclk
, ratio
[i
] * bclk
, cores
[i
]);
2488 dump_nhm_cst_cfg(void)
2490 unsigned long long msr
;
2492 get_msr(base_cpu
, MSR_PKG_CST_CONFIG_CONTROL
, &msr
);
2494 fprintf(outf
, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu
, msr
);
2496 fprintf(outf
, " (%s%s%s%s%slocked, pkg-cstate-limit=%d (%s)",
2497 (msr
& SNB_C3_AUTO_UNDEMOTE
) ? "UNdemote-C3, " : "",
2498 (msr
& SNB_C1_AUTO_UNDEMOTE
) ? "UNdemote-C1, " : "",
2499 (msr
& NHM_C3_AUTO_DEMOTE
) ? "demote-C3, " : "",
2500 (msr
& NHM_C1_AUTO_DEMOTE
) ? "demote-C1, " : "",
2501 (msr
& (1 << 15)) ? "" : "UN",
2502 (unsigned int)msr
& 0xF,
2503 pkg_cstate_limit_strings
[pkg_cstate_limit
]);
2505 #define AUTOMATIC_CSTATE_CONVERSION (1UL << 16)
2506 if (has_automatic_cstate_conversion
) {
2507 fprintf(outf
, ", automatic c-state conversion=%s",
2508 (msr
& AUTOMATIC_CSTATE_CONVERSION
) ? "on" : "off");
2511 fprintf(outf
, ")\n");
2517 dump_config_tdp(void)
2519 unsigned long long msr
;
2521 get_msr(base_cpu
, MSR_CONFIG_TDP_NOMINAL
, &msr
);
2522 fprintf(outf
, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu
, msr
);
2523 fprintf(outf
, " (base_ratio=%d)\n", (unsigned int)msr
& 0xFF);
2525 get_msr(base_cpu
, MSR_CONFIG_TDP_LEVEL_1
, &msr
);
2526 fprintf(outf
, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu
, msr
);
2528 fprintf(outf
, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr
>> 48) & 0x7FFF);
2529 fprintf(outf
, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr
>> 32) & 0x7FFF);
2530 fprintf(outf
, "LVL1_RATIO=%d ", (unsigned int)(msr
>> 16) & 0xFF);
2531 fprintf(outf
, "PKG_TDP_LVL1=%d", (unsigned int)(msr
) & 0x7FFF);
2533 fprintf(outf
, ")\n");
2535 get_msr(base_cpu
, MSR_CONFIG_TDP_LEVEL_2
, &msr
);
2536 fprintf(outf
, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu
, msr
);
2538 fprintf(outf
, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr
>> 48) & 0x7FFF);
2539 fprintf(outf
, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr
>> 32) & 0x7FFF);
2540 fprintf(outf
, "LVL2_RATIO=%d ", (unsigned int)(msr
>> 16) & 0xFF);
2541 fprintf(outf
, "PKG_TDP_LVL2=%d", (unsigned int)(msr
) & 0x7FFF);
2543 fprintf(outf
, ")\n");
2545 get_msr(base_cpu
, MSR_CONFIG_TDP_CONTROL
, &msr
);
2546 fprintf(outf
, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu
, msr
);
2548 fprintf(outf
, "TDP_LEVEL=%d ", (unsigned int)(msr
) & 0x3);
2549 fprintf(outf
, " lock=%d", (unsigned int)(msr
>> 31) & 1);
2550 fprintf(outf
, ")\n");
2552 get_msr(base_cpu
, MSR_TURBO_ACTIVATION_RATIO
, &msr
);
2553 fprintf(outf
, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu
, msr
);
2554 fprintf(outf
, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr
) & 0xFF);
2555 fprintf(outf
, " lock=%d", (unsigned int)(msr
>> 31) & 1);
2556 fprintf(outf
, ")\n");
2559 unsigned int irtl_time_units
[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
2561 void print_irtl(void)
2563 unsigned long long msr
;
2565 get_msr(base_cpu
, MSR_PKGC3_IRTL
, &msr
);
2566 fprintf(outf
, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu
, msr
);
2567 fprintf(outf
, "%svalid, %lld ns)\n", msr
& (1 << 15) ? "" : "NOT",
2568 (msr
& 0x3FF) * irtl_time_units
[(msr
>> 10) & 0x3]);
2570 get_msr(base_cpu
, MSR_PKGC6_IRTL
, &msr
);
2571 fprintf(outf
, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu
, msr
);
2572 fprintf(outf
, "%svalid, %lld ns)\n", msr
& (1 << 15) ? "" : "NOT",
2573 (msr
& 0x3FF) * irtl_time_units
[(msr
>> 10) & 0x3]);
2575 get_msr(base_cpu
, MSR_PKGC7_IRTL
, &msr
);
2576 fprintf(outf
, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu
, msr
);
2577 fprintf(outf
, "%svalid, %lld ns)\n", msr
& (1 << 15) ? "" : "NOT",
2578 (msr
& 0x3FF) * irtl_time_units
[(msr
>> 10) & 0x3]);
2583 get_msr(base_cpu
, MSR_PKGC8_IRTL
, &msr
);
2584 fprintf(outf
, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu
, msr
);
2585 fprintf(outf
, "%svalid, %lld ns)\n", msr
& (1 << 15) ? "" : "NOT",
2586 (msr
& 0x3FF) * irtl_time_units
[(msr
>> 10) & 0x3]);
2588 get_msr(base_cpu
, MSR_PKGC9_IRTL
, &msr
);
2589 fprintf(outf
, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu
, msr
);
2590 fprintf(outf
, "%svalid, %lld ns)\n", msr
& (1 << 15) ? "" : "NOT",
2591 (msr
& 0x3FF) * irtl_time_units
[(msr
>> 10) & 0x3]);
2593 get_msr(base_cpu
, MSR_PKGC10_IRTL
, &msr
);
2594 fprintf(outf
, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu
, msr
);
2595 fprintf(outf
, "%svalid, %lld ns)\n", msr
& (1 << 15) ? "" : "NOT",
2596 (msr
& 0x3FF) * irtl_time_units
[(msr
>> 10) & 0x3]);
2599 void free_fd_percpu(void)
2603 for (i
= 0; i
< topo
.max_cpu_num
+ 1; ++i
) {
2604 if (fd_percpu
[i
] != 0)
2605 close(fd_percpu
[i
]);
2611 void free_all_buffers(void)
2615 CPU_FREE(cpu_present_set
);
2616 cpu_present_set
= NULL
;
2617 cpu_present_setsize
= 0;
2619 CPU_FREE(cpu_affinity_set
);
2620 cpu_affinity_set
= NULL
;
2621 cpu_affinity_setsize
= 0;
2629 package_even
= NULL
;
2639 free(output_buffer
);
2640 output_buffer
= NULL
;
2645 free(irq_column_2_cpu
);
2648 for (i
= 0; i
<= topo
.max_cpu_num
; ++i
) {
2649 if (cpus
[i
].put_ids
)
2650 CPU_FREE(cpus
[i
].put_ids
);
2657 * Parse a file containing a single int.
2658 * Return 0 if file can not be opened
2659 * Exit if file can be opened, but can not be parsed
2661 int parse_int_file(const char *fmt
, ...)
2664 char path
[PATH_MAX
];
2668 va_start(args
, fmt
);
2669 vsnprintf(path
, sizeof(path
), fmt
, args
);
2671 filep
= fopen(path
, "r");
2674 if (fscanf(filep
, "%d", &value
) != 1)
2675 err(1, "%s: failed to parse number from file", path
);
2681 * cpu_is_first_core_in_package(cpu)
2682 * return 1 if given CPU is 1st core in package
2684 int cpu_is_first_core_in_package(int cpu
)
2686 return cpu
== parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu
);
2689 int get_physical_package_id(int cpu
)
2691 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu
);
2694 int get_die_id(int cpu
)
2696 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/die_id", cpu
);
2699 int get_core_id(int cpu
)
2701 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu
);
2704 void set_node_data(void)
2706 int pkg
, node
, lnode
, cpu
, cpux
;
2709 /* initialize logical_node_id */
2710 for (cpu
= 0; cpu
<= topo
.max_cpu_num
; ++cpu
)
2711 cpus
[cpu
].logical_node_id
= -1;
2714 for (pkg
= 0; pkg
< topo
.num_packages
; pkg
++) {
2716 for (cpu
= 0; cpu
<= topo
.max_cpu_num
; ++cpu
) {
2717 if (cpus
[cpu
].physical_package_id
!= pkg
)
2719 /* find a cpu with an unset logical_node_id */
2720 if (cpus
[cpu
].logical_node_id
!= -1)
2722 cpus
[cpu
].logical_node_id
= lnode
;
2723 node
= cpus
[cpu
].physical_node_id
;
2726 * find all matching cpus on this pkg and set
2727 * the logical_node_id
2729 for (cpux
= cpu
; cpux
<= topo
.max_cpu_num
; cpux
++) {
2730 if ((cpus
[cpux
].physical_package_id
== pkg
) &&
2731 (cpus
[cpux
].physical_node_id
== node
)) {
2732 cpus
[cpux
].logical_node_id
= lnode
;
2737 if (lnode
> topo
.nodes_per_pkg
)
2738 topo
.nodes_per_pkg
= lnode
;
2740 if (cpu_count
>= topo
.max_cpu_num
)
2745 int get_physical_node_id(struct cpu_topology
*thiscpu
)
2750 int cpu
= thiscpu
->logical_cpu_id
;
2752 for (i
= 0; i
<= topo
.max_cpu_num
; i
++) {
2753 sprintf(path
, "/sys/devices/system/cpu/cpu%d/node%i/cpulist",
2755 filep
= fopen(path
, "r");
2764 int get_thread_siblings(struct cpu_topology
*thiscpu
)
2766 char path
[80], character
;
2769 int so
, shift
, sib_core
;
2770 int cpu
= thiscpu
->logical_cpu_id
;
2771 int offset
= topo
.max_cpu_num
+ 1;
2775 thiscpu
->put_ids
= CPU_ALLOC((topo
.max_cpu_num
+ 1));
2776 if (thiscpu
->thread_id
< 0)
2777 thiscpu
->thread_id
= thread_id
++;
2778 if (!thiscpu
->put_ids
)
2781 size
= CPU_ALLOC_SIZE((topo
.max_cpu_num
+ 1));
2782 CPU_ZERO_S(size
, thiscpu
->put_ids
);
2785 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu
);
2786 filep
= fopen(path
, "r");
2789 warnx("%s: open failed", path
);
2793 offset
-= BITMASK_SIZE
;
2794 if (fscanf(filep
, "%lx%c", &map
, &character
) != 2)
2795 err(1, "%s: failed to parse file", path
);
2796 for (shift
= 0; shift
< BITMASK_SIZE
; shift
++) {
2797 if ((map
>> shift
) & 0x1) {
2798 so
= shift
+ offset
;
2799 sib_core
= get_core_id(so
);
2800 if (sib_core
== thiscpu
->physical_core_id
) {
2801 CPU_SET_S(so
, size
, thiscpu
->put_ids
);
2803 (cpus
[so
].thread_id
< 0))
2804 cpus
[so
].thread_id
=
2809 } while (!strncmp(&character
, ",", 1));
2812 return CPU_COUNT_S(size
, thiscpu
->put_ids
);
2816 * run func(thread, core, package) in topology order
2817 * skip non-present cpus
2820 int for_all_cpus_2(int (func
)(struct thread_data
*, struct core_data
*,
2821 struct pkg_data
*, struct thread_data
*, struct core_data
*,
2822 struct pkg_data
*), struct thread_data
*thread_base
,
2823 struct core_data
*core_base
, struct pkg_data
*pkg_base
,
2824 struct thread_data
*thread_base2
, struct core_data
*core_base2
,
2825 struct pkg_data
*pkg_base2
)
2827 int retval
, pkg_no
, node_no
, core_no
, thread_no
;
2829 for (pkg_no
= 0; pkg_no
< topo
.num_packages
; ++pkg_no
) {
2830 for (node_no
= 0; node_no
< topo
.nodes_per_pkg
; ++node_no
) {
2831 for (core_no
= 0; core_no
< topo
.cores_per_node
;
2833 for (thread_no
= 0; thread_no
<
2834 topo
.threads_per_core
; ++thread_no
) {
2835 struct thread_data
*t
, *t2
;
2836 struct core_data
*c
, *c2
;
2837 struct pkg_data
*p
, *p2
;
2839 t
= GET_THREAD(thread_base
, thread_no
,
2843 if (cpu_is_not_present(t
->cpu_id
))
2846 t2
= GET_THREAD(thread_base2
, thread_no
,
2850 c
= GET_CORE(core_base
, core_no
,
2852 c2
= GET_CORE(core_base2
, core_no
,
2856 p
= GET_PKG(pkg_base
, pkg_no
);
2857 p2
= GET_PKG(pkg_base2
, pkg_no
);
2859 retval
= func(t
, c
, p
, t2
, c2
, p2
);
2870 * run func(cpu) on every cpu in /proc/stat
2871 * return max_cpu number
2873 int for_all_proc_cpus(int (func
)(int))
2879 fp
= fopen_or_die(proc_stat
, "r");
2881 retval
= fscanf(fp
, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
2883 err(1, "%s: failed to parse format", proc_stat
);
2886 retval
= fscanf(fp
, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num
);
2890 retval
= func(cpu_num
);
2900 void re_initialize(void)
2903 setup_all_buffers();
2904 fprintf(outf
, "turbostat: re-initialized with num_cpus %d\n", topo
.num_cpus
);
2907 void set_max_cpu_num(void)
2911 unsigned long dummy
;
2914 base_cpu
= sched_getcpu();
2916 err(1, "cannot find calling cpu ID");
2918 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings",
2921 filep
= fopen_or_die(pathname
, "r");
2922 topo
.max_cpu_num
= 0;
2923 while (fscanf(filep
, "%lx,", &dummy
) == 1)
2924 topo
.max_cpu_num
+= BITMASK_SIZE
;
2926 topo
.max_cpu_num
--; /* 0 based */
2931 * remember the last one seen, it will be the max
2933 int count_cpus(int cpu
)
2938 int mark_cpu_present(int cpu
)
2940 CPU_SET_S(cpu
, cpu_present_setsize
, cpu_present_set
);
2944 int init_thread_id(int cpu
)
2946 cpus
[cpu
].thread_id
= -1;
2951 * snapshot_proc_interrupts()
2953 * read and record summary of /proc/interrupts
2955 * return 1 if config change requires a restart, else return 0
2957 int snapshot_proc_interrupts(void)
2963 fp
= fopen_or_die("/proc/interrupts", "r");
2967 /* read 1st line of /proc/interrupts to get cpu* name for each column */
2968 for (column
= 0; column
< topo
.num_cpus
; ++column
) {
2971 retval
= fscanf(fp
, " CPU%d", &cpu_number
);
2975 if (cpu_number
> topo
.max_cpu_num
) {
2976 warn("/proc/interrupts: cpu%d: > %d", cpu_number
, topo
.max_cpu_num
);
2980 irq_column_2_cpu
[column
] = cpu_number
;
2981 irqs_per_cpu
[cpu_number
] = 0;
2984 /* read /proc/interrupt count lines and sum up irqs per cpu */
2989 retval
= fscanf(fp
, " %s:", buf
); /* flush irq# "N:" */
2993 /* read the count per cpu */
2994 for (column
= 0; column
< topo
.num_cpus
; ++column
) {
2996 int cpu_number
, irq_count
;
2998 retval
= fscanf(fp
, " %d", &irq_count
);
3002 cpu_number
= irq_column_2_cpu
[column
];
3003 irqs_per_cpu
[cpu_number
] += irq_count
;
3007 while (getc(fp
) != '\n')
3008 ; /* flush interrupt description */
3014 * snapshot_gfx_rc6_ms()
3016 * record snapshot of
3017 * /sys/class/drm/card0/power/rc6_residency_ms
3019 * return 1 if config change requires a restart, else return 0
3021 int snapshot_gfx_rc6_ms(void)
3026 fp
= fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
3028 retval
= fscanf(fp
, "%lld", &gfx_cur_rc6_ms
);
3037 * snapshot_gfx_mhz()
3039 * record snapshot of
3040 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
3042 * return 1 if config change requires a restart, else return 0
3044 int snapshot_gfx_mhz(void)
3050 fp
= fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
3056 retval
= fscanf(fp
, "%d", &gfx_cur_mhz
);
3064 * snapshot_gfx_cur_mhz()
3066 * record snapshot of
3067 * /sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz
3069 * return 1 if config change requires a restart, else return 0
3071 int snapshot_gfx_act_mhz(void)
3077 fp
= fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", "r");
3083 retval
= fscanf(fp
, "%d", &gfx_act_mhz
);
3085 err(1, "GFX ACT MHz");
3091 * snapshot_cpu_lpi()
3093 * record snapshot of
3094 * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
3096 int snapshot_cpu_lpi_us(void)
3101 fp
= fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
3103 retval
= fscanf(fp
, "%lld", &cpuidle_cur_cpu_lpi_us
);
3105 fprintf(stderr
, "Disabling Low Power Idle CPU output\n");
3106 BIC_NOT_PRESENT(BIC_CPU_LPI
);
3116 * snapshot_sys_lpi()
3118 * record snapshot of sys_lpi_file
3120 int snapshot_sys_lpi_us(void)
3125 fp
= fopen_or_die(sys_lpi_file
, "r");
3127 retval
= fscanf(fp
, "%lld", &cpuidle_cur_sys_lpi_us
);
3129 fprintf(stderr
, "Disabling Low Power Idle System output\n");
3130 BIC_NOT_PRESENT(BIC_SYS_LPI
);
3139 * snapshot /proc and /sys files
3141 * return 1 if configuration restart needed, else return 0
3143 int snapshot_proc_sysfs_files(void)
3145 if (DO_BIC(BIC_IRQ
))
3146 if (snapshot_proc_interrupts())
3149 if (DO_BIC(BIC_GFX_rc6
))
3150 snapshot_gfx_rc6_ms();
3152 if (DO_BIC(BIC_GFXMHz
))
3155 if (DO_BIC(BIC_GFXACTMHz
))
3156 snapshot_gfx_act_mhz();
3158 if (DO_BIC(BIC_CPU_LPI
))
3159 snapshot_cpu_lpi_us();
3161 if (DO_BIC(BIC_SYS_LPI
))
3162 snapshot_sys_lpi_us();
3169 static void signal_handler (int signal
)
3175 fprintf(stderr
, " SIGINT\n");
3179 fprintf(stderr
, "SIGUSR1\n");
3184 void setup_signal_handler(void)
3186 struct sigaction sa
;
3188 memset(&sa
, 0, sizeof(sa
));
3190 sa
.sa_handler
= &signal_handler
;
3192 if (sigaction(SIGINT
, &sa
, NULL
) < 0)
3193 err(1, "sigaction SIGINT");
3194 if (sigaction(SIGUSR1
, &sa
, NULL
) < 0)
3195 err(1, "sigaction SIGUSR1");
3200 struct timeval tout
;
3201 struct timespec rest
;
3206 FD_SET(0, &readfds
);
3209 nanosleep(&interval_ts
, NULL
);
3214 retval
= select(1, &readfds
, NULL
, NULL
, &tout
);
3217 switch (getc(stdin
)) {
3223 * 'stdin' is a pipe closed on the other end. There
3224 * won't be any further input.
3227 /* Sleep the rest of the time */
3228 rest
.tv_sec
= (tout
.tv_sec
+ tout
.tv_usec
/ 1000000);
3229 rest
.tv_nsec
= (tout
.tv_usec
% 1000000) * 1000;
3230 nanosleep(&rest
, NULL
);
3235 int get_msr_sum(int cpu
, off_t offset
, unsigned long long *msr
)
3238 unsigned long long msr_cur
, msr_last
;
3240 if (!per_cpu_msr_sum
)
3243 idx
= offset_to_idx(offset
);
3246 /* get_msr_sum() = sum + (get_msr() - last) */
3247 ret
= get_msr(cpu
, offset
, &msr_cur
);
3250 msr_last
= per_cpu_msr_sum
[cpu
].entries
[idx
].last
;
3251 DELTA_WRAP32(msr_cur
, msr_last
);
3252 *msr
= msr_last
+ per_cpu_msr_sum
[cpu
].entries
[idx
].sum
;
3259 /* Timer callback, update the sum of MSRs periodically. */
3260 static int update_msr_sum(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
3263 int cpu
= t
->cpu_id
;
3265 for (i
= IDX_PKG_ENERGY
; i
< IDX_COUNT
; i
++) {
3266 unsigned long long msr_cur
, msr_last
;
3271 offset
= idx_to_offset(i
);
3274 ret
= get_msr(cpu
, offset
, &msr_cur
);
3276 fprintf(outf
, "Can not update msr(0x%x)\n", offset
);
3280 msr_last
= per_cpu_msr_sum
[cpu
].entries
[i
].last
;
3281 per_cpu_msr_sum
[cpu
].entries
[i
].last
= msr_cur
& 0xffffffff;
3283 DELTA_WRAP32(msr_cur
, msr_last
);
3284 per_cpu_msr_sum
[cpu
].entries
[i
].sum
+= msr_last
;
3290 msr_record_handler(union sigval v
)
3292 for_all_cpus(update_msr_sum
, EVEN_COUNTERS
);
3295 void msr_sum_record(void)
3297 struct itimerspec its
;
3298 struct sigevent sev
;
3300 per_cpu_msr_sum
= calloc(topo
.max_cpu_num
+ 1, sizeof(struct msr_sum_array
));
3301 if (!per_cpu_msr_sum
) {
3302 fprintf(outf
, "Can not allocate memory for long time MSR.\n");
3306 * Signal handler might be restricted, so use thread notifier instead.
3308 memset(&sev
, 0, sizeof(struct sigevent
));
3309 sev
.sigev_notify
= SIGEV_THREAD
;
3310 sev
.sigev_notify_function
= msr_record_handler
;
3312 sev
.sigev_value
.sival_ptr
= &timerid
;
3313 if (timer_create(CLOCK_REALTIME
, &sev
, &timerid
) == -1) {
3314 fprintf(outf
, "Can not create timer.\n");
3318 its
.it_value
.tv_sec
= 0;
3319 its
.it_value
.tv_nsec
= 1;
3321 * A wraparound time has been calculated early.
3322 * Some sources state that the peak power for a
3323 * microprocessor is usually 1.5 times the TDP rating,
3324 * use 2 * TDP for safety.
3326 its
.it_interval
.tv_sec
= rapl_joule_counter_range
/ 2;
3327 its
.it_interval
.tv_nsec
= 0;
3329 if (timer_settime(timerid
, 0, &its
, NULL
) == -1) {
3330 fprintf(outf
, "Can not set timer.\n");
3336 timer_delete(timerid
);
3338 free(per_cpu_msr_sum
);
3341 void turbostat_loop()
3347 setup_signal_handler();
3352 snapshot_proc_sysfs_files();
3353 retval
= for_all_cpus(get_counters
, EVEN_COUNTERS
);
3354 first_counter_read
= 0;
3357 } else if (retval
== -1) {
3358 if (restarted
> 10) {
3366 gettimeofday(&tv_even
, (struct timezone
*)NULL
);
3369 if (for_all_proc_cpus(cpu_is_not_present
)) {
3374 if (snapshot_proc_sysfs_files())
3376 retval
= for_all_cpus(get_counters
, ODD_COUNTERS
);
3379 } else if (retval
== -1) {
3383 gettimeofday(&tv_odd
, (struct timezone
*)NULL
);
3384 timersub(&tv_odd
, &tv_even
, &tv_delta
);
3385 if (for_all_cpus_2(delta_cpu
, ODD_COUNTERS
, EVEN_COUNTERS
)) {
3389 compute_average(EVEN_COUNTERS
);
3390 format_all_counters(EVEN_COUNTERS
);
3391 flush_output_stdout();
3394 if (num_iterations
&& ++done_iters
>= num_iterations
)
3397 if (snapshot_proc_sysfs_files())
3399 retval
= for_all_cpus(get_counters
, EVEN_COUNTERS
);
3402 } else if (retval
== -1) {
3406 gettimeofday(&tv_even
, (struct timezone
*)NULL
);
3407 timersub(&tv_even
, &tv_odd
, &tv_delta
);
3408 if (for_all_cpus_2(delta_cpu
, EVEN_COUNTERS
, ODD_COUNTERS
)) {
3412 compute_average(ODD_COUNTERS
);
3413 format_all_counters(ODD_COUNTERS
);
3414 flush_output_stdout();
3417 if (num_iterations
&& ++done_iters
>= num_iterations
)
3422 void check_dev_msr()
3427 sprintf(pathname
, "/dev/cpu/%d/msr", base_cpu
);
3428 if (stat(pathname
, &sb
))
3429 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
3430 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
3434 * check for CAP_SYS_RAWIO
3435 * return 0 on success
3438 int check_for_cap_sys_rawio(void)
3441 cap_flag_value_t cap_flag_value
;
3443 caps
= cap_get_proc();
3445 err(-6, "cap_get_proc\n");
3447 if (cap_get_flag(caps
, CAP_SYS_RAWIO
, CAP_EFFECTIVE
, &cap_flag_value
))
3448 err(-6, "cap_get\n");
3450 if (cap_flag_value
!= CAP_SET
) {
3451 warnx("capget(CAP_SYS_RAWIO) failed,"
3452 " try \"# setcap cap_sys_rawio=ep %s\"", progname
);
3456 if (cap_free(caps
) == -1)
3457 err(-6, "cap_free\n");
3461 void check_permissions(void)
3466 /* check for CAP_SYS_RAWIO */
3467 do_exit
+= check_for_cap_sys_rawio();
3469 /* test file permissions */
3470 sprintf(pathname
, "/dev/cpu/%d/msr", base_cpu
);
3471 if (euidaccess(pathname
, R_OK
)) {
3473 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
3476 /* if all else fails, thell them to be root */
3479 warnx("... or simply run as root");
3486 * NHM adds support for additional MSRs:
3488 * MSR_SMI_COUNT 0x00000034
3490 * MSR_PLATFORM_INFO 0x000000ce
3491 * MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
3493 * MSR_MISC_PWR_MGMT 0x000001aa
3495 * MSR_PKG_C3_RESIDENCY 0x000003f8
3496 * MSR_PKG_C6_RESIDENCY 0x000003f9
3497 * MSR_CORE_C3_RESIDENCY 0x000003fc
3498 * MSR_CORE_C6_RESIDENCY 0x000003fd
3501 * sets global pkg_cstate_limit to decode MSR_PKG_CST_CONFIG_CONTROL
3502 * sets has_misc_feature_control
3504 int probe_nhm_msrs(unsigned int family
, unsigned int model
)
3506 unsigned long long msr
;
3507 unsigned int base_ratio
;
3508 int *pkg_cstate_limits
;
3516 bclk
= discover_bclk(family
, model
);
3519 case INTEL_FAM6_NEHALEM
: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
3520 case INTEL_FAM6_NEHALEM_EX
: /* Nehalem-EX Xeon - Beckton */
3521 pkg_cstate_limits
= nhm_pkg_cstate_limits
;
3523 case INTEL_FAM6_SANDYBRIDGE
: /* SNB */
3524 case INTEL_FAM6_SANDYBRIDGE_X
: /* SNB Xeon */
3525 case INTEL_FAM6_IVYBRIDGE
: /* IVB */
3526 case INTEL_FAM6_IVYBRIDGE_X
: /* IVB Xeon */
3527 pkg_cstate_limits
= snb_pkg_cstate_limits
;
3528 has_misc_feature_control
= 1;
3530 case INTEL_FAM6_HASWELL
: /* HSW */
3531 case INTEL_FAM6_HASWELL_G
: /* HSW */
3532 case INTEL_FAM6_HASWELL_X
: /* HSX */
3533 case INTEL_FAM6_HASWELL_L
: /* HSW */
3534 case INTEL_FAM6_BROADWELL
: /* BDW */
3535 case INTEL_FAM6_BROADWELL_G
: /* BDW */
3536 case INTEL_FAM6_BROADWELL_X
: /* BDX */
3537 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
3538 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
3539 pkg_cstate_limits
= hsw_pkg_cstate_limits
;
3540 has_misc_feature_control
= 1;
3542 case INTEL_FAM6_SKYLAKE_X
: /* SKX */
3543 pkg_cstate_limits
= skx_pkg_cstate_limits
;
3544 has_misc_feature_control
= 1;
3546 case INTEL_FAM6_ATOM_SILVERMONT
: /* BYT */
3547 no_MSR_MISC_PWR_MGMT
= 1;
3548 case INTEL_FAM6_ATOM_SILVERMONT_D
: /* AVN */
3549 pkg_cstate_limits
= slv_pkg_cstate_limits
;
3551 case INTEL_FAM6_ATOM_AIRMONT
: /* AMT */
3552 pkg_cstate_limits
= amt_pkg_cstate_limits
;
3553 no_MSR_MISC_PWR_MGMT
= 1;
3555 case INTEL_FAM6_XEON_PHI_KNL
: /* PHI */
3556 pkg_cstate_limits
= phi_pkg_cstate_limits
;
3558 case INTEL_FAM6_ATOM_GOLDMONT
: /* BXT */
3559 case INTEL_FAM6_ATOM_GOLDMONT_PLUS
:
3560 case INTEL_FAM6_ATOM_GOLDMONT_D
: /* DNV */
3561 case INTEL_FAM6_ATOM_TREMONT
: /* EHL */
3562 case INTEL_FAM6_ATOM_TREMONT_D
: /* JVL */
3563 pkg_cstate_limits
= glm_pkg_cstate_limits
;
3568 get_msr(base_cpu
, MSR_PKG_CST_CONFIG_CONTROL
, &msr
);
3569 pkg_cstate_limit
= pkg_cstate_limits
[msr
& 0xF];
3571 get_msr(base_cpu
, MSR_PLATFORM_INFO
, &msr
);
3572 base_ratio
= (msr
>> 8) & 0xFF;
3574 base_hz
= base_ratio
* bclk
* 1000000;
3579 * SLV client has support for unique MSRs:
3581 * MSR_CC6_DEMOTION_POLICY_CONFIG
3582 * MSR_MC6_DEMOTION_POLICY_CONFIG
3585 int has_slv_msrs(unsigned int family
, unsigned int model
)
3591 case INTEL_FAM6_ATOM_SILVERMONT
:
3592 case INTEL_FAM6_ATOM_SILVERMONT_MID
:
3593 case INTEL_FAM6_ATOM_AIRMONT_MID
:
3598 int is_dnv(unsigned int family
, unsigned int model
)
3605 case INTEL_FAM6_ATOM_GOLDMONT_D
:
3610 int is_bdx(unsigned int family
, unsigned int model
)
3617 case INTEL_FAM6_BROADWELL_X
:
3622 int is_skx(unsigned int family
, unsigned int model
)
3629 case INTEL_FAM6_SKYLAKE_X
:
3634 int is_ehl(unsigned int family
, unsigned int model
)
3640 case INTEL_FAM6_ATOM_TREMONT
:
3645 int is_jvl(unsigned int family
, unsigned int model
)
3651 case INTEL_FAM6_ATOM_TREMONT_D
:
3657 int has_turbo_ratio_limit(unsigned int family
, unsigned int model
)
3659 if (has_slv_msrs(family
, model
))
3663 /* Nehalem compatible, but do not include turbo-ratio limit support */
3664 case INTEL_FAM6_NEHALEM_EX
: /* Nehalem-EX Xeon - Beckton */
3665 case INTEL_FAM6_XEON_PHI_KNL
: /* PHI - Knights Landing (different MSR definition) */
3671 int has_atom_turbo_ratio_limit(unsigned int family
, unsigned int model
)
3673 if (has_slv_msrs(family
, model
))
3678 int has_ivt_turbo_ratio_limit(unsigned int family
, unsigned int model
)
3687 case INTEL_FAM6_IVYBRIDGE_X
: /* IVB Xeon */
3688 case INTEL_FAM6_HASWELL_X
: /* HSW Xeon */
3694 int has_hsw_turbo_ratio_limit(unsigned int family
, unsigned int model
)
3703 case INTEL_FAM6_HASWELL_X
: /* HSW Xeon */
3710 int has_knl_turbo_ratio_limit(unsigned int family
, unsigned int model
)
3719 case INTEL_FAM6_XEON_PHI_KNL
: /* Knights Landing */
3725 int has_glm_turbo_ratio_limit(unsigned int family
, unsigned int model
)
3734 case INTEL_FAM6_ATOM_GOLDMONT
:
3735 case INTEL_FAM6_SKYLAKE_X
:
3741 int has_config_tdp(unsigned int family
, unsigned int model
)
3750 case INTEL_FAM6_IVYBRIDGE
: /* IVB */
3751 case INTEL_FAM6_HASWELL
: /* HSW */
3752 case INTEL_FAM6_HASWELL_X
: /* HSX */
3753 case INTEL_FAM6_HASWELL_L
: /* HSW */
3754 case INTEL_FAM6_HASWELL_G
: /* HSW */
3755 case INTEL_FAM6_BROADWELL
: /* BDW */
3756 case INTEL_FAM6_BROADWELL_G
: /* BDW */
3757 case INTEL_FAM6_BROADWELL_X
: /* BDX */
3758 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
3759 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
3760 case INTEL_FAM6_SKYLAKE_X
: /* SKX */
3762 case INTEL_FAM6_XEON_PHI_KNL
: /* Knights Landing */
3770 remove_underbar(char *s
)
3784 dump_cstate_pstate_config_info(unsigned int family
, unsigned int model
)
3786 if (!do_nhm_platform_info
)
3789 dump_nhm_platform_info();
3791 if (has_hsw_turbo_ratio_limit(family
, model
))
3792 dump_hsw_turbo_ratio_limits();
3794 if (has_ivt_turbo_ratio_limit(family
, model
))
3795 dump_ivt_turbo_ratio_limits();
3797 if (has_turbo_ratio_limit(family
, model
))
3798 dump_turbo_ratio_limits(family
, model
);
3800 if (has_atom_turbo_ratio_limit(family
, model
))
3801 dump_atom_turbo_ratio_limits();
3803 if (has_knl_turbo_ratio_limit(family
, model
))
3804 dump_knl_turbo_ratio_limits();
3806 if (has_config_tdp(family
, model
))
3812 static void dump_sysfs_file(char *path
)
3815 char cpuidle_buf
[64];
3817 input
= fopen(path
, "r");
3818 if (input
== NULL
) {
3820 fprintf(outf
, "NSFOD %s\n", path
);
3823 if (!fgets(cpuidle_buf
, sizeof(cpuidle_buf
), input
))
3824 err(1, "%s: failed to read file", path
);
3827 fprintf(outf
, "%s: %s", strrchr(path
, '/') + 1, cpuidle_buf
);
3830 dump_sysfs_cstate_config(void)
3839 if (access("/sys/devices/system/cpu/cpuidle", R_OK
)) {
3840 fprintf(outf
, "cpuidle not loaded\n");
3844 dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver");
3845 dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor");
3846 dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro");
3848 for (state
= 0; state
< 10; ++state
) {
3850 sprintf(path
, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
3852 input
= fopen(path
, "r");
3855 if (!fgets(name_buf
, sizeof(name_buf
), input
))
3856 err(1, "%s: failed to read file", path
);
3858 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
3859 sp
= strchr(name_buf
, '-');
3861 sp
= strchrnul(name_buf
, '\n');
3865 remove_underbar(name_buf
);
3867 sprintf(path
, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
3869 input
= fopen(path
, "r");
3872 if (!fgets(desc
, sizeof(desc
), input
))
3873 err(1, "%s: failed to read file", path
);
3875 fprintf(outf
, "cpu%d: %s: %s", base_cpu
, name_buf
, desc
);
3880 dump_sysfs_pstate_config(void)
3883 char driver_buf
[64];
3884 char governor_buf
[64];
3888 sprintf(path
, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver",
3890 input
= fopen(path
, "r");
3891 if (input
== NULL
) {
3892 fprintf(outf
, "NSFOD %s\n", path
);
3895 if (!fgets(driver_buf
, sizeof(driver_buf
), input
))
3896 err(1, "%s: failed to read file", path
);
3899 sprintf(path
, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
3901 input
= fopen(path
, "r");
3902 if (input
== NULL
) {
3903 fprintf(outf
, "NSFOD %s\n", path
);
3906 if (!fgets(governor_buf
, sizeof(governor_buf
), input
))
3907 err(1, "%s: failed to read file", path
);
3910 fprintf(outf
, "cpu%d: cpufreq driver: %s", base_cpu
, driver_buf
);
3911 fprintf(outf
, "cpu%d: cpufreq governor: %s", base_cpu
, governor_buf
);
3913 sprintf(path
, "/sys/devices/system/cpu/cpufreq/boost");
3914 input
= fopen(path
, "r");
3915 if (input
!= NULL
) {
3916 if (fscanf(input
, "%d", &turbo
) != 1)
3917 err(1, "%s: failed to parse number from file", path
);
3918 fprintf(outf
, "cpufreq boost: %d\n", turbo
);
3922 sprintf(path
, "/sys/devices/system/cpu/intel_pstate/no_turbo");
3923 input
= fopen(path
, "r");
3924 if (input
!= NULL
) {
3925 if (fscanf(input
, "%d", &turbo
) != 1)
3926 err(1, "%s: failed to parse number from file", path
);
3927 fprintf(outf
, "cpufreq intel_pstate no_turbo: %d\n", turbo
);
3935 * Decode the ENERGY_PERF_BIAS MSR
3937 int print_epb(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
3947 /* EPB is per-package */
3948 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
) || !(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
3951 if (cpu_migrate(cpu
)) {
3952 fprintf(outf
, "print_epb: Could not migrate to CPU %d\n", cpu
);
3961 case ENERGY_PERF_BIAS_PERFORMANCE
:
3962 epb_string
= "performance";
3964 case ENERGY_PERF_BIAS_NORMAL
:
3965 epb_string
= "balanced";
3967 case ENERGY_PERF_BIAS_POWERSAVE
:
3968 epb_string
= "powersave";
3971 epb_string
= "custom";
3974 fprintf(outf
, "cpu%d: EPB: %d (%s)\n", cpu
, epb
, epb_string
);
3980 * Decode the MSR_HWP_CAPABILITIES
3982 int print_hwp(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
3984 unsigned long long msr
;
3992 /* MSR_HWP_CAPABILITIES is per-package */
3993 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
) || !(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
3996 if (cpu_migrate(cpu
)) {
3997 fprintf(outf
, "print_hwp: Could not migrate to CPU %d\n", cpu
);
4001 if (get_msr(cpu
, MSR_PM_ENABLE
, &msr
))
4004 fprintf(outf
, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
4005 cpu
, msr
, (msr
& (1 << 0)) ? "" : "No-");
4007 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
4008 if ((msr
& (1 << 0)) == 0)
4011 if (get_msr(cpu
, MSR_HWP_CAPABILITIES
, &msr
))
4014 fprintf(outf
, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
4015 "(high %d guar %d eff %d low %d)\n",
4017 (unsigned int)HWP_HIGHEST_PERF(msr
),
4018 (unsigned int)HWP_GUARANTEED_PERF(msr
),
4019 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr
),
4020 (unsigned int)HWP_LOWEST_PERF(msr
));
4022 if (get_msr(cpu
, MSR_HWP_REQUEST
, &msr
))
4025 fprintf(outf
, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
4026 "(min %d max %d des %d epp 0x%x window 0x%x pkg 0x%x)\n",
4028 (unsigned int)(((msr
) >> 0) & 0xff),
4029 (unsigned int)(((msr
) >> 8) & 0xff),
4030 (unsigned int)(((msr
) >> 16) & 0xff),
4031 (unsigned int)(((msr
) >> 24) & 0xff),
4032 (unsigned int)(((msr
) >> 32) & 0xff3),
4033 (unsigned int)(((msr
) >> 42) & 0x1));
4036 if (get_msr(cpu
, MSR_HWP_REQUEST_PKG
, &msr
))
4039 fprintf(outf
, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
4040 "(min %d max %d des %d epp 0x%x window 0x%x)\n",
4042 (unsigned int)(((msr
) >> 0) & 0xff),
4043 (unsigned int)(((msr
) >> 8) & 0xff),
4044 (unsigned int)(((msr
) >> 16) & 0xff),
4045 (unsigned int)(((msr
) >> 24) & 0xff),
4046 (unsigned int)(((msr
) >> 32) & 0xff3));
4048 if (has_hwp_notify
) {
4049 if (get_msr(cpu
, MSR_HWP_INTERRUPT
, &msr
))
4052 fprintf(outf
, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
4053 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
4055 ((msr
) & 0x1) ? "EN" : "Dis",
4056 ((msr
) & 0x2) ? "EN" : "Dis");
4058 if (get_msr(cpu
, MSR_HWP_STATUS
, &msr
))
4061 fprintf(outf
, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
4062 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
4064 ((msr
) & 0x1) ? "" : "No-",
4065 ((msr
) & 0x2) ? "" : "No-");
4071 * print_perf_limit()
4073 int print_perf_limit(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
4075 unsigned long long msr
;
4081 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
) || !(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
4084 if (cpu_migrate(cpu
)) {
4085 fprintf(outf
, "print_perf_limit: Could not migrate to CPU %d\n", cpu
);
4089 if (do_core_perf_limit_reasons
) {
4090 get_msr(cpu
, MSR_CORE_PERF_LIMIT_REASONS
, &msr
);
4091 fprintf(outf
, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu
, msr
);
4092 fprintf(outf
, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
4093 (msr
& 1 << 15) ? "bit15, " : "",
4094 (msr
& 1 << 14) ? "bit14, " : "",
4095 (msr
& 1 << 13) ? "Transitions, " : "",
4096 (msr
& 1 << 12) ? "MultiCoreTurbo, " : "",
4097 (msr
& 1 << 11) ? "PkgPwrL2, " : "",
4098 (msr
& 1 << 10) ? "PkgPwrL1, " : "",
4099 (msr
& 1 << 9) ? "CorePwr, " : "",
4100 (msr
& 1 << 8) ? "Amps, " : "",
4101 (msr
& 1 << 6) ? "VR-Therm, " : "",
4102 (msr
& 1 << 5) ? "Auto-HWP, " : "",
4103 (msr
& 1 << 4) ? "Graphics, " : "",
4104 (msr
& 1 << 2) ? "bit2, " : "",
4105 (msr
& 1 << 1) ? "ThermStatus, " : "",
4106 (msr
& 1 << 0) ? "PROCHOT, " : "");
4107 fprintf(outf
, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
4108 (msr
& 1 << 31) ? "bit31, " : "",
4109 (msr
& 1 << 30) ? "bit30, " : "",
4110 (msr
& 1 << 29) ? "Transitions, " : "",
4111 (msr
& 1 << 28) ? "MultiCoreTurbo, " : "",
4112 (msr
& 1 << 27) ? "PkgPwrL2, " : "",
4113 (msr
& 1 << 26) ? "PkgPwrL1, " : "",
4114 (msr
& 1 << 25) ? "CorePwr, " : "",
4115 (msr
& 1 << 24) ? "Amps, " : "",
4116 (msr
& 1 << 22) ? "VR-Therm, " : "",
4117 (msr
& 1 << 21) ? "Auto-HWP, " : "",
4118 (msr
& 1 << 20) ? "Graphics, " : "",
4119 (msr
& 1 << 18) ? "bit18, " : "",
4120 (msr
& 1 << 17) ? "ThermStatus, " : "",
4121 (msr
& 1 << 16) ? "PROCHOT, " : "");
4124 if (do_gfx_perf_limit_reasons
) {
4125 get_msr(cpu
, MSR_GFX_PERF_LIMIT_REASONS
, &msr
);
4126 fprintf(outf
, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu
, msr
);
4127 fprintf(outf
, " (Active: %s%s%s%s%s%s%s%s)",
4128 (msr
& 1 << 0) ? "PROCHOT, " : "",
4129 (msr
& 1 << 1) ? "ThermStatus, " : "",
4130 (msr
& 1 << 4) ? "Graphics, " : "",
4131 (msr
& 1 << 6) ? "VR-Therm, " : "",
4132 (msr
& 1 << 8) ? "Amps, " : "",
4133 (msr
& 1 << 9) ? "GFXPwr, " : "",
4134 (msr
& 1 << 10) ? "PkgPwrL1, " : "",
4135 (msr
& 1 << 11) ? "PkgPwrL2, " : "");
4136 fprintf(outf
, " (Logged: %s%s%s%s%s%s%s%s)\n",
4137 (msr
& 1 << 16) ? "PROCHOT, " : "",
4138 (msr
& 1 << 17) ? "ThermStatus, " : "",
4139 (msr
& 1 << 20) ? "Graphics, " : "",
4140 (msr
& 1 << 22) ? "VR-Therm, " : "",
4141 (msr
& 1 << 24) ? "Amps, " : "",
4142 (msr
& 1 << 25) ? "GFXPwr, " : "",
4143 (msr
& 1 << 26) ? "PkgPwrL1, " : "",
4144 (msr
& 1 << 27) ? "PkgPwrL2, " : "");
4146 if (do_ring_perf_limit_reasons
) {
4147 get_msr(cpu
, MSR_RING_PERF_LIMIT_REASONS
, &msr
);
4148 fprintf(outf
, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu
, msr
);
4149 fprintf(outf
, " (Active: %s%s%s%s%s%s)",
4150 (msr
& 1 << 0) ? "PROCHOT, " : "",
4151 (msr
& 1 << 1) ? "ThermStatus, " : "",
4152 (msr
& 1 << 6) ? "VR-Therm, " : "",
4153 (msr
& 1 << 8) ? "Amps, " : "",
4154 (msr
& 1 << 10) ? "PkgPwrL1, " : "",
4155 (msr
& 1 << 11) ? "PkgPwrL2, " : "");
4156 fprintf(outf
, " (Logged: %s%s%s%s%s%s)\n",
4157 (msr
& 1 << 16) ? "PROCHOT, " : "",
4158 (msr
& 1 << 17) ? "ThermStatus, " : "",
4159 (msr
& 1 << 22) ? "VR-Therm, " : "",
4160 (msr
& 1 << 24) ? "Amps, " : "",
4161 (msr
& 1 << 26) ? "PkgPwrL1, " : "",
4162 (msr
& 1 << 27) ? "PkgPwrL2, " : "");
4167 #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
4168 #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
4170 double get_tdp_intel(unsigned int model
)
4172 unsigned long long msr
;
4174 if (do_rapl
& RAPL_PKG_POWER_INFO
)
4175 if (!get_msr(base_cpu
, MSR_PKG_POWER_INFO
, &msr
))
4176 return ((msr
>> 0) & RAPL_POWER_GRANULARITY
) * rapl_power_units
;
4179 case INTEL_FAM6_ATOM_SILVERMONT
:
4180 case INTEL_FAM6_ATOM_SILVERMONT_D
:
4187 double get_tdp_amd(unsigned int family
)
4189 /* This is the max stock TDP of HEDT/Server Fam17h+ chips */
4194 * rapl_dram_energy_units_probe()
4195 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
4198 rapl_dram_energy_units_probe(int model
, double rapl_energy_units
)
4200 /* only called for genuine_intel, family 6 */
4203 case INTEL_FAM6_HASWELL_X
: /* HSX */
4204 case INTEL_FAM6_BROADWELL_X
: /* BDX */
4205 case INTEL_FAM6_XEON_PHI_KNL
: /* KNL */
4206 return (rapl_dram_energy_units
= 15.3 / 1000000);
4208 return (rapl_energy_units
);
4212 void rapl_probe_intel(unsigned int family
, unsigned int model
)
4214 unsigned long long msr
;
4215 unsigned int time_unit
;
4222 case INTEL_FAM6_SANDYBRIDGE
:
4223 case INTEL_FAM6_IVYBRIDGE
:
4224 case INTEL_FAM6_HASWELL
: /* HSW */
4225 case INTEL_FAM6_HASWELL_L
: /* HSW */
4226 case INTEL_FAM6_HASWELL_G
: /* HSW */
4227 case INTEL_FAM6_BROADWELL
: /* BDW */
4228 case INTEL_FAM6_BROADWELL_G
: /* BDW */
4229 do_rapl
= RAPL_PKG
| RAPL_CORES
| RAPL_CORE_POLICY
| RAPL_GFX
| RAPL_PKG_POWER_INFO
;
4231 BIC_PRESENT(BIC_Pkg_J
);
4232 BIC_PRESENT(BIC_Cor_J
);
4233 BIC_PRESENT(BIC_GFX_J
);
4235 BIC_PRESENT(BIC_PkgWatt
);
4236 BIC_PRESENT(BIC_CorWatt
);
4237 BIC_PRESENT(BIC_GFXWatt
);
4240 case INTEL_FAM6_ATOM_GOLDMONT
: /* BXT */
4241 case INTEL_FAM6_ATOM_GOLDMONT_PLUS
:
4242 do_rapl
= RAPL_PKG
| RAPL_PKG_POWER_INFO
;
4244 BIC_PRESENT(BIC_Pkg_J
);
4246 BIC_PRESENT(BIC_PkgWatt
);
4248 case INTEL_FAM6_ATOM_TREMONT
: /* EHL */
4249 do_rapl
= RAPL_PKG
| RAPL_CORES
| RAPL_CORE_POLICY
| RAPL_DRAM
| RAPL_DRAM_PERF_STATUS
| RAPL_PKG_PERF_STATUS
| RAPL_GFX
| RAPL_PKG_POWER_INFO
;
4251 BIC_PRESENT(BIC_Pkg_J
);
4252 BIC_PRESENT(BIC_Cor_J
);
4253 BIC_PRESENT(BIC_RAM_J
);
4254 BIC_PRESENT(BIC_GFX_J
);
4256 BIC_PRESENT(BIC_PkgWatt
);
4257 BIC_PRESENT(BIC_CorWatt
);
4258 BIC_PRESENT(BIC_RAMWatt
);
4259 BIC_PRESENT(BIC_GFXWatt
);
4262 case INTEL_FAM6_ATOM_TREMONT_D
: /* JVL */
4263 do_rapl
= RAPL_PKG
| RAPL_PKG_PERF_STATUS
| RAPL_PKG_POWER_INFO
;
4264 BIC_PRESENT(BIC_PKG__
);
4266 BIC_PRESENT(BIC_Pkg_J
);
4268 BIC_PRESENT(BIC_PkgWatt
);
4270 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
4271 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
4272 do_rapl
= RAPL_PKG
| RAPL_CORES
| RAPL_CORE_POLICY
| RAPL_DRAM
| RAPL_DRAM_PERF_STATUS
| RAPL_PKG_PERF_STATUS
| RAPL_GFX
| RAPL_PKG_POWER_INFO
;
4273 BIC_PRESENT(BIC_PKG__
);
4274 BIC_PRESENT(BIC_RAM__
);
4276 BIC_PRESENT(BIC_Pkg_J
);
4277 BIC_PRESENT(BIC_Cor_J
);
4278 BIC_PRESENT(BIC_RAM_J
);
4279 BIC_PRESENT(BIC_GFX_J
);
4281 BIC_PRESENT(BIC_PkgWatt
);
4282 BIC_PRESENT(BIC_CorWatt
);
4283 BIC_PRESENT(BIC_RAMWatt
);
4284 BIC_PRESENT(BIC_GFXWatt
);
4287 case INTEL_FAM6_HASWELL_X
: /* HSX */
4288 case INTEL_FAM6_BROADWELL_X
: /* BDX */
4289 case INTEL_FAM6_SKYLAKE_X
: /* SKX */
4290 case INTEL_FAM6_XEON_PHI_KNL
: /* KNL */
4291 do_rapl
= RAPL_PKG
| RAPL_DRAM
| RAPL_DRAM_POWER_INFO
| RAPL_DRAM_PERF_STATUS
| RAPL_PKG_PERF_STATUS
| RAPL_PKG_POWER_INFO
;
4292 BIC_PRESENT(BIC_PKG__
);
4293 BIC_PRESENT(BIC_RAM__
);
4295 BIC_PRESENT(BIC_Pkg_J
);
4296 BIC_PRESENT(BIC_RAM_J
);
4298 BIC_PRESENT(BIC_PkgWatt
);
4299 BIC_PRESENT(BIC_RAMWatt
);
4302 case INTEL_FAM6_SANDYBRIDGE_X
:
4303 case INTEL_FAM6_IVYBRIDGE_X
:
4304 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
;
4305 BIC_PRESENT(BIC_PKG__
);
4306 BIC_PRESENT(BIC_RAM__
);
4308 BIC_PRESENT(BIC_Pkg_J
);
4309 BIC_PRESENT(BIC_Cor_J
);
4310 BIC_PRESENT(BIC_RAM_J
);
4312 BIC_PRESENT(BIC_PkgWatt
);
4313 BIC_PRESENT(BIC_CorWatt
);
4314 BIC_PRESENT(BIC_RAMWatt
);
4317 case INTEL_FAM6_ATOM_SILVERMONT
: /* BYT */
4318 case INTEL_FAM6_ATOM_SILVERMONT_D
: /* AVN */
4319 do_rapl
= RAPL_PKG
| RAPL_CORES
;
4321 BIC_PRESENT(BIC_Pkg_J
);
4322 BIC_PRESENT(BIC_Cor_J
);
4324 BIC_PRESENT(BIC_PkgWatt
);
4325 BIC_PRESENT(BIC_CorWatt
);
4328 case INTEL_FAM6_ATOM_GOLDMONT_D
: /* DNV */
4329 do_rapl
= RAPL_PKG
| RAPL_DRAM
| RAPL_DRAM_POWER_INFO
| RAPL_DRAM_PERF_STATUS
| RAPL_PKG_PERF_STATUS
| RAPL_PKG_POWER_INFO
| RAPL_CORES_ENERGY_STATUS
;
4330 BIC_PRESENT(BIC_PKG__
);
4331 BIC_PRESENT(BIC_RAM__
);
4333 BIC_PRESENT(BIC_Pkg_J
);
4334 BIC_PRESENT(BIC_Cor_J
);
4335 BIC_PRESENT(BIC_RAM_J
);
4337 BIC_PRESENT(BIC_PkgWatt
);
4338 BIC_PRESENT(BIC_CorWatt
);
4339 BIC_PRESENT(BIC_RAMWatt
);
4346 /* units on package 0, verify later other packages match */
4347 if (get_msr(base_cpu
, MSR_RAPL_POWER_UNIT
, &msr
))
4350 rapl_power_units
= 1.0 / (1 << (msr
& 0xF));
4351 if (model
== INTEL_FAM6_ATOM_SILVERMONT
)
4352 rapl_energy_units
= 1.0 * (1 << (msr
>> 8 & 0x1F)) / 1000000;
4354 rapl_energy_units
= 1.0 / (1 << (msr
>> 8 & 0x1F));
4356 rapl_dram_energy_units
= rapl_dram_energy_units_probe(model
, rapl_energy_units
);
4358 time_unit
= msr
>> 16 & 0xF;
4362 rapl_time_units
= 1.0 / (1 << (time_unit
));
4364 tdp
= get_tdp_intel(model
);
4366 rapl_joule_counter_range
= 0xFFFFFFFF * rapl_energy_units
/ tdp
;
4368 fprintf(outf
, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range
, tdp
);
4371 void rapl_probe_amd(unsigned int family
, unsigned int model
)
4373 unsigned long long msr
;
4374 unsigned int eax
, ebx
, ecx
, edx
;
4375 unsigned int has_rapl
= 0;
4378 if (max_extended_level
>= 0x80000007) {
4379 __cpuid(0x80000007, eax
, ebx
, ecx
, edx
);
4380 /* RAPL (Fam 17h+) */
4381 has_rapl
= edx
& (1 << 14);
4384 if (!has_rapl
|| family
< 0x17)
4387 do_rapl
= RAPL_AMD_F17H
| RAPL_PER_CORE_ENERGY
;
4389 BIC_PRESENT(BIC_Pkg_J
);
4390 BIC_PRESENT(BIC_Cor_J
);
4392 BIC_PRESENT(BIC_PkgWatt
);
4393 BIC_PRESENT(BIC_CorWatt
);
4396 if (get_msr(base_cpu
, MSR_RAPL_PWR_UNIT
, &msr
))
4399 rapl_time_units
= ldexp(1.0, -(msr
>> 16 & 0xf));
4400 rapl_energy_units
= ldexp(1.0, -(msr
>> 8 & 0x1f));
4401 rapl_power_units
= ldexp(1.0, -(msr
& 0xf));
4403 tdp
= get_tdp_amd(family
);
4405 rapl_joule_counter_range
= 0xFFFFFFFF * rapl_energy_units
/ tdp
;
4407 fprintf(outf
, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range
, tdp
);
4413 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
4415 void rapl_probe(unsigned int family
, unsigned int model
)
4418 rapl_probe_intel(family
, model
);
4419 if (authentic_amd
|| hygon_genuine
)
4420 rapl_probe_amd(family
, model
);
4423 void perf_limit_reasons_probe(unsigned int family
, unsigned int model
)
4432 case INTEL_FAM6_HASWELL
: /* HSW */
4433 case INTEL_FAM6_HASWELL_L
: /* HSW */
4434 case INTEL_FAM6_HASWELL_G
: /* HSW */
4435 do_gfx_perf_limit_reasons
= 1;
4436 case INTEL_FAM6_HASWELL_X
: /* HSX */
4437 do_core_perf_limit_reasons
= 1;
4438 do_ring_perf_limit_reasons
= 1;
4444 void automatic_cstate_conversion_probe(unsigned int family
, unsigned int model
)
4446 if (is_skx(family
, model
) || is_bdx(family
, model
))
4447 has_automatic_cstate_conversion
= 1;
4450 int print_thermal(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
4452 unsigned long long msr
;
4453 unsigned int dts
, dts2
;
4456 if (!(do_dts
|| do_ptm
))
4461 /* DTS is per-core, no need to print for each thread */
4462 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
))
4465 if (cpu_migrate(cpu
)) {
4466 fprintf(outf
, "print_thermal: Could not migrate to CPU %d\n", cpu
);
4470 if (do_ptm
&& (t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
)) {
4471 if (get_msr(cpu
, MSR_IA32_PACKAGE_THERM_STATUS
, &msr
))
4474 dts
= (msr
>> 16) & 0x7F;
4475 fprintf(outf
, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
4476 cpu
, msr
, tcc_activation_temp
- dts
);
4478 if (get_msr(cpu
, MSR_IA32_PACKAGE_THERM_INTERRUPT
, &msr
))
4481 dts
= (msr
>> 16) & 0x7F;
4482 dts2
= (msr
>> 8) & 0x7F;
4483 fprintf(outf
, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
4484 cpu
, msr
, tcc_activation_temp
- dts
, tcc_activation_temp
- dts2
);
4488 if (do_dts
&& debug
) {
4489 unsigned int resolution
;
4491 if (get_msr(cpu
, MSR_IA32_THERM_STATUS
, &msr
))
4494 dts
= (msr
>> 16) & 0x7F;
4495 resolution
= (msr
>> 27) & 0xF;
4496 fprintf(outf
, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
4497 cpu
, msr
, tcc_activation_temp
- dts
, resolution
);
4499 if (get_msr(cpu
, MSR_IA32_THERM_INTERRUPT
, &msr
))
4502 dts
= (msr
>> 16) & 0x7F;
4503 dts2
= (msr
>> 8) & 0x7F;
4504 fprintf(outf
, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
4505 cpu
, msr
, tcc_activation_temp
- dts
, tcc_activation_temp
- dts2
);
4511 void print_power_limit_msr(int cpu
, unsigned long long msr
, char *label
)
4513 fprintf(outf
, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
4515 ((msr
>> 15) & 1) ? "EN" : "DIS",
4516 ((msr
>> 0) & 0x7FFF) * rapl_power_units
,
4517 (1.0 + (((msr
>> 22) & 0x3)/4.0)) * (1 << ((msr
>> 17) & 0x1F)) * rapl_time_units
,
4518 (((msr
>> 16) & 1) ? "EN" : "DIS"));
4523 int print_rapl(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
4525 unsigned long long msr
;
4526 const char *msr_name
;
4532 /* RAPL counters are per package, so print only for 1st thread/package */
4533 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
) || !(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
4537 if (cpu_migrate(cpu
)) {
4538 fprintf(outf
, "print_rapl: Could not migrate to CPU %d\n", cpu
);
4542 if (do_rapl
& RAPL_AMD_F17H
) {
4543 msr_name
= "MSR_RAPL_PWR_UNIT";
4544 if (get_msr(cpu
, MSR_RAPL_PWR_UNIT
, &msr
))
4547 msr_name
= "MSR_RAPL_POWER_UNIT";
4548 if (get_msr(cpu
, MSR_RAPL_POWER_UNIT
, &msr
))
4552 fprintf(outf
, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu
, msr_name
, msr
,
4553 rapl_power_units
, rapl_energy_units
, rapl_time_units
);
4555 if (do_rapl
& RAPL_PKG_POWER_INFO
) {
4557 if (get_msr(cpu
, MSR_PKG_POWER_INFO
, &msr
))
4561 fprintf(outf
, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
4563 ((msr
>> 0) & RAPL_POWER_GRANULARITY
) * rapl_power_units
,
4564 ((msr
>> 16) & RAPL_POWER_GRANULARITY
) * rapl_power_units
,
4565 ((msr
>> 32) & RAPL_POWER_GRANULARITY
) * rapl_power_units
,
4566 ((msr
>> 48) & RAPL_TIME_GRANULARITY
) * rapl_time_units
);
4569 if (do_rapl
& RAPL_PKG
) {
4571 if (get_msr(cpu
, MSR_PKG_POWER_LIMIT
, &msr
))
4574 fprintf(outf
, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
4575 cpu
, msr
, (msr
>> 63) & 1 ? "" : "UN");
4577 print_power_limit_msr(cpu
, msr
, "PKG Limit #1");
4578 fprintf(outf
, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
4580 ((msr
>> 47) & 1) ? "EN" : "DIS",
4581 ((msr
>> 32) & 0x7FFF) * rapl_power_units
,
4582 (1.0 + (((msr
>> 54) & 0x3)/4.0)) * (1 << ((msr
>> 49) & 0x1F)) * rapl_time_units
,
4583 ((msr
>> 48) & 1) ? "EN" : "DIS");
4586 if (do_rapl
& RAPL_DRAM_POWER_INFO
) {
4587 if (get_msr(cpu
, MSR_DRAM_POWER_INFO
, &msr
))
4590 fprintf(outf
, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
4592 ((msr
>> 0) & RAPL_POWER_GRANULARITY
) * rapl_power_units
,
4593 ((msr
>> 16) & RAPL_POWER_GRANULARITY
) * rapl_power_units
,
4594 ((msr
>> 32) & RAPL_POWER_GRANULARITY
) * rapl_power_units
,
4595 ((msr
>> 48) & RAPL_TIME_GRANULARITY
) * rapl_time_units
);
4597 if (do_rapl
& RAPL_DRAM
) {
4598 if (get_msr(cpu
, MSR_DRAM_POWER_LIMIT
, &msr
))
4600 fprintf(outf
, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
4601 cpu
, msr
, (msr
>> 31) & 1 ? "" : "UN");
4603 print_power_limit_msr(cpu
, msr
, "DRAM Limit");
4605 if (do_rapl
& RAPL_CORE_POLICY
) {
4606 if (get_msr(cpu
, MSR_PP0_POLICY
, &msr
))
4609 fprintf(outf
, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu
, msr
& 0xF);
4611 if (do_rapl
& RAPL_CORES_POWER_LIMIT
) {
4612 if (get_msr(cpu
, MSR_PP0_POWER_LIMIT
, &msr
))
4614 fprintf(outf
, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
4615 cpu
, msr
, (msr
>> 31) & 1 ? "" : "UN");
4616 print_power_limit_msr(cpu
, msr
, "Cores Limit");
4618 if (do_rapl
& RAPL_GFX
) {
4619 if (get_msr(cpu
, MSR_PP1_POLICY
, &msr
))
4622 fprintf(outf
, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu
, msr
& 0xF);
4624 if (get_msr(cpu
, MSR_PP1_POWER_LIMIT
, &msr
))
4626 fprintf(outf
, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
4627 cpu
, msr
, (msr
>> 31) & 1 ? "" : "UN");
4628 print_power_limit_msr(cpu
, msr
, "GFX Limit");
4634 * SNB adds support for additional MSRs:
4636 * MSR_PKG_C7_RESIDENCY 0x000003fa
4637 * MSR_CORE_C7_RESIDENCY 0x000003fe
4638 * MSR_PKG_C2_RESIDENCY 0x0000060d
4641 int has_snb_msrs(unsigned int family
, unsigned int model
)
4647 case INTEL_FAM6_SANDYBRIDGE
:
4648 case INTEL_FAM6_SANDYBRIDGE_X
:
4649 case INTEL_FAM6_IVYBRIDGE
: /* IVB */
4650 case INTEL_FAM6_IVYBRIDGE_X
: /* IVB Xeon */
4651 case INTEL_FAM6_HASWELL
: /* HSW */
4652 case INTEL_FAM6_HASWELL_X
: /* HSW */
4653 case INTEL_FAM6_HASWELL_L
: /* HSW */
4654 case INTEL_FAM6_HASWELL_G
: /* HSW */
4655 case INTEL_FAM6_BROADWELL
: /* BDW */
4656 case INTEL_FAM6_BROADWELL_G
: /* BDW */
4657 case INTEL_FAM6_BROADWELL_X
: /* BDX */
4658 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
4659 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
4660 case INTEL_FAM6_SKYLAKE_X
: /* SKX */
4661 case INTEL_FAM6_ATOM_GOLDMONT
: /* BXT */
4662 case INTEL_FAM6_ATOM_GOLDMONT_PLUS
:
4663 case INTEL_FAM6_ATOM_GOLDMONT_D
: /* DNV */
4664 case INTEL_FAM6_ATOM_TREMONT
: /* EHL */
4665 case INTEL_FAM6_ATOM_TREMONT_D
: /* JVL */
4672 * HSW ULT added support for C8/C9/C10 MSRs:
4674 * MSR_PKG_C8_RESIDENCY 0x00000630
4675 * MSR_PKG_C9_RESIDENCY 0x00000631
4676 * MSR_PKG_C10_RESIDENCY 0x00000632
4678 * MSR_PKGC8_IRTL 0x00000633
4679 * MSR_PKGC9_IRTL 0x00000634
4680 * MSR_PKGC10_IRTL 0x00000635
4683 int has_c8910_msrs(unsigned int family
, unsigned int model
)
4689 case INTEL_FAM6_HASWELL_L
: /* HSW */
4690 case INTEL_FAM6_BROADWELL
: /* BDW */
4691 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
4692 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
4693 case INTEL_FAM6_ATOM_GOLDMONT
: /* BXT */
4694 case INTEL_FAM6_ATOM_GOLDMONT_PLUS
:
4695 case INTEL_FAM6_ATOM_TREMONT
: /* EHL */
4702 * SKL adds support for additional MSRS:
4704 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
4705 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
4706 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
4707 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
4709 int has_skl_msrs(unsigned int family
, unsigned int model
)
4715 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
4716 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
4722 int is_slm(unsigned int family
, unsigned int model
)
4727 case INTEL_FAM6_ATOM_SILVERMONT
: /* BYT */
4728 case INTEL_FAM6_ATOM_SILVERMONT_D
: /* AVN */
4734 int is_knl(unsigned int family
, unsigned int model
)
4739 case INTEL_FAM6_XEON_PHI_KNL
: /* KNL */
4745 int is_cnl(unsigned int family
, unsigned int model
)
4751 case INTEL_FAM6_CANNONLAKE_L
: /* CNL */
4758 unsigned int get_aperf_mperf_multiplier(unsigned int family
, unsigned int model
)
4760 if (is_knl(family
, model
))
4765 #define SLM_BCLK_FREQS 5
4766 double slm_freq_table
[SLM_BCLK_FREQS
] = { 83.3, 100.0, 133.3, 116.7, 80.0};
4768 double slm_bclk(void)
4770 unsigned long long msr
= 3;
4774 if (get_msr(base_cpu
, MSR_FSB_FREQ
, &msr
))
4775 fprintf(outf
, "SLM BCLK: unknown\n");
4778 if (i
>= SLM_BCLK_FREQS
) {
4779 fprintf(outf
, "SLM BCLK[%d] invalid\n", i
);
4782 freq
= slm_freq_table
[i
];
4785 fprintf(outf
, "SLM BCLK: %.1f Mhz\n", freq
);
4790 double discover_bclk(unsigned int family
, unsigned int model
)
4792 if (has_snb_msrs(family
, model
) || is_knl(family
, model
))
4794 else if (is_slm(family
, model
))
4801 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
4802 * the Thermal Control Circuit (TCC) activates.
4803 * This is usually equal to tjMax.
4805 * Older processors do not have this MSR, so there we guess,
4806 * but also allow cmdline over-ride with -T.
4808 * Several MSR temperature values are in units of degrees-C
4809 * below this value, including the Digital Thermal Sensor (DTS),
4810 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
4812 int read_tcc_activation_temp()
4814 unsigned long long msr
;
4815 unsigned int tcc
, target_c
, offset_c
;
4817 /* Temperature Target MSR is Nehalem and newer only */
4818 if (!do_nhm_platform_info
)
4821 if (get_msr(base_cpu
, MSR_IA32_TEMPERATURE_TARGET
, &msr
))
4824 target_c
= (msr
>> 16) & 0xFF;
4826 offset_c
= (msr
>> 24) & 0xF;
4828 tcc
= target_c
- offset_c
;
4831 fprintf(outf
, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C) (%d default - %d offset)\n",
4832 base_cpu
, msr
, tcc
, target_c
, offset_c
);
4837 int set_temperature_target(struct thread_data
*t
, struct core_data
*c
, struct pkg_data
*p
)
4839 /* tcc_activation_temp is used only for dts or ptm */
4840 if (!(do_dts
|| do_ptm
))
4843 /* this is a per-package concept */
4844 if (!(t
->flags
& CPU_IS_FIRST_THREAD_IN_CORE
) || !(t
->flags
& CPU_IS_FIRST_CORE_IN_PACKAGE
))
4847 if (tcc_activation_temp_override
!= 0) {
4848 tcc_activation_temp
= tcc_activation_temp_override
;
4849 fprintf(outf
, "Using cmdline TCC Target (%d C)\n", tcc_activation_temp
);
4853 tcc_activation_temp
= read_tcc_activation_temp();
4854 if (tcc_activation_temp
)
4857 tcc_activation_temp
= TJMAX_DEFAULT
;
4858 fprintf(outf
, "Guessing tjMax %d C, Please use -T to specify\n", tcc_activation_temp
);
4863 void decode_feature_control_msr(void)
4865 unsigned long long msr
;
4867 if (!get_msr(base_cpu
, MSR_IA32_FEAT_CTL
, &msr
))
4868 fprintf(outf
, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
4870 msr
& FEAT_CTL_LOCKED
? "" : "UN-",
4871 msr
& (1 << 18) ? "SGX" : "");
4874 void decode_misc_enable_msr(void)
4876 unsigned long long msr
;
4881 if (!get_msr(base_cpu
, MSR_IA32_MISC_ENABLE
, &msr
))
4882 fprintf(outf
, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
4884 msr
& MSR_IA32_MISC_ENABLE_TM1
? "" : "No-",
4885 msr
& MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP
? "" : "No-",
4886 msr
& MSR_IA32_MISC_ENABLE_MWAIT
? "" : "No-",
4887 msr
& MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE
? "No-" : "",
4888 msr
& MSR_IA32_MISC_ENABLE_TURBO_DISABLE
? "No-" : "");
4891 void decode_misc_feature_control(void)
4893 unsigned long long msr
;
4895 if (!has_misc_feature_control
)
4898 if (!get_msr(base_cpu
, MSR_MISC_FEATURE_CONTROL
, &msr
))
4899 fprintf(outf
, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
4901 msr
& (0 << 0) ? "No-" : "",
4902 msr
& (1 << 0) ? "No-" : "",
4903 msr
& (2 << 0) ? "No-" : "",
4904 msr
& (3 << 0) ? "No-" : "");
4907 * Decode MSR_MISC_PWR_MGMT
4909 * Decode the bits according to the Nehalem documentation
4910 * bit[0] seems to continue to have same meaning going forward
4913 void decode_misc_pwr_mgmt_msr(void)
4915 unsigned long long msr
;
4917 if (!do_nhm_platform_info
)
4920 if (no_MSR_MISC_PWR_MGMT
)
4923 if (!get_msr(base_cpu
, MSR_MISC_PWR_MGMT
, &msr
))
4924 fprintf(outf
, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
4926 msr
& (1 << 0) ? "DIS" : "EN",
4927 msr
& (1 << 1) ? "EN" : "DIS",
4928 msr
& (1 << 8) ? "EN" : "DIS");
4931 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
4933 * This MSRs are present on Silvermont processors,
4934 * Intel Atom processor E3000 series (Baytrail), and friends.
4936 void decode_c6_demotion_policy_msr(void)
4938 unsigned long long msr
;
4940 if (!get_msr(base_cpu
, MSR_CC6_DEMOTION_POLICY_CONFIG
, &msr
))
4941 fprintf(outf
, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
4942 base_cpu
, msr
, msr
& (1 << 0) ? "EN" : "DIS");
4944 if (!get_msr(base_cpu
, MSR_MC6_DEMOTION_POLICY_CONFIG
, &msr
))
4945 fprintf(outf
, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
4946 base_cpu
, msr
, msr
& (1 << 0) ? "EN" : "DIS");
4950 * When models are the same, for the purpose of turbostat, reuse
4952 unsigned int intel_model_duplicates(unsigned int model
)
4956 case INTEL_FAM6_NEHALEM_EP
: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
4957 case INTEL_FAM6_NEHALEM
: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
4958 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
4959 case INTEL_FAM6_WESTMERE
: /* Westmere Client - Clarkdale, Arrandale */
4960 case INTEL_FAM6_WESTMERE_EP
: /* Westmere EP - Gulftown */
4961 return INTEL_FAM6_NEHALEM
;
4963 case INTEL_FAM6_NEHALEM_EX
: /* Nehalem-EX Xeon - Beckton */
4964 case INTEL_FAM6_WESTMERE_EX
: /* Westmere-EX Xeon - Eagleton */
4965 return INTEL_FAM6_NEHALEM_EX
;
4967 case INTEL_FAM6_XEON_PHI_KNM
:
4968 return INTEL_FAM6_XEON_PHI_KNL
;
4970 case INTEL_FAM6_BROADWELL_X
:
4971 case INTEL_FAM6_BROADWELL_D
: /* BDX-DE */
4972 return INTEL_FAM6_BROADWELL_X
;
4974 case INTEL_FAM6_SKYLAKE_L
:
4975 case INTEL_FAM6_SKYLAKE
:
4976 case INTEL_FAM6_KABYLAKE_L
:
4977 case INTEL_FAM6_KABYLAKE
:
4978 case INTEL_FAM6_COMETLAKE_L
:
4979 case INTEL_FAM6_COMETLAKE
:
4980 return INTEL_FAM6_SKYLAKE_L
;
4982 case INTEL_FAM6_ICELAKE_L
:
4983 case INTEL_FAM6_ICELAKE_NNPI
:
4984 case INTEL_FAM6_TIGERLAKE_L
:
4985 case INTEL_FAM6_TIGERLAKE
:
4986 case INTEL_FAM6_ROCKETLAKE
:
4987 case INTEL_FAM6_LAKEFIELD
:
4988 case INTEL_FAM6_ALDERLAKE
:
4989 return INTEL_FAM6_CANNONLAKE_L
;
4991 case INTEL_FAM6_ATOM_TREMONT_L
:
4992 return INTEL_FAM6_ATOM_TREMONT
;
4994 case INTEL_FAM6_ICELAKE_X
:
4995 case INTEL_FAM6_SAPPHIRERAPIDS_X
:
4996 return INTEL_FAM6_SKYLAKE_X
;
5001 void print_dev_latency(void)
5003 char *path
= "/dev/cpu_dma_latency";
5008 fd
= open(path
, O_RDONLY
);
5010 warn("fopen %s\n", path
);
5014 retval
= read(fd
, (void *)&value
, sizeof(int));
5015 if (retval
!= sizeof(int)) {
5016 warn("read %s\n", path
);
5020 fprintf(outf
, "/dev/cpu_dma_latency: %d usec (%s)\n",
5021 value
, value
== 2000000000 ? "default" : "constrained");
5026 void process_cpuid()
5028 unsigned int eax
, ebx
, ecx
, edx
;
5029 unsigned int fms
, family
, model
, stepping
, ecx_flags
, edx_flags
;
5030 unsigned int has_turbo
;
5032 eax
= ebx
= ecx
= edx
= 0;
5034 __cpuid(0, max_level
, ebx
, ecx
, edx
);
5036 if (ebx
== 0x756e6547 && ecx
== 0x6c65746e && edx
== 0x49656e69)
5038 else if (ebx
== 0x68747541 && ecx
== 0x444d4163 && edx
== 0x69746e65)
5040 else if (ebx
== 0x6f677948 && ecx
== 0x656e6975 && edx
== 0x6e65476e)
5044 fprintf(outf
, "CPUID(0): %.4s%.4s%.4s ",
5045 (char *)&ebx
, (char *)&edx
, (char *)&ecx
);
5047 __cpuid(1, fms
, ebx
, ecx
, edx
);
5048 family
= (fms
>> 8) & 0xf;
5049 model
= (fms
>> 4) & 0xf;
5050 stepping
= fms
& 0xf;
5052 family
+= (fms
>> 20) & 0xff;
5054 model
+= ((fms
>> 16) & 0xf) << 4;
5059 * check max extended function levels of CPUID.
5060 * This is needed to check for invariant TSC.
5061 * This check is valid for both Intel and AMD.
5063 ebx
= ecx
= edx
= 0;
5064 __cpuid(0x80000000, max_extended_level
, ebx
, ecx
, edx
);
5067 fprintf(outf
, "0x%x CPUID levels; 0x%x xlevels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
5068 max_level
, max_extended_level
, family
, model
, stepping
, family
, model
, stepping
);
5069 fprintf(outf
, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n",
5070 ecx_flags
& (1 << 0) ? "SSE3" : "-",
5071 ecx_flags
& (1 << 3) ? "MONITOR" : "-",
5072 ecx_flags
& (1 << 6) ? "SMX" : "-",
5073 ecx_flags
& (1 << 7) ? "EIST" : "-",
5074 ecx_flags
& (1 << 8) ? "TM2" : "-",
5075 edx_flags
& (1 << 4) ? "TSC" : "-",
5076 edx_flags
& (1 << 5) ? "MSR" : "-",
5077 edx_flags
& (1 << 22) ? "ACPI-TM" : "-",
5078 edx_flags
& (1 << 28) ? "HT" : "-",
5079 edx_flags
& (1 << 29) ? "TM" : "-");
5082 model
= intel_model_duplicates(model
);
5084 if (!(edx_flags
& (1 << 5)))
5085 errx(1, "CPUID: no MSR");
5087 if (max_extended_level
>= 0x80000007) {
5090 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
5091 * this check is valid for both Intel and AMD
5093 __cpuid(0x80000007, eax
, ebx
, ecx
, edx
);
5094 has_invariant_tsc
= edx
& (1 << 8);
5098 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
5099 * this check is valid for both Intel and AMD
5102 __cpuid(0x6, eax
, ebx
, ecx
, edx
);
5103 has_aperf
= ecx
& (1 << 0);
5105 BIC_PRESENT(BIC_Avg_MHz
);
5106 BIC_PRESENT(BIC_Busy
);
5107 BIC_PRESENT(BIC_Bzy_MHz
);
5109 do_dts
= eax
& (1 << 0);
5111 BIC_PRESENT(BIC_CoreTmp
);
5112 has_turbo
= eax
& (1 << 1);
5113 do_ptm
= eax
& (1 << 6);
5115 BIC_PRESENT(BIC_PkgTmp
);
5116 has_hwp
= eax
& (1 << 7);
5117 has_hwp_notify
= eax
& (1 << 8);
5118 has_hwp_activity_window
= eax
& (1 << 9);
5119 has_hwp_epp
= eax
& (1 << 10);
5120 has_hwp_pkg
= eax
& (1 << 11);
5121 has_epb
= ecx
& (1 << 3);
5124 fprintf(outf
, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
5125 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
5126 has_aperf
? "" : "No-",
5127 has_turbo
? "" : "No-",
5128 do_dts
? "" : "No-",
5129 do_ptm
? "" : "No-",
5130 has_hwp
? "" : "No-",
5131 has_hwp_notify
? "" : "No-",
5132 has_hwp_activity_window
? "" : "No-",
5133 has_hwp_epp
? "" : "No-",
5134 has_hwp_pkg
? "" : "No-",
5135 has_epb
? "" : "No-");
5138 decode_misc_enable_msr();
5141 if (max_level
>= 0x7 && !quiet
) {
5146 __cpuid_count(0x7, 0, eax
, ebx
, ecx
, edx
);
5148 has_sgx
= ebx
& (1 << 2);
5149 fprintf(outf
, "CPUID(7): %sSGX\n", has_sgx
? "" : "No-");
5152 decode_feature_control_msr();
5155 if (max_level
>= 0x15) {
5156 unsigned int eax_crystal
;
5157 unsigned int ebx_tsc
;
5160 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
5162 eax_crystal
= ebx_tsc
= crystal_hz
= edx
= 0;
5163 __cpuid(0x15, eax_crystal
, ebx_tsc
, crystal_hz
, edx
);
5167 if (!quiet
&& (ebx
!= 0))
5168 fprintf(outf
, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
5169 eax_crystal
, ebx_tsc
, crystal_hz
);
5171 if (crystal_hz
== 0)
5173 case INTEL_FAM6_SKYLAKE_L
: /* SKL */
5174 crystal_hz
= 24000000; /* 24.0 MHz */
5176 case INTEL_FAM6_ATOM_GOLDMONT_D
: /* DNV */
5177 crystal_hz
= 25000000; /* 25.0 MHz */
5179 case INTEL_FAM6_ATOM_GOLDMONT
: /* BXT */
5180 case INTEL_FAM6_ATOM_GOLDMONT_PLUS
:
5181 crystal_hz
= 19200000; /* 19.2 MHz */
5188 tsc_hz
= (unsigned long long) crystal_hz
* ebx_tsc
/ eax_crystal
;
5190 fprintf(outf
, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
5191 tsc_hz
/ 1000000, crystal_hz
, ebx_tsc
, eax_crystal
);
5195 if (max_level
>= 0x16) {
5196 unsigned int base_mhz
, max_mhz
, bus_mhz
, edx
;
5199 * CPUID 16H Base MHz, Max MHz, Bus MHz
5201 base_mhz
= max_mhz
= bus_mhz
= edx
= 0;
5203 __cpuid(0x16, base_mhz
, max_mhz
, bus_mhz
, edx
);
5205 fprintf(outf
, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
5206 base_mhz
, max_mhz
, bus_mhz
);
5210 aperf_mperf_multiplier
= get_aperf_mperf_multiplier(family
, model
);
5212 BIC_PRESENT(BIC_IRQ
);
5213 BIC_PRESENT(BIC_TSC_MHz
);
5215 if (probe_nhm_msrs(family
, model
)) {
5216 do_nhm_platform_info
= 1;
5217 BIC_PRESENT(BIC_CPU_c1
);
5218 BIC_PRESENT(BIC_CPU_c3
);
5219 BIC_PRESENT(BIC_CPU_c6
);
5220 BIC_PRESENT(BIC_SMI
);
5222 do_snb_cstates
= has_snb_msrs(family
, model
);
5225 BIC_PRESENT(BIC_CPU_c7
);
5227 do_irtl_snb
= has_snb_msrs(family
, model
);
5228 if (do_snb_cstates
&& (pkg_cstate_limit
>= PCL__2
))
5229 BIC_PRESENT(BIC_Pkgpc2
);
5230 if (pkg_cstate_limit
>= PCL__3
)
5231 BIC_PRESENT(BIC_Pkgpc3
);
5232 if (pkg_cstate_limit
>= PCL__6
)
5233 BIC_PRESENT(BIC_Pkgpc6
);
5234 if (do_snb_cstates
&& (pkg_cstate_limit
>= PCL__7
))
5235 BIC_PRESENT(BIC_Pkgpc7
);
5236 if (has_slv_msrs(family
, model
)) {
5237 BIC_NOT_PRESENT(BIC_Pkgpc2
);
5238 BIC_NOT_PRESENT(BIC_Pkgpc3
);
5239 BIC_PRESENT(BIC_Pkgpc6
);
5240 BIC_NOT_PRESENT(BIC_Pkgpc7
);
5241 BIC_PRESENT(BIC_Mod_c6
);
5242 use_c1_residency_msr
= 1;
5244 if (is_jvl(family
, model
)) {
5245 BIC_NOT_PRESENT(BIC_CPU_c3
);
5246 BIC_NOT_PRESENT(BIC_CPU_c7
);
5247 BIC_NOT_PRESENT(BIC_Pkgpc2
);
5248 BIC_NOT_PRESENT(BIC_Pkgpc3
);
5249 BIC_NOT_PRESENT(BIC_Pkgpc6
);
5250 BIC_NOT_PRESENT(BIC_Pkgpc7
);
5252 if (is_dnv(family
, model
)) {
5253 BIC_PRESENT(BIC_CPU_c1
);
5254 BIC_NOT_PRESENT(BIC_CPU_c3
);
5255 BIC_NOT_PRESENT(BIC_Pkgpc3
);
5256 BIC_NOT_PRESENT(BIC_CPU_c7
);
5257 BIC_NOT_PRESENT(BIC_Pkgpc7
);
5258 use_c1_residency_msr
= 1;
5260 if (is_skx(family
, model
)) {
5261 BIC_NOT_PRESENT(BIC_CPU_c3
);
5262 BIC_NOT_PRESENT(BIC_Pkgpc3
);
5263 BIC_NOT_PRESENT(BIC_CPU_c7
);
5264 BIC_NOT_PRESENT(BIC_Pkgpc7
);
5266 if (is_bdx(family
, model
)) {
5267 BIC_NOT_PRESENT(BIC_CPU_c7
);
5268 BIC_NOT_PRESENT(BIC_Pkgpc7
);
5270 if (has_c8910_msrs(family
, model
)) {
5271 if (pkg_cstate_limit
>= PCL__8
)
5272 BIC_PRESENT(BIC_Pkgpc8
);
5273 if (pkg_cstate_limit
>= PCL__9
)
5274 BIC_PRESENT(BIC_Pkgpc9
);
5275 if (pkg_cstate_limit
>= PCL_10
)
5276 BIC_PRESENT(BIC_Pkgpc10
);
5278 do_irtl_hsw
= has_c8910_msrs(family
, model
);
5279 if (has_skl_msrs(family
, model
)) {
5280 BIC_PRESENT(BIC_Totl_c0
);
5281 BIC_PRESENT(BIC_Any_c0
);
5282 BIC_PRESENT(BIC_GFX_c0
);
5283 BIC_PRESENT(BIC_CPUGFX
);
5285 do_slm_cstates
= is_slm(family
, model
);
5286 do_knl_cstates
= is_knl(family
, model
);
5288 if (do_slm_cstates
|| do_knl_cstates
|| is_cnl(family
, model
) ||
5289 is_ehl(family
, model
))
5290 BIC_NOT_PRESENT(BIC_CPU_c3
);
5293 decode_misc_pwr_mgmt_msr();
5295 if (!quiet
&& has_slv_msrs(family
, model
))
5296 decode_c6_demotion_policy_msr();
5298 rapl_probe(family
, model
);
5299 perf_limit_reasons_probe(family
, model
);
5300 automatic_cstate_conversion_probe(family
, model
);
5303 dump_cstate_pstate_config_info(family
, model
);
5306 print_dev_latency();
5308 dump_sysfs_cstate_config();
5310 dump_sysfs_pstate_config();
5312 if (has_skl_msrs(family
, model
))
5313 calculate_tsc_tweak();
5315 if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK
))
5316 BIC_PRESENT(BIC_GFX_rc6
);
5318 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK
))
5319 BIC_PRESENT(BIC_GFXMHz
);
5321 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", R_OK
))
5322 BIC_PRESENT(BIC_GFXACTMHz
);
5324 if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK
))
5325 BIC_PRESENT(BIC_CPU_LPI
);
5327 BIC_NOT_PRESENT(BIC_CPU_LPI
);
5329 if (!access(sys_lpi_file_sysfs
, R_OK
)) {
5330 sys_lpi_file
= sys_lpi_file_sysfs
;
5331 BIC_PRESENT(BIC_SYS_LPI
);
5332 } else if (!access(sys_lpi_file_debugfs
, R_OK
)) {
5333 sys_lpi_file
= sys_lpi_file_debugfs
;
5334 BIC_PRESENT(BIC_SYS_LPI
);
5336 sys_lpi_file_sysfs
= NULL
;
5337 BIC_NOT_PRESENT(BIC_SYS_LPI
);
5341 decode_misc_feature_control();
5347 * in /dev/cpu/ return success for names that are numbers
5348 * ie. filter out ".", "..", "microcode".
5350 int dir_filter(const struct dirent
*dirp
)
5352 if (isdigit(dirp
->d_name
[0]))
5358 int open_dev_cpu_msr(int dummy1
)
5363 void topology_probe()
5366 int max_core_id
= 0;
5367 int max_package_id
= 0;
5369 int max_siblings
= 0;
5371 /* Initialize num_cpus, max_cpu_num */
5374 for_all_proc_cpus(count_cpus
);
5375 if (!summary_only
&& topo
.num_cpus
> 1)
5376 BIC_PRESENT(BIC_CPU
);
5379 fprintf(outf
, "num_cpus %d max_cpu_num %d\n", topo
.num_cpus
, topo
.max_cpu_num
);
5381 cpus
= calloc(1, (topo
.max_cpu_num
+ 1) * sizeof(struct cpu_topology
));
5383 err(1, "calloc cpus");
5386 * Allocate and initialize cpu_present_set
5388 cpu_present_set
= CPU_ALLOC((topo
.max_cpu_num
+ 1));
5389 if (cpu_present_set
== NULL
)
5390 err(3, "CPU_ALLOC");
5391 cpu_present_setsize
= CPU_ALLOC_SIZE((topo
.max_cpu_num
+ 1));
5392 CPU_ZERO_S(cpu_present_setsize
, cpu_present_set
);
5393 for_all_proc_cpus(mark_cpu_present
);
5396 * Validate that all cpus in cpu_subset are also in cpu_present_set
5398 for (i
= 0; i
< CPU_SUBSET_MAXCPUS
; ++i
) {
5399 if (CPU_ISSET_S(i
, cpu_subset_size
, cpu_subset
))
5400 if (!CPU_ISSET_S(i
, cpu_present_setsize
, cpu_present_set
))
5401 err(1, "cpu%d not present", i
);
5405 * Allocate and initialize cpu_affinity_set
5407 cpu_affinity_set
= CPU_ALLOC((topo
.max_cpu_num
+ 1));
5408 if (cpu_affinity_set
== NULL
)
5409 err(3, "CPU_ALLOC");
5410 cpu_affinity_setsize
= CPU_ALLOC_SIZE((topo
.max_cpu_num
+ 1));
5411 CPU_ZERO_S(cpu_affinity_setsize
, cpu_affinity_set
);
5413 for_all_proc_cpus(init_thread_id
);
5417 * find max_core_id, max_package_id
5419 for (i
= 0; i
<= topo
.max_cpu_num
; ++i
) {
5422 if (cpu_is_not_present(i
)) {
5424 fprintf(outf
, "cpu%d NOT PRESENT\n", i
);
5428 cpus
[i
].logical_cpu_id
= i
;
5430 /* get package information */
5431 cpus
[i
].physical_package_id
= get_physical_package_id(i
);
5432 if (cpus
[i
].physical_package_id
> max_package_id
)
5433 max_package_id
= cpus
[i
].physical_package_id
;
5435 /* get die information */
5436 cpus
[i
].die_id
= get_die_id(i
);
5437 if (cpus
[i
].die_id
> max_die_id
)
5438 max_die_id
= cpus
[i
].die_id
;
5440 /* get numa node information */
5441 cpus
[i
].physical_node_id
= get_physical_node_id(&cpus
[i
]);
5442 if (cpus
[i
].physical_node_id
> topo
.max_node_num
)
5443 topo
.max_node_num
= cpus
[i
].physical_node_id
;
5445 /* get core information */
5446 cpus
[i
].physical_core_id
= get_core_id(i
);
5447 if (cpus
[i
].physical_core_id
> max_core_id
)
5448 max_core_id
= cpus
[i
].physical_core_id
;
5450 /* get thread information */
5451 siblings
= get_thread_siblings(&cpus
[i
]);
5452 if (siblings
> max_siblings
)
5453 max_siblings
= siblings
;
5454 if (cpus
[i
].thread_id
== 0)
5458 topo
.cores_per_node
= max_core_id
+ 1;
5460 fprintf(outf
, "max_core_id %d, sizing for %d cores per package\n",
5461 max_core_id
, topo
.cores_per_node
);
5462 if (!summary_only
&& topo
.cores_per_node
> 1)
5463 BIC_PRESENT(BIC_Core
);
5465 topo
.num_die
= max_die_id
+ 1;
5467 fprintf(outf
, "max_die_id %d, sizing for %d die\n",
5468 max_die_id
, topo
.num_die
);
5469 if (!summary_only
&& topo
.num_die
> 1)
5470 BIC_PRESENT(BIC_Die
);
5472 topo
.num_packages
= max_package_id
+ 1;
5474 fprintf(outf
, "max_package_id %d, sizing for %d packages\n",
5475 max_package_id
, topo
.num_packages
);
5476 if (!summary_only
&& topo
.num_packages
> 1)
5477 BIC_PRESENT(BIC_Package
);
5481 fprintf(outf
, "nodes_per_pkg %d\n", topo
.nodes_per_pkg
);
5482 if (!summary_only
&& topo
.nodes_per_pkg
> 1)
5483 BIC_PRESENT(BIC_Node
);
5485 topo
.threads_per_core
= max_siblings
;
5487 fprintf(outf
, "max_siblings %d\n", max_siblings
);
5492 for (i
= 0; i
<= topo
.max_cpu_num
; ++i
) {
5493 if (cpu_is_not_present(i
))
5496 "cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n",
5497 i
, cpus
[i
].physical_package_id
, cpus
[i
].die_id
,
5498 cpus
[i
].physical_node_id
,
5499 cpus
[i
].logical_node_id
,
5500 cpus
[i
].physical_core_id
,
5507 allocate_counters(struct thread_data
**t
, struct core_data
**c
,
5508 struct pkg_data
**p
)
5511 int num_cores
= topo
.cores_per_node
* topo
.nodes_per_pkg
*
5513 int num_threads
= topo
.threads_per_core
* num_cores
;
5515 *t
= calloc(num_threads
, sizeof(struct thread_data
));
5519 for (i
= 0; i
< num_threads
; i
++)
5520 (*t
)[i
].cpu_id
= -1;
5522 *c
= calloc(num_cores
, sizeof(struct core_data
));
5526 for (i
= 0; i
< num_cores
; i
++)
5527 (*c
)[i
].core_id
= -1;
5529 *p
= calloc(topo
.num_packages
, sizeof(struct pkg_data
));
5533 for (i
= 0; i
< topo
.num_packages
; i
++)
5534 (*p
)[i
].package_id
= i
;
5538 err(1, "calloc counters");
5543 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
5545 void init_counter(struct thread_data
*thread_base
, struct core_data
*core_base
,
5546 struct pkg_data
*pkg_base
, int cpu_id
)
5548 int pkg_id
= cpus
[cpu_id
].physical_package_id
;
5549 int node_id
= cpus
[cpu_id
].logical_node_id
;
5550 int core_id
= cpus
[cpu_id
].physical_core_id
;
5551 int thread_id
= cpus
[cpu_id
].thread_id
;
5552 struct thread_data
*t
;
5553 struct core_data
*c
;
5557 /* Workaround for systems where physical_node_id==-1
5558 * and logical_node_id==(-1 - topo.num_cpus)
5563 t
= GET_THREAD(thread_base
, thread_id
, core_id
, node_id
, pkg_id
);
5564 c
= GET_CORE(core_base
, core_id
, node_id
, pkg_id
);
5565 p
= GET_PKG(pkg_base
, pkg_id
);
5568 if (thread_id
== 0) {
5569 t
->flags
|= CPU_IS_FIRST_THREAD_IN_CORE
;
5570 if (cpu_is_first_core_in_package(cpu_id
))
5571 t
->flags
|= CPU_IS_FIRST_CORE_IN_PACKAGE
;
5574 c
->core_id
= core_id
;
5575 p
->package_id
= pkg_id
;
5579 int initialize_counters(int cpu_id
)
5581 init_counter(EVEN_COUNTERS
, cpu_id
);
5582 init_counter(ODD_COUNTERS
, cpu_id
);
5586 void allocate_output_buffer()
5588 output_buffer
= calloc(1, (1 + topo
.num_cpus
) * 2048);
5589 outp
= output_buffer
;
5591 err(-1, "calloc output buffer");
5593 void allocate_fd_percpu(void)
5595 fd_percpu
= calloc(topo
.max_cpu_num
+ 1, sizeof(int));
5596 if (fd_percpu
== NULL
)
5597 err(-1, "calloc fd_percpu");
5599 void allocate_irq_buffers(void)
5601 irq_column_2_cpu
= calloc(topo
.num_cpus
, sizeof(int));
5602 if (irq_column_2_cpu
== NULL
)
5603 err(-1, "calloc %d", topo
.num_cpus
);
5605 irqs_per_cpu
= calloc(topo
.max_cpu_num
+ 1, sizeof(int));
5606 if (irqs_per_cpu
== NULL
)
5607 err(-1, "calloc %d", topo
.max_cpu_num
+ 1);
5609 void setup_all_buffers(void)
5612 allocate_irq_buffers();
5613 allocate_fd_percpu();
5614 allocate_counters(&thread_even
, &core_even
, &package_even
);
5615 allocate_counters(&thread_odd
, &core_odd
, &package_odd
);
5616 allocate_output_buffer();
5617 for_all_proc_cpus(initialize_counters
);
5620 void set_base_cpu(void)
5622 base_cpu
= sched_getcpu();
5624 err(-ENODEV
, "No valid cpus found");
5627 fprintf(outf
, "base_cpu = %d\n", base_cpu
);
5630 void turbostat_init()
5632 setup_all_buffers();
5635 check_permissions();
5640 for_all_cpus(print_hwp
, ODD_COUNTERS
);
5643 for_all_cpus(print_epb
, ODD_COUNTERS
);
5646 for_all_cpus(print_perf_limit
, ODD_COUNTERS
);
5649 for_all_cpus(print_rapl
, ODD_COUNTERS
);
5651 for_all_cpus(set_temperature_target
, ODD_COUNTERS
);
5654 for_all_cpus(print_thermal
, ODD_COUNTERS
);
5656 if (!quiet
&& do_irtl_snb
)
5660 int fork_it(char **argv
)
5665 snapshot_proc_sysfs_files();
5666 status
= for_all_cpus(get_counters
, EVEN_COUNTERS
);
5667 first_counter_read
= 0;
5670 /* clear affinity side-effect of get_counters() */
5671 sched_setaffinity(0, cpu_present_setsize
, cpu_present_set
);
5672 gettimeofday(&tv_even
, (struct timezone
*)NULL
);
5677 execvp(argv
[0], argv
);
5678 err(errno
, "exec %s", argv
[0]);
5682 if (child_pid
== -1)
5685 signal(SIGINT
, SIG_IGN
);
5686 signal(SIGQUIT
, SIG_IGN
);
5687 if (waitpid(child_pid
, &status
, 0) == -1)
5688 err(status
, "waitpid");
5690 if (WIFEXITED(status
))
5691 status
= WEXITSTATUS(status
);
5694 * n.b. fork_it() does not check for errors from for_all_cpus()
5695 * because re-starting is problematic when forking
5697 snapshot_proc_sysfs_files();
5698 for_all_cpus(get_counters
, ODD_COUNTERS
);
5699 gettimeofday(&tv_odd
, (struct timezone
*)NULL
);
5700 timersub(&tv_odd
, &tv_even
, &tv_delta
);
5701 if (for_all_cpus_2(delta_cpu
, ODD_COUNTERS
, EVEN_COUNTERS
))
5702 fprintf(outf
, "%s: Counter reset detected\n", progname
);
5704 compute_average(EVEN_COUNTERS
);
5705 format_all_counters(EVEN_COUNTERS
);
5708 fprintf(outf
, "%.6f sec\n", tv_delta
.tv_sec
+ tv_delta
.tv_usec
/1000000.0);
5710 flush_output_stderr();
5715 int get_and_dump_counters(void)
5719 snapshot_proc_sysfs_files();
5720 status
= for_all_cpus(get_counters
, ODD_COUNTERS
);
5724 status
= for_all_cpus(dump_counters
, ODD_COUNTERS
);
5728 flush_output_stdout();
5733 void print_version() {
5734 fprintf(outf
, "turbostat version 20.09.30"
5735 " - Len Brown <lenb@kernel.org>\n");
5738 int add_counter(unsigned int msr_num
, char *path
, char *name
,
5739 unsigned int width
, enum counter_scope scope
,
5740 enum counter_type type
, enum counter_format format
, int flags
)
5742 struct msr_counter
*msrp
;
5744 msrp
= calloc(1, sizeof(struct msr_counter
));
5750 msrp
->msr_num
= msr_num
;
5751 strncpy(msrp
->name
, name
, NAME_BYTES
- 1);
5753 strncpy(msrp
->path
, path
, PATH_BYTES
- 1);
5754 msrp
->width
= width
;
5756 msrp
->format
= format
;
5757 msrp
->flags
= flags
;
5762 msrp
->next
= sys
.tp
;
5764 sys
.added_thread_counters
++;
5765 if (sys
.added_thread_counters
> MAX_ADDED_THREAD_COUNTERS
) {
5766 fprintf(stderr
, "exceeded max %d added thread counters\n",
5767 MAX_ADDED_COUNTERS
);
5773 msrp
->next
= sys
.cp
;
5775 sys
.added_core_counters
++;
5776 if (sys
.added_core_counters
> MAX_ADDED_COUNTERS
) {
5777 fprintf(stderr
, "exceeded max %d added core counters\n",
5778 MAX_ADDED_COUNTERS
);
5784 msrp
->next
= sys
.pp
;
5786 sys
.added_package_counters
++;
5787 if (sys
.added_package_counters
> MAX_ADDED_COUNTERS
) {
5788 fprintf(stderr
, "exceeded max %d added package counters\n",
5789 MAX_ADDED_COUNTERS
);
5798 void parse_add_command(char *add_command
)
5802 char name_buffer
[NAME_BYTES
] = "";
5805 enum counter_scope scope
= SCOPE_CPU
;
5806 enum counter_type type
= COUNTER_CYCLES
;
5807 enum counter_format format
= FORMAT_DELTA
;
5809 while (add_command
) {
5811 if (sscanf(add_command
, "msr0x%x", &msr_num
) == 1)
5814 if (sscanf(add_command
, "msr%d", &msr_num
) == 1)
5817 if (*add_command
== '/') {
5822 if (sscanf(add_command
, "u%d", &width
) == 1) {
5823 if ((width
== 32) || (width
== 64))
5827 if (!strncmp(add_command
, "cpu", strlen("cpu"))) {
5831 if (!strncmp(add_command
, "core", strlen("core"))) {
5835 if (!strncmp(add_command
, "package", strlen("package"))) {
5836 scope
= SCOPE_PACKAGE
;
5839 if (!strncmp(add_command
, "cycles", strlen("cycles"))) {
5840 type
= COUNTER_CYCLES
;
5843 if (!strncmp(add_command
, "seconds", strlen("seconds"))) {
5844 type
= COUNTER_SECONDS
;
5847 if (!strncmp(add_command
, "usec", strlen("usec"))) {
5848 type
= COUNTER_USEC
;
5851 if (!strncmp(add_command
, "raw", strlen("raw"))) {
5852 format
= FORMAT_RAW
;
5855 if (!strncmp(add_command
, "delta", strlen("delta"))) {
5856 format
= FORMAT_DELTA
;
5859 if (!strncmp(add_command
, "percent", strlen("percent"))) {
5860 format
= FORMAT_PERCENT
;
5864 if (sscanf(add_command
, "%18s,%*s", name_buffer
) == 1) { /* 18 < NAME_BYTES */
5867 eos
= strchr(name_buffer
, ',');
5874 add_command
= strchr(add_command
, ',');
5876 *add_command
= '\0';
5881 if ((msr_num
== 0) && (path
== NULL
)) {
5882 fprintf(stderr
, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
5886 /* generate default column header */
5887 if (*name_buffer
== '\0') {
5889 sprintf(name_buffer
, "M0x%x%s", msr_num
, format
== FORMAT_PERCENT
? "%" : "");
5891 sprintf(name_buffer
, "M0X%x%s", msr_num
, format
== FORMAT_PERCENT
? "%" : "");
5894 if (add_counter(msr_num
, path
, name_buffer
, width
, scope
, type
, format
, 0))
5903 int is_deferred_skip(char *name
)
5907 for (i
= 0; i
< deferred_skip_index
; ++i
)
5908 if (!strcmp(name
, deferred_skip_names
[i
]))
5913 void probe_sysfs(void)
5921 if (!DO_BIC(BIC_sysfs
))
5924 for (state
= 10; state
>= 0; --state
) {
5926 sprintf(path
, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
5928 input
= fopen(path
, "r");
5931 if (!fgets(name_buf
, sizeof(name_buf
), input
))
5932 err(1, "%s: failed to read file", path
);
5934 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
5935 sp
= strchr(name_buf
, '-');
5937 sp
= strchrnul(name_buf
, '\n');
5941 remove_underbar(name_buf
);
5945 sprintf(path
, "cpuidle/state%d/time", state
);
5947 if (is_deferred_skip(name_buf
))
5950 add_counter(0, path
, name_buf
, 64, SCOPE_CPU
, COUNTER_USEC
,
5951 FORMAT_PERCENT
, SYSFS_PERCPU
);
5954 for (state
= 10; state
>= 0; --state
) {
5956 sprintf(path
, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
5958 input
= fopen(path
, "r");
5961 if (!fgets(name_buf
, sizeof(name_buf
), input
))
5962 err(1, "%s: failed to read file", path
);
5963 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
5964 sp
= strchr(name_buf
, '-');
5966 sp
= strchrnul(name_buf
, '\n');
5970 remove_underbar(name_buf
);
5972 sprintf(path
, "cpuidle/state%d/usage", state
);
5974 if (is_deferred_skip(name_buf
))
5977 add_counter(0, path
, name_buf
, 64, SCOPE_CPU
, COUNTER_ITEMS
,
5978 FORMAT_DELTA
, SYSFS_PERCPU
);
5985 * parse cpuset with following syntax
5986 * 1,2,4..6,8-10 and set bits in cpu_subset
5988 void parse_cpu_command(char *optarg
)
5990 unsigned int start
, end
;
5993 if (!strcmp(optarg
, "core")) {
5999 if (!strcmp(optarg
, "package")) {
6005 if (show_core_only
|| show_pkg_only
)
6008 cpu_subset
= CPU_ALLOC(CPU_SUBSET_MAXCPUS
);
6009 if (cpu_subset
== NULL
)
6010 err(3, "CPU_ALLOC");
6011 cpu_subset_size
= CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS
);
6013 CPU_ZERO_S(cpu_subset_size
, cpu_subset
);
6017 while (next
&& *next
) {
6019 if (*next
== '-') /* no negative cpu numbers */
6022 start
= strtoul(next
, &next
, 10);
6024 if (start
>= CPU_SUBSET_MAXCPUS
)
6026 CPU_SET_S(start
, cpu_subset_size
, cpu_subset
);
6037 next
+= 1; /* start range */
6038 } else if (*next
== '.') {
6041 next
+= 1; /* start range */
6046 end
= strtoul(next
, &next
, 10);
6050 while (++start
<= end
) {
6051 if (start
>= CPU_SUBSET_MAXCPUS
)
6053 CPU_SET_S(start
, cpu_subset_size
, cpu_subset
);
6058 else if (*next
!= '\0')
6065 fprintf(stderr
, "\"--cpu %s\" malformed\n", optarg
);
6071 void cmdline(int argc
, char **argv
)
6074 int option_index
= 0;
6075 static struct option long_options
[] = {
6076 {"add", required_argument
, 0, 'a'},
6077 {"cpu", required_argument
, 0, 'c'},
6078 {"Dump", no_argument
, 0, 'D'},
6079 {"debug", no_argument
, 0, 'd'}, /* internal, not documented */
6080 {"enable", required_argument
, 0, 'e'},
6081 {"interval", required_argument
, 0, 'i'},
6082 {"num_iterations", required_argument
, 0, 'n'},
6083 {"help", no_argument
, 0, 'h'},
6084 {"hide", required_argument
, 0, 'H'}, // meh, -h taken by --help
6085 {"Joules", no_argument
, 0, 'J'},
6086 {"list", no_argument
, 0, 'l'},
6087 {"out", required_argument
, 0, 'o'},
6088 {"quiet", no_argument
, 0, 'q'},
6089 {"show", required_argument
, 0, 's'},
6090 {"Summary", no_argument
, 0, 'S'},
6091 {"TCC", required_argument
, 0, 'T'},
6092 {"version", no_argument
, 0, 'v' },
6098 while ((opt
= getopt_long_only(argc
, argv
, "+C:c:Dde:hi:Jn:o:qST:v",
6099 long_options
, &option_index
)) != -1) {
6102 parse_add_command(optarg
);
6105 parse_cpu_command(optarg
);
6111 /* --enable specified counter */
6112 bic_enabled
= bic_enabled
| bic_lookup(optarg
, SHOW_LIST
);
6116 ENABLE_BIC(BIC_DISABLED_BY_DEFAULT
);
6120 * --hide: do not show those specified
6121 * multiple invocations simply clear more bits in enabled mask
6123 bic_enabled
&= ~bic_lookup(optarg
, HIDE_LIST
);
6131 double interval
= strtod(optarg
, NULL
);
6133 if (interval
< 0.001) {
6134 fprintf(outf
, "interval %f seconds is too small\n",
6139 interval_tv
.tv_sec
= interval_ts
.tv_sec
= interval
;
6140 interval_tv
.tv_usec
= (interval
- interval_tv
.tv_sec
) * 1000000;
6141 interval_ts
.tv_nsec
= (interval
- interval_ts
.tv_sec
) * 1000000000;
6148 ENABLE_BIC(BIC_DISABLED_BY_DEFAULT
);
6153 outf
= fopen_or_die(optarg
, "w");
6159 num_iterations
= strtod(optarg
, NULL
);
6161 if (num_iterations
<= 0) {
6162 fprintf(outf
, "iterations %d should be positive number\n",
6169 * --show: show only those specified
6170 * The 1st invocation will clear and replace the enabled mask
6171 * subsequent invocations can add to it.
6174 bic_enabled
= bic_lookup(optarg
, SHOW_LIST
);
6176 bic_enabled
|= bic_lookup(optarg
, SHOW_LIST
);
6183 tcc_activation_temp_override
= atoi(optarg
);
6193 int main(int argc
, char **argv
)
6196 cmdline(argc
, argv
);
6205 /* dump counters and exit */
6207 return get_and_dump_counters();
6209 /* list header and exit */
6210 if (list_header_only
) {
6212 flush_output_stdout();
6218 * if any params left, it must be a command to fork
6221 return fork_it(argv
+ optind
);