blob: 48b540a2fe81e618a43abf31c239c43b8ba55023 [file] [log] [blame]
Len Brown103a8fe2010-10-22 23:53:03 -04001/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
Len Brown144b44b2013-11-09 00:30:16 -05005 * Copyright (c) 2013 Intel Corporation.
Len Brown103a8fe2010-10-22 23:53:03 -04006 * Len Brown <len.brown@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
Len Brown88c32812012-03-29 21:44:40 -040022#define _GNU_SOURCE
Josh Triplettb731f312013-08-20 17:20:12 -070023#include MSRHEADER
Len Brown869ce692016-06-16 23:22:37 -040024#include INTEL_FAMILY_HEADER
Josh Triplett95aebc42013-08-20 17:20:16 -070025#include <stdarg.h>
Len Brown103a8fe2010-10-22 23:53:03 -040026#include <stdio.h>
Josh Triplettb2c95d92013-08-20 17:20:18 -070027#include <err.h>
Len Brown103a8fe2010-10-22 23:53:03 -040028#include <unistd.h>
29#include <sys/types.h>
30#include <sys/wait.h>
31#include <sys/stat.h>
32#include <sys/resource.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <sys/time.h>
36#include <stdlib.h>
Len Brownd8af6f52015-02-10 01:56:38 -050037#include <getopt.h>
Len Brown103a8fe2010-10-22 23:53:03 -040038#include <dirent.h>
39#include <string.h>
40#include <ctype.h>
Len Brown88c32812012-03-29 21:44:40 -040041#include <sched.h>
Len Brown2a0609c2016-02-12 22:44:48 -050042#include <time.h>
Josh Triplett2b928652013-08-20 17:20:14 -070043#include <cpuid.h>
Len Brown98481e72014-08-15 00:36:50 -040044#include <linux/capability.h>
45#include <errno.h>
Len Brown103a8fe2010-10-22 23:53:03 -040046
Len Brown103a8fe2010-10-22 23:53:03 -040047char *proc_stat = "/proc/stat";
Len Brownb7d8c142016-02-13 23:36:17 -050048FILE *outf;
Len Brown36229892016-02-26 20:51:02 -050049int *fd_percpu;
Len Brown2a0609c2016-02-12 22:44:48 -050050struct timespec interval_ts = {5, 0};
Len Brownd8af6f52015-02-10 01:56:38 -050051unsigned int debug;
Len Brown96e47152017-01-21 02:26:00 -050052unsigned int quiet;
Len Brownd8af6f52015-02-10 01:56:38 -050053unsigned int rapl_joules;
54unsigned int summary_only;
55unsigned int dump_only;
Len Brown103a8fe2010-10-22 23:53:03 -040056unsigned int do_snb_cstates;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -070057unsigned int do_knl_cstates;
Len Brown0b2bb692015-03-26 00:50:30 -040058unsigned int do_skl_residency;
Len Brown144b44b2013-11-09 00:30:16 -050059unsigned int do_slm_cstates;
60unsigned int use_c1_residency_msr;
Len Brown103a8fe2010-10-22 23:53:03 -040061unsigned int has_aperf;
Len Brown889facb2012-11-08 00:48:57 -050062unsigned int has_epb;
Len Brown5a634262016-04-06 17:15:55 -040063unsigned int do_irtl_snb;
64unsigned int do_irtl_hsw;
Len Brownfc04cc62014-02-06 00:55:19 -050065unsigned int units = 1000000; /* MHz etc */
Len Brown103a8fe2010-10-22 23:53:03 -040066unsigned int genuine_intel;
67unsigned int has_invariant_tsc;
Len Brownd7899442015-01-23 00:12:33 -050068unsigned int do_nhm_platform_info;
Len Browncf4cbe52017-01-01 13:08:33 -050069unsigned int no_MSR_MISC_PWR_MGMT;
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +020070unsigned int aperf_mperf_multiplier = 1;
Len Brown103a8fe2010-10-22 23:53:03 -040071double bclk;
Len Browna2b7b742015-09-26 00:12:38 -040072double base_hz;
Len Brown21ed5572015-10-19 22:37:40 -040073unsigned int has_base_hz;
Len Browna2b7b742015-09-26 00:12:38 -040074double tsc_tweak = 1.0;
Len Brownc98d5d92012-06-04 00:56:40 -040075unsigned int show_pkg_only;
76unsigned int show_core_only;
77char *output_buffer, *outp;
Len Brown889facb2012-11-08 00:48:57 -050078unsigned int do_rapl;
79unsigned int do_dts;
80unsigned int do_ptm;
Len Brownfdf676e2016-02-27 01:28:12 -050081unsigned long long gfx_cur_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -050082unsigned int gfx_cur_mhz;
Len Brown889facb2012-11-08 00:48:57 -050083unsigned int tcc_activation_temp;
84unsigned int tcc_activation_temp_override;
Andrey Semin40ee8e32014-12-05 00:07:00 -050085double rapl_power_units, rapl_time_units;
86double rapl_dram_energy_units, rapl_energy_units;
Len Brown889facb2012-11-08 00:48:57 -050087double rapl_joule_counter_range;
Len Brown3a9a9412014-08-15 02:39:52 -040088unsigned int do_core_perf_limit_reasons;
89unsigned int do_gfx_perf_limit_reasons;
90unsigned int do_ring_perf_limit_reasons;
Len Brown8a5bdf42015-04-01 21:02:57 -040091unsigned int crystal_hz;
92unsigned long long tsc_hz;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -040093int base_cpu;
Len Brown21ed5572015-10-19 22:37:40 -040094double discover_bclk(unsigned int family, unsigned int model);
Len Brown7f5c2582015-12-01 01:36:39 -050095unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
96 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */
97unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
98unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
99unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
100unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
Len Brown33148d62017-01-21 01:26:16 -0500101unsigned int has_misc_feature_control;
Len Brown889facb2012-11-08 00:48:57 -0500102
Len Browne6f9bb32013-12-03 02:19:19 -0500103#define RAPL_PKG (1 << 0)
104 /* 0x610 MSR_PKG_POWER_LIMIT */
105 /* 0x611 MSR_PKG_ENERGY_STATUS */
106#define RAPL_PKG_PERF_STATUS (1 << 1)
107 /* 0x613 MSR_PKG_PERF_STATUS */
108#define RAPL_PKG_POWER_INFO (1 << 2)
109 /* 0x614 MSR_PKG_POWER_INFO */
110
111#define RAPL_DRAM (1 << 3)
112 /* 0x618 MSR_DRAM_POWER_LIMIT */
113 /* 0x619 MSR_DRAM_ENERGY_STATUS */
Len Browne6f9bb32013-12-03 02:19:19 -0500114#define RAPL_DRAM_PERF_STATUS (1 << 4)
115 /* 0x61b MSR_DRAM_PERF_STATUS */
Len Brown0b2bb692015-03-26 00:50:30 -0400116#define RAPL_DRAM_POWER_INFO (1 << 5)
117 /* 0x61c MSR_DRAM_POWER_INFO */
Len Browne6f9bb32013-12-03 02:19:19 -0500118
Jacob Pan91484942016-06-16 09:48:20 -0700119#define RAPL_CORES_POWER_LIMIT (1 << 6)
Len Browne6f9bb32013-12-03 02:19:19 -0500120 /* 0x638 MSR_PP0_POWER_LIMIT */
Len Brown0b2bb692015-03-26 00:50:30 -0400121#define RAPL_CORE_POLICY (1 << 7)
Len Browne6f9bb32013-12-03 02:19:19 -0500122 /* 0x63a MSR_PP0_POLICY */
123
Len Brown0b2bb692015-03-26 00:50:30 -0400124#define RAPL_GFX (1 << 8)
Len Browne6f9bb32013-12-03 02:19:19 -0500125 /* 0x640 MSR_PP1_POWER_LIMIT */
126 /* 0x641 MSR_PP1_ENERGY_STATUS */
127 /* 0x642 MSR_PP1_POLICY */
Jacob Pan91484942016-06-16 09:48:20 -0700128
129#define RAPL_CORES_ENERGY_STATUS (1 << 9)
130 /* 0x639 MSR_PP0_ENERGY_STATUS */
131#define RAPL_CORES (RAPL_CORES_ENERGY_STATUS | RAPL_CORES_POWER_LIMIT)
Len Brown889facb2012-11-08 00:48:57 -0500132#define TJMAX_DEFAULT 100
133
134#define MAX(a, b) ((a) > (b) ? (a) : (b))
Len Brown103a8fe2010-10-22 23:53:03 -0400135
Len Brown388e9c82016-12-22 23:57:55 -0500136/*
137 * buffer size used by sscanf() for added column names
138 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
139 */
140#define NAME_BYTES 20
Len Brown495c76542017-02-08 02:41:51 -0500141#define PATH_BYTES 128
Len Brown388e9c82016-12-22 23:57:55 -0500142
Len Brown103a8fe2010-10-22 23:53:03 -0400143int backwards_count;
144char *progname;
Len Brown103a8fe2010-10-22 23:53:03 -0400145
Len Brown1ef7d212017-02-10 23:54:15 -0500146#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
147cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset;
148size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
Len Brown678a3bd2017-02-09 22:22:13 -0500149#define MAX_ADDED_COUNTERS 16
Len Brown103a8fe2010-10-22 23:53:03 -0400150
Len Brownc98d5d92012-06-04 00:56:40 -0400151struct thread_data {
152 unsigned long long tsc;
153 unsigned long long aperf;
154 unsigned long long mperf;
Len Brown144b44b2013-11-09 00:30:16 -0500155 unsigned long long c1;
Len Brown562a2d32016-02-26 23:48:05 -0500156 unsigned int irq_count;
Len Brown1ed51012013-02-10 17:19:24 -0500157 unsigned int smi_count;
Len Brownc98d5d92012-06-04 00:56:40 -0400158 unsigned int cpu_id;
159 unsigned int flags;
160#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
161#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
Len Brown678a3bd2017-02-09 22:22:13 -0500162 unsigned long long counter[MAX_ADDED_COUNTERS];
Len Brownc98d5d92012-06-04 00:56:40 -0400163} *thread_even, *thread_odd;
Len Brown103a8fe2010-10-22 23:53:03 -0400164
Len Brownc98d5d92012-06-04 00:56:40 -0400165struct core_data {
166 unsigned long long c3;
167 unsigned long long c6;
168 unsigned long long c7;
Len Brown0539ba12017-02-10 00:27:20 -0500169 unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */
Len Brown889facb2012-11-08 00:48:57 -0500170 unsigned int core_temp_c;
Len Brownc98d5d92012-06-04 00:56:40 -0400171 unsigned int core_id;
Len Brown678a3bd2017-02-09 22:22:13 -0500172 unsigned long long counter[MAX_ADDED_COUNTERS];
Len Brownc98d5d92012-06-04 00:56:40 -0400173} *core_even, *core_odd;
Len Brown103a8fe2010-10-22 23:53:03 -0400174
Len Brownc98d5d92012-06-04 00:56:40 -0400175struct pkg_data {
176 unsigned long long pc2;
177 unsigned long long pc3;
178 unsigned long long pc6;
179 unsigned long long pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800180 unsigned long long pc8;
181 unsigned long long pc9;
182 unsigned long long pc10;
Len Brown0b2bb692015-03-26 00:50:30 -0400183 unsigned long long pkg_wtd_core_c0;
184 unsigned long long pkg_any_core_c0;
185 unsigned long long pkg_any_gfxe_c0;
186 unsigned long long pkg_both_core_gfxe_c0;
Len Brown9185e982016-04-06 17:16:00 -0400187 long long gfx_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -0500188 unsigned int gfx_mhz;
Len Brownc98d5d92012-06-04 00:56:40 -0400189 unsigned int package_id;
Len Brown889facb2012-11-08 00:48:57 -0500190 unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
191 unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
192 unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
193 unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
194 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
195 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
196 unsigned int pkg_temp_c;
Len Brown678a3bd2017-02-09 22:22:13 -0500197 unsigned long long counter[MAX_ADDED_COUNTERS];
Len Brownc98d5d92012-06-04 00:56:40 -0400198} *package_even, *package_odd;
199
200#define ODD_COUNTERS thread_odd, core_odd, package_odd
201#define EVEN_COUNTERS thread_even, core_even, package_even
202
203#define GET_THREAD(thread_base, thread_no, core_no, pkg_no) \
204 (thread_base + (pkg_no) * topo.num_cores_per_pkg * \
205 topo.num_threads_per_core + \
206 (core_no) * topo.num_threads_per_core + (thread_no))
207#define GET_CORE(core_base, core_no, pkg_no) \
208 (core_base + (pkg_no) * topo.num_cores_per_pkg + (core_no))
209#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
210
Len Brown388e9c82016-12-22 23:57:55 -0500211enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE};
Len Brown41618e62017-02-09 18:25:22 -0500212enum counter_type {COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC};
Len Brown388e9c82016-12-22 23:57:55 -0500213enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT};
214
215struct msr_counter {
216 unsigned int msr_num;
217 char name[NAME_BYTES];
Len Brown495c76542017-02-08 02:41:51 -0500218 char path[PATH_BYTES];
Len Brown388e9c82016-12-22 23:57:55 -0500219 unsigned int width;
220 enum counter_type type;
221 enum counter_format format;
222 struct msr_counter *next;
Len Brown812db3f2017-02-10 00:25:41 -0500223 unsigned int flags;
224#define FLAGS_HIDE (1 << 0)
225#define FLAGS_SHOW (1 << 1)
Len Brown41618e62017-02-09 18:25:22 -0500226#define SYSFS_PERCPU (1 << 1)
Len Brown388e9c82016-12-22 23:57:55 -0500227};
228
229struct sys_counters {
Len Brown678a3bd2017-02-09 22:22:13 -0500230 unsigned int added_thread_counters;
231 unsigned int added_core_counters;
232 unsigned int added_package_counters;
Len Brown388e9c82016-12-22 23:57:55 -0500233 struct msr_counter *tp;
234 struct msr_counter *cp;
235 struct msr_counter *pp;
236} sys;
237
Len Brownc98d5d92012-06-04 00:56:40 -0400238struct system_summary {
239 struct thread_data threads;
240 struct core_data cores;
241 struct pkg_data packages;
Len Brown388e9c82016-12-22 23:57:55 -0500242} average;
Len Brownc98d5d92012-06-04 00:56:40 -0400243
244
245struct topo_params {
246 int num_packages;
247 int num_cpus;
248 int num_cores;
249 int max_cpu_num;
250 int num_cores_per_pkg;
251 int num_threads_per_core;
252} topo;
253
254struct timeval tv_even, tv_odd, tv_delta;
255
Len Brown562a2d32016-02-26 23:48:05 -0500256int *irq_column_2_cpu; /* /proc/interrupts column numbers */
257int *irqs_per_cpu; /* indexed by cpu_num */
258
Len Brownc98d5d92012-06-04 00:56:40 -0400259void setup_all_buffers(void);
260
261int cpu_is_not_present(int cpu)
Len Brownd15cf7c2012-06-03 23:24:00 -0400262{
Len Brownc98d5d92012-06-04 00:56:40 -0400263 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brownd15cf7c2012-06-03 23:24:00 -0400264}
Len Brown88c32812012-03-29 21:44:40 -0400265/*
Len Brownc98d5d92012-06-04 00:56:40 -0400266 * run func(thread, core, package) in topology order
267 * skip non-present cpus
Len Brown88c32812012-03-29 21:44:40 -0400268 */
Len Brownd15cf7c2012-06-03 23:24:00 -0400269
Len Brownc98d5d92012-06-04 00:56:40 -0400270int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
271 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
Len Brown88c32812012-03-29 21:44:40 -0400272{
Len Brownc98d5d92012-06-04 00:56:40 -0400273 int retval, pkg_no, core_no, thread_no;
274
275 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
276 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
277 for (thread_no = 0; thread_no <
278 topo.num_threads_per_core; ++thread_no) {
279 struct thread_data *t;
280 struct core_data *c;
281 struct pkg_data *p;
282
283 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
284
285 if (cpu_is_not_present(t->cpu_id))
286 continue;
287
288 c = GET_CORE(core_base, core_no, pkg_no);
289 p = GET_PKG(pkg_base, pkg_no);
290
291 retval = func(t, c, p);
292 if (retval)
293 return retval;
294 }
295 }
296 }
297 return 0;
Len Brown88c32812012-03-29 21:44:40 -0400298}
299
300int cpu_migrate(int cpu)
301{
Len Brownc98d5d92012-06-04 00:56:40 -0400302 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
303 CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set);
304 if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1)
Len Brown88c32812012-03-29 21:44:40 -0400305 return -1;
306 else
307 return 0;
308}
Len Brown36229892016-02-26 20:51:02 -0500309int get_msr_fd(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -0400310{
Len Brown103a8fe2010-10-22 23:53:03 -0400311 char pathname[32];
312 int fd;
313
Len Brown36229892016-02-26 20:51:02 -0500314 fd = fd_percpu[cpu];
315
316 if (fd)
317 return fd;
318
Len Brown103a8fe2010-10-22 23:53:03 -0400319 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
320 fd = open(pathname, O_RDONLY);
Len Brown15aaa342012-03-29 22:19:58 -0400321 if (fd < 0)
Len Brown98481e72014-08-15 00:36:50 -0400322 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
Len Brown103a8fe2010-10-22 23:53:03 -0400323
Len Brown36229892016-02-26 20:51:02 -0500324 fd_percpu[cpu] = fd;
325
326 return fd;
327}
328
329int get_msr(int cpu, off_t offset, unsigned long long *msr)
330{
331 ssize_t retval;
332
333 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
Len Brown15aaa342012-03-29 22:19:58 -0400334
Len Brown98481e72014-08-15 00:36:50 -0400335 if (retval != sizeof *msr)
Len Browncf4cbe52017-01-01 13:08:33 -0500336 err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
Len Brown15aaa342012-03-29 22:19:58 -0400337
338 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400339}
340
Len Brownfc04cc62014-02-06 00:55:19 -0500341/*
Len Brown812db3f2017-02-10 00:25:41 -0500342 * Each string in this array is compared in --show and --hide cmdline.
343 * Thus, strings that are proper sub-sets must follow their more specific peers.
Len Brownfc04cc62014-02-06 00:55:19 -0500344 */
Len Brown812db3f2017-02-10 00:25:41 -0500345struct msr_counter bic[] = {
346 { 0x0, "Package" },
347 { 0x0, "Avg_MHz" },
348 { 0x0, "Bzy_MHz" },
349 { 0x0, "TSC_MHz" },
350 { 0x0, "IRQ" },
Len Brown495c76542017-02-08 02:41:51 -0500351 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL},
Len Brown812db3f2017-02-10 00:25:41 -0500352 { 0x0, "Busy%" },
353 { 0x0, "CPU%c1" },
354 { 0x0, "CPU%c3" },
355 { 0x0, "CPU%c6" },
356 { 0x0, "CPU%c7" },
357 { 0x0, "ThreadC" },
358 { 0x0, "CoreTmp" },
359 { 0x0, "CoreCnt" },
360 { 0x0, "PkgTmp" },
361 { 0x0, "GFX%rc6" },
362 { 0x0, "GFXMHz" },
363 { 0x0, "Pkg%pc2" },
364 { 0x0, "Pkg%pc3" },
365 { 0x0, "Pkg%pc6" },
366 { 0x0, "Pkg%pc7" },
Len Brown0f47c082017-01-27 00:50:45 -0500367 { 0x0, "Pkg%pc8" },
368 { 0x0, "Pkg%pc9" },
369 { 0x0, "Pkg%pc10" },
Len Brown812db3f2017-02-10 00:25:41 -0500370 { 0x0, "PkgWatt" },
371 { 0x0, "CorWatt" },
372 { 0x0, "GFXWatt" },
373 { 0x0, "PkgCnt" },
374 { 0x0, "RAMWatt" },
375 { 0x0, "PKG_%" },
376 { 0x0, "RAM_%" },
377 { 0x0, "Pkg_J" },
378 { 0x0, "Cor_J" },
379 { 0x0, "GFX_J" },
380 { 0x0, "RAM_J" },
381 { 0x0, "Core" },
382 { 0x0, "CPU" },
Len Brown0539ba12017-02-10 00:27:20 -0500383 { 0x0, "Mod%c6" },
Len Brown41618e62017-02-09 18:25:22 -0500384 { 0x0, "sysfs" },
Len Brown812db3f2017-02-10 00:25:41 -0500385};
386
387#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
388#define BIC_Package (1ULL << 0)
389#define BIC_Avg_MHz (1ULL << 1)
390#define BIC_Bzy_MHz (1ULL << 2)
391#define BIC_TSC_MHz (1ULL << 3)
392#define BIC_IRQ (1ULL << 4)
393#define BIC_SMI (1ULL << 5)
394#define BIC_Busy (1ULL << 6)
395#define BIC_CPU_c1 (1ULL << 7)
396#define BIC_CPU_c3 (1ULL << 8)
397#define BIC_CPU_c6 (1ULL << 9)
398#define BIC_CPU_c7 (1ULL << 10)
399#define BIC_ThreadC (1ULL << 11)
400#define BIC_CoreTmp (1ULL << 12)
401#define BIC_CoreCnt (1ULL << 13)
402#define BIC_PkgTmp (1ULL << 14)
403#define BIC_GFX_rc6 (1ULL << 15)
404#define BIC_GFXMHz (1ULL << 16)
405#define BIC_Pkgpc2 (1ULL << 17)
406#define BIC_Pkgpc3 (1ULL << 18)
407#define BIC_Pkgpc6 (1ULL << 19)
408#define BIC_Pkgpc7 (1ULL << 20)
Len Brown0f47c082017-01-27 00:50:45 -0500409#define BIC_Pkgpc8 (1ULL << 21)
410#define BIC_Pkgpc9 (1ULL << 22)
411#define BIC_Pkgpc10 (1ULL << 23)
412#define BIC_PkgWatt (1ULL << 24)
413#define BIC_CorWatt (1ULL << 25)
414#define BIC_GFXWatt (1ULL << 26)
415#define BIC_PkgCnt (1ULL << 27)
416#define BIC_RAMWatt (1ULL << 28)
417#define BIC_PKG__ (1ULL << 29)
418#define BIC_RAM__ (1ULL << 30)
419#define BIC_Pkg_J (1ULL << 31)
420#define BIC_Cor_J (1ULL << 32)
421#define BIC_GFX_J (1ULL << 33)
422#define BIC_RAM_J (1ULL << 34)
423#define BIC_Core (1ULL << 35)
424#define BIC_CPU (1ULL << 36)
425#define BIC_Mod_c6 (1ULL << 37)
Len Brown41618e62017-02-09 18:25:22 -0500426#define BIC_sysfs (1ULL << 38)
Len Brown812db3f2017-02-10 00:25:41 -0500427
428unsigned long long bic_enabled = 0xFFFFFFFFFFFFFFFFULL;
Len Brown41618e62017-02-09 18:25:22 -0500429unsigned long long bic_present = BIC_sysfs;
Len Brown812db3f2017-02-10 00:25:41 -0500430
431#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
432#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
Len Brown0f47c082017-01-27 00:50:45 -0500433#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
Len Brown812db3f2017-02-10 00:25:41 -0500434
435/*
436 * bic_lookup
437 * for all the strings in comma separate name_list,
438 * set the approprate bit in return value.
439 */
440unsigned long long bic_lookup(char *name_list)
441{
442 int i;
443 unsigned long long retval = 0;
444
445 while (name_list) {
446 char *comma;
447
448 comma = strchr(name_list, ',');
449
450 if (comma)
451 *comma = '\0';
452
453 for (i = 0; i < MAX_BIC; ++i) {
454 if (!strcmp(name_list, bic[i].name)) {
455 retval |= (1ULL << i);
456 break;
457 }
458 }
459 if (i == MAX_BIC) {
460 fprintf(stderr, "Invalid counter name: %s\n", name_list);
461 exit(-1);
462 }
463
464 name_list = comma;
465 if (name_list)
466 name_list++;
467
468 }
469 return retval;
470}
Len Brownfc04cc62014-02-06 00:55:19 -0500471
Len Browna829eb42011-02-10 23:36:34 -0500472void print_header(void)
Len Brown103a8fe2010-10-22 23:53:03 -0400473{
Len Brown388e9c82016-12-22 23:57:55 -0500474 struct msr_counter *mp;
475
Len Brown812db3f2017-02-10 00:25:41 -0500476 if (DO_BIC(BIC_Package))
Len Brown3d109de2016-04-22 23:24:27 -0400477 outp += sprintf(outp, "\tPackage");
Len Brown812db3f2017-02-10 00:25:41 -0500478 if (DO_BIC(BIC_Core))
Len Brown3d109de2016-04-22 23:24:27 -0400479 outp += sprintf(outp, "\tCore");
Len Brown812db3f2017-02-10 00:25:41 -0500480 if (DO_BIC(BIC_CPU))
Len Brown3d109de2016-04-22 23:24:27 -0400481 outp += sprintf(outp, "\tCPU");
Len Brown812db3f2017-02-10 00:25:41 -0500482 if (DO_BIC(BIC_Avg_MHz))
Len Brown3d109de2016-04-22 23:24:27 -0400483 outp += sprintf(outp, "\tAvg_MHz");
Len Brown812db3f2017-02-10 00:25:41 -0500484 if (DO_BIC(BIC_Busy))
Len Brown3d109de2016-04-22 23:24:27 -0400485 outp += sprintf(outp, "\tBusy%%");
Len Brown812db3f2017-02-10 00:25:41 -0500486 if (DO_BIC(BIC_Bzy_MHz))
Len Brown3d109de2016-04-22 23:24:27 -0400487 outp += sprintf(outp, "\tBzy_MHz");
Len Brown812db3f2017-02-10 00:25:41 -0500488 if (DO_BIC(BIC_TSC_MHz))
489 outp += sprintf(outp, "\tTSC_MHz");
Len Brown1cc21f72015-02-23 00:34:57 -0500490
Len Brown812db3f2017-02-10 00:25:41 -0500491 if (DO_BIC(BIC_IRQ))
Len Brown3d109de2016-04-22 23:24:27 -0400492 outp += sprintf(outp, "\tIRQ");
Len Brown812db3f2017-02-10 00:25:41 -0500493 if (DO_BIC(BIC_SMI))
Len Brown3d109de2016-04-22 23:24:27 -0400494 outp += sprintf(outp, "\tSMI");
Len Brown1cc21f72015-02-23 00:34:57 -0500495
Len Brown388e9c82016-12-22 23:57:55 -0500496 for (mp = sys.tp; mp; mp = mp->next) {
497 if (mp->format == FORMAT_RAW) {
498 if (mp->width == 64)
499 outp += sprintf(outp, "\t%18.18s", mp->name);
500 else
501 outp += sprintf(outp, "\t%10.10s", mp->name);
502 } else {
Len Brown41618e62017-02-09 18:25:22 -0500503 outp += sprintf(outp, "\t%s", mp->name);
Len Brown388e9c82016-12-22 23:57:55 -0500504 }
505 }
506
Len Brown41618e62017-02-09 18:25:22 -0500507 if (DO_BIC(BIC_CPU_c1))
508 outp += sprintf(outp, "\tCPU%%c1");
Len Brown812db3f2017-02-10 00:25:41 -0500509 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates)
Len Brown678a3bd2017-02-09 22:22:13 -0500510 outp += sprintf(outp, "\tCPU%%c3");
Len Brown812db3f2017-02-10 00:25:41 -0500511 if (DO_BIC(BIC_CPU_c6))
Len Brown678a3bd2017-02-09 22:22:13 -0500512 outp += sprintf(outp, "\tCPU%%c6");
Len Brown812db3f2017-02-10 00:25:41 -0500513 if (DO_BIC(BIC_CPU_c7))
Len Brown678a3bd2017-02-09 22:22:13 -0500514 outp += sprintf(outp, "\tCPU%%c7");
515
Len Brown0539ba12017-02-10 00:27:20 -0500516 if (DO_BIC(BIC_Mod_c6))
517 outp += sprintf(outp, "\tMod%%c6");
Len Brown678a3bd2017-02-09 22:22:13 -0500518
Len Brown812db3f2017-02-10 00:25:41 -0500519 if (DO_BIC(BIC_CoreTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400520 outp += sprintf(outp, "\tCoreTmp");
Len Brown388e9c82016-12-22 23:57:55 -0500521
522 for (mp = sys.cp; mp; mp = mp->next) {
523 if (mp->format == FORMAT_RAW) {
524 if (mp->width == 64)
525 outp += sprintf(outp, "\t%18.18s", mp->name);
526 else
527 outp += sprintf(outp, "\t%10.10s", mp->name);
528 } else {
Len Brown41618e62017-02-09 18:25:22 -0500529 outp += sprintf(outp, "\t%s", mp->name);
Len Brown388e9c82016-12-22 23:57:55 -0500530 }
531 }
532
Len Brown812db3f2017-02-10 00:25:41 -0500533 if (DO_BIC(BIC_PkgTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400534 outp += sprintf(outp, "\tPkgTmp");
Len Brown889facb2012-11-08 00:48:57 -0500535
Len Brown812db3f2017-02-10 00:25:41 -0500536 if (DO_BIC(BIC_GFX_rc6))
Len Brown3d109de2016-04-22 23:24:27 -0400537 outp += sprintf(outp, "\tGFX%%rc6");
Len Brownfdf676e2016-02-27 01:28:12 -0500538
Len Brown812db3f2017-02-10 00:25:41 -0500539 if (DO_BIC(BIC_GFXMHz))
Len Brown3d109de2016-04-22 23:24:27 -0400540 outp += sprintf(outp, "\tGFXMHz");
Len Brown27d47352016-02-27 00:37:54 -0500541
Len Brown0b2bb692015-03-26 00:50:30 -0400542 if (do_skl_residency) {
Len Brown3d109de2016-04-22 23:24:27 -0400543 outp += sprintf(outp, "\tTotl%%C0");
544 outp += sprintf(outp, "\tAny%%C0");
545 outp += sprintf(outp, "\tGFX%%C0");
546 outp += sprintf(outp, "\tCPUGFX%%");
Len Brown0b2bb692015-03-26 00:50:30 -0400547 }
548
Len Brown0f47c082017-01-27 00:50:45 -0500549 if (DO_BIC(BIC_Pkgpc2))
Len Brown3d109de2016-04-22 23:24:27 -0400550 outp += sprintf(outp, "\tPkg%%pc2");
Len Brown0f47c082017-01-27 00:50:45 -0500551 if (DO_BIC(BIC_Pkgpc3))
Len Brown3d109de2016-04-22 23:24:27 -0400552 outp += sprintf(outp, "\tPkg%%pc3");
Len Brown0f47c082017-01-27 00:50:45 -0500553 if (DO_BIC(BIC_Pkgpc6))
Len Brown3d109de2016-04-22 23:24:27 -0400554 outp += sprintf(outp, "\tPkg%%pc6");
Len Brown0f47c082017-01-27 00:50:45 -0500555 if (DO_BIC(BIC_Pkgpc7))
Len Brown3d109de2016-04-22 23:24:27 -0400556 outp += sprintf(outp, "\tPkg%%pc7");
Len Brown0f47c082017-01-27 00:50:45 -0500557 if (DO_BIC(BIC_Pkgpc8))
Len Brown3d109de2016-04-22 23:24:27 -0400558 outp += sprintf(outp, "\tPkg%%pc8");
Len Brown0f47c082017-01-27 00:50:45 -0500559 if (DO_BIC(BIC_Pkgpc9))
Len Brown3d109de2016-04-22 23:24:27 -0400560 outp += sprintf(outp, "\tPkg%%pc9");
Len Brown0f47c082017-01-27 00:50:45 -0500561 if (DO_BIC(BIC_Pkgpc10))
Len Brown3d109de2016-04-22 23:24:27 -0400562 outp += sprintf(outp, "\tPk%%pc10");
Len Brown103a8fe2010-10-22 23:53:03 -0400563
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800564 if (do_rapl && !rapl_joules) {
Len Brown812db3f2017-02-10 00:25:41 -0500565 if (DO_BIC(BIC_PkgWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400566 outp += sprintf(outp, "\tPkgWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500567 if (DO_BIC(BIC_CorWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400568 outp += sprintf(outp, "\tCorWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500569 if (DO_BIC(BIC_GFXWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400570 outp += sprintf(outp, "\tGFXWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500571 if (DO_BIC(BIC_RAMWatt))
Len Brown3d109de2016-04-22 23:24:27 -0400572 outp += sprintf(outp, "\tRAMWatt");
Len Brown812db3f2017-02-10 00:25:41 -0500573 if (DO_BIC(BIC_PKG__))
Len Brown3d109de2016-04-22 23:24:27 -0400574 outp += sprintf(outp, "\tPKG_%%");
Len Brown812db3f2017-02-10 00:25:41 -0500575 if (DO_BIC(BIC_RAM__))
Len Brown3d109de2016-04-22 23:24:27 -0400576 outp += sprintf(outp, "\tRAM_%%");
Len Brownd7899442015-01-23 00:12:33 -0500577 } else if (do_rapl && rapl_joules) {
Len Brown812db3f2017-02-10 00:25:41 -0500578 if (DO_BIC(BIC_Pkg_J))
Len Brown3d109de2016-04-22 23:24:27 -0400579 outp += sprintf(outp, "\tPkg_J");
Len Brown812db3f2017-02-10 00:25:41 -0500580 if (DO_BIC(BIC_Cor_J))
Len Brown3d109de2016-04-22 23:24:27 -0400581 outp += sprintf(outp, "\tCor_J");
Len Brown812db3f2017-02-10 00:25:41 -0500582 if (DO_BIC(BIC_GFX_J))
Len Brown3d109de2016-04-22 23:24:27 -0400583 outp += sprintf(outp, "\tGFX_J");
Len Brown812db3f2017-02-10 00:25:41 -0500584 if (DO_BIC(BIC_RAM_J))
Len Brown3d109de2016-04-22 23:24:27 -0400585 outp += sprintf(outp, "\tRAM_J");
Len Brown812db3f2017-02-10 00:25:41 -0500586 if (DO_BIC(BIC_PKG__))
Len Brown3d109de2016-04-22 23:24:27 -0400587 outp += sprintf(outp, "\tPKG_%%");
Len Brown812db3f2017-02-10 00:25:41 -0500588 if (DO_BIC(BIC_RAM__))
Len Brown3d109de2016-04-22 23:24:27 -0400589 outp += sprintf(outp, "\tRAM_%%");
Dirk Brandewie5c56be92013-12-16 10:23:41 -0800590 }
Len Brown388e9c82016-12-22 23:57:55 -0500591 for (mp = sys.pp; mp; mp = mp->next) {
592 if (mp->format == FORMAT_RAW) {
593 if (mp->width == 64)
594 outp += sprintf(outp, "\t%18.18s", mp->name);
595 else
596 outp += sprintf(outp, "\t%10.10s", mp->name);
597 } else {
Len Brown41618e62017-02-09 18:25:22 -0500598 outp += sprintf(outp, "\t%s", mp->name);
Len Brown388e9c82016-12-22 23:57:55 -0500599 }
600 }
601
Len Brownc98d5d92012-06-04 00:56:40 -0400602 outp += sprintf(outp, "\n");
Len Brown103a8fe2010-10-22 23:53:03 -0400603}
604
Len Brownc98d5d92012-06-04 00:56:40 -0400605int dump_counters(struct thread_data *t, struct core_data *c,
606 struct pkg_data *p)
Len Brown103a8fe2010-10-22 23:53:03 -0400607{
Len Brown388e9c82016-12-22 23:57:55 -0500608 int i;
609 struct msr_counter *mp;
610
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200611 outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
Len Brown103a8fe2010-10-22 23:53:03 -0400612
Len Brownc98d5d92012-06-04 00:56:40 -0400613 if (t) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200614 outp += sprintf(outp, "CPU: %d flags 0x%x\n",
615 t->cpu_id, t->flags);
616 outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
617 outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
618 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
619 outp += sprintf(outp, "c1: %016llX\n", t->c1);
Len Brown6886fee2016-12-24 15:18:37 -0500620
Len Brown812db3f2017-02-10 00:25:41 -0500621 if (DO_BIC(BIC_IRQ))
Len Brown218f0e82017-02-14 22:07:52 -0500622 outp += sprintf(outp, "IRQ: %d\n", t->irq_count);
Len Brown812db3f2017-02-10 00:25:41 -0500623 if (DO_BIC(BIC_SMI))
Len Brown218f0e82017-02-14 22:07:52 -0500624 outp += sprintf(outp, "SMI: %d\n", t->smi_count);
Len Brown388e9c82016-12-22 23:57:55 -0500625
626 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
627 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n",
628 i, mp->msr_num, t->counter[i]);
629 }
Len Brownc98d5d92012-06-04 00:56:40 -0400630 }
Len Brown103a8fe2010-10-22 23:53:03 -0400631
Len Brownc98d5d92012-06-04 00:56:40 -0400632 if (c) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200633 outp += sprintf(outp, "core: %d\n", c->core_id);
634 outp += sprintf(outp, "c3: %016llX\n", c->c3);
635 outp += sprintf(outp, "c6: %016llX\n", c->c6);
636 outp += sprintf(outp, "c7: %016llX\n", c->c7);
637 outp += sprintf(outp, "DTS: %dC\n", c->core_temp_c);
Len Brown388e9c82016-12-22 23:57:55 -0500638
639 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
640 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n",
641 i, mp->msr_num, c->counter[i]);
642 }
Len Brown0539ba12017-02-10 00:27:20 -0500643 outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
Len Brownc98d5d92012-06-04 00:56:40 -0400644 }
645
646 if (p) {
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200647 outp += sprintf(outp, "package: %d\n", p->package_id);
Len Brown0b2bb692015-03-26 00:50:30 -0400648
649 outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0);
650 outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0);
651 outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0);
652 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
653
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200654 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
Len Brown0f47c082017-01-27 00:50:45 -0500655 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -0500656 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
Len Brown0f47c082017-01-27 00:50:45 -0500657 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -0500658 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
Len Brown0f47c082017-01-27 00:50:45 -0500659 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -0500660 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200661 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
662 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
663 outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
664 outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
665 outp += sprintf(outp, "Joules COR: %0X\n", p->energy_cores);
666 outp += sprintf(outp, "Joules GFX: %0X\n", p->energy_gfx);
667 outp += sprintf(outp, "Joules RAM: %0X\n", p->energy_dram);
668 outp += sprintf(outp, "Throttle PKG: %0X\n",
669 p->rapl_pkg_perf_status);
670 outp += sprintf(outp, "Throttle RAM: %0X\n",
671 p->rapl_dram_perf_status);
672 outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
Len Brown388e9c82016-12-22 23:57:55 -0500673
674 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
675 outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n",
676 i, mp->msr_num, p->counter[i]);
677 }
Len Brownc98d5d92012-06-04 00:56:40 -0400678 }
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +0200679
680 outp += sprintf(outp, "\n");
681
Len Brownc98d5d92012-06-04 00:56:40 -0400682 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400683}
684
Len Browne23da032012-02-06 18:37:16 -0500685/*
686 * column formatting convention & formats
Len Browne23da032012-02-06 18:37:16 -0500687 */
Len Brownc98d5d92012-06-04 00:56:40 -0400688int format_counters(struct thread_data *t, struct core_data *c,
689 struct pkg_data *p)
Len Brown103a8fe2010-10-22 23:53:03 -0400690{
Len Brown008d396e2017-02-10 00:29:51 -0500691 double interval_float, tsc;
Len Brownfc04cc62014-02-06 00:55:19 -0500692 char *fmt8;
Len Brown388e9c82016-12-22 23:57:55 -0500693 int i;
694 struct msr_counter *mp;
Len Brown103a8fe2010-10-22 23:53:03 -0400695
Len Brownc98d5d92012-06-04 00:56:40 -0400696 /* if showing only 1st thread in core and this isn't one, bail out */
697 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
698 return 0;
699
700 /* if showing only 1st thread in pkg and this isn't one, bail out */
701 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
702 return 0;
703
Len Brown1ef7d212017-02-10 23:54:15 -0500704 /*if not summary line and --cpu is used */
705 if ((t != &average.threads) &&
706 (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
707 return 0;
708
Len Brown103a8fe2010-10-22 23:53:03 -0400709 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
710
Len Brown008d396e2017-02-10 00:29:51 -0500711 tsc = t->tsc * tsc_tweak;
712
Len Brownc98d5d92012-06-04 00:56:40 -0400713 /* topo columns, print blanks on 1st (average) line */
714 if (t == &average.threads) {
Len Brown812db3f2017-02-10 00:25:41 -0500715 if (DO_BIC(BIC_Package))
Len Brown3d109de2016-04-22 23:24:27 -0400716 outp += sprintf(outp, "\t-");
Len Brown812db3f2017-02-10 00:25:41 -0500717 if (DO_BIC(BIC_Core))
Len Brown3d109de2016-04-22 23:24:27 -0400718 outp += sprintf(outp, "\t-");
Len Brown812db3f2017-02-10 00:25:41 -0500719 if (DO_BIC(BIC_CPU))
Len Brown3d109de2016-04-22 23:24:27 -0400720 outp += sprintf(outp, "\t-");
Len Brown103a8fe2010-10-22 23:53:03 -0400721 } else {
Len Brown812db3f2017-02-10 00:25:41 -0500722 if (DO_BIC(BIC_Package)) {
Len Brownc98d5d92012-06-04 00:56:40 -0400723 if (p)
Len Brown3d109de2016-04-22 23:24:27 -0400724 outp += sprintf(outp, "\t%d", p->package_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400725 else
Len Brown3d109de2016-04-22 23:24:27 -0400726 outp += sprintf(outp, "\t-");
Len Brownc98d5d92012-06-04 00:56:40 -0400727 }
Len Brown812db3f2017-02-10 00:25:41 -0500728 if (DO_BIC(BIC_Core)) {
Len Brownc98d5d92012-06-04 00:56:40 -0400729 if (c)
Len Brown3d109de2016-04-22 23:24:27 -0400730 outp += sprintf(outp, "\t%d", c->core_id);
Len Brownc98d5d92012-06-04 00:56:40 -0400731 else
Len Brown3d109de2016-04-22 23:24:27 -0400732 outp += sprintf(outp, "\t-");
Len Brownc98d5d92012-06-04 00:56:40 -0400733 }
Len Brown812db3f2017-02-10 00:25:41 -0500734 if (DO_BIC(BIC_CPU))
Len Brown3d109de2016-04-22 23:24:27 -0400735 outp += sprintf(outp, "\t%d", t->cpu_id);
Len Brown103a8fe2010-10-22 23:53:03 -0400736 }
Len Brownfc04cc62014-02-06 00:55:19 -0500737
Len Brown812db3f2017-02-10 00:25:41 -0500738 if (DO_BIC(BIC_Avg_MHz))
Len Brown3d109de2016-04-22 23:24:27 -0400739 outp += sprintf(outp, "\t%.0f",
Len Brownfc04cc62014-02-06 00:55:19 -0500740 1.0 / units * t->aperf / interval_float);
741
Len Brown812db3f2017-02-10 00:25:41 -0500742 if (DO_BIC(BIC_Busy))
Len Brown008d396e2017-02-10 00:29:51 -0500743 outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/tsc);
Len Brown103a8fe2010-10-22 23:53:03 -0400744
Len Brown812db3f2017-02-10 00:25:41 -0500745 if (DO_BIC(BIC_Bzy_MHz)) {
Len Brown21ed5572015-10-19 22:37:40 -0400746 if (has_base_hz)
Len Brown3d109de2016-04-22 23:24:27 -0400747 outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf);
Len Brown21ed5572015-10-19 22:37:40 -0400748 else
Len Brown3d109de2016-04-22 23:24:27 -0400749 outp += sprintf(outp, "\t%.0f",
Len Brown008d396e2017-02-10 00:29:51 -0500750 tsc / units * t->aperf / t->mperf / interval_float);
Len Brown21ed5572015-10-19 22:37:40 -0400751 }
Len Brown103a8fe2010-10-22 23:53:03 -0400752
Len Brown812db3f2017-02-10 00:25:41 -0500753 if (DO_BIC(BIC_TSC_MHz))
754 outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float);
Len Brown103a8fe2010-10-22 23:53:03 -0400755
Len Brown562a2d32016-02-26 23:48:05 -0500756 /* IRQ */
Len Brown812db3f2017-02-10 00:25:41 -0500757 if (DO_BIC(BIC_IRQ))
Len Brown3d109de2016-04-22 23:24:27 -0400758 outp += sprintf(outp, "\t%d", t->irq_count);
Len Brown562a2d32016-02-26 23:48:05 -0500759
Len Brown1cc21f72015-02-23 00:34:57 -0500760 /* SMI */
Len Brown812db3f2017-02-10 00:25:41 -0500761 if (DO_BIC(BIC_SMI))
Len Brown3d109de2016-04-22 23:24:27 -0400762 outp += sprintf(outp, "\t%d", t->smi_count);
Len Brown1cc21f72015-02-23 00:34:57 -0500763
Len Brown678a3bd2017-02-09 22:22:13 -0500764 /* Added counters */
765 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
766 if (mp->format == FORMAT_RAW) {
767 if (mp->width == 32)
768 outp += sprintf(outp, "\t0x%08lx", (unsigned long) t->counter[i]);
769 else
770 outp += sprintf(outp, "\t0x%016llx", t->counter[i]);
771 } else if (mp->format == FORMAT_DELTA) {
772 outp += sprintf(outp, "\t%lld", t->counter[i]);
773 } else if (mp->format == FORMAT_PERCENT) {
Len Brown41618e62017-02-09 18:25:22 -0500774 if (mp->type == COUNTER_USEC)
775 outp += sprintf(outp, "\t%.2f", t->counter[i]/interval_float/10000);
776 else
777 outp += sprintf(outp, "\t%.2f", 100.0 * t->counter[i]/tsc);
Len Brown678a3bd2017-02-09 22:22:13 -0500778 }
779 }
780
Len Brown41618e62017-02-09 18:25:22 -0500781 /* C1 */
782 if (DO_BIC(BIC_CPU_c1))
783 outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/tsc);
784
785
Len Brownc98d5d92012-06-04 00:56:40 -0400786 /* print per-core data only for 1st thread in core */
787 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
788 goto done;
789
Len Brown812db3f2017-02-10 00:25:41 -0500790 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates)
Len Brown008d396e2017-02-10 00:29:51 -0500791 outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/tsc);
Len Brown812db3f2017-02-10 00:25:41 -0500792 if (DO_BIC(BIC_CPU_c6))
Len Brown008d396e2017-02-10 00:29:51 -0500793 outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/tsc);
Len Brown812db3f2017-02-10 00:25:41 -0500794 if (DO_BIC(BIC_CPU_c7))
Len Brown008d396e2017-02-10 00:29:51 -0500795 outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/tsc);
Len Brownc98d5d92012-06-04 00:56:40 -0400796
Len Brown0539ba12017-02-10 00:27:20 -0500797 /* Mod%c6 */
798 if (DO_BIC(BIC_Mod_c6))
Len Brown008d396e2017-02-10 00:29:51 -0500799 outp += sprintf(outp, "\t%.2f", 100.0 * c->mc6_us / tsc);
Len Brown0539ba12017-02-10 00:27:20 -0500800
Len Brown812db3f2017-02-10 00:25:41 -0500801 if (DO_BIC(BIC_CoreTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400802 outp += sprintf(outp, "\t%d", c->core_temp_c);
Len Brown889facb2012-11-08 00:48:57 -0500803
Len Brown388e9c82016-12-22 23:57:55 -0500804 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
805 if (mp->format == FORMAT_RAW) {
806 if (mp->width == 32)
807 outp += sprintf(outp, "\t0x%08lx", (unsigned long) c->counter[i]);
808 else
809 outp += sprintf(outp, "\t0x%016llx", c->counter[i]);
810 } else if (mp->format == FORMAT_DELTA) {
Len Brown678a3bd2017-02-09 22:22:13 -0500811 outp += sprintf(outp, "\t%lld", c->counter[i]);
Len Brown388e9c82016-12-22 23:57:55 -0500812 } else if (mp->format == FORMAT_PERCENT) {
Len Brown008d396e2017-02-10 00:29:51 -0500813 outp += sprintf(outp, "\t%.2f", 100.0 * c->counter[i]/tsc);
Len Brown388e9c82016-12-22 23:57:55 -0500814 }
815 }
816
Len Brownc98d5d92012-06-04 00:56:40 -0400817 /* print per-package data only for 1st core in package */
818 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
819 goto done;
820
Len Brown0b2bb692015-03-26 00:50:30 -0400821 /* PkgTmp */
Len Brown812db3f2017-02-10 00:25:41 -0500822 if (DO_BIC(BIC_PkgTmp))
Len Brown3d109de2016-04-22 23:24:27 -0400823 outp += sprintf(outp, "\t%d", p->pkg_temp_c);
Len Brown889facb2012-11-08 00:48:57 -0500824
Len Brownfdf676e2016-02-27 01:28:12 -0500825 /* GFXrc6 */
Len Brown812db3f2017-02-10 00:25:41 -0500826 if (DO_BIC(BIC_GFX_rc6)) {
Len Brownba3dec92016-04-22 20:31:46 -0400827 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
Len Brown3d109de2016-04-22 23:24:27 -0400828 outp += sprintf(outp, "\t**.**");
Len Brown9185e982016-04-06 17:16:00 -0400829 } else {
Len Brown3d109de2016-04-22 23:24:27 -0400830 outp += sprintf(outp, "\t%.2f",
Len Brown9185e982016-04-06 17:16:00 -0400831 p->gfx_rc6_ms / 10.0 / interval_float);
832 }
833 }
Len Brownfdf676e2016-02-27 01:28:12 -0500834
Len Brown27d47352016-02-27 00:37:54 -0500835 /* GFXMHz */
Len Brown812db3f2017-02-10 00:25:41 -0500836 if (DO_BIC(BIC_GFXMHz))
Len Brown3d109de2016-04-22 23:24:27 -0400837 outp += sprintf(outp, "\t%d", p->gfx_mhz);
Len Brown27d47352016-02-27 00:37:54 -0500838
Len Brown0b2bb692015-03-26 00:50:30 -0400839 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
840 if (do_skl_residency) {
Len Brown008d396e2017-02-10 00:29:51 -0500841 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/tsc);
842 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/tsc);
843 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/tsc);
844 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/tsc);
Len Brown0b2bb692015-03-26 00:50:30 -0400845 }
846
Len Brown0f47c082017-01-27 00:50:45 -0500847 if (DO_BIC(BIC_Pkgpc2))
Len Brown008d396e2017-02-10 00:29:51 -0500848 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500849 if (DO_BIC(BIC_Pkgpc3))
Len Brown008d396e2017-02-10 00:29:51 -0500850 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500851 if (DO_BIC(BIC_Pkgpc6))
Len Brown008d396e2017-02-10 00:29:51 -0500852 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500853 if (DO_BIC(BIC_Pkgpc7))
Len Brown008d396e2017-02-10 00:29:51 -0500854 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500855 if (DO_BIC(BIC_Pkgpc8))
Len Brown008d396e2017-02-10 00:29:51 -0500856 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500857 if (DO_BIC(BIC_Pkgpc9))
Len Brown008d396e2017-02-10 00:29:51 -0500858 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/tsc);
Len Brown0f47c082017-01-27 00:50:45 -0500859 if (DO_BIC(BIC_Pkgpc10))
Len Brown008d396e2017-02-10 00:29:51 -0500860 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/tsc);
Len Brown889facb2012-11-08 00:48:57 -0500861
862 /*
863 * If measurement interval exceeds minimum RAPL Joule Counter range,
864 * indicate that results are suspect by printing "**" in fraction place.
865 */
Len Brownfc04cc62014-02-06 00:55:19 -0500866 if (interval_float < rapl_joule_counter_range)
Len Brown3d109de2016-04-22 23:24:27 -0400867 fmt8 = "\t%.2f";
Len Brownfc04cc62014-02-06 00:55:19 -0500868 else
Len Browne975db52016-04-06 23:56:02 -0400869 fmt8 = "%6.0f**";
Len Brown889facb2012-11-08 00:48:57 -0500870
Len Brown812db3f2017-02-10 00:25:41 -0500871 if (DO_BIC(BIC_PkgWatt))
872 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float);
873 if (DO_BIC(BIC_CorWatt))
874 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float);
875 if (DO_BIC(BIC_GFXWatt))
876 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float);
877 if (DO_BIC(BIC_RAMWatt))
878 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units / interval_float);
879 if (DO_BIC(BIC_Pkg_J))
880 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units);
881 if (DO_BIC(BIC_Cor_J))
882 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units);
883 if (DO_BIC(BIC_GFX_J))
884 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units);
885 if (DO_BIC(BIC_RAM_J))
886 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units);
887 if (DO_BIC(BIC_PKG__))
888 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
889 if (DO_BIC(BIC_RAM__))
890 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
891
Len Brown388e9c82016-12-22 23:57:55 -0500892 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
893 if (mp->format == FORMAT_RAW) {
894 if (mp->width == 32)
895 outp += sprintf(outp, "\t0x%08lx", (unsigned long) p->counter[i]);
896 else
897 outp += sprintf(outp, "\t0x%016llx", p->counter[i]);
898 } else if (mp->format == FORMAT_DELTA) {
Len Brown678a3bd2017-02-09 22:22:13 -0500899 outp += sprintf(outp, "\t%lld", p->counter[i]);
Len Brown388e9c82016-12-22 23:57:55 -0500900 } else if (mp->format == FORMAT_PERCENT) {
Len Brown008d396e2017-02-10 00:29:51 -0500901 outp += sprintf(outp, "\t%.2f", 100.0 * p->counter[i]/tsc);
Len Brown388e9c82016-12-22 23:57:55 -0500902 }
903 }
904
Len Brownc98d5d92012-06-04 00:56:40 -0400905done:
Len Brownc98d5d92012-06-04 00:56:40 -0400906 outp += sprintf(outp, "\n");
907
908 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -0400909}
910
Len Brownb7d8c142016-02-13 23:36:17 -0500911void flush_output_stdout(void)
Len Brown103a8fe2010-10-22 23:53:03 -0400912{
Len Brownb7d8c142016-02-13 23:36:17 -0500913 FILE *filep;
914
915 if (outf == stderr)
916 filep = stdout;
917 else
918 filep = outf;
919
920 fputs(output_buffer, filep);
921 fflush(filep);
922
Len Brownc98d5d92012-06-04 00:56:40 -0400923 outp = output_buffer;
924}
Len Brownb7d8c142016-02-13 23:36:17 -0500925void flush_output_stderr(void)
Len Brownc98d5d92012-06-04 00:56:40 -0400926{
Len Brownb7d8c142016-02-13 23:36:17 -0500927 fputs(output_buffer, outf);
928 fflush(outf);
Len Brownc98d5d92012-06-04 00:56:40 -0400929 outp = output_buffer;
930}
931void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
932{
Len Browne23da032012-02-06 18:37:16 -0500933 static int printed;
Len Brown103a8fe2010-10-22 23:53:03 -0400934
Len Browne23da032012-02-06 18:37:16 -0500935 if (!printed || !summary_only)
936 print_header();
Len Brown103a8fe2010-10-22 23:53:03 -0400937
Len Brownc98d5d92012-06-04 00:56:40 -0400938 if (topo.num_cpus > 1)
939 format_counters(&average.threads, &average.cores,
940 &average.packages);
Len Brown103a8fe2010-10-22 23:53:03 -0400941
Len Browne23da032012-02-06 18:37:16 -0500942 printed = 1;
943
944 if (summary_only)
945 return;
946
Len Brownc98d5d92012-06-04 00:56:40 -0400947 for_all_cpus(format_counters, t, c, p);
Len Brown103a8fe2010-10-22 23:53:03 -0400948}
949
Len Brown889facb2012-11-08 00:48:57 -0500950#define DELTA_WRAP32(new, old) \
951 if (new > old) { \
952 old = new - old; \
953 } else { \
954 old = 0x100000000 + new - old; \
955 }
956
Len Brownba3dec92016-04-22 20:31:46 -0400957int
Len Brownc98d5d92012-06-04 00:56:40 -0400958delta_package(struct pkg_data *new, struct pkg_data *old)
Len Brown103a8fe2010-10-22 23:53:03 -0400959{
Len Brown388e9c82016-12-22 23:57:55 -0500960 int i;
961 struct msr_counter *mp;
Len Brown0b2bb692015-03-26 00:50:30 -0400962
963 if (do_skl_residency) {
964 old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
965 old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0;
966 old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0;
967 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
968 }
Len Brownc98d5d92012-06-04 00:56:40 -0400969 old->pc2 = new->pc2 - old->pc2;
Len Brown0f47c082017-01-27 00:50:45 -0500970 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -0500971 old->pc3 = new->pc3 - old->pc3;
Len Brown0f47c082017-01-27 00:50:45 -0500972 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -0500973 old->pc6 = new->pc6 - old->pc6;
Len Brown0f47c082017-01-27 00:50:45 -0500974 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -0500975 old->pc7 = new->pc7 - old->pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -0800976 old->pc8 = new->pc8 - old->pc8;
977 old->pc9 = new->pc9 - old->pc9;
978 old->pc10 = new->pc10 - old->pc10;
Len Brown889facb2012-11-08 00:48:57 -0500979 old->pkg_temp_c = new->pkg_temp_c;
980
Len Brown9185e982016-04-06 17:16:00 -0400981 /* flag an error when rc6 counter resets/wraps */
982 if (old->gfx_rc6_ms > new->gfx_rc6_ms)
983 old->gfx_rc6_ms = -1;
984 else
985 old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
986
Len Brown27d47352016-02-27 00:37:54 -0500987 old->gfx_mhz = new->gfx_mhz;
988
Len Brown889facb2012-11-08 00:48:57 -0500989 DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
990 DELTA_WRAP32(new->energy_cores, old->energy_cores);
991 DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
992 DELTA_WRAP32(new->energy_dram, old->energy_dram);
993 DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
994 DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
Len Brownba3dec92016-04-22 20:31:46 -0400995
Len Brown388e9c82016-12-22 23:57:55 -0500996 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
997 if (mp->format == FORMAT_RAW)
998 old->counter[i] = new->counter[i];
999 else
1000 old->counter[i] = new->counter[i] - old->counter[i];
1001 }
1002
Len Brownba3dec92016-04-22 20:31:46 -04001003 return 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001004}
Len Brown103a8fe2010-10-22 23:53:03 -04001005
Len Brownc98d5d92012-06-04 00:56:40 -04001006void
1007delta_core(struct core_data *new, struct core_data *old)
1008{
Len Brown388e9c82016-12-22 23:57:55 -05001009 int i;
1010 struct msr_counter *mp;
1011
Len Brownc98d5d92012-06-04 00:56:40 -04001012 old->c3 = new->c3 - old->c3;
1013 old->c6 = new->c6 - old->c6;
1014 old->c7 = new->c7 - old->c7;
Len Brown889facb2012-11-08 00:48:57 -05001015 old->core_temp_c = new->core_temp_c;
Len Brown0539ba12017-02-10 00:27:20 -05001016 old->mc6_us = new->mc6_us - old->mc6_us;
Len Brown388e9c82016-12-22 23:57:55 -05001017
1018 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1019 if (mp->format == FORMAT_RAW)
1020 old->counter[i] = new->counter[i];
1021 else
1022 old->counter[i] = new->counter[i] - old->counter[i];
1023 }
Len Brownc98d5d92012-06-04 00:56:40 -04001024}
Len Brown103a8fe2010-10-22 23:53:03 -04001025
Len Brownc3ae3312012-06-13 21:31:46 -04001026/*
1027 * old = new - old
1028 */
Len Brownba3dec92016-04-22 20:31:46 -04001029int
Len Brownc98d5d92012-06-04 00:56:40 -04001030delta_thread(struct thread_data *new, struct thread_data *old,
1031 struct core_data *core_delta)
1032{
Len Brown388e9c82016-12-22 23:57:55 -05001033 int i;
1034 struct msr_counter *mp;
1035
Len Brownc98d5d92012-06-04 00:56:40 -04001036 old->tsc = new->tsc - old->tsc;
Len Brown103a8fe2010-10-22 23:53:03 -04001037
Len Brownc98d5d92012-06-04 00:56:40 -04001038 /* check for TSC < 1 Mcycles over interval */
Josh Triplettb2c95d92013-08-20 17:20:18 -07001039 if (old->tsc < (1000 * 1000))
1040 errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n"
1041 "You can disable all c-states by booting with \"idle=poll\"\n"
1042 "or just the deep ones with \"processor.max_cstate=1\"");
Len Brown103a8fe2010-10-22 23:53:03 -04001043
Len Brownc98d5d92012-06-04 00:56:40 -04001044 old->c1 = new->c1 - old->c1;
Len Brown103a8fe2010-10-22 23:53:03 -04001045
Len Brown812db3f2017-02-10 00:25:41 -05001046 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
Len Browna7296172015-01-23 01:33:58 -05001047 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
1048 old->aperf = new->aperf - old->aperf;
1049 old->mperf = new->mperf - old->mperf;
1050 } else {
Len Brownba3dec92016-04-22 20:31:46 -04001051 return -1;
Len Brownc98d5d92012-06-04 00:56:40 -04001052 }
Len Brownc98d5d92012-06-04 00:56:40 -04001053 }
Len Brown103a8fe2010-10-22 23:53:03 -04001054
Len Brown103a8fe2010-10-22 23:53:03 -04001055
Len Brown144b44b2013-11-09 00:30:16 -05001056 if (use_c1_residency_msr) {
1057 /*
1058 * Some models have a dedicated C1 residency MSR,
1059 * which should be more accurate than the derivation below.
1060 */
1061 } else {
1062 /*
1063 * As counter collection is not atomic,
1064 * it is possible for mperf's non-halted cycles + idle states
1065 * to exceed TSC's all cycles: show c1 = 0% in that case.
1066 */
1067 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
1068 old->c1 = 0;
1069 else {
1070 /* normal case, derive c1 */
Len Brown008d396e2017-02-10 00:29:51 -05001071 old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3
Len Brownc98d5d92012-06-04 00:56:40 -04001072 - core_delta->c6 - core_delta->c7;
Len Brown144b44b2013-11-09 00:30:16 -05001073 }
Len Brownc98d5d92012-06-04 00:56:40 -04001074 }
Len Brownc3ae3312012-06-13 21:31:46 -04001075
Len Brownc98d5d92012-06-04 00:56:40 -04001076 if (old->mperf == 0) {
Len Brownb7d8c142016-02-13 23:36:17 -05001077 if (debug > 1)
1078 fprintf(outf, "cpu%d MPERF 0!\n", old->cpu_id);
Len Brownc98d5d92012-06-04 00:56:40 -04001079 old->mperf = 1; /* divide by 0 protection */
1080 }
1081
Len Brown812db3f2017-02-10 00:25:41 -05001082 if (DO_BIC(BIC_IRQ))
Len Brown562a2d32016-02-26 23:48:05 -05001083 old->irq_count = new->irq_count - old->irq_count;
1084
Len Brown812db3f2017-02-10 00:25:41 -05001085 if (DO_BIC(BIC_SMI))
Len Brown1ed51012013-02-10 17:19:24 -05001086 old->smi_count = new->smi_count - old->smi_count;
Len Brownba3dec92016-04-22 20:31:46 -04001087
Len Brown388e9c82016-12-22 23:57:55 -05001088 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1089 if (mp->format == FORMAT_RAW)
1090 old->counter[i] = new->counter[i];
1091 else
1092 old->counter[i] = new->counter[i] - old->counter[i];
1093 }
Len Brownba3dec92016-04-22 20:31:46 -04001094 return 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001095}
1096
1097int delta_cpu(struct thread_data *t, struct core_data *c,
1098 struct pkg_data *p, struct thread_data *t2,
1099 struct core_data *c2, struct pkg_data *p2)
1100{
Len Brownba3dec92016-04-22 20:31:46 -04001101 int retval = 0;
1102
Len Brownc98d5d92012-06-04 00:56:40 -04001103 /* calculate core delta only for 1st thread in core */
1104 if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
1105 delta_core(c, c2);
1106
1107 /* always calculate thread delta */
Len Brownba3dec92016-04-22 20:31:46 -04001108 retval = delta_thread(t, t2, c2); /* c2 is core delta */
1109 if (retval)
1110 return retval;
Len Brownc98d5d92012-06-04 00:56:40 -04001111
1112 /* calculate package delta only for 1st core in package */
1113 if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
Len Brownba3dec92016-04-22 20:31:46 -04001114 retval = delta_package(p, p2);
Len Brownc98d5d92012-06-04 00:56:40 -04001115
Len Brownba3dec92016-04-22 20:31:46 -04001116 return retval;
Len Brownc98d5d92012-06-04 00:56:40 -04001117}
1118
1119void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1120{
Len Brown388e9c82016-12-22 23:57:55 -05001121 int i;
1122 struct msr_counter *mp;
1123
Len Brownc98d5d92012-06-04 00:56:40 -04001124 t->tsc = 0;
1125 t->aperf = 0;
1126 t->mperf = 0;
1127 t->c1 = 0;
1128
Len Brown562a2d32016-02-26 23:48:05 -05001129 t->irq_count = 0;
1130 t->smi_count = 0;
1131
Len Brownc98d5d92012-06-04 00:56:40 -04001132 /* tells format_counters to dump all fields from this set */
1133 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
1134
1135 c->c3 = 0;
1136 c->c6 = 0;
1137 c->c7 = 0;
Len Brown0539ba12017-02-10 00:27:20 -05001138 c->mc6_us = 0;
Len Brown889facb2012-11-08 00:48:57 -05001139 c->core_temp_c = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001140
Len Brown0b2bb692015-03-26 00:50:30 -04001141 p->pkg_wtd_core_c0 = 0;
1142 p->pkg_any_core_c0 = 0;
1143 p->pkg_any_gfxe_c0 = 0;
1144 p->pkg_both_core_gfxe_c0 = 0;
1145
Len Brownc98d5d92012-06-04 00:56:40 -04001146 p->pc2 = 0;
Len Brown0f47c082017-01-27 00:50:45 -05001147 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -05001148 p->pc3 = 0;
Len Brown0f47c082017-01-27 00:50:45 -05001149 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -05001150 p->pc6 = 0;
Len Brown0f47c082017-01-27 00:50:45 -05001151 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -05001152 p->pc7 = 0;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001153 p->pc8 = 0;
1154 p->pc9 = 0;
1155 p->pc10 = 0;
Len Brown889facb2012-11-08 00:48:57 -05001156
1157 p->energy_pkg = 0;
1158 p->energy_dram = 0;
1159 p->energy_cores = 0;
1160 p->energy_gfx = 0;
1161 p->rapl_pkg_perf_status = 0;
1162 p->rapl_dram_perf_status = 0;
1163 p->pkg_temp_c = 0;
Len Brown27d47352016-02-27 00:37:54 -05001164
Len Brownfdf676e2016-02-27 01:28:12 -05001165 p->gfx_rc6_ms = 0;
Len Brown27d47352016-02-27 00:37:54 -05001166 p->gfx_mhz = 0;
Len Brown388e9c82016-12-22 23:57:55 -05001167 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
1168 t->counter[i] = 0;
1169
1170 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next)
1171 c->counter[i] = 0;
1172
1173 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
1174 p->counter[i] = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04001175}
1176int sum_counters(struct thread_data *t, struct core_data *c,
1177 struct pkg_data *p)
1178{
Len Brown388e9c82016-12-22 23:57:55 -05001179 int i;
1180 struct msr_counter *mp;
1181
Len Brownc98d5d92012-06-04 00:56:40 -04001182 average.threads.tsc += t->tsc;
1183 average.threads.aperf += t->aperf;
1184 average.threads.mperf += t->mperf;
1185 average.threads.c1 += t->c1;
1186
Len Brown562a2d32016-02-26 23:48:05 -05001187 average.threads.irq_count += t->irq_count;
1188 average.threads.smi_count += t->smi_count;
1189
Len Brown388e9c82016-12-22 23:57:55 -05001190 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1191 if (mp->format == FORMAT_RAW)
1192 continue;
1193 average.threads.counter[i] += t->counter[i];
1194 }
1195
Len Brownc98d5d92012-06-04 00:56:40 -04001196 /* sum per-core values only for 1st thread in core */
1197 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1198 return 0;
1199
1200 average.cores.c3 += c->c3;
1201 average.cores.c6 += c->c6;
1202 average.cores.c7 += c->c7;
Len Brown0539ba12017-02-10 00:27:20 -05001203 average.cores.mc6_us += c->mc6_us;
Len Brownc98d5d92012-06-04 00:56:40 -04001204
Len Brown889facb2012-11-08 00:48:57 -05001205 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
1206
Len Brown388e9c82016-12-22 23:57:55 -05001207 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1208 if (mp->format == FORMAT_RAW)
1209 continue;
1210 average.cores.counter[i] += c->counter[i];
1211 }
1212
Len Brownc98d5d92012-06-04 00:56:40 -04001213 /* sum per-pkg values only for 1st core in pkg */
1214 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1215 return 0;
1216
Len Brown0b2bb692015-03-26 00:50:30 -04001217 if (do_skl_residency) {
1218 average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0;
1219 average.packages.pkg_any_core_c0 += p->pkg_any_core_c0;
1220 average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0;
1221 average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0;
1222 }
1223
Len Brownc98d5d92012-06-04 00:56:40 -04001224 average.packages.pc2 += p->pc2;
Len Brown0f47c082017-01-27 00:50:45 -05001225 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -05001226 average.packages.pc3 += p->pc3;
Len Brown0f47c082017-01-27 00:50:45 -05001227 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -05001228 average.packages.pc6 += p->pc6;
Len Brown0f47c082017-01-27 00:50:45 -05001229 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -05001230 average.packages.pc7 += p->pc7;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001231 average.packages.pc8 += p->pc8;
1232 average.packages.pc9 += p->pc9;
1233 average.packages.pc10 += p->pc10;
Len Brownc98d5d92012-06-04 00:56:40 -04001234
Len Brown889facb2012-11-08 00:48:57 -05001235 average.packages.energy_pkg += p->energy_pkg;
1236 average.packages.energy_dram += p->energy_dram;
1237 average.packages.energy_cores += p->energy_cores;
1238 average.packages.energy_gfx += p->energy_gfx;
1239
Len Brownfdf676e2016-02-27 01:28:12 -05001240 average.packages.gfx_rc6_ms = p->gfx_rc6_ms;
Len Brown27d47352016-02-27 00:37:54 -05001241 average.packages.gfx_mhz = p->gfx_mhz;
1242
Len Brown889facb2012-11-08 00:48:57 -05001243 average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c);
1244
1245 average.packages.rapl_pkg_perf_status += p->rapl_pkg_perf_status;
1246 average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
Len Brown388e9c82016-12-22 23:57:55 -05001247
1248 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1249 if (mp->format == FORMAT_RAW)
1250 continue;
1251 average.packages.counter[i] += p->counter[i];
1252 }
Len Brownc98d5d92012-06-04 00:56:40 -04001253 return 0;
1254}
1255/*
1256 * sum the counters for all cpus in the system
1257 * compute the weighted average
1258 */
1259void compute_average(struct thread_data *t, struct core_data *c,
1260 struct pkg_data *p)
1261{
Len Brown388e9c82016-12-22 23:57:55 -05001262 int i;
1263 struct msr_counter *mp;
1264
Len Brownc98d5d92012-06-04 00:56:40 -04001265 clear_counters(&average.threads, &average.cores, &average.packages);
1266
1267 for_all_cpus(sum_counters, t, c, p);
1268
1269 average.threads.tsc /= topo.num_cpus;
1270 average.threads.aperf /= topo.num_cpus;
1271 average.threads.mperf /= topo.num_cpus;
1272 average.threads.c1 /= topo.num_cpus;
1273
1274 average.cores.c3 /= topo.num_cores;
1275 average.cores.c6 /= topo.num_cores;
1276 average.cores.c7 /= topo.num_cores;
Len Brown0539ba12017-02-10 00:27:20 -05001277 average.cores.mc6_us /= topo.num_cores;
Len Brownc98d5d92012-06-04 00:56:40 -04001278
Len Brown0b2bb692015-03-26 00:50:30 -04001279 if (do_skl_residency) {
1280 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
1281 average.packages.pkg_any_core_c0 /= topo.num_packages;
1282 average.packages.pkg_any_gfxe_c0 /= topo.num_packages;
1283 average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages;
1284 }
1285
Len Brownc98d5d92012-06-04 00:56:40 -04001286 average.packages.pc2 /= topo.num_packages;
Len Brown0f47c082017-01-27 00:50:45 -05001287 if (DO_BIC(BIC_Pkgpc3))
Len Brownee7e38e2015-02-09 23:39:45 -05001288 average.packages.pc3 /= topo.num_packages;
Len Brown0f47c082017-01-27 00:50:45 -05001289 if (DO_BIC(BIC_Pkgpc6))
Len Brownee7e38e2015-02-09 23:39:45 -05001290 average.packages.pc6 /= topo.num_packages;
Len Brown0f47c082017-01-27 00:50:45 -05001291 if (DO_BIC(BIC_Pkgpc7))
Len Brownee7e38e2015-02-09 23:39:45 -05001292 average.packages.pc7 /= topo.num_packages;
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001293
1294 average.packages.pc8 /= topo.num_packages;
1295 average.packages.pc9 /= topo.num_packages;
1296 average.packages.pc10 /= topo.num_packages;
Len Brown388e9c82016-12-22 23:57:55 -05001297
1298 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1299 if (mp->format == FORMAT_RAW)
1300 continue;
Len Brown41618e62017-02-09 18:25:22 -05001301 if (mp->flags & SYSFS_PERCPU && mp->type == COUNTER_ITEMS)
1302 continue;
Len Brown388e9c82016-12-22 23:57:55 -05001303 average.threads.counter[i] /= topo.num_cpus;
1304 }
1305 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1306 if (mp->format == FORMAT_RAW)
1307 continue;
1308 average.cores.counter[i] /= topo.num_cores;
1309 }
1310 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1311 if (mp->format == FORMAT_RAW)
1312 continue;
1313 average.packages.counter[i] /= topo.num_packages;
1314 }
Len Brownc98d5d92012-06-04 00:56:40 -04001315}
1316
1317static unsigned long long rdtsc(void)
1318{
1319 unsigned int low, high;
1320
1321 asm volatile("rdtsc" : "=a" (low), "=d" (high));
1322
1323 return low | ((unsigned long long)high) << 32;
1324}
1325
Len Brownc98d5d92012-06-04 00:56:40 -04001326/*
Len Brown495c76542017-02-08 02:41:51 -05001327 * Open a file, and exit on failure
1328 */
1329FILE *fopen_or_die(const char *path, const char *mode)
1330{
1331 FILE *filep = fopen(path, mode);
1332
1333 if (!filep)
1334 err(1, "%s: open failed", path);
1335 return filep;
1336}
1337/*
1338 * snapshot_sysfs_counter()
1339 *
1340 * return snapshot of given counter
1341 */
1342unsigned long long snapshot_sysfs_counter(char *path)
1343{
1344 FILE *fp;
1345 int retval;
1346 unsigned long long counter;
1347
1348 fp = fopen_or_die(path, "r");
1349
1350 retval = fscanf(fp, "%lld", &counter);
1351 if (retval != 1)
1352 err(1, "snapshot_sysfs_counter(%s)", path);
1353
1354 fclose(fp);
1355
1356 return counter;
1357}
1358
1359int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
1360{
1361 if (mp->msr_num != 0) {
1362 if (get_msr(cpu, mp->msr_num, counterp))
1363 return -1;
1364 } else {
Len Brown41618e62017-02-09 18:25:22 -05001365 char path[128];
1366
1367 if (mp->flags & SYSFS_PERCPU) {
1368 sprintf(path, "/sys/devices/system/cpu/cpu%d/%s",
1369 cpu, mp->path);
1370
1371 *counterp = snapshot_sysfs_counter(path);
1372 } else {
1373 *counterp = snapshot_sysfs_counter(mp->path);
1374 }
Len Brown495c76542017-02-08 02:41:51 -05001375 }
1376
1377 return 0;
1378}
1379
1380/*
Len Brownc98d5d92012-06-04 00:56:40 -04001381 * get_counters(...)
1382 * migrate to cpu
1383 * acquire and record local counters for that cpu
1384 */
1385int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1386{
1387 int cpu = t->cpu_id;
Len Brown889facb2012-11-08 00:48:57 -05001388 unsigned long long msr;
Len Brown0102b062016-02-27 03:11:29 -05001389 int aperf_mperf_retry_count = 0;
Len Brown388e9c82016-12-22 23:57:55 -05001390 struct msr_counter *mp;
1391 int i;
Len Brownc98d5d92012-06-04 00:56:40 -04001392
Len Browne52966c2012-11-08 22:38:05 -05001393 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05001394 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brownc98d5d92012-06-04 00:56:40 -04001395 return -1;
Len Browne52966c2012-11-08 22:38:05 -05001396 }
Len Brownc98d5d92012-06-04 00:56:40 -04001397
Len Brown0102b062016-02-27 03:11:29 -05001398retry:
Len Brownc98d5d92012-06-04 00:56:40 -04001399 t->tsc = rdtsc(); /* we are running on local CPU of interest */
1400
Len Brown812db3f2017-02-10 00:25:41 -05001401 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
Len Brown0102b062016-02-27 03:11:29 -05001402 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
1403
1404 /*
1405 * The TSC, APERF and MPERF must be read together for
1406 * APERF/MPERF and MPERF/TSC to give accurate results.
1407 *
1408 * Unfortunately, APERF and MPERF are read by
1409 * individual system call, so delays may occur
1410 * between them. If the time to read them
1411 * varies by a large amount, we re-read them.
1412 */
1413
1414 /*
1415 * This initial dummy APERF read has been seen to
1416 * reduce jitter in the subsequent reads.
1417 */
1418
Len Brown9c63a652012-10-31 01:29:52 -04001419 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
Len Brownc98d5d92012-06-04 00:56:40 -04001420 return -3;
Len Brown0102b062016-02-27 03:11:29 -05001421
1422 t->tsc = rdtsc(); /* re-read close to APERF */
1423
1424 tsc_before = t->tsc;
1425
1426 if (get_msr(cpu, MSR_IA32_APERF, &t->aperf))
1427 return -3;
1428
1429 tsc_between = rdtsc();
1430
Len Brown9c63a652012-10-31 01:29:52 -04001431 if (get_msr(cpu, MSR_IA32_MPERF, &t->mperf))
Len Brownc98d5d92012-06-04 00:56:40 -04001432 return -4;
Len Brown0102b062016-02-27 03:11:29 -05001433
1434 tsc_after = rdtsc();
1435
1436 aperf_time = tsc_between - tsc_before;
1437 mperf_time = tsc_after - tsc_between;
1438
1439 /*
1440 * If the system call latency to read APERF and MPERF
1441 * differ by more than 2x, then try again.
1442 */
1443 if ((aperf_time > (2 * mperf_time)) || (mperf_time > (2 * aperf_time))) {
1444 aperf_mperf_retry_count++;
1445 if (aperf_mperf_retry_count < 5)
1446 goto retry;
1447 else
1448 warnx("cpu%d jitter %lld %lld",
1449 cpu, aperf_time, mperf_time);
1450 }
1451 aperf_mperf_retry_count = 0;
1452
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02001453 t->aperf = t->aperf * aperf_mperf_multiplier;
1454 t->mperf = t->mperf * aperf_mperf_multiplier;
Len Brownc98d5d92012-06-04 00:56:40 -04001455 }
1456
Len Brown812db3f2017-02-10 00:25:41 -05001457 if (DO_BIC(BIC_IRQ))
Len Brown562a2d32016-02-26 23:48:05 -05001458 t->irq_count = irqs_per_cpu[cpu];
Len Brown812db3f2017-02-10 00:25:41 -05001459 if (DO_BIC(BIC_SMI)) {
Len Brown1ed51012013-02-10 17:19:24 -05001460 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
1461 return -5;
1462 t->smi_count = msr & 0xFFFFFFFF;
1463 }
Len Brown0539ba12017-02-10 00:27:20 -05001464 if (DO_BIC(BIC_CPU_c1) && use_c1_residency_msr) {
Len Brown144b44b2013-11-09 00:30:16 -05001465 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
1466 return -6;
1467 }
1468
Len Brown388e9c82016-12-22 23:57:55 -05001469 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
Len Brown495c76542017-02-08 02:41:51 -05001470 if (get_mp(cpu, mp, &t->counter[i]))
Len Brown388e9c82016-12-22 23:57:55 -05001471 return -10;
1472 }
1473
Len Brownc98d5d92012-06-04 00:56:40 -04001474 /* collect core counters only for 1st thread in core */
1475 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1476 return 0;
1477
Len Brown812db3f2017-02-10 00:25:41 -05001478 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates) {
Len Brownc98d5d92012-06-04 00:56:40 -04001479 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
1480 return -6;
Len Brown144b44b2013-11-09 00:30:16 -05001481 }
1482
Len Brown812db3f2017-02-10 00:25:41 -05001483 if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) {
Len Brownc98d5d92012-06-04 00:56:40 -04001484 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
1485 return -7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001486 } else if (do_knl_cstates) {
1487 if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
1488 return -7;
Len Brownc98d5d92012-06-04 00:56:40 -04001489 }
1490
Len Brown812db3f2017-02-10 00:25:41 -05001491 if (DO_BIC(BIC_CPU_c7))
Len Brownc98d5d92012-06-04 00:56:40 -04001492 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
1493 return -8;
1494
Len Brown0539ba12017-02-10 00:27:20 -05001495 if (DO_BIC(BIC_Mod_c6))
1496 if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
1497 return -8;
1498
Len Brown812db3f2017-02-10 00:25:41 -05001499 if (DO_BIC(BIC_CoreTmp)) {
Len Brown889facb2012-11-08 00:48:57 -05001500 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1501 return -9;
1502 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1503 }
1504
Len Brown388e9c82016-12-22 23:57:55 -05001505 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
Len Brown495c76542017-02-08 02:41:51 -05001506 if (get_mp(cpu, mp, &c->counter[i]))
Len Brown388e9c82016-12-22 23:57:55 -05001507 return -10;
1508 }
Len Brown889facb2012-11-08 00:48:57 -05001509
Len Brownc98d5d92012-06-04 00:56:40 -04001510 /* collect package counters only for 1st core in package */
1511 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
1512 return 0;
1513
Len Brown0b2bb692015-03-26 00:50:30 -04001514 if (do_skl_residency) {
1515 if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0))
1516 return -10;
1517 if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0))
1518 return -11;
1519 if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0))
1520 return -12;
1521 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
1522 return -13;
1523 }
Len Brown0f47c082017-01-27 00:50:45 -05001524 if (DO_BIC(BIC_Pkgpc3))
Len Brownc98d5d92012-06-04 00:56:40 -04001525 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
1526 return -9;
Len Brown0f47c082017-01-27 00:50:45 -05001527 if (DO_BIC(BIC_Pkgpc6)) {
Len Brown0539ba12017-02-10 00:27:20 -05001528 if (do_slm_cstates) {
1529 if (get_msr(cpu, MSR_ATOM_PKG_C6_RESIDENCY, &p->pc6))
1530 return -10;
1531 } else {
1532 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
1533 return -10;
1534 }
1535 }
1536
Len Brown0f47c082017-01-27 00:50:45 -05001537 if (DO_BIC(BIC_Pkgpc2))
Len Brownc98d5d92012-06-04 00:56:40 -04001538 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
1539 return -11;
Len Brown0f47c082017-01-27 00:50:45 -05001540 if (DO_BIC(BIC_Pkgpc7))
Len Brownc98d5d92012-06-04 00:56:40 -04001541 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
1542 return -12;
Len Brown0f47c082017-01-27 00:50:45 -05001543 if (DO_BIC(BIC_Pkgpc8))
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001544 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
1545 return -13;
Len Brown0f47c082017-01-27 00:50:45 -05001546 if (DO_BIC(BIC_Pkgpc9))
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001547 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
1548 return -13;
Len Brown0f47c082017-01-27 00:50:45 -05001549 if (DO_BIC(BIC_Pkgpc10))
Kristen Carlson Accardica587102012-11-21 05:22:43 -08001550 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
1551 return -13;
Len Brown0f47c082017-01-27 00:50:45 -05001552
Len Brown889facb2012-11-08 00:48:57 -05001553 if (do_rapl & RAPL_PKG) {
1554 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
1555 return -13;
1556 p->energy_pkg = msr & 0xFFFFFFFF;
1557 }
Jacob Pan91484942016-06-16 09:48:20 -07001558 if (do_rapl & RAPL_CORES_ENERGY_STATUS) {
Len Brown889facb2012-11-08 00:48:57 -05001559 if (get_msr(cpu, MSR_PP0_ENERGY_STATUS, &msr))
1560 return -14;
1561 p->energy_cores = msr & 0xFFFFFFFF;
1562 }
1563 if (do_rapl & RAPL_DRAM) {
1564 if (get_msr(cpu, MSR_DRAM_ENERGY_STATUS, &msr))
1565 return -15;
1566 p->energy_dram = msr & 0xFFFFFFFF;
1567 }
1568 if (do_rapl & RAPL_GFX) {
1569 if (get_msr(cpu, MSR_PP1_ENERGY_STATUS, &msr))
1570 return -16;
1571 p->energy_gfx = msr & 0xFFFFFFFF;
1572 }
1573 if (do_rapl & RAPL_PKG_PERF_STATUS) {
1574 if (get_msr(cpu, MSR_PKG_PERF_STATUS, &msr))
1575 return -16;
1576 p->rapl_pkg_perf_status = msr & 0xFFFFFFFF;
1577 }
1578 if (do_rapl & RAPL_DRAM_PERF_STATUS) {
1579 if (get_msr(cpu, MSR_DRAM_PERF_STATUS, &msr))
1580 return -16;
1581 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
1582 }
Len Brown812db3f2017-02-10 00:25:41 -05001583 if (DO_BIC(BIC_PkgTmp)) {
Len Brown889facb2012-11-08 00:48:57 -05001584 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1585 return -17;
1586 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1587 }
Len Brownfdf676e2016-02-27 01:28:12 -05001588
Len Brown812db3f2017-02-10 00:25:41 -05001589 if (DO_BIC(BIC_GFX_rc6))
Len Brownfdf676e2016-02-27 01:28:12 -05001590 p->gfx_rc6_ms = gfx_cur_rc6_ms;
1591
Len Brown812db3f2017-02-10 00:25:41 -05001592 if (DO_BIC(BIC_GFXMHz))
Len Brown27d47352016-02-27 00:37:54 -05001593 p->gfx_mhz = gfx_cur_mhz;
1594
Len Brown388e9c82016-12-22 23:57:55 -05001595 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
Len Brown495c76542017-02-08 02:41:51 -05001596 if (get_mp(cpu, mp, &p->counter[i]))
Len Brown388e9c82016-12-22 23:57:55 -05001597 return -10;
1598 }
1599
Len Brown103a8fe2010-10-22 23:53:03 -04001600 return 0;
1601}
1602
Len Brownee7e38e2015-02-09 23:39:45 -05001603/*
1604 * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
1605 * If you change the values, note they are used both in comparisons
1606 * (>= PCL__7) and to index pkg_cstate_limit_strings[].
1607 */
1608
1609#define PCLUKN 0 /* Unknown */
1610#define PCLRSV 1 /* Reserved */
1611#define PCL__0 2 /* PC0 */
1612#define PCL__1 3 /* PC1 */
1613#define PCL__2 4 /* PC2 */
1614#define PCL__3 5 /* PC3 */
1615#define PCL__4 6 /* PC4 */
1616#define PCL__6 7 /* PC6 */
1617#define PCL_6N 8 /* PC6 No Retention */
1618#define PCL_6R 9 /* PC6 Retention */
1619#define PCL__7 10 /* PC7 */
1620#define PCL_7S 11 /* PC7 Shrink */
Len Brown0b2bb692015-03-26 00:50:30 -04001621#define PCL__8 12 /* PC8 */
1622#define PCL__9 13 /* PC9 */
1623#define PCLUNL 14 /* Unlimited */
Len Brownee7e38e2015-02-09 23:39:45 -05001624
1625int pkg_cstate_limit = PCLUKN;
1626char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
Len Brown0b2bb692015-03-26 00:50:30 -04001627 "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"};
Len Brownee7e38e2015-02-09 23:39:45 -05001628
Len Browne9257f52015-04-01 21:02:57 -04001629int 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};
1630int 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};
1631int 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};
Len Brown0539ba12017-02-10 00:27:20 -05001632int 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};
Len Brownf2642882017-01-07 23:13:15 -05001633int 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};
Len Browne9257f52015-04-01 21:02:57 -04001634int 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};
Len Browne4085d52016-04-06 17:15:56 -04001635int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Brownd8ebb442016-12-01 20:27:46 -05001636int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
Len Brownee7e38e2015-02-09 23:39:45 -05001637
Len Browna2b7b742015-09-26 00:12:38 -04001638
1639static void
1640calculate_tsc_tweak()
1641{
Len Browna2b7b742015-09-26 00:12:38 -04001642 tsc_tweak = base_hz / tsc_hz;
1643}
1644
Len Brownfcd17212015-03-23 20:29:09 -04001645static void
1646dump_nhm_platform_info(void)
Len Brown103a8fe2010-10-22 23:53:03 -04001647{
1648 unsigned long long msr;
1649 unsigned int ratio;
1650
Len Brownec0adc52015-11-12 02:42:31 -05001651 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown103a8fe2010-10-22 23:53:03 -04001652
Len Brownb7d8c142016-02-13 23:36:17 -05001653 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001654
Len Brown103a8fe2010-10-22 23:53:03 -04001655 ratio = (msr >> 40) & 0xFF;
Len Brown710f2732017-01-11 22:12:25 -05001656 fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001657 ratio, bclk, ratio * bclk);
1658
1659 ratio = (msr >> 8) & 0xFF;
Len Brown710f2732017-01-11 22:12:25 -05001660 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
Len Brown103a8fe2010-10-22 23:53:03 -04001661 ratio, bclk, ratio * bclk);
1662
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001663 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001664 fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
Len Brownbfae2052015-06-17 12:27:21 -04001665 base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
Len Brown67920412013-01-31 15:22:15 -05001666
Len Brownfcd17212015-03-23 20:29:09 -04001667 return;
1668}
1669
1670static void
1671dump_hsw_turbo_ratio_limits(void)
1672{
1673 unsigned long long msr;
1674 unsigned int ratio;
1675
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001676 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001677
Len Brownb7d8c142016-02-13 23:36:17 -05001678 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001679
1680 ratio = (msr >> 8) & 0xFF;
1681 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001682 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001683 ratio, bclk, ratio * bclk);
1684
1685 ratio = (msr >> 0) & 0xFF;
1686 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001687 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n",
Len Brownfcd17212015-03-23 20:29:09 -04001688 ratio, bclk, ratio * bclk);
1689 return;
1690}
1691
1692static void
1693dump_ivt_turbo_ratio_limits(void)
1694{
1695 unsigned long long msr;
1696 unsigned int ratio;
Len Brown6574a5d2012-09-21 00:01:31 -04001697
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001698 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001699
Len Brownb7d8c142016-02-13 23:36:17 -05001700 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001701
1702 ratio = (msr >> 56) & 0xFF;
1703 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001704 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001705 ratio, bclk, ratio * bclk);
1706
1707 ratio = (msr >> 48) & 0xFF;
1708 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001709 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001710 ratio, bclk, ratio * bclk);
1711
1712 ratio = (msr >> 40) & 0xFF;
1713 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001714 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001715 ratio, bclk, ratio * bclk);
1716
1717 ratio = (msr >> 32) & 0xFF;
1718 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001719 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001720 ratio, bclk, ratio * bclk);
1721
1722 ratio = (msr >> 24) & 0xFF;
1723 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001724 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001725 ratio, bclk, ratio * bclk);
1726
1727 ratio = (msr >> 16) & 0xFF;
1728 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001729 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001730 ratio, bclk, ratio * bclk);
1731
1732 ratio = (msr >> 8) & 0xFF;
1733 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001734 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001735 ratio, bclk, ratio * bclk);
1736
1737 ratio = (msr >> 0) & 0xFF;
1738 if (ratio)
Len Brown710f2732017-01-11 22:12:25 -05001739 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n",
Len Brown6574a5d2012-09-21 00:01:31 -04001740 ratio, bclk, ratio * bclk);
Len Brownfcd17212015-03-23 20:29:09 -04001741 return;
1742}
Len Brown31e07522017-01-31 23:07:49 -05001743int has_turbo_ratio_group_limits(int family, int model)
1744{
1745
1746 if (!genuine_intel)
1747 return 0;
1748
1749 switch (model) {
1750 case INTEL_FAM6_ATOM_GOLDMONT:
1751 case INTEL_FAM6_SKYLAKE_X:
1752 case INTEL_FAM6_ATOM_DENVERTON:
1753 return 1;
1754 }
1755 return 0;
1756}
Len Brown6574a5d2012-09-21 00:01:31 -04001757
Len Brownfcd17212015-03-23 20:29:09 -04001758static void
Len Brown31e07522017-01-31 23:07:49 -05001759dump_turbo_ratio_limits(int family, int model)
Len Brownfcd17212015-03-23 20:29:09 -04001760{
Len Brown31e07522017-01-31 23:07:49 -05001761 unsigned long long msr, core_counts;
1762 unsigned int ratio, group_size;
Len Brown103a8fe2010-10-22 23:53:03 -04001763
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04001764 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001765 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
Len Brown6574a5d2012-09-21 00:01:31 -04001766
Len Brown31e07522017-01-31 23:07:49 -05001767 if (has_turbo_ratio_group_limits(family, model)) {
1768 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
1769 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
1770 } else {
1771 core_counts = 0x0807060504030201;
1772 }
1773
Len Brown6574a5d2012-09-21 00:01:31 -04001774 ratio = (msr >> 56) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001775 group_size = (core_counts >> 56) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001776 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001777 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1778 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001779
1780 ratio = (msr >> 48) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001781 group_size = (core_counts >> 48) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001782 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001783 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1784 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001785
1786 ratio = (msr >> 40) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001787 group_size = (core_counts >> 40) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001788 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001789 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1790 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001791
1792 ratio = (msr >> 32) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001793 group_size = (core_counts >> 32) & 0xFF;
Len Brown6574a5d2012-09-21 00:01:31 -04001794 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001795 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1796 ratio, bclk, ratio * bclk, group_size);
Len Brown6574a5d2012-09-21 00:01:31 -04001797
Len Brown103a8fe2010-10-22 23:53:03 -04001798 ratio = (msr >> 24) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001799 group_size = (core_counts >> 24) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001800 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001801 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1802 ratio, bclk, ratio * bclk, group_size);
Len Brown103a8fe2010-10-22 23:53:03 -04001803
1804 ratio = (msr >> 16) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001805 group_size = (core_counts >> 16) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001806 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001807 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1808 ratio, bclk, ratio * bclk, group_size);
Len Brown103a8fe2010-10-22 23:53:03 -04001809
1810 ratio = (msr >> 8) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001811 group_size = (core_counts >> 8) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001812 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001813 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1814 ratio, bclk, ratio * bclk, group_size);
Len Brown103a8fe2010-10-22 23:53:03 -04001815
1816 ratio = (msr >> 0) & 0xFF;
Len Brown31e07522017-01-31 23:07:49 -05001817 group_size = (core_counts >> 0) & 0xFF;
Len Brown103a8fe2010-10-22 23:53:03 -04001818 if (ratio)
Len Brown31e07522017-01-31 23:07:49 -05001819 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1820 ratio, bclk, ratio * bclk, group_size);
Len Brownfcd17212015-03-23 20:29:09 -04001821 return;
1822}
Len Brown3a9a9412014-08-15 02:39:52 -04001823
Len Brownfcd17212015-03-23 20:29:09 -04001824static void
Len Brown0f7887c2017-01-12 23:49:18 -05001825dump_atom_turbo_ratio_limits(void)
1826{
1827 unsigned long long msr;
1828 unsigned int ratio;
1829
1830 get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
1831 fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
1832
1833 ratio = (msr >> 0) & 0x3F;
1834 if (ratio)
1835 fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n",
1836 ratio, bclk, ratio * bclk);
1837
1838 ratio = (msr >> 8) & 0x3F;
1839 if (ratio)
1840 fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n",
1841 ratio, bclk, ratio * bclk);
1842
1843 ratio = (msr >> 16) & 0x3F;
1844 if (ratio)
1845 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
1846 ratio, bclk, ratio * bclk);
1847
1848 get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
1849 fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
1850
1851 ratio = (msr >> 24) & 0x3F;
1852 if (ratio)
1853 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n",
1854 ratio, bclk, ratio * bclk);
1855
1856 ratio = (msr >> 16) & 0x3F;
1857 if (ratio)
1858 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n",
1859 ratio, bclk, ratio * bclk);
1860
1861 ratio = (msr >> 8) & 0x3F;
1862 if (ratio)
1863 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n",
1864 ratio, bclk, ratio * bclk);
1865
1866 ratio = (msr >> 0) & 0x3F;
1867 if (ratio)
1868 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n",
1869 ratio, bclk, ratio * bclk);
1870}
1871
1872static void
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001873dump_knl_turbo_ratio_limits(void)
1874{
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001875 const unsigned int buckets_no = 7;
1876
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001877 unsigned long long msr;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001878 int delta_cores, delta_ratio;
1879 int i, b_nr;
1880 unsigned int cores[buckets_no];
1881 unsigned int ratio[buckets_no];
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001882
Srinivas Pandruvadaebf59262016-07-06 16:07:56 -07001883 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001884
Len Brownb7d8c142016-02-13 23:36:17 -05001885 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
Len Brownbfae2052015-06-17 12:27:21 -04001886 base_cpu, msr);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001887
1888 /**
1889 * Turbo encoding in KNL is as follows:
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001890 * [0] -- Reserved
1891 * [7:1] -- Base value of number of active cores of bucket 1.
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001892 * [15:8] -- Base value of freq ratio of bucket 1.
1893 * [20:16] -- +ve delta of number of active cores of bucket 2.
1894 * i.e. active cores of bucket 2 =
1895 * active cores of bucket 1 + delta
1896 * [23:21] -- Negative delta of freq ratio of bucket 2.
1897 * i.e. freq ratio of bucket 2 =
1898 * freq ratio of bucket 1 - delta
1899 * [28:24]-- +ve delta of number of active cores of bucket 3.
1900 * [31:29]-- -ve delta of freq ratio of bucket 3.
1901 * [36:32]-- +ve delta of number of active cores of bucket 4.
1902 * [39:37]-- -ve delta of freq ratio of bucket 4.
1903 * [44:40]-- +ve delta of number of active cores of bucket 5.
1904 * [47:45]-- -ve delta of freq ratio of bucket 5.
1905 * [52:48]-- +ve delta of number of active cores of bucket 6.
1906 * [55:53]-- -ve delta of freq ratio of bucket 6.
1907 * [60:56]-- +ve delta of number of active cores of bucket 7.
1908 * [63:61]-- -ve delta of freq ratio of bucket 7.
1909 */
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001910
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001911 b_nr = 0;
1912 cores[b_nr] = (msr & 0xFF) >> 1;
1913 ratio[b_nr] = (msr >> 8) & 0xFF;
1914
1915 for (i = 16; i < 64; i += 8) {
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001916 delta_cores = (msr >> i) & 0x1F;
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001917 delta_ratio = (msr >> (i + 5)) & 0x7;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001918
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001919 cores[b_nr + 1] = cores[b_nr] + delta_cores;
1920 ratio[b_nr + 1] = ratio[b_nr] - delta_ratio;
1921 b_nr++;
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001922 }
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001923
1924 for (i = buckets_no - 1; i >= 0; i--)
1925 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
Len Brownb7d8c142016-02-13 23:36:17 -05001926 fprintf(outf,
Len Brown710f2732017-01-11 22:12:25 -05001927 "%d * %.1f = %.1f MHz max turbo %d active cores\n",
Hubert Chrzaniukcbf97ab2016-02-10 14:55:22 +01001928 ratio[i], bclk, ratio[i] * bclk, cores[i]);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07001929}
1930
1931static void
Len Brownfcd17212015-03-23 20:29:09 -04001932dump_nhm_cst_cfg(void)
1933{
1934 unsigned long long msr;
1935
Len Brown1df2e552017-01-07 23:24:57 -05001936 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
Len Brownfcd17212015-03-23 20:29:09 -04001937
1938#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
1939#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
1940
Len Brown1df2e552017-01-07 23:24:57 -05001941 fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
Len Brownfcd17212015-03-23 20:29:09 -04001942
Len Brownb7d8c142016-02-13 23:36:17 -05001943 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
Len Brownfcd17212015-03-23 20:29:09 -04001944 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
1945 (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
1946 (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
1947 (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
1948 (msr & (1 << 15)) ? "" : "UN",
Len Brown6c34f162016-03-13 03:21:22 -04001949 (unsigned int)msr & 0xF,
Len Brownfcd17212015-03-23 20:29:09 -04001950 pkg_cstate_limit_strings[pkg_cstate_limit]);
1951 return;
Len Brown103a8fe2010-10-22 23:53:03 -04001952}
1953
Len Brown6fb31432015-06-17 16:23:45 -04001954static void
1955dump_config_tdp(void)
1956{
1957 unsigned long long msr;
1958
1959 get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001960 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001961 fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF);
Len Brown6fb31432015-06-17 16:23:45 -04001962
1963 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001964 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001965 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001966 fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1967 fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1968 fprintf(outf, "LVL1_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1969 fprintf(outf, "PKG_TDP_LVL1=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001970 }
Len Brownb7d8c142016-02-13 23:36:17 -05001971 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001972
1973 get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001974 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001975 if (msr) {
Chen Yu685b5352015-12-13 21:09:31 +08001976 fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF);
1977 fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF);
1978 fprintf(outf, "LVL2_RATIO=%d ", (unsigned int)(msr >> 16) & 0xFF);
1979 fprintf(outf, "PKG_TDP_LVL2=%d", (unsigned int)(msr) & 0x7FFF);
Len Brown6fb31432015-06-17 16:23:45 -04001980 }
Len Brownb7d8c142016-02-13 23:36:17 -05001981 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001982
1983 get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001984 fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr);
Len Brown6fb31432015-06-17 16:23:45 -04001985 if ((msr) & 0x3)
Len Brownb7d8c142016-02-13 23:36:17 -05001986 fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3);
1987 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1988 fprintf(outf, ")\n");
Len Brown36229892016-02-26 20:51:02 -05001989
Len Brown6fb31432015-06-17 16:23:45 -04001990 get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05001991 fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr);
Chen Yu685b5352015-12-13 21:09:31 +08001992 fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF);
Len Brownb7d8c142016-02-13 23:36:17 -05001993 fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
1994 fprintf(outf, ")\n");
Len Brown6fb31432015-06-17 16:23:45 -04001995}
Len Brown5a634262016-04-06 17:15:55 -04001996
1997unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
1998
1999void print_irtl(void)
2000{
2001 unsigned long long msr;
2002
2003 get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
2004 fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
2005 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2006 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2007
2008 get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
2009 fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
2010 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2011 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2012
2013 get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
2014 fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
2015 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2016 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2017
2018 if (!do_irtl_hsw)
2019 return;
2020
2021 get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
2022 fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
2023 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2024 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2025
2026 get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
2027 fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
2028 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2029 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2030
2031 get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
2032 fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
2033 fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
2034 (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
2035
2036}
Len Brown36229892016-02-26 20:51:02 -05002037void free_fd_percpu(void)
2038{
2039 int i;
2040
Mika Westerberg01a67ad2016-04-22 11:13:23 +03002041 for (i = 0; i < topo.max_cpu_num + 1; ++i) {
Len Brown36229892016-02-26 20:51:02 -05002042 if (fd_percpu[i] != 0)
2043 close(fd_percpu[i]);
2044 }
2045
2046 free(fd_percpu);
Len Brown6fb31432015-06-17 16:23:45 -04002047}
2048
Len Brownc98d5d92012-06-04 00:56:40 -04002049void free_all_buffers(void)
Len Brown103a8fe2010-10-22 23:53:03 -04002050{
Len Brownc98d5d92012-06-04 00:56:40 -04002051 CPU_FREE(cpu_present_set);
2052 cpu_present_set = NULL;
Len Brown36229892016-02-26 20:51:02 -05002053 cpu_present_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002054
Len Brownc98d5d92012-06-04 00:56:40 -04002055 CPU_FREE(cpu_affinity_set);
2056 cpu_affinity_set = NULL;
2057 cpu_affinity_setsize = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002058
Len Brownc98d5d92012-06-04 00:56:40 -04002059 free(thread_even);
2060 free(core_even);
2061 free(package_even);
2062
2063 thread_even = NULL;
2064 core_even = NULL;
2065 package_even = NULL;
2066
2067 free(thread_odd);
2068 free(core_odd);
2069 free(package_odd);
2070
2071 thread_odd = NULL;
2072 core_odd = NULL;
2073 package_odd = NULL;
2074
2075 free(output_buffer);
2076 output_buffer = NULL;
2077 outp = NULL;
Len Brown36229892016-02-26 20:51:02 -05002078
2079 free_fd_percpu();
Len Brown562a2d32016-02-26 23:48:05 -05002080
2081 free(irq_column_2_cpu);
2082 free(irqs_per_cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002083}
2084
Josh Triplett57a42a32013-08-20 17:20:17 -07002085
2086/*
Josh Triplett95aebc42013-08-20 17:20:16 -07002087 * Parse a file containing a single int.
2088 */
2089int parse_int_file(const char *fmt, ...)
2090{
2091 va_list args;
2092 char path[PATH_MAX];
2093 FILE *filep;
2094 int value;
2095
2096 va_start(args, fmt);
2097 vsnprintf(path, sizeof(path), fmt, args);
2098 va_end(args);
Josh Triplett57a42a32013-08-20 17:20:17 -07002099 filep = fopen_or_die(path, "r");
Josh Triplettb2c95d92013-08-20 17:20:18 -07002100 if (fscanf(filep, "%d", &value) != 1)
2101 err(1, "%s: failed to parse number from file", path);
Josh Triplett95aebc42013-08-20 17:20:16 -07002102 fclose(filep);
2103 return value;
2104}
2105
2106/*
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002107 * get_cpu_position_in_core(cpu)
2108 * return the position of the CPU among its HT siblings in the core
2109 * return -1 if the sibling is not in list
Len Brownc98d5d92012-06-04 00:56:40 -04002110 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002111int get_cpu_position_in_core(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04002112{
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002113 char path[64];
2114 FILE *filep;
2115 int this_cpu;
2116 char character;
2117 int i;
2118
2119 sprintf(path,
2120 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list",
2121 cpu);
2122 filep = fopen(path, "r");
2123 if (filep == NULL) {
2124 perror(path);
2125 exit(1);
2126 }
2127
2128 for (i = 0; i < topo.num_threads_per_core; i++) {
2129 fscanf(filep, "%d", &this_cpu);
2130 if (this_cpu == cpu) {
2131 fclose(filep);
2132 return i;
2133 }
2134
2135 /* Account for no separator after last thread*/
2136 if (i != (topo.num_threads_per_core - 1))
2137 fscanf(filep, "%c", &character);
2138 }
2139
2140 fclose(filep);
2141 return -1;
Len Brown103a8fe2010-10-22 23:53:03 -04002142}
2143
Len Brownc98d5d92012-06-04 00:56:40 -04002144/*
2145 * cpu_is_first_core_in_package(cpu)
2146 * return 1 if given CPU is 1st core in package
2147 */
2148int cpu_is_first_core_in_package(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04002149{
Josh Triplett95aebc42013-08-20 17:20:16 -07002150 return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002151}
2152
2153int get_physical_package_id(int cpu)
2154{
Josh Triplett95aebc42013-08-20 17:20:16 -07002155 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002156}
2157
2158int get_core_id(int cpu)
2159{
Josh Triplett95aebc42013-08-20 17:20:16 -07002160 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
Len Brown103a8fe2010-10-22 23:53:03 -04002161}
2162
Len Brownc98d5d92012-06-04 00:56:40 -04002163int get_num_ht_siblings(int cpu)
2164{
2165 char path[80];
2166 FILE *filep;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002167 int sib1;
2168 int matches = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04002169 char character;
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002170 char str[100];
2171 char *ch;
Len Brownc98d5d92012-06-04 00:56:40 -04002172
2173 sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
Josh Triplett57a42a32013-08-20 17:20:17 -07002174 filep = fopen_or_die(path, "r");
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002175
Len Brownc98d5d92012-06-04 00:56:40 -04002176 /*
2177 * file format:
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002178 * A ',' separated or '-' separated set of numbers
2179 * (eg 1-2 or 1,3,4,5)
Len Brownc98d5d92012-06-04 00:56:40 -04002180 */
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002181 fscanf(filep, "%d%c\n", &sib1, &character);
2182 fseek(filep, 0, SEEK_SET);
2183 fgets(str, 100, filep);
2184 ch = strchr(str, character);
2185 while (ch != NULL) {
2186 matches++;
2187 ch = strchr(ch+1, character);
2188 }
Len Brownc98d5d92012-06-04 00:56:40 -04002189
2190 fclose(filep);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07002191 return matches+1;
Len Brownc98d5d92012-06-04 00:56:40 -04002192}
2193
Len Brown103a8fe2010-10-22 23:53:03 -04002194/*
Len Brownc98d5d92012-06-04 00:56:40 -04002195 * run func(thread, core, package) in topology order
2196 * skip non-present cpus
Len Brown103a8fe2010-10-22 23:53:03 -04002197 */
2198
Len Brownc98d5d92012-06-04 00:56:40 -04002199int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
2200 struct pkg_data *, struct thread_data *, struct core_data *,
2201 struct pkg_data *), struct thread_data *thread_base,
2202 struct core_data *core_base, struct pkg_data *pkg_base,
2203 struct thread_data *thread_base2, struct core_data *core_base2,
2204 struct pkg_data *pkg_base2)
2205{
2206 int retval, pkg_no, core_no, thread_no;
2207
2208 for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
2209 for (core_no = 0; core_no < topo.num_cores_per_pkg; ++core_no) {
2210 for (thread_no = 0; thread_no <
2211 topo.num_threads_per_core; ++thread_no) {
2212 struct thread_data *t, *t2;
2213 struct core_data *c, *c2;
2214 struct pkg_data *p, *p2;
2215
2216 t = GET_THREAD(thread_base, thread_no, core_no, pkg_no);
2217
2218 if (cpu_is_not_present(t->cpu_id))
2219 continue;
2220
2221 t2 = GET_THREAD(thread_base2, thread_no, core_no, pkg_no);
2222
2223 c = GET_CORE(core_base, core_no, pkg_no);
2224 c2 = GET_CORE(core_base2, core_no, pkg_no);
2225
2226 p = GET_PKG(pkg_base, pkg_no);
2227 p2 = GET_PKG(pkg_base2, pkg_no);
2228
2229 retval = func(t, c, p, t2, c2, p2);
2230 if (retval)
2231 return retval;
2232 }
2233 }
2234 }
2235 return 0;
2236}
2237
2238/*
2239 * run func(cpu) on every cpu in /proc/stat
2240 * return max_cpu number
2241 */
2242int for_all_proc_cpus(int (func)(int))
Len Brown103a8fe2010-10-22 23:53:03 -04002243{
2244 FILE *fp;
Len Brownc98d5d92012-06-04 00:56:40 -04002245 int cpu_num;
Len Brown103a8fe2010-10-22 23:53:03 -04002246 int retval;
2247
Josh Triplett57a42a32013-08-20 17:20:17 -07002248 fp = fopen_or_die(proc_stat, "r");
Len Brown103a8fe2010-10-22 23:53:03 -04002249
2250 retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
Josh Triplettb2c95d92013-08-20 17:20:18 -07002251 if (retval != 0)
2252 err(1, "%s: failed to parse format", proc_stat);
Len Brown103a8fe2010-10-22 23:53:03 -04002253
Len Brownc98d5d92012-06-04 00:56:40 -04002254 while (1) {
2255 retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
Len Brown103a8fe2010-10-22 23:53:03 -04002256 if (retval != 1)
2257 break;
2258
Len Brownc98d5d92012-06-04 00:56:40 -04002259 retval = func(cpu_num);
2260 if (retval) {
2261 fclose(fp);
2262 return(retval);
2263 }
Len Brown103a8fe2010-10-22 23:53:03 -04002264 }
2265 fclose(fp);
Len Brownc98d5d92012-06-04 00:56:40 -04002266 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002267}
2268
2269void re_initialize(void)
2270{
Len Brownc98d5d92012-06-04 00:56:40 -04002271 free_all_buffers();
2272 setup_all_buffers();
2273 printf("turbostat: re-initialized with num_cpus %d\n", topo.num_cpus);
Len Brown103a8fe2010-10-22 23:53:03 -04002274}
2275
Len Brownc98d5d92012-06-04 00:56:40 -04002276
Len Brown103a8fe2010-10-22 23:53:03 -04002277/*
Len Brownc98d5d92012-06-04 00:56:40 -04002278 * count_cpus()
2279 * remember the last one seen, it will be the max
Len Brown103a8fe2010-10-22 23:53:03 -04002280 */
Len Brownc98d5d92012-06-04 00:56:40 -04002281int count_cpus(int cpu)
Len Brown103a8fe2010-10-22 23:53:03 -04002282{
Len Brownc98d5d92012-06-04 00:56:40 -04002283 if (topo.max_cpu_num < cpu)
2284 topo.max_cpu_num = cpu;
Len Brown103a8fe2010-10-22 23:53:03 -04002285
Len Brownc98d5d92012-06-04 00:56:40 -04002286 topo.num_cpus += 1;
2287 return 0;
2288}
2289int mark_cpu_present(int cpu)
2290{
2291 CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
Len Brown15aaa342012-03-29 22:19:58 -04002292 return 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002293}
2294
Len Brown562a2d32016-02-26 23:48:05 -05002295/*
2296 * snapshot_proc_interrupts()
2297 *
2298 * read and record summary of /proc/interrupts
2299 *
2300 * return 1 if config change requires a restart, else return 0
2301 */
2302int snapshot_proc_interrupts(void)
2303{
2304 static FILE *fp;
2305 int column, retval;
2306
2307 if (fp == NULL)
2308 fp = fopen_or_die("/proc/interrupts", "r");
2309 else
2310 rewind(fp);
2311
2312 /* read 1st line of /proc/interrupts to get cpu* name for each column */
2313 for (column = 0; column < topo.num_cpus; ++column) {
2314 int cpu_number;
2315
2316 retval = fscanf(fp, " CPU%d", &cpu_number);
2317 if (retval != 1)
2318 break;
2319
2320 if (cpu_number > topo.max_cpu_num) {
2321 warn("/proc/interrupts: cpu%d: > %d", cpu_number, topo.max_cpu_num);
2322 return 1;
2323 }
2324
2325 irq_column_2_cpu[column] = cpu_number;
2326 irqs_per_cpu[cpu_number] = 0;
2327 }
2328
2329 /* read /proc/interrupt count lines and sum up irqs per cpu */
2330 while (1) {
2331 int column;
2332 char buf[64];
2333
2334 retval = fscanf(fp, " %s:", buf); /* flush irq# "N:" */
2335 if (retval != 1)
2336 break;
2337
2338 /* read the count per cpu */
2339 for (column = 0; column < topo.num_cpus; ++column) {
2340
2341 int cpu_number, irq_count;
2342
2343 retval = fscanf(fp, " %d", &irq_count);
2344 if (retval != 1)
2345 break;
2346
2347 cpu_number = irq_column_2_cpu[column];
2348 irqs_per_cpu[cpu_number] += irq_count;
2349
2350 }
2351
2352 while (getc(fp) != '\n')
2353 ; /* flush interrupt description */
2354
2355 }
2356 return 0;
2357}
Len Brown27d47352016-02-27 00:37:54 -05002358/*
Len Brownfdf676e2016-02-27 01:28:12 -05002359 * snapshot_gfx_rc6_ms()
2360 *
2361 * record snapshot of
2362 * /sys/class/drm/card0/power/rc6_residency_ms
2363 *
2364 * return 1 if config change requires a restart, else return 0
2365 */
2366int snapshot_gfx_rc6_ms(void)
2367{
2368 FILE *fp;
2369 int retval;
2370
2371 fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
2372
2373 retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
2374 if (retval != 1)
2375 err(1, "GFX rc6");
2376
2377 fclose(fp);
2378
2379 return 0;
2380}
2381/*
Len Brown27d47352016-02-27 00:37:54 -05002382 * snapshot_gfx_mhz()
2383 *
2384 * record snapshot of
2385 * /sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz
2386 *
2387 * return 1 if config change requires a restart, else return 0
2388 */
2389int snapshot_gfx_mhz(void)
2390{
2391 static FILE *fp;
2392 int retval;
2393
2394 if (fp == NULL)
2395 fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
2396 else
2397 rewind(fp);
2398
2399 retval = fscanf(fp, "%d", &gfx_cur_mhz);
2400 if (retval != 1)
2401 err(1, "GFX MHz");
2402
2403 return 0;
2404}
Len Brown562a2d32016-02-26 23:48:05 -05002405
2406/*
2407 * snapshot /proc and /sys files
2408 *
2409 * return 1 if configuration restart needed, else return 0
2410 */
2411int snapshot_proc_sysfs_files(void)
2412{
Len Brown218f0e82017-02-14 22:07:52 -05002413 if (DO_BIC(BIC_IRQ))
2414 if (snapshot_proc_interrupts())
2415 return 1;
Len Brown562a2d32016-02-26 23:48:05 -05002416
Len Brown812db3f2017-02-10 00:25:41 -05002417 if (DO_BIC(BIC_GFX_rc6))
Len Brownfdf676e2016-02-27 01:28:12 -05002418 snapshot_gfx_rc6_ms();
2419
Len Brown812db3f2017-02-10 00:25:41 -05002420 if (DO_BIC(BIC_GFXMHz))
Len Brown27d47352016-02-27 00:37:54 -05002421 snapshot_gfx_mhz();
2422
Len Brown562a2d32016-02-26 23:48:05 -05002423 return 0;
2424}
2425
Len Brown103a8fe2010-10-22 23:53:03 -04002426void turbostat_loop()
2427{
Len Brownc98d5d92012-06-04 00:56:40 -04002428 int retval;
Len Browne52966c2012-11-08 22:38:05 -05002429 int restarted = 0;
Len Brownc98d5d92012-06-04 00:56:40 -04002430
Len Brown103a8fe2010-10-22 23:53:03 -04002431restart:
Len Browne52966c2012-11-08 22:38:05 -05002432 restarted++;
2433
Len Brown562a2d32016-02-26 23:48:05 -05002434 snapshot_proc_sysfs_files();
Len Brownc98d5d92012-06-04 00:56:40 -04002435 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002436 if (retval < -1) {
2437 exit(retval);
2438 } else if (retval == -1) {
Len Browne52966c2012-11-08 22:38:05 -05002439 if (restarted > 1) {
2440 exit(retval);
2441 }
Len Brownc98d5d92012-06-04 00:56:40 -04002442 re_initialize();
2443 goto restart;
2444 }
Len Browne52966c2012-11-08 22:38:05 -05002445 restarted = 0;
Len Brown103a8fe2010-10-22 23:53:03 -04002446 gettimeofday(&tv_even, (struct timezone *)NULL);
2447
2448 while (1) {
Len Brownc98d5d92012-06-04 00:56:40 -04002449 if (for_all_proc_cpus(cpu_is_not_present)) {
Len Brown103a8fe2010-10-22 23:53:03 -04002450 re_initialize();
2451 goto restart;
2452 }
Len Brown2a0609c2016-02-12 22:44:48 -05002453 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002454 if (snapshot_proc_sysfs_files())
2455 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002456 retval = for_all_cpus(get_counters, ODD_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002457 if (retval < -1) {
2458 exit(retval);
2459 } else if (retval == -1) {
Len Brown15aaa342012-03-29 22:19:58 -04002460 re_initialize();
2461 goto restart;
2462 }
Len Brown103a8fe2010-10-22 23:53:03 -04002463 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002464 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002465 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS)) {
2466 re_initialize();
2467 goto restart;
2468 }
Len Brownc98d5d92012-06-04 00:56:40 -04002469 compute_average(EVEN_COUNTERS);
2470 format_all_counters(EVEN_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002471 flush_output_stdout();
Len Brown2a0609c2016-02-12 22:44:48 -05002472 nanosleep(&interval_ts, NULL);
Len Brown562a2d32016-02-26 23:48:05 -05002473 if (snapshot_proc_sysfs_files())
2474 goto restart;
Len Brownc98d5d92012-06-04 00:56:40 -04002475 retval = for_all_cpus(get_counters, EVEN_COUNTERS);
Len Brownd91bb172012-11-01 00:08:19 -04002476 if (retval < -1) {
2477 exit(retval);
2478 } else if (retval == -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04002479 re_initialize();
2480 goto restart;
2481 }
Len Brown103a8fe2010-10-22 23:53:03 -04002482 gettimeofday(&tv_even, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04002483 timersub(&tv_even, &tv_odd, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04002484 if (for_all_cpus_2(delta_cpu, EVEN_COUNTERS, ODD_COUNTERS)) {
2485 re_initialize();
2486 goto restart;
2487 }
Len Brownc98d5d92012-06-04 00:56:40 -04002488 compute_average(ODD_COUNTERS);
2489 format_all_counters(ODD_COUNTERS);
Len Brownb7d8c142016-02-13 23:36:17 -05002490 flush_output_stdout();
Len Brown103a8fe2010-10-22 23:53:03 -04002491 }
2492}
2493
2494void check_dev_msr()
2495{
2496 struct stat sb;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002497 char pathname[32];
Len Brown103a8fe2010-10-22 23:53:03 -04002498
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002499 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2500 if (stat(pathname, &sb))
Len Browna21d38c2015-03-24 16:37:35 -04002501 if (system("/sbin/modprobe msr > /dev/null 2>&1"))
2502 err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
Len Brown103a8fe2010-10-22 23:53:03 -04002503}
2504
Len Brown98481e72014-08-15 00:36:50 -04002505void check_permissions()
Len Brown103a8fe2010-10-22 23:53:03 -04002506{
Len Brown98481e72014-08-15 00:36:50 -04002507 struct __user_cap_header_struct cap_header_data;
2508 cap_user_header_t cap_header = &cap_header_data;
2509 struct __user_cap_data_struct cap_data_data;
2510 cap_user_data_t cap_data = &cap_data_data;
2511 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
2512 int do_exit = 0;
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002513 char pathname[32];
Len Brown98481e72014-08-15 00:36:50 -04002514
2515 /* check for CAP_SYS_RAWIO */
2516 cap_header->pid = getpid();
2517 cap_header->version = _LINUX_CAPABILITY_VERSION;
2518 if (capget(cap_header, cap_data) < 0)
2519 err(-6, "capget(2) failed");
2520
2521 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
2522 do_exit++;
2523 warnx("capget(CAP_SYS_RAWIO) failed,"
2524 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
2525 }
2526
2527 /* test file permissions */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04002528 sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
2529 if (euidaccess(pathname, R_OK)) {
Len Brown98481e72014-08-15 00:36:50 -04002530 do_exit++;
2531 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
2532 }
2533
2534 /* if all else fails, thell them to be root */
2535 if (do_exit)
2536 if (getuid() != 0)
Len Brownd7899442015-01-23 00:12:33 -05002537 warnx("... or simply run as root");
Len Brown98481e72014-08-15 00:36:50 -04002538
2539 if (do_exit)
2540 exit(-6);
Len Brown103a8fe2010-10-22 23:53:03 -04002541}
2542
Len Brownd7899442015-01-23 00:12:33 -05002543/*
2544 * NHM adds support for additional MSRs:
2545 *
2546 * MSR_SMI_COUNT 0x00000034
2547 *
Len Brownec0adc52015-11-12 02:42:31 -05002548 * MSR_PLATFORM_INFO 0x000000ce
Len Brown1df2e552017-01-07 23:24:57 -05002549 * MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
Len Brownd7899442015-01-23 00:12:33 -05002550 *
Len Browncf4cbe52017-01-01 13:08:33 -05002551 * MSR_MISC_PWR_MGMT 0x000001aa
2552 *
Len Brownd7899442015-01-23 00:12:33 -05002553 * MSR_PKG_C3_RESIDENCY 0x000003f8
2554 * MSR_PKG_C6_RESIDENCY 0x000003f9
2555 * MSR_CORE_C3_RESIDENCY 0x000003fc
2556 * MSR_CORE_C6_RESIDENCY 0x000003fd
2557 *
Len Brownee7e38e2015-02-09 23:39:45 -05002558 * Side effect:
Len Brown1df2e552017-01-07 23:24:57 -05002559 * sets global pkg_cstate_limit to decode MSR_PKG_CST_CONFIG_CONTROL
Len Brown33148d62017-01-21 01:26:16 -05002560 * sets has_misc_feature_control
Len Brownd7899442015-01-23 00:12:33 -05002561 */
Len Brownee7e38e2015-02-09 23:39:45 -05002562int probe_nhm_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04002563{
Len Brownee7e38e2015-02-09 23:39:45 -05002564 unsigned long long msr;
Len Brown21ed5572015-10-19 22:37:40 -04002565 unsigned int base_ratio;
Len Brownee7e38e2015-02-09 23:39:45 -05002566 int *pkg_cstate_limits;
2567
Len Brown103a8fe2010-10-22 23:53:03 -04002568 if (!genuine_intel)
2569 return 0;
2570
2571 if (family != 6)
2572 return 0;
2573
Len Brown21ed5572015-10-19 22:37:40 -04002574 bclk = discover_bclk(family, model);
2575
Len Brown103a8fe2010-10-22 23:53:03 -04002576 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002577 case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
2578 case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
Len Brown103a8fe2010-10-22 23:53:03 -04002579 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
Len Brown869ce692016-06-16 23:22:37 -04002580 case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */
2581 case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */
2582 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2583 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
Len Brownee7e38e2015-02-09 23:39:45 -05002584 pkg_cstate_limits = nhm_pkg_cstate_limits;
2585 break;
Len Brown869ce692016-06-16 23:22:37 -04002586 case INTEL_FAM6_SANDYBRIDGE: /* SNB */
2587 case INTEL_FAM6_SANDYBRIDGE_X: /* SNB Xeon */
2588 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2589 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
Len Brownee7e38e2015-02-09 23:39:45 -05002590 pkg_cstate_limits = snb_pkg_cstate_limits;
Len Brown33148d62017-01-21 01:26:16 -05002591 has_misc_feature_control = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002592 break;
Len Brown869ce692016-06-16 23:22:37 -04002593 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2594 case INTEL_FAM6_HASWELL_X: /* HSX */
2595 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2596 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2597 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2598 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2599 case INTEL_FAM6_BROADWELL_X: /* BDX */
2600 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2601 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2602 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2603 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2604 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brownee7e38e2015-02-09 23:39:45 -05002605 pkg_cstate_limits = hsw_pkg_cstate_limits;
Len Brown33148d62017-01-21 01:26:16 -05002606 has_misc_feature_control = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002607 break;
Len Brownd8ebb442016-12-01 20:27:46 -05002608 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2609 pkg_cstate_limits = skx_pkg_cstate_limits;
Len Brown33148d62017-01-21 01:26:16 -05002610 has_misc_feature_control = 1;
Len Brownd8ebb442016-12-01 20:27:46 -05002611 break;
Len Brown869ce692016-06-16 23:22:37 -04002612 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
Len Browncf4cbe52017-01-01 13:08:33 -05002613 no_MSR_MISC_PWR_MGMT = 1;
Len Brown869ce692016-06-16 23:22:37 -04002614 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brownee7e38e2015-02-09 23:39:45 -05002615 pkg_cstate_limits = slv_pkg_cstate_limits;
2616 break;
Len Brown869ce692016-06-16 23:22:37 -04002617 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
Len Brownee7e38e2015-02-09 23:39:45 -05002618 pkg_cstate_limits = amt_pkg_cstate_limits;
Len Browncf4cbe52017-01-01 13:08:33 -05002619 no_MSR_MISC_PWR_MGMT = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002620 break;
Len Brown869ce692016-06-16 23:22:37 -04002621 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
Len Brown005c82d2016-12-01 01:35:38 -05002622 case INTEL_FAM6_XEON_PHI_KNM:
Len Brownee7e38e2015-02-09 23:39:45 -05002623 pkg_cstate_limits = phi_pkg_cstate_limits;
2624 break;
Len Brown869ce692016-06-16 23:22:37 -04002625 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05002626 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Len Brown869ce692016-06-16 23:22:37 -04002627 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Browne4085d52016-04-06 17:15:56 -04002628 pkg_cstate_limits = bxt_pkg_cstate_limits;
2629 break;
Len Brown103a8fe2010-10-22 23:53:03 -04002630 default:
2631 return 0;
2632 }
Len Brown1df2e552017-01-07 23:24:57 -05002633 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
Len Browne9257f52015-04-01 21:02:57 -04002634 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
Len Brownee7e38e2015-02-09 23:39:45 -05002635
Len Brownec0adc52015-11-12 02:42:31 -05002636 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
Len Brown21ed5572015-10-19 22:37:40 -04002637 base_ratio = (msr >> 8) & 0xFF;
2638
2639 base_hz = base_ratio * bclk * 1000000;
2640 has_base_hz = 1;
Len Brownee7e38e2015-02-09 23:39:45 -05002641 return 1;
Len Brown103a8fe2010-10-22 23:53:03 -04002642}
Len Brown0f7887c2017-01-12 23:49:18 -05002643/*
Len Brown495c76542017-02-08 02:41:51 -05002644 * SLV client has support for unique MSRs:
Len Brown0f7887c2017-01-12 23:49:18 -05002645 *
2646 * MSR_CC6_DEMOTION_POLICY_CONFIG
2647 * MSR_MC6_DEMOTION_POLICY_CONFIG
2648 */
2649
2650int has_slv_msrs(unsigned int family, unsigned int model)
2651{
2652 if (!genuine_intel)
2653 return 0;
2654
2655 switch (model) {
2656 case INTEL_FAM6_ATOM_SILVERMONT1:
2657 case INTEL_FAM6_ATOM_MERRIFIELD:
2658 case INTEL_FAM6_ATOM_MOOREFIELD:
2659 return 1;
2660 }
2661 return 0;
2662}
Len Brown7170a372017-01-27 02:13:27 -05002663int is_dnv(unsigned int family, unsigned int model)
2664{
2665
2666 if (!genuine_intel)
2667 return 0;
2668
2669 switch (model) {
2670 case INTEL_FAM6_ATOM_DENVERTON:
2671 return 1;
2672 }
2673 return 0;
2674}
Len Brownade0eba2017-02-10 01:56:47 -05002675int is_bdx(unsigned int family, unsigned int model)
2676{
2677
2678 if (!genuine_intel)
2679 return 0;
2680
2681 switch (model) {
2682 case INTEL_FAM6_BROADWELL_X:
2683 case INTEL_FAM6_BROADWELL_XEON_D:
2684 return 1;
2685 }
2686 return 0;
2687}
Len Brown34c761972017-01-27 02:36:41 -05002688int is_skx(unsigned int family, unsigned int model)
2689{
2690
2691 if (!genuine_intel)
2692 return 0;
2693
2694 switch (model) {
2695 case INTEL_FAM6_SKYLAKE_X:
2696 return 1;
2697 }
2698 return 0;
2699}
Len Brown0f7887c2017-01-12 23:49:18 -05002700
Len Brown31e07522017-01-31 23:07:49 -05002701int has_turbo_ratio_limit(unsigned int family, unsigned int model)
Len Brownd7899442015-01-23 00:12:33 -05002702{
Len Brown0f7887c2017-01-12 23:49:18 -05002703 if (has_slv_msrs(family, model))
2704 return 0;
2705
Len Brownd7899442015-01-23 00:12:33 -05002706 switch (model) {
2707 /* Nehalem compatible, but do not include turbo-ratio limit support */
Len Brown869ce692016-06-16 23:22:37 -04002708 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
2709 case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */
2710 case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */
Len Brown005c82d2016-12-01 01:35:38 -05002711 case INTEL_FAM6_XEON_PHI_KNM:
Len Brownd7899442015-01-23 00:12:33 -05002712 return 0;
2713 default:
2714 return 1;
2715 }
2716}
Len Brown0f7887c2017-01-12 23:49:18 -05002717int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
2718{
2719 if (has_slv_msrs(family, model))
2720 return 1;
2721
2722 return 0;
2723}
Len Brown6574a5d2012-09-21 00:01:31 -04002724int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
2725{
2726 if (!genuine_intel)
2727 return 0;
2728
2729 if (family != 6)
2730 return 0;
2731
2732 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002733 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2734 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brown6574a5d2012-09-21 00:01:31 -04002735 return 1;
2736 default:
2737 return 0;
2738 }
2739}
Len Brownfcd17212015-03-23 20:29:09 -04002740int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
2741{
2742 if (!genuine_intel)
2743 return 0;
2744
2745 if (family != 6)
2746 return 0;
2747
2748 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002749 case INTEL_FAM6_HASWELL_X: /* HSW Xeon */
Len Brownfcd17212015-03-23 20:29:09 -04002750 return 1;
2751 default:
2752 return 0;
2753 }
2754}
2755
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002756int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
2757{
2758 if (!genuine_intel)
2759 return 0;
2760
2761 if (family != 6)
2762 return 0;
2763
2764 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002765 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown005c82d2016-12-01 01:35:38 -05002766 case INTEL_FAM6_XEON_PHI_KNM:
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002767 return 1;
2768 default:
2769 return 0;
2770 }
2771}
Len Brown31e07522017-01-31 23:07:49 -05002772int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
2773{
2774 if (!genuine_intel)
2775 return 0;
2776
2777 if (family != 6)
2778 return 0;
2779
2780 switch (model) {
2781 case INTEL_FAM6_ATOM_GOLDMONT:
2782 case INTEL_FAM6_SKYLAKE_X:
2783 return 1;
2784 default:
2785 return 0;
2786 }
2787}
Len Brown6fb31432015-06-17 16:23:45 -04002788int has_config_tdp(unsigned int family, unsigned int model)
2789{
2790 if (!genuine_intel)
2791 return 0;
2792
2793 if (family != 6)
2794 return 0;
2795
2796 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04002797 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2798 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2799 case INTEL_FAM6_HASWELL_X: /* HSX */
2800 case INTEL_FAM6_HASWELL_ULT: /* HSW */
2801 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
2802 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2803 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2804 case INTEL_FAM6_BROADWELL_X: /* BDX */
2805 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
2806 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2807 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2808 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2809 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2810 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brown6fb31432015-06-17 16:23:45 -04002811
Len Brown869ce692016-06-16 23:22:37 -04002812 case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
Len Brown005c82d2016-12-01 01:35:38 -05002813 case INTEL_FAM6_XEON_PHI_KNM:
Len Brown6fb31432015-06-17 16:23:45 -04002814 return 1;
2815 default:
2816 return 0;
2817 }
2818}
2819
Len Brownfcd17212015-03-23 20:29:09 -04002820static void
Colin Ian King1b693172016-03-02 13:50:25 +00002821dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
Len Brownfcd17212015-03-23 20:29:09 -04002822{
2823 if (!do_nhm_platform_info)
2824 return;
2825
2826 dump_nhm_platform_info();
2827
2828 if (has_hsw_turbo_ratio_limit(family, model))
2829 dump_hsw_turbo_ratio_limits();
2830
2831 if (has_ivt_turbo_ratio_limit(family, model))
2832 dump_ivt_turbo_ratio_limits();
2833
Len Brown31e07522017-01-31 23:07:49 -05002834 if (has_turbo_ratio_limit(family, model))
2835 dump_turbo_ratio_limits(family, model);
Len Brownfcd17212015-03-23 20:29:09 -04002836
Len Brown0f7887c2017-01-12 23:49:18 -05002837 if (has_atom_turbo_ratio_limit(family, model))
2838 dump_atom_turbo_ratio_limits();
2839
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07002840 if (has_knl_turbo_ratio_limit(family, model))
2841 dump_knl_turbo_ratio_limits();
2842
Len Brown6fb31432015-06-17 16:23:45 -04002843 if (has_config_tdp(family, model))
2844 dump_config_tdp();
2845
Len Brownfcd17212015-03-23 20:29:09 -04002846 dump_nhm_cst_cfg();
2847}
2848
Len Brown41618e62017-02-09 18:25:22 -05002849static void
2850dump_sysfs_cstate_config(void)
2851{
2852 char path[64];
2853 char name_buf[16];
2854 char desc[64];
2855 FILE *input;
2856 int state;
2857 char *sp;
2858
2859 if (!DO_BIC(BIC_sysfs))
2860 return;
2861
2862 for (state = 0; state < 10; ++state) {
2863
2864 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
2865 base_cpu, state);
2866 input = fopen(path, "r");
2867 if (input == NULL)
2868 continue;
2869 fgets(name_buf, sizeof(name_buf), input);
2870
2871 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
2872 sp = strchr(name_buf, '-');
2873 if (!sp)
2874 sp = strchrnul(name_buf, '\n');
2875 *sp = '\0';
2876
2877 fclose(input);
2878
2879 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
2880 base_cpu, state);
2881 input = fopen(path, "r");
2882 if (input == NULL)
2883 continue;
2884 fgets(desc, sizeof(desc), input);
2885
2886 fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
2887 fclose(input);
2888 }
2889}
2890
Len Brown6574a5d2012-09-21 00:01:31 -04002891
Len Brown889facb2012-11-08 00:48:57 -05002892/*
2893 * print_epb()
2894 * Decode the ENERGY_PERF_BIAS MSR
2895 */
2896int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2897{
2898 unsigned long long msr;
2899 char *epb_string;
2900 int cpu;
2901
2902 if (!has_epb)
2903 return 0;
2904
2905 cpu = t->cpu_id;
2906
2907 /* EPB is per-package */
2908 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2909 return 0;
2910
2911 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002912 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05002913 return -1;
2914 }
2915
2916 if (get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr))
2917 return 0;
2918
Len Browne9be7dd2015-05-26 12:19:37 -04002919 switch (msr & 0xF) {
Len Brown889facb2012-11-08 00:48:57 -05002920 case ENERGY_PERF_BIAS_PERFORMANCE:
2921 epb_string = "performance";
2922 break;
2923 case ENERGY_PERF_BIAS_NORMAL:
2924 epb_string = "balanced";
2925 break;
2926 case ENERGY_PERF_BIAS_POWERSAVE:
2927 epb_string = "powersave";
2928 break;
2929 default:
2930 epb_string = "custom";
2931 break;
2932 }
Len Brownb7d8c142016-02-13 23:36:17 -05002933 fprintf(outf, "cpu%d: MSR_IA32_ENERGY_PERF_BIAS: 0x%08llx (%s)\n", cpu, msr, epb_string);
Len Brown889facb2012-11-08 00:48:57 -05002934
2935 return 0;
2936}
Len Brown7f5c2582015-12-01 01:36:39 -05002937/*
2938 * print_hwp()
2939 * Decode the MSR_HWP_CAPABILITIES
2940 */
2941int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2942{
2943 unsigned long long msr;
2944 int cpu;
2945
2946 if (!has_hwp)
2947 return 0;
2948
2949 cpu = t->cpu_id;
2950
2951 /* MSR_HWP_CAPABILITIES is per-package */
2952 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
2953 return 0;
2954
2955 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05002956 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown7f5c2582015-12-01 01:36:39 -05002957 return -1;
2958 }
2959
2960 if (get_msr(cpu, MSR_PM_ENABLE, &msr))
2961 return 0;
2962
Len Brownb7d8c142016-02-13 23:36:17 -05002963 fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n",
Len Brown7f5c2582015-12-01 01:36:39 -05002964 cpu, msr, (msr & (1 << 0)) ? "" : "No-");
2965
2966 /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
2967 if ((msr & (1 << 0)) == 0)
2968 return 0;
2969
2970 if (get_msr(cpu, MSR_HWP_CAPABILITIES, &msr))
2971 return 0;
2972
Len Brownb7d8c142016-02-13 23:36:17 -05002973 fprintf(outf, "cpu%d: MSR_HWP_CAPABILITIES: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002974 "(high 0x%x guar 0x%x eff 0x%x low 0x%x)\n",
2975 cpu, msr,
2976 (unsigned int)HWP_HIGHEST_PERF(msr),
2977 (unsigned int)HWP_GUARANTEED_PERF(msr),
2978 (unsigned int)HWP_MOSTEFFICIENT_PERF(msr),
2979 (unsigned int)HWP_LOWEST_PERF(msr));
2980
2981 if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
2982 return 0;
2983
Len Brownb7d8c142016-02-13 23:36:17 -05002984 fprintf(outf, "cpu%d: MSR_HWP_REQUEST: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002985 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x pkg 0x%x)\n",
2986 cpu, msr,
2987 (unsigned int)(((msr) >> 0) & 0xff),
2988 (unsigned int)(((msr) >> 8) & 0xff),
2989 (unsigned int)(((msr) >> 16) & 0xff),
2990 (unsigned int)(((msr) >> 24) & 0xff),
2991 (unsigned int)(((msr) >> 32) & 0xff3),
2992 (unsigned int)(((msr) >> 42) & 0x1));
2993
2994 if (has_hwp_pkg) {
2995 if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
2996 return 0;
2997
Len Brownb7d8c142016-02-13 23:36:17 -05002998 fprintf(outf, "cpu%d: MSR_HWP_REQUEST_PKG: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05002999 "(min 0x%x max 0x%x des 0x%x epp 0x%x window 0x%x)\n",
3000 cpu, msr,
3001 (unsigned int)(((msr) >> 0) & 0xff),
3002 (unsigned int)(((msr) >> 8) & 0xff),
3003 (unsigned int)(((msr) >> 16) & 0xff),
3004 (unsigned int)(((msr) >> 24) & 0xff),
3005 (unsigned int)(((msr) >> 32) & 0xff3));
3006 }
3007 if (has_hwp_notify) {
3008 if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
3009 return 0;
3010
Len Brownb7d8c142016-02-13 23:36:17 -05003011 fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05003012 "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
3013 cpu, msr,
3014 ((msr) & 0x1) ? "EN" : "Dis",
3015 ((msr) & 0x2) ? "EN" : "Dis");
3016 }
3017 if (get_msr(cpu, MSR_HWP_STATUS, &msr))
3018 return 0;
3019
Len Brownb7d8c142016-02-13 23:36:17 -05003020 fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
Len Brown7f5c2582015-12-01 01:36:39 -05003021 "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
3022 cpu, msr,
3023 ((msr) & 0x1) ? "" : "No-",
3024 ((msr) & 0x2) ? "" : "No-");
Len Brown889facb2012-11-08 00:48:57 -05003025
3026 return 0;
3027}
3028
Len Brown3a9a9412014-08-15 02:39:52 -04003029/*
3030 * print_perf_limit()
3031 */
3032int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3033{
3034 unsigned long long msr;
3035 int cpu;
3036
3037 cpu = t->cpu_id;
3038
3039 /* per-package */
3040 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3041 return 0;
3042
3043 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003044 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown3a9a9412014-08-15 02:39:52 -04003045 return -1;
3046 }
3047
3048 if (do_core_perf_limit_reasons) {
3049 get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05003050 fprintf(outf, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3051 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
Len Browne33cbe82015-03-13 16:30:57 -04003052 (msr & 1 << 15) ? "bit15, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04003053 (msr & 1 << 14) ? "bit14, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04003054 (msr & 1 << 13) ? "Transitions, " : "",
3055 (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
3056 (msr & 1 << 11) ? "PkgPwrL2, " : "",
3057 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3058 (msr & 1 << 9) ? "CorePwr, " : "",
3059 (msr & 1 << 8) ? "Amps, " : "",
3060 (msr & 1 << 6) ? "VR-Therm, " : "",
3061 (msr & 1 << 5) ? "Auto-HWP, " : "",
3062 (msr & 1 << 4) ? "Graphics, " : "",
3063 (msr & 1 << 2) ? "bit2, " : "",
3064 (msr & 1 << 1) ? "ThermStatus, " : "",
3065 (msr & 1 << 0) ? "PROCHOT, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05003066 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
Len Browne33cbe82015-03-13 16:30:57 -04003067 (msr & 1 << 31) ? "bit31, " : "",
Len Brown3a9a9412014-08-15 02:39:52 -04003068 (msr & 1 << 30) ? "bit30, " : "",
Len Browne33cbe82015-03-13 16:30:57 -04003069 (msr & 1 << 29) ? "Transitions, " : "",
3070 (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
3071 (msr & 1 << 27) ? "PkgPwrL2, " : "",
3072 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3073 (msr & 1 << 25) ? "CorePwr, " : "",
3074 (msr & 1 << 24) ? "Amps, " : "",
3075 (msr & 1 << 22) ? "VR-Therm, " : "",
3076 (msr & 1 << 21) ? "Auto-HWP, " : "",
3077 (msr & 1 << 20) ? "Graphics, " : "",
3078 (msr & 1 << 18) ? "bit18, " : "",
3079 (msr & 1 << 17) ? "ThermStatus, " : "",
3080 (msr & 1 << 16) ? "PROCHOT, " : "");
Len Brown3a9a9412014-08-15 02:39:52 -04003081
3082 }
3083 if (do_gfx_perf_limit_reasons) {
3084 get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05003085 fprintf(outf, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3086 fprintf(outf, " (Active: %s%s%s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04003087 (msr & 1 << 0) ? "PROCHOT, " : "",
3088 (msr & 1 << 1) ? "ThermStatus, " : "",
3089 (msr & 1 << 4) ? "Graphics, " : "",
3090 (msr & 1 << 6) ? "VR-Therm, " : "",
3091 (msr & 1 << 8) ? "Amps, " : "",
3092 (msr & 1 << 9) ? "GFXPwr, " : "",
3093 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3094 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05003095 fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04003096 (msr & 1 << 16) ? "PROCHOT, " : "",
3097 (msr & 1 << 17) ? "ThermStatus, " : "",
3098 (msr & 1 << 20) ? "Graphics, " : "",
3099 (msr & 1 << 22) ? "VR-Therm, " : "",
3100 (msr & 1 << 24) ? "Amps, " : "",
3101 (msr & 1 << 25) ? "GFXPwr, " : "",
3102 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3103 (msr & 1 << 27) ? "PkgPwrL2, " : "");
3104 }
3105 if (do_ring_perf_limit_reasons) {
3106 get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
Len Brownb7d8c142016-02-13 23:36:17 -05003107 fprintf(outf, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
3108 fprintf(outf, " (Active: %s%s%s%s%s%s)",
Len Brown3a9a9412014-08-15 02:39:52 -04003109 (msr & 1 << 0) ? "PROCHOT, " : "",
3110 (msr & 1 << 1) ? "ThermStatus, " : "",
3111 (msr & 1 << 6) ? "VR-Therm, " : "",
3112 (msr & 1 << 8) ? "Amps, " : "",
3113 (msr & 1 << 10) ? "PkgPwrL1, " : "",
3114 (msr & 1 << 11) ? "PkgPwrL2, " : "");
Len Brownb7d8c142016-02-13 23:36:17 -05003115 fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
Len Brown3a9a9412014-08-15 02:39:52 -04003116 (msr & 1 << 16) ? "PROCHOT, " : "",
3117 (msr & 1 << 17) ? "ThermStatus, " : "",
3118 (msr & 1 << 22) ? "VR-Therm, " : "",
3119 (msr & 1 << 24) ? "Amps, " : "",
3120 (msr & 1 << 26) ? "PkgPwrL1, " : "",
3121 (msr & 1 << 27) ? "PkgPwrL2, " : "");
3122 }
3123 return 0;
3124}
3125
Len Brown889facb2012-11-08 00:48:57 -05003126#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
3127#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
3128
Colin Ian King1b693172016-03-02 13:50:25 +00003129double get_tdp(unsigned int model)
Len Brown144b44b2013-11-09 00:30:16 -05003130{
3131 unsigned long long msr;
3132
3133 if (do_rapl & RAPL_PKG_POWER_INFO)
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003134 if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr))
Len Brown144b44b2013-11-09 00:30:16 -05003135 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
3136
3137 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003138 case INTEL_FAM6_ATOM_SILVERMONT1:
3139 case INTEL_FAM6_ATOM_SILVERMONT2:
Len Brown144b44b2013-11-09 00:30:16 -05003140 return 30.0;
3141 default:
3142 return 135.0;
3143 }
3144}
3145
Andrey Semin40ee8e32014-12-05 00:07:00 -05003146/*
3147 * rapl_dram_energy_units_probe()
3148 * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
3149 */
3150static double
3151rapl_dram_energy_units_probe(int model, double rapl_energy_units)
3152{
3153 /* only called for genuine_intel, family 6 */
3154
3155 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003156 case INTEL_FAM6_HASWELL_X: /* HSX */
3157 case INTEL_FAM6_BROADWELL_X: /* BDX */
3158 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3159 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003160 case INTEL_FAM6_XEON_PHI_KNM:
Andrey Semin40ee8e32014-12-05 00:07:00 -05003161 return (rapl_dram_energy_units = 15.3 / 1000000);
3162 default:
3163 return (rapl_energy_units);
3164 }
3165}
3166
Len Brown144b44b2013-11-09 00:30:16 -05003167
Len Brown889facb2012-11-08 00:48:57 -05003168/*
3169 * rapl_probe()
3170 *
Len Brown144b44b2013-11-09 00:30:16 -05003171 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
Len Brown889facb2012-11-08 00:48:57 -05003172 */
3173void rapl_probe(unsigned int family, unsigned int model)
3174{
3175 unsigned long long msr;
Len Brown144b44b2013-11-09 00:30:16 -05003176 unsigned int time_unit;
Len Brown889facb2012-11-08 00:48:57 -05003177 double tdp;
3178
3179 if (!genuine_intel)
3180 return;
3181
3182 if (family != 6)
3183 return;
3184
3185 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003186 case INTEL_FAM6_SANDYBRIDGE:
3187 case INTEL_FAM6_IVYBRIDGE:
3188 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3189 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3190 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3191 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3192 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
Len Brown144b44b2013-11-09 00:30:16 -05003193 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003194 if (rapl_joules) {
3195 BIC_PRESENT(BIC_Pkg_J);
3196 BIC_PRESENT(BIC_Cor_J);
3197 BIC_PRESENT(BIC_GFX_J);
3198 } else {
3199 BIC_PRESENT(BIC_PkgWatt);
3200 BIC_PRESENT(BIC_CorWatt);
3201 BIC_PRESENT(BIC_GFXWatt);
3202 }
Len Brown889facb2012-11-08 00:48:57 -05003203 break;
Len Brown869ce692016-06-16 23:22:37 -04003204 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003205 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Len Browne4085d52016-04-06 17:15:56 -04003206 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003207 if (rapl_joules)
3208 BIC_PRESENT(BIC_Pkg_J);
3209 else
3210 BIC_PRESENT(BIC_PkgWatt);
Len Browne4085d52016-04-06 17:15:56 -04003211 break;
Len Brown869ce692016-06-16 23:22:37 -04003212 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3213 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3214 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3215 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04003216 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003217 BIC_PRESENT(BIC_PKG__);
3218 BIC_PRESENT(BIC_RAM__);
3219 if (rapl_joules) {
3220 BIC_PRESENT(BIC_Pkg_J);
3221 BIC_PRESENT(BIC_Cor_J);
3222 BIC_PRESENT(BIC_RAM_J);
3223 } else {
3224 BIC_PRESENT(BIC_PkgWatt);
3225 BIC_PRESENT(BIC_CorWatt);
3226 BIC_PRESENT(BIC_RAMWatt);
3227 }
Len Brown0b2bb692015-03-26 00:50:30 -04003228 break;
Len Brown869ce692016-06-16 23:22:37 -04003229 case INTEL_FAM6_HASWELL_X: /* HSX */
3230 case INTEL_FAM6_BROADWELL_X: /* BDX */
3231 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3232 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3233 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003234 case INTEL_FAM6_XEON_PHI_KNM:
Len Brown0b2bb692015-03-26 00:50:30 -04003235 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
Len Brown812db3f2017-02-10 00:25:41 -05003236 BIC_PRESENT(BIC_PKG__);
3237 BIC_PRESENT(BIC_RAM__);
3238 if (rapl_joules) {
3239 BIC_PRESENT(BIC_Pkg_J);
3240 BIC_PRESENT(BIC_RAM_J);
3241 } else {
3242 BIC_PRESENT(BIC_PkgWatt);
3243 BIC_PRESENT(BIC_RAMWatt);
3244 }
Len Browne6f9bb32013-12-03 02:19:19 -05003245 break;
Len Brown869ce692016-06-16 23:22:37 -04003246 case INTEL_FAM6_SANDYBRIDGE_X:
3247 case INTEL_FAM6_IVYBRIDGE_X:
Len Brown0b2bb692015-03-26 00:50:30 -04003248 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;
Len Brown812db3f2017-02-10 00:25:41 -05003249 BIC_PRESENT(BIC_PKG__);
3250 BIC_PRESENT(BIC_RAM__);
3251 if (rapl_joules) {
3252 BIC_PRESENT(BIC_Pkg_J);
3253 BIC_PRESENT(BIC_Cor_J);
3254 BIC_PRESENT(BIC_RAM_J);
3255 } else {
3256 BIC_PRESENT(BIC_PkgWatt);
3257 BIC_PRESENT(BIC_CorWatt);
3258 BIC_PRESENT(BIC_RAMWatt);
3259 }
Len Brown144b44b2013-11-09 00:30:16 -05003260 break;
Len Brown869ce692016-06-16 23:22:37 -04003261 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3262 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Jacob Pan91484942016-06-16 09:48:20 -07003263 do_rapl = RAPL_PKG | RAPL_CORES;
Len Brown812db3f2017-02-10 00:25:41 -05003264 if (rapl_joules) {
3265 BIC_PRESENT(BIC_Pkg_J);
3266 BIC_PRESENT(BIC_Cor_J);
3267 } else {
3268 BIC_PRESENT(BIC_PkgWatt);
3269 BIC_PRESENT(BIC_CorWatt);
3270 }
Len Brown889facb2012-11-08 00:48:57 -05003271 break;
Len Brown869ce692016-06-16 23:22:37 -04003272 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Jacob Pan0f644902016-06-16 09:48:22 -07003273 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;
Len Brown812db3f2017-02-10 00:25:41 -05003274 BIC_PRESENT(BIC_PKG__);
3275 BIC_PRESENT(BIC_RAM__);
3276 if (rapl_joules) {
3277 BIC_PRESENT(BIC_Pkg_J);
3278 BIC_PRESENT(BIC_Cor_J);
3279 BIC_PRESENT(BIC_RAM_J);
3280 } else {
3281 BIC_PRESENT(BIC_PkgWatt);
3282 BIC_PRESENT(BIC_CorWatt);
3283 BIC_PRESENT(BIC_RAMWatt);
3284 }
Jacob Pan0f644902016-06-16 09:48:22 -07003285 break;
Len Brown889facb2012-11-08 00:48:57 -05003286 default:
3287 return;
3288 }
3289
3290 /* units on package 0, verify later other packages match */
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003291 if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr))
Len Brown889facb2012-11-08 00:48:57 -05003292 return;
3293
3294 rapl_power_units = 1.0 / (1 << (msr & 0xF));
Len Brown869ce692016-06-16 23:22:37 -04003295 if (model == INTEL_FAM6_ATOM_SILVERMONT1)
Len Brown144b44b2013-11-09 00:30:16 -05003296 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
3297 else
3298 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
Len Brown889facb2012-11-08 00:48:57 -05003299
Andrey Semin40ee8e32014-12-05 00:07:00 -05003300 rapl_dram_energy_units = rapl_dram_energy_units_probe(model, rapl_energy_units);
3301
Len Brown144b44b2013-11-09 00:30:16 -05003302 time_unit = msr >> 16 & 0xF;
3303 if (time_unit == 0)
3304 time_unit = 0xA;
Len Brown889facb2012-11-08 00:48:57 -05003305
Len Brown144b44b2013-11-09 00:30:16 -05003306 rapl_time_units = 1.0 / (1 << (time_unit));
3307
3308 tdp = get_tdp(model);
Len Brown889facb2012-11-08 00:48:57 -05003309
3310 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
Len Brown96e47152017-01-21 02:26:00 -05003311 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003312 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
Len Brown889facb2012-11-08 00:48:57 -05003313
3314 return;
3315}
3316
Colin Ian King1b693172016-03-02 13:50:25 +00003317void perf_limit_reasons_probe(unsigned int family, unsigned int model)
Len Brown3a9a9412014-08-15 02:39:52 -04003318{
3319 if (!genuine_intel)
3320 return;
3321
3322 if (family != 6)
3323 return;
3324
3325 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003326 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3327 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3328 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
Len Brown3a9a9412014-08-15 02:39:52 -04003329 do_gfx_perf_limit_reasons = 1;
Len Brown869ce692016-06-16 23:22:37 -04003330 case INTEL_FAM6_HASWELL_X: /* HSX */
Len Brown3a9a9412014-08-15 02:39:52 -04003331 do_core_perf_limit_reasons = 1;
3332 do_ring_perf_limit_reasons = 1;
3333 default:
3334 return;
3335 }
3336}
3337
Len Brown889facb2012-11-08 00:48:57 -05003338int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3339{
3340 unsigned long long msr;
3341 unsigned int dts;
3342 int cpu;
3343
3344 if (!(do_dts || do_ptm))
3345 return 0;
3346
3347 cpu = t->cpu_id;
3348
3349 /* DTS is per-core, no need to print for each thread */
Len Brown388e9c82016-12-22 23:57:55 -05003350 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
Len Brown889facb2012-11-08 00:48:57 -05003351 return 0;
3352
3353 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003354 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003355 return -1;
3356 }
3357
3358 if (do_ptm && (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) {
3359 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
3360 return 0;
3361
3362 dts = (msr >> 16) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05003363 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003364 cpu, msr, tcc_activation_temp - dts);
3365
3366#ifdef THERM_DEBUG
3367 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
3368 return 0;
3369
3370 dts = (msr >> 16) & 0x7F;
3371 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05003372 fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003373 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
3374#endif
3375 }
3376
3377
3378 if (do_dts) {
3379 unsigned int resolution;
3380
3381 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
3382 return 0;
3383
3384 dts = (msr >> 16) & 0x7F;
3385 resolution = (msr >> 27) & 0xF;
Len Brownb7d8c142016-02-13 23:36:17 -05003386 fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
Len Brown889facb2012-11-08 00:48:57 -05003387 cpu, msr, tcc_activation_temp - dts, resolution);
3388
3389#ifdef THERM_DEBUG
3390 if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
3391 return 0;
3392
3393 dts = (msr >> 16) & 0x7F;
3394 dts2 = (msr >> 8) & 0x7F;
Len Brownb7d8c142016-02-13 23:36:17 -05003395 fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003396 cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2);
3397#endif
3398 }
3399
3400 return 0;
3401}
Len Brown36229892016-02-26 20:51:02 -05003402
Len Brown889facb2012-11-08 00:48:57 -05003403void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
3404{
Len Brownb7d8c142016-02-13 23:36:17 -05003405 fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05003406 cpu, label,
3407 ((msr >> 15) & 1) ? "EN" : "DIS",
3408 ((msr >> 0) & 0x7FFF) * rapl_power_units,
3409 (1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
3410 (((msr >> 16) & 1) ? "EN" : "DIS"));
3411
3412 return;
3413}
3414
3415int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3416{
3417 unsigned long long msr;
3418 int cpu;
Len Brown889facb2012-11-08 00:48:57 -05003419
3420 if (!do_rapl)
3421 return 0;
3422
3423 /* RAPL counters are per package, so print only for 1st thread/package */
3424 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3425 return 0;
3426
3427 cpu = t->cpu_id;
3428 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003429 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003430 return -1;
3431 }
3432
3433 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
3434 return -1;
3435
Len Brown96e47152017-01-21 02:26:00 -05003436 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr,
3437 rapl_power_units, rapl_energy_units, rapl_time_units);
3438
Len Brown144b44b2013-11-09 00:30:16 -05003439 if (do_rapl & RAPL_PKG_POWER_INFO) {
3440
Len Brown889facb2012-11-08 00:48:57 -05003441 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
3442 return -5;
3443
3444
Len Brownb7d8c142016-02-13 23:36:17 -05003445 fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
Len Brown889facb2012-11-08 00:48:57 -05003446 cpu, msr,
3447 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3448 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3449 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3450 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
3451
Len Brown144b44b2013-11-09 00:30:16 -05003452 }
3453 if (do_rapl & RAPL_PKG) {
3454
Len Brown889facb2012-11-08 00:48:57 -05003455 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
3456 return -9;
3457
Len Brownb7d8c142016-02-13 23:36:17 -05003458 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown96e47152017-01-21 02:26:00 -05003459 cpu, msr, (msr >> 63) & 1 ? "" : "UN");
Len Brown889facb2012-11-08 00:48:57 -05003460
3461 print_power_limit_msr(cpu, msr, "PKG Limit #1");
Len Brownb7d8c142016-02-13 23:36:17 -05003462 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
Len Brown889facb2012-11-08 00:48:57 -05003463 cpu,
3464 ((msr >> 47) & 1) ? "EN" : "DIS",
3465 ((msr >> 32) & 0x7FFF) * rapl_power_units,
3466 (1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
3467 ((msr >> 48) & 1) ? "EN" : "DIS");
3468 }
3469
Len Brown0b2bb692015-03-26 00:50:30 -04003470 if (do_rapl & RAPL_DRAM_POWER_INFO) {
Len Brown889facb2012-11-08 00:48:57 -05003471 if (get_msr(cpu, MSR_DRAM_POWER_INFO, &msr))
3472 return -6;
3473
Len Brownb7d8c142016-02-13 23:36:17 -05003474 fprintf(outf, "cpu%d: MSR_DRAM_POWER_INFO,: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
Len Brown889facb2012-11-08 00:48:57 -05003475 cpu, msr,
3476 ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3477 ((msr >> 16) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3478 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
3479 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
Len Brown0b2bb692015-03-26 00:50:30 -04003480 }
3481 if (do_rapl & RAPL_DRAM) {
Len Brown889facb2012-11-08 00:48:57 -05003482 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
3483 return -9;
Len Brownb7d8c142016-02-13 23:36:17 -05003484 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
Len Brown96e47152017-01-21 02:26:00 -05003485 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
Len Brown889facb2012-11-08 00:48:57 -05003486
3487 print_power_limit_msr(cpu, msr, "DRAM Limit");
3488 }
Len Brown144b44b2013-11-09 00:30:16 -05003489 if (do_rapl & RAPL_CORE_POLICY) {
Len Brown96e47152017-01-21 02:26:00 -05003490 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
3491 return -7;
Len Brown889facb2012-11-08 00:48:57 -05003492
Len Brown96e47152017-01-21 02:26:00 -05003493 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown144b44b2013-11-09 00:30:16 -05003494 }
Jacob Pan91484942016-06-16 09:48:20 -07003495 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
Len Brown96e47152017-01-21 02:26:00 -05003496 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
3497 return -9;
3498 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
3499 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3500 print_power_limit_msr(cpu, msr, "Cores Limit");
Len Brown889facb2012-11-08 00:48:57 -05003501 }
3502 if (do_rapl & RAPL_GFX) {
Len Brown96e47152017-01-21 02:26:00 -05003503 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
3504 return -8;
Len Brown889facb2012-11-08 00:48:57 -05003505
Len Brown96e47152017-01-21 02:26:00 -05003506 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
Len Brown889facb2012-11-08 00:48:57 -05003507
Len Brown96e47152017-01-21 02:26:00 -05003508 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
3509 return -9;
3510 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
3511 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3512 print_power_limit_msr(cpu, msr, "GFX Limit");
Len Brown889facb2012-11-08 00:48:57 -05003513 }
3514 return 0;
3515}
3516
Len Brownd7899442015-01-23 00:12:33 -05003517/*
3518 * SNB adds support for additional MSRs:
3519 *
3520 * MSR_PKG_C7_RESIDENCY 0x000003fa
3521 * MSR_CORE_C7_RESIDENCY 0x000003fe
3522 * MSR_PKG_C2_RESIDENCY 0x0000060d
3523 */
Len Brown103a8fe2010-10-22 23:53:03 -04003524
Len Brownd7899442015-01-23 00:12:33 -05003525int has_snb_msrs(unsigned int family, unsigned int model)
Len Brown103a8fe2010-10-22 23:53:03 -04003526{
3527 if (!genuine_intel)
3528 return 0;
3529
3530 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003531 case INTEL_FAM6_SANDYBRIDGE:
3532 case INTEL_FAM6_SANDYBRIDGE_X:
3533 case INTEL_FAM6_IVYBRIDGE: /* IVB */
3534 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
3535 case INTEL_FAM6_HASWELL_CORE: /* HSW */
3536 case INTEL_FAM6_HASWELL_X: /* HSW */
3537 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3538 case INTEL_FAM6_HASWELL_GT3E: /* HSW */
3539 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3540 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
3541 case INTEL_FAM6_BROADWELL_X: /* BDX */
3542 case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */
3543 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3544 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3545 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3546 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
3547 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3548 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003549 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Xiaolong Wang5bbac262016-09-30 17:53:40 +08003550 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Brown103a8fe2010-10-22 23:53:03 -04003551 return 1;
3552 }
3553 return 0;
3554}
3555
Len Brownd7899442015-01-23 00:12:33 -05003556/*
3557 * HSW adds support for additional MSRs:
3558 *
Len Brown5a634262016-04-06 17:15:55 -04003559 * MSR_PKG_C8_RESIDENCY 0x00000630
3560 * MSR_PKG_C9_RESIDENCY 0x00000631
3561 * MSR_PKG_C10_RESIDENCY 0x00000632
3562 *
3563 * MSR_PKGC8_IRTL 0x00000633
3564 * MSR_PKGC9_IRTL 0x00000634
3565 * MSR_PKGC10_IRTL 0x00000635
3566 *
Len Brownd7899442015-01-23 00:12:33 -05003567 */
3568int has_hsw_msrs(unsigned int family, unsigned int model)
Kristen Carlson Accardica587102012-11-21 05:22:43 -08003569{
3570 if (!genuine_intel)
3571 return 0;
3572
3573 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003574 case INTEL_FAM6_HASWELL_ULT: /* HSW */
3575 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
3576 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3577 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3578 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3579 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
3580 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003581 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Kristen Carlson Accardica587102012-11-21 05:22:43 -08003582 return 1;
3583 }
3584 return 0;
3585}
3586
Len Brown0b2bb692015-03-26 00:50:30 -04003587/*
3588 * SKL adds support for additional MSRS:
3589 *
3590 * MSR_PKG_WEIGHTED_CORE_C0_RES 0x00000658
3591 * MSR_PKG_ANY_CORE_C0_RES 0x00000659
3592 * MSR_PKG_ANY_GFXE_C0_RES 0x0000065A
3593 * MSR_PKG_BOTH_CORE_GFXE_C0_RES 0x0000065B
3594 */
3595int has_skl_msrs(unsigned int family, unsigned int model)
3596{
3597 if (!genuine_intel)
3598 return 0;
3599
3600 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003601 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3602 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3603 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3604 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Brown0b2bb692015-03-26 00:50:30 -04003605 return 1;
3606 }
3607 return 0;
3608}
3609
Len Brown144b44b2013-11-09 00:30:16 -05003610int is_slm(unsigned int family, unsigned int model)
3611{
3612 if (!genuine_intel)
3613 return 0;
3614 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003615 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
3616 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
Len Brown144b44b2013-11-09 00:30:16 -05003617 return 1;
3618 }
3619 return 0;
3620}
3621
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003622int is_knl(unsigned int family, unsigned int model)
3623{
3624 if (!genuine_intel)
3625 return 0;
3626 switch (model) {
Len Brown869ce692016-06-16 23:22:37 -04003627 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
Len Brown005c82d2016-12-01 01:35:38 -05003628 case INTEL_FAM6_XEON_PHI_KNM:
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07003629 return 1;
3630 }
3631 return 0;
3632}
3633
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02003634unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
3635{
3636 if (is_knl(family, model))
3637 return 1024;
3638 return 1;
3639}
3640
Len Brown144b44b2013-11-09 00:30:16 -05003641#define SLM_BCLK_FREQS 5
3642double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
3643
3644double slm_bclk(void)
3645{
3646 unsigned long long msr = 3;
3647 unsigned int i;
3648 double freq;
3649
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003650 if (get_msr(base_cpu, MSR_FSB_FREQ, &msr))
Len Brownb7d8c142016-02-13 23:36:17 -05003651 fprintf(outf, "SLM BCLK: unknown\n");
Len Brown144b44b2013-11-09 00:30:16 -05003652
3653 i = msr & 0xf;
3654 if (i >= SLM_BCLK_FREQS) {
Len Brownb7d8c142016-02-13 23:36:17 -05003655 fprintf(outf, "SLM BCLK[%d] invalid\n", i);
Colin Ian King0a91e552016-04-25 13:03:15 +01003656 i = 3;
Len Brown144b44b2013-11-09 00:30:16 -05003657 }
3658 freq = slm_freq_table[i];
3659
Len Brown96e47152017-01-21 02:26:00 -05003660 if (!quiet)
Len Brown8f6196c2017-01-07 22:40:23 -05003661 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
Len Brown144b44b2013-11-09 00:30:16 -05003662
3663 return freq;
3664}
3665
Len Brown103a8fe2010-10-22 23:53:03 -04003666double discover_bclk(unsigned int family, unsigned int model)
3667{
Chrzaniuk, Hubert121b48b2016-02-10 16:35:17 +01003668 if (has_snb_msrs(family, model) || is_knl(family, model))
Len Brown103a8fe2010-10-22 23:53:03 -04003669 return 100.00;
Len Brown144b44b2013-11-09 00:30:16 -05003670 else if (is_slm(family, model))
3671 return slm_bclk();
Len Brown103a8fe2010-10-22 23:53:03 -04003672 else
3673 return 133.33;
3674}
3675
Len Brown889facb2012-11-08 00:48:57 -05003676/*
3677 * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
3678 * the Thermal Control Circuit (TCC) activates.
3679 * This is usually equal to tjMax.
3680 *
3681 * Older processors do not have this MSR, so there we guess,
3682 * but also allow cmdline over-ride with -T.
3683 *
3684 * Several MSR temperature values are in units of degrees-C
3685 * below this value, including the Digital Thermal Sensor (DTS),
3686 * Package Thermal Management Sensor (PTM), and thermal event thresholds.
3687 */
3688int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3689{
3690 unsigned long long msr;
3691 unsigned int target_c_local;
3692 int cpu;
3693
3694 /* tcc_activation_temp is used only for dts or ptm */
3695 if (!(do_dts || do_ptm))
3696 return 0;
3697
3698 /* this is a per-package concept */
3699 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
3700 return 0;
3701
3702 cpu = t->cpu_id;
3703 if (cpu_migrate(cpu)) {
Len Brownb7d8c142016-02-13 23:36:17 -05003704 fprintf(outf, "Could not migrate to CPU %d\n", cpu);
Len Brown889facb2012-11-08 00:48:57 -05003705 return -1;
3706 }
3707
3708 if (tcc_activation_temp_override != 0) {
3709 tcc_activation_temp = tcc_activation_temp_override;
Len Brownb7d8c142016-02-13 23:36:17 -05003710 fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003711 cpu, tcc_activation_temp);
3712 return 0;
3713 }
3714
3715 /* Temperature Target MSR is Nehalem and newer only */
Len Brownd7899442015-01-23 00:12:33 -05003716 if (!do_nhm_platform_info)
Len Brown889facb2012-11-08 00:48:57 -05003717 goto guess;
3718
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04003719 if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
Len Brown889facb2012-11-08 00:48:57 -05003720 goto guess;
3721
Jean Delvare34821242014-05-01 11:40:19 +02003722 target_c_local = (msr >> 16) & 0xFF;
Len Brown889facb2012-11-08 00:48:57 -05003723
Len Brown96e47152017-01-21 02:26:00 -05003724 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003725 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
Len Brown889facb2012-11-08 00:48:57 -05003726 cpu, msr, target_c_local);
3727
Jean Delvare34821242014-05-01 11:40:19 +02003728 if (!target_c_local)
Len Brown889facb2012-11-08 00:48:57 -05003729 goto guess;
3730
3731 tcc_activation_temp = target_c_local;
3732
3733 return 0;
3734
3735guess:
3736 tcc_activation_temp = TJMAX_DEFAULT;
Len Brownb7d8c142016-02-13 23:36:17 -05003737 fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n",
Len Brown889facb2012-11-08 00:48:57 -05003738 cpu, tcc_activation_temp);
3739
3740 return 0;
3741}
Len Brown69807a62015-11-21 12:22:47 -05003742
Len Brownaa8d8cc2016-03-11 13:26:03 -05003743void decode_feature_control_msr(void)
3744{
3745 unsigned long long msr;
3746
3747 if (!get_msr(base_cpu, MSR_IA32_FEATURE_CONTROL, &msr))
3748 fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
3749 base_cpu, msr,
3750 msr & FEATURE_CONTROL_LOCKED ? "" : "UN-",
3751 msr & (1 << 18) ? "SGX" : "");
3752}
3753
Len Brown69807a62015-11-21 12:22:47 -05003754void decode_misc_enable_msr(void)
3755{
3756 unsigned long long msr;
3757
3758 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
Len Browne6512622017-01-11 23:17:24 -05003759 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
Len Brown69807a62015-11-21 12:22:47 -05003760 base_cpu, msr,
Len Browne6512622017-01-11 23:17:24 -05003761 msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
3762 msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
3763 msr & MSR_IA32_MISC_ENABLE_MWAIT ? "No-" : "",
3764 msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "",
3765 msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
Len Brown69807a62015-11-21 12:22:47 -05003766}
3767
Len Brown33148d62017-01-21 01:26:16 -05003768void decode_misc_feature_control(void)
3769{
3770 unsigned long long msr;
3771
3772 if (!has_misc_feature_control)
3773 return;
3774
3775 if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
3776 fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
3777 base_cpu, msr,
3778 msr & (0 << 0) ? "No-" : "",
3779 msr & (1 << 0) ? "No-" : "",
3780 msr & (2 << 0) ? "No-" : "",
3781 msr & (3 << 0) ? "No-" : "");
3782}
Len Brownf0057312015-12-03 01:35:36 -05003783/*
3784 * Decode MSR_MISC_PWR_MGMT
3785 *
3786 * Decode the bits according to the Nehalem documentation
3787 * bit[0] seems to continue to have same meaning going forward
3788 * bit[1] less so...
3789 */
3790void decode_misc_pwr_mgmt_msr(void)
3791{
3792 unsigned long long msr;
3793
3794 if (!do_nhm_platform_info)
3795 return;
3796
Len Browncf4cbe52017-01-01 13:08:33 -05003797 if (no_MSR_MISC_PWR_MGMT)
3798 return;
3799
Len Brownf0057312015-12-03 01:35:36 -05003800 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
Srinivas Pandruvadaddadb8a2016-11-11 14:29:48 -08003801 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
Len Brownf0057312015-12-03 01:35:36 -05003802 base_cpu, msr,
3803 msr & (1 << 0) ? "DIS" : "EN",
Srinivas Pandruvadaddadb8a2016-11-11 14:29:48 -08003804 msr & (1 << 1) ? "EN" : "DIS",
3805 msr & (1 << 8) ? "EN" : "DIS");
Len Brownf0057312015-12-03 01:35:36 -05003806}
Len Brown71616c82017-01-07 22:37:48 -05003807/*
3808 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
3809 *
3810 * This MSRs are present on Silvermont processors,
3811 * Intel Atom processor E3000 series (Baytrail), and friends.
3812 */
3813void decode_c6_demotion_policy_msr(void)
3814{
3815 unsigned long long msr;
3816
3817 if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
3818 fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
3819 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
3820
3821 if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
3822 fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
3823 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
3824}
Len Brown7f5c2582015-12-01 01:36:39 -05003825
Len Brownfcd17212015-03-23 20:29:09 -04003826void process_cpuid()
Len Brown103a8fe2010-10-22 23:53:03 -04003827{
Len Brown61a87ba2015-11-23 02:30:51 -05003828 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
Len Brown103a8fe2010-10-22 23:53:03 -04003829 unsigned int fms, family, model, stepping;
Len Brownb3a34e92017-01-21 00:50:08 -05003830 unsigned int has_turbo;
Len Brown103a8fe2010-10-22 23:53:03 -04003831
3832 eax = ebx = ecx = edx = 0;
3833
Len Brown5aea2f72016-03-13 03:14:35 -04003834 __cpuid(0, max_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003835
3836 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
3837 genuine_intel = 1;
3838
Len Brown96e47152017-01-21 02:26:00 -05003839 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003840 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
Len Brown103a8fe2010-10-22 23:53:03 -04003841 (char *)&ebx, (char *)&edx, (char *)&ecx);
3842
Len Brown5aea2f72016-03-13 03:14:35 -04003843 __cpuid(1, fms, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003844 family = (fms >> 8) & 0xf;
3845 model = (fms >> 4) & 0xf;
3846 stepping = fms & 0xf;
3847 if (family == 6 || family == 0xf)
3848 model += ((fms >> 16) & 0xf) << 4;
3849
Len Brown96e47152017-01-21 02:26:00 -05003850 if (!quiet) {
Len Brownb7d8c142016-02-13 23:36:17 -05003851 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
Len Brown103a8fe2010-10-22 23:53:03 -04003852 max_level, family, model, stepping, family, model, stepping);
Len Brownaa8d8cc2016-03-11 13:26:03 -05003853 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
Len Brown69807a62015-11-21 12:22:47 -05003854 ecx & (1 << 0) ? "SSE3" : "-",
3855 ecx & (1 << 3) ? "MONITOR" : "-",
Len Brownaa8d8cc2016-03-11 13:26:03 -05003856 ecx & (1 << 6) ? "SMX" : "-",
Len Brown69807a62015-11-21 12:22:47 -05003857 ecx & (1 << 7) ? "EIST" : "-",
3858 ecx & (1 << 8) ? "TM2" : "-",
3859 edx & (1 << 4) ? "TSC" : "-",
3860 edx & (1 << 5) ? "MSR" : "-",
3861 edx & (1 << 22) ? "ACPI-TM" : "-",
3862 edx & (1 << 29) ? "TM" : "-");
3863 }
Len Brown103a8fe2010-10-22 23:53:03 -04003864
Josh Triplettb2c95d92013-08-20 17:20:18 -07003865 if (!(edx & (1 << 5)))
3866 errx(1, "CPUID: no MSR");
Len Brown103a8fe2010-10-22 23:53:03 -04003867
3868 /*
3869 * check max extended function levels of CPUID.
3870 * This is needed to check for invariant TSC.
3871 * This check is valid for both Intel and AMD.
3872 */
3873 ebx = ecx = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003874 __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
Len Brown103a8fe2010-10-22 23:53:03 -04003875
Len Brown61a87ba2015-11-23 02:30:51 -05003876 if (max_extended_level >= 0x80000007) {
Len Brown103a8fe2010-10-22 23:53:03 -04003877
Len Brownd7899442015-01-23 00:12:33 -05003878 /*
3879 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
3880 * this check is valid for both Intel and AMD
3881 */
Len Brown5aea2f72016-03-13 03:14:35 -04003882 __cpuid(0x80000007, eax, ebx, ecx, edx);
Len Brownd7899442015-01-23 00:12:33 -05003883 has_invariant_tsc = edx & (1 << 8);
3884 }
Len Brown103a8fe2010-10-22 23:53:03 -04003885
3886 /*
3887 * APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
3888 * this check is valid for both Intel and AMD
3889 */
3890
Len Brown5aea2f72016-03-13 03:14:35 -04003891 __cpuid(0x6, eax, ebx, ecx, edx);
Thomas Renninger8209e052011-01-21 15:11:19 +01003892 has_aperf = ecx & (1 << 0);
Len Brown812db3f2017-02-10 00:25:41 -05003893 if (has_aperf) {
3894 BIC_PRESENT(BIC_Avg_MHz);
3895 BIC_PRESENT(BIC_Busy);
3896 BIC_PRESENT(BIC_Bzy_MHz);
3897 }
Len Brown889facb2012-11-08 00:48:57 -05003898 do_dts = eax & (1 << 0);
Len Brown812db3f2017-02-10 00:25:41 -05003899 if (do_dts)
3900 BIC_PRESENT(BIC_CoreTmp);
Len Brownb3a34e92017-01-21 00:50:08 -05003901 has_turbo = eax & (1 << 1);
Len Brown889facb2012-11-08 00:48:57 -05003902 do_ptm = eax & (1 << 6);
Len Brown812db3f2017-02-10 00:25:41 -05003903 if (do_ptm)
3904 BIC_PRESENT(BIC_PkgTmp);
Len Brown7f5c2582015-12-01 01:36:39 -05003905 has_hwp = eax & (1 << 7);
3906 has_hwp_notify = eax & (1 << 8);
3907 has_hwp_activity_window = eax & (1 << 9);
3908 has_hwp_epp = eax & (1 << 10);
3909 has_hwp_pkg = eax & (1 << 11);
Len Brown889facb2012-11-08 00:48:57 -05003910 has_epb = ecx & (1 << 3);
3911
Len Brown96e47152017-01-21 02:26:00 -05003912 if (!quiet)
Len Brownb3a34e92017-01-21 00:50:08 -05003913 fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
Len Brown7f5c2582015-12-01 01:36:39 -05003914 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
3915 has_aperf ? "" : "No-",
Len Brownb3a34e92017-01-21 00:50:08 -05003916 has_turbo ? "" : "No-",
Len Brown7f5c2582015-12-01 01:36:39 -05003917 do_dts ? "" : "No-",
3918 do_ptm ? "" : "No-",
3919 has_hwp ? "" : "No-",
3920 has_hwp_notify ? "" : "No-",
3921 has_hwp_activity_window ? "" : "No-",
3922 has_hwp_epp ? "" : "No-",
3923 has_hwp_pkg ? "" : "No-",
3924 has_epb ? "" : "No-");
Len Brown103a8fe2010-10-22 23:53:03 -04003925
Len Brown96e47152017-01-21 02:26:00 -05003926 if (!quiet)
Len Brown69807a62015-11-21 12:22:47 -05003927 decode_misc_enable_msr();
3928
Len Brown33148d62017-01-21 01:26:16 -05003929
Len Brown96e47152017-01-21 02:26:00 -05003930 if (max_level >= 0x7 && !quiet) {
Len Brownaa8d8cc2016-03-11 13:26:03 -05003931 int has_sgx;
3932
3933 ecx = 0;
3934
3935 __cpuid_count(0x7, 0, eax, ebx, ecx, edx);
3936
3937 has_sgx = ebx & (1 << 2);
3938 fprintf(outf, "CPUID(7): %sSGX\n", has_sgx ? "" : "No-");
3939
3940 if (has_sgx)
3941 decode_feature_control_msr();
3942 }
3943
Len Brown61a87ba2015-11-23 02:30:51 -05003944 if (max_level >= 0x15) {
Len Brown8a5bdf42015-04-01 21:02:57 -04003945 unsigned int eax_crystal;
3946 unsigned int ebx_tsc;
3947
3948 /*
3949 * CPUID 15H TSC/Crystal ratio, possibly Crystal Hz
3950 */
3951 eax_crystal = ebx_tsc = crystal_hz = edx = 0;
Len Brown5aea2f72016-03-13 03:14:35 -04003952 __cpuid(0x15, eax_crystal, ebx_tsc, crystal_hz, edx);
Len Brown8a5bdf42015-04-01 21:02:57 -04003953
3954 if (ebx_tsc != 0) {
3955
Len Brown96e47152017-01-21 02:26:00 -05003956 if (!quiet && (ebx != 0))
Len Brownb7d8c142016-02-13 23:36:17 -05003957 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003958 eax_crystal, ebx_tsc, crystal_hz);
3959
3960 if (crystal_hz == 0)
3961 switch(model) {
Len Brown869ce692016-06-16 23:22:37 -04003962 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
3963 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
3964 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3965 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
Len Browne8efbc82016-04-06 17:15:57 -04003966 crystal_hz = 24000000; /* 24.0 MHz */
3967 break;
Len Brown869ce692016-06-16 23:22:37 -04003968 case INTEL_FAM6_SKYLAKE_X: /* SKX */
Len Brown7268d402016-12-01 23:10:39 -05003969 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
Len Brownec53e592016-04-06 17:15:58 -04003970 crystal_hz = 25000000; /* 25.0 MHz */
3971 break;
Len Brown869ce692016-06-16 23:22:37 -04003972 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
Len Brownac01ac12017-01-27 01:45:35 -05003973 case INTEL_FAM6_ATOM_GEMINI_LAKE:
Len Browne8efbc82016-04-06 17:15:57 -04003974 crystal_hz = 19200000; /* 19.2 MHz */
Len Brown8a5bdf42015-04-01 21:02:57 -04003975 break;
3976 default:
3977 crystal_hz = 0;
3978 }
3979
3980 if (crystal_hz) {
3981 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
Len Brown96e47152017-01-21 02:26:00 -05003982 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003983 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
Len Brown8a5bdf42015-04-01 21:02:57 -04003984 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
3985 }
3986 }
3987 }
Len Brown61a87ba2015-11-23 02:30:51 -05003988 if (max_level >= 0x16) {
3989 unsigned int base_mhz, max_mhz, bus_mhz, edx;
3990
3991 /*
3992 * CPUID 16H Base MHz, Max MHz, Bus MHz
3993 */
3994 base_mhz = max_mhz = bus_mhz = edx = 0;
3995
Len Brown5aea2f72016-03-13 03:14:35 -04003996 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
Len Brown96e47152017-01-21 02:26:00 -05003997 if (!quiet)
Len Brownb7d8c142016-02-13 23:36:17 -05003998 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
Len Brown61a87ba2015-11-23 02:30:51 -05003999 base_mhz, max_mhz, bus_mhz);
4000 }
Len Brown8a5bdf42015-04-01 21:02:57 -04004001
Hubert Chrzaniukb2b34df2015-09-14 13:31:00 +02004002 if (has_aperf)
4003 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
4004
Len Brown812db3f2017-02-10 00:25:41 -05004005 BIC_PRESENT(BIC_IRQ);
4006 BIC_PRESENT(BIC_TSC_MHz);
4007
4008 if (probe_nhm_msrs(family, model)) {
4009 do_nhm_platform_info = 1;
4010 BIC_PRESENT(BIC_CPU_c1);
4011 BIC_PRESENT(BIC_CPU_c3);
4012 BIC_PRESENT(BIC_CPU_c6);
4013 BIC_PRESENT(BIC_SMI);
4014 }
Len Brownd7899442015-01-23 00:12:33 -05004015 do_snb_cstates = has_snb_msrs(family, model);
Len Brown812db3f2017-02-10 00:25:41 -05004016
4017 if (do_snb_cstates)
4018 BIC_PRESENT(BIC_CPU_c7);
4019
Len Brown5a634262016-04-06 17:15:55 -04004020 do_irtl_snb = has_snb_msrs(family, model);
Len Brown0f47c082017-01-27 00:50:45 -05004021 if (do_snb_cstates && (pkg_cstate_limit >= PCL__2))
4022 BIC_PRESENT(BIC_Pkgpc2);
4023 if (pkg_cstate_limit >= PCL__3)
4024 BIC_PRESENT(BIC_Pkgpc3);
4025 if (pkg_cstate_limit >= PCL__6)
4026 BIC_PRESENT(BIC_Pkgpc6);
4027 if (do_snb_cstates && (pkg_cstate_limit >= PCL__7))
4028 BIC_PRESENT(BIC_Pkgpc7);
Len Brown0539ba12017-02-10 00:27:20 -05004029 if (has_slv_msrs(family, model)) {
Len Brown0f47c082017-01-27 00:50:45 -05004030 BIC_NOT_PRESENT(BIC_Pkgpc2);
4031 BIC_NOT_PRESENT(BIC_Pkgpc3);
4032 BIC_PRESENT(BIC_Pkgpc6);
4033 BIC_NOT_PRESENT(BIC_Pkgpc7);
Len Brown0539ba12017-02-10 00:27:20 -05004034 BIC_PRESENT(BIC_Mod_c6);
4035 use_c1_residency_msr = 1;
4036 }
Len Brown7170a372017-01-27 02:13:27 -05004037 if (is_dnv(family, model)) {
4038 BIC_PRESENT(BIC_CPU_c1);
4039 BIC_NOT_PRESENT(BIC_CPU_c3);
4040 BIC_NOT_PRESENT(BIC_Pkgpc3);
4041 BIC_NOT_PRESENT(BIC_CPU_c7);
4042 BIC_NOT_PRESENT(BIC_Pkgpc7);
4043 use_c1_residency_msr = 1;
4044 }
Len Brown34c761972017-01-27 02:36:41 -05004045 if (is_skx(family, model)) {
4046 BIC_NOT_PRESENT(BIC_CPU_c3);
4047 BIC_NOT_PRESENT(BIC_Pkgpc3);
4048 BIC_NOT_PRESENT(BIC_CPU_c7);
4049 BIC_NOT_PRESENT(BIC_Pkgpc7);
4050 }
Len Brownade0eba2017-02-10 01:56:47 -05004051 if (is_bdx(family, model)) {
4052 BIC_NOT_PRESENT(BIC_CPU_c7);
4053 BIC_NOT_PRESENT(BIC_Pkgpc7);
4054 }
Len Brown0f47c082017-01-27 00:50:45 -05004055 if (has_hsw_msrs(family, model)) {
4056 BIC_PRESENT(BIC_Pkgpc8);
4057 BIC_PRESENT(BIC_Pkgpc9);
4058 BIC_PRESENT(BIC_Pkgpc10);
4059 }
Len Brown5a634262016-04-06 17:15:55 -04004060 do_irtl_hsw = has_hsw_msrs(family, model);
Len Brown0b2bb692015-03-26 00:50:30 -04004061 do_skl_residency = has_skl_msrs(family, model);
Len Brown144b44b2013-11-09 00:30:16 -05004062 do_slm_cstates = is_slm(family, model);
Dasaratharaman Chandramoulifb5d4322015-05-20 09:49:34 -07004063 do_knl_cstates = is_knl(family, model);
Len Brown103a8fe2010-10-22 23:53:03 -04004064
Len Brown96e47152017-01-21 02:26:00 -05004065 if (!quiet)
Len Brownf0057312015-12-03 01:35:36 -05004066 decode_misc_pwr_mgmt_msr();
4067
Len Brown96e47152017-01-21 02:26:00 -05004068 if (!quiet && has_slv_msrs(family, model))
Len Brown71616c82017-01-07 22:37:48 -05004069 decode_c6_demotion_policy_msr();
4070
Len Brown889facb2012-11-08 00:48:57 -05004071 rapl_probe(family, model);
Len Brown3a9a9412014-08-15 02:39:52 -04004072 perf_limit_reasons_probe(family, model);
Len Brown889facb2012-11-08 00:48:57 -05004073
Len Brown96e47152017-01-21 02:26:00 -05004074 if (!quiet)
Colin Ian King1b693172016-03-02 13:50:25 +00004075 dump_cstate_pstate_config_info(family, model);
Len Brownfcd17212015-03-23 20:29:09 -04004076
Len Brown41618e62017-02-09 18:25:22 -05004077 if (!quiet)
4078 dump_sysfs_cstate_config();
4079
Len Browna2b7b742015-09-26 00:12:38 -04004080 if (has_skl_msrs(family, model))
4081 calculate_tsc_tweak();
4082
Len Brown812db3f2017-02-10 00:25:41 -05004083 if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
4084 BIC_PRESENT(BIC_GFX_rc6);
Len Brownfdf676e2016-02-27 01:28:12 -05004085
Len Brown812db3f2017-02-10 00:25:41 -05004086 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
4087 BIC_PRESENT(BIC_GFXMHz);
Len Brown27d47352016-02-27 00:37:54 -05004088
Len Brown96e47152017-01-21 02:26:00 -05004089 if (!quiet)
Len Brown33148d62017-01-21 01:26:16 -05004090 decode_misc_feature_control();
4091
Len Brown889facb2012-11-08 00:48:57 -05004092 return;
Len Brown103a8fe2010-10-22 23:53:03 -04004093}
4094
Len Brownd8af6f52015-02-10 01:56:38 -05004095void help()
Len Brown103a8fe2010-10-22 23:53:03 -04004096{
Len Brownb7d8c142016-02-13 23:36:17 -05004097 fprintf(outf,
Len Brownd8af6f52015-02-10 01:56:38 -05004098 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
4099 "\n"
4100 "Turbostat forks the specified COMMAND and prints statistics\n"
4101 "when COMMAND completes.\n"
4102 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
4103 "to print statistics, until interrupted.\n"
Len Brown388e9c82016-12-22 23:57:55 -05004104 "--add add a counter\n"
4105 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
Len Brown1ef7d212017-02-10 23:54:15 -05004106 "--cpu cpu-set limit output to summary plus cpu-set cpu-set\n"
Len Brown96e47152017-01-21 02:26:00 -05004107 "--quiet skip decoding system configuration header\n"
Len Brownd8af6f52015-02-10 01:56:38 -05004108 "--interval sec Override default 5-second measurement interval\n"
4109 "--help print this help message\n"
Len Brownb7d8c142016-02-13 23:36:17 -05004110 "--out file create or truncate \"file\" for all output\n"
Len Brownd8af6f52015-02-10 01:56:38 -05004111 "--version print version information\n"
4112 "\n"
4113 "For more help, run \"man turbostat\"\n");
Len Brown103a8fe2010-10-22 23:53:03 -04004114}
4115
4116
4117/*
4118 * in /dev/cpu/ return success for names that are numbers
4119 * ie. filter out ".", "..", "microcode".
4120 */
4121int dir_filter(const struct dirent *dirp)
4122{
4123 if (isdigit(dirp->d_name[0]))
4124 return 1;
4125 else
4126 return 0;
4127}
4128
4129int open_dev_cpu_msr(int dummy1)
4130{
4131 return 0;
4132}
4133
Len Brownc98d5d92012-06-04 00:56:40 -04004134void topology_probe()
4135{
4136 int i;
4137 int max_core_id = 0;
4138 int max_package_id = 0;
4139 int max_siblings = 0;
4140 struct cpu_topology {
4141 int core_id;
4142 int physical_package_id;
4143 } *cpus;
4144
4145 /* Initialize num_cpus, max_cpu_num */
4146 topo.num_cpus = 0;
4147 topo.max_cpu_num = 0;
4148 for_all_proc_cpus(count_cpus);
4149 if (!summary_only && topo.num_cpus > 1)
Len Brown812db3f2017-02-10 00:25:41 -05004150 BIC_PRESENT(BIC_CPU);
Len Brownc98d5d92012-06-04 00:56:40 -04004151
Len Brownd8af6f52015-02-10 01:56:38 -05004152 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004153 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
Len Brownc98d5d92012-06-04 00:56:40 -04004154
4155 cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
Josh Triplettb2c95d92013-08-20 17:20:18 -07004156 if (cpus == NULL)
4157 err(1, "calloc cpus");
Len Brownc98d5d92012-06-04 00:56:40 -04004158
4159 /*
4160 * Allocate and initialize cpu_present_set
4161 */
4162 cpu_present_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07004163 if (cpu_present_set == NULL)
4164 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04004165 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
4166 CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
4167 for_all_proc_cpus(mark_cpu_present);
4168
4169 /*
Len Brown1ef7d212017-02-10 23:54:15 -05004170 * Validate that all cpus in cpu_subset are also in cpu_present_set
4171 */
4172 for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
4173 if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
4174 if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
4175 err(1, "cpu%d not present", i);
4176 }
4177
4178 /*
Len Brownc98d5d92012-06-04 00:56:40 -04004179 * Allocate and initialize cpu_affinity_set
4180 */
4181 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
Josh Triplettb2c95d92013-08-20 17:20:18 -07004182 if (cpu_affinity_set == NULL)
4183 err(3, "CPU_ALLOC");
Len Brownc98d5d92012-06-04 00:56:40 -04004184 cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
4185 CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set);
4186
4187
4188 /*
4189 * For online cpus
4190 * find max_core_id, max_package_id
4191 */
4192 for (i = 0; i <= topo.max_cpu_num; ++i) {
4193 int siblings;
4194
4195 if (cpu_is_not_present(i)) {
Len Brownd8af6f52015-02-10 01:56:38 -05004196 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004197 fprintf(outf, "cpu%d NOT PRESENT\n", i);
Len Brownc98d5d92012-06-04 00:56:40 -04004198 continue;
4199 }
4200 cpus[i].core_id = get_core_id(i);
4201 if (cpus[i].core_id > max_core_id)
4202 max_core_id = cpus[i].core_id;
4203
4204 cpus[i].physical_package_id = get_physical_package_id(i);
4205 if (cpus[i].physical_package_id > max_package_id)
4206 max_package_id = cpus[i].physical_package_id;
4207
4208 siblings = get_num_ht_siblings(i);
4209 if (siblings > max_siblings)
4210 max_siblings = siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05004211 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004212 fprintf(outf, "cpu %d pkg %d core %d\n",
Len Brownc98d5d92012-06-04 00:56:40 -04004213 i, cpus[i].physical_package_id, cpus[i].core_id);
4214 }
4215 topo.num_cores_per_pkg = max_core_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05004216 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004217 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
Len Brownc98d5d92012-06-04 00:56:40 -04004218 max_core_id, topo.num_cores_per_pkg);
Len Brown0f47c082017-01-27 00:50:45 -05004219 if (!summary_only && topo.num_cores_per_pkg > 1)
Len Brown812db3f2017-02-10 00:25:41 -05004220 BIC_PRESENT(BIC_Core);
Len Brownc98d5d92012-06-04 00:56:40 -04004221
4222 topo.num_packages = max_package_id + 1;
Len Brownd8af6f52015-02-10 01:56:38 -05004223 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004224 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
Len Brownc98d5d92012-06-04 00:56:40 -04004225 max_package_id, topo.num_packages);
Len Brown1cc21f72015-02-23 00:34:57 -05004226 if (debug && !summary_only && topo.num_packages > 1)
Len Brown812db3f2017-02-10 00:25:41 -05004227 BIC_PRESENT(BIC_Package);
Len Brownc98d5d92012-06-04 00:56:40 -04004228
4229 topo.num_threads_per_core = max_siblings;
Len Brownd8af6f52015-02-10 01:56:38 -05004230 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004231 fprintf(outf, "max_siblings %d\n", max_siblings);
Len Brownc98d5d92012-06-04 00:56:40 -04004232
4233 free(cpus);
4234}
4235
4236void
4237allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
4238{
4239 int i;
4240
4241 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
Len Brown678a3bd2017-02-09 22:22:13 -05004242 topo.num_packages, sizeof(struct thread_data));
Len Brownc98d5d92012-06-04 00:56:40 -04004243 if (*t == NULL)
4244 goto error;
4245
4246 for (i = 0; i < topo.num_threads_per_core *
4247 topo.num_cores_per_pkg * topo.num_packages; i++)
4248 (*t)[i].cpu_id = -1;
4249
4250 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
Len Brown678a3bd2017-02-09 22:22:13 -05004251 sizeof(struct core_data));
Len Brownc98d5d92012-06-04 00:56:40 -04004252 if (*c == NULL)
4253 goto error;
4254
4255 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
4256 (*c)[i].core_id = -1;
4257
Len Brown678a3bd2017-02-09 22:22:13 -05004258 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
Len Brownc98d5d92012-06-04 00:56:40 -04004259 if (*p == NULL)
4260 goto error;
4261
4262 for (i = 0; i < topo.num_packages; i++)
4263 (*p)[i].package_id = i;
4264
4265 return;
4266error:
Josh Triplettb2c95d92013-08-20 17:20:18 -07004267 err(1, "calloc counters");
Len Brownc98d5d92012-06-04 00:56:40 -04004268}
4269/*
4270 * init_counter()
4271 *
4272 * set cpu_id, core_num, pkg_num
4273 * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
4274 *
4275 * increment topo.num_cores when 1st core in pkg seen
4276 */
4277void init_counter(struct thread_data *thread_base, struct core_data *core_base,
4278 struct pkg_data *pkg_base, int thread_num, int core_num,
4279 int pkg_num, int cpu_id)
4280{
4281 struct thread_data *t;
4282 struct core_data *c;
4283 struct pkg_data *p;
4284
4285 t = GET_THREAD(thread_base, thread_num, core_num, pkg_num);
4286 c = GET_CORE(core_base, core_num, pkg_num);
4287 p = GET_PKG(pkg_base, pkg_num);
4288
4289 t->cpu_id = cpu_id;
4290 if (thread_num == 0) {
4291 t->flags |= CPU_IS_FIRST_THREAD_IN_CORE;
4292 if (cpu_is_first_core_in_package(cpu_id))
4293 t->flags |= CPU_IS_FIRST_CORE_IN_PACKAGE;
4294 }
4295
4296 c->core_id = core_num;
4297 p->package_id = pkg_num;
4298}
4299
4300
4301int initialize_counters(int cpu_id)
4302{
4303 int my_thread_id, my_core_id, my_package_id;
4304
4305 my_package_id = get_physical_package_id(cpu_id);
4306 my_core_id = get_core_id(cpu_id);
Dasaratharaman Chandramoulie275b382015-04-15 10:09:50 -07004307 my_thread_id = get_cpu_position_in_core(cpu_id);
4308 if (!my_thread_id)
Len Brownc98d5d92012-06-04 00:56:40 -04004309 topo.num_cores++;
Len Brownc98d5d92012-06-04 00:56:40 -04004310
4311 init_counter(EVEN_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
4312 init_counter(ODD_COUNTERS, my_thread_id, my_core_id, my_package_id, cpu_id);
4313 return 0;
4314}
4315
4316void allocate_output_buffer()
4317{
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004318 output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
Len Brownc98d5d92012-06-04 00:56:40 -04004319 outp = output_buffer;
Josh Triplettb2c95d92013-08-20 17:20:18 -07004320 if (outp == NULL)
4321 err(-1, "calloc output buffer");
Len Brownc98d5d92012-06-04 00:56:40 -04004322}
Len Brown36229892016-02-26 20:51:02 -05004323void allocate_fd_percpu(void)
4324{
Mika Westerberg01a67ad2016-04-22 11:13:23 +03004325 fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown36229892016-02-26 20:51:02 -05004326 if (fd_percpu == NULL)
4327 err(-1, "calloc fd_percpu");
4328}
Len Brown562a2d32016-02-26 23:48:05 -05004329void allocate_irq_buffers(void)
4330{
4331 irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
4332 if (irq_column_2_cpu == NULL)
4333 err(-1, "calloc %d", topo.num_cpus);
Len Brownc98d5d92012-06-04 00:56:40 -04004334
Mika Westerberg01a67ad2016-04-22 11:13:23 +03004335 irqs_per_cpu = calloc(topo.max_cpu_num + 1, sizeof(int));
Len Brown562a2d32016-02-26 23:48:05 -05004336 if (irqs_per_cpu == NULL)
Mika Westerberg01a67ad2016-04-22 11:13:23 +03004337 err(-1, "calloc %d", topo.max_cpu_num + 1);
Len Brown562a2d32016-02-26 23:48:05 -05004338}
Len Brownc98d5d92012-06-04 00:56:40 -04004339void setup_all_buffers(void)
4340{
4341 topology_probe();
Len Brown562a2d32016-02-26 23:48:05 -05004342 allocate_irq_buffers();
Len Brown36229892016-02-26 20:51:02 -05004343 allocate_fd_percpu();
Len Brownc98d5d92012-06-04 00:56:40 -04004344 allocate_counters(&thread_even, &core_even, &package_even);
4345 allocate_counters(&thread_odd, &core_odd, &package_odd);
4346 allocate_output_buffer();
4347 for_all_proc_cpus(initialize_counters);
4348}
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004349
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04004350void set_base_cpu(void)
4351{
4352 base_cpu = sched_getcpu();
4353 if (base_cpu < 0)
4354 err(-ENODEV, "No valid cpus found");
4355
4356 if (debug > 1)
Len Brownb7d8c142016-02-13 23:36:17 -05004357 fprintf(outf, "base_cpu = %d\n", base_cpu);
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04004358}
4359
Len Brown103a8fe2010-10-22 23:53:03 -04004360void turbostat_init()
4361{
Prarit Bhargava7ce7d5d2015-05-25 08:34:28 -04004362 setup_all_buffers();
4363 set_base_cpu();
Len Brown103a8fe2010-10-22 23:53:03 -04004364 check_dev_msr();
Len Brown98481e72014-08-15 00:36:50 -04004365 check_permissions();
Len Brownfcd17212015-03-23 20:29:09 -04004366 process_cpuid();
Len Brown103a8fe2010-10-22 23:53:03 -04004367
Len Brown103a8fe2010-10-22 23:53:03 -04004368
Len Brown96e47152017-01-21 02:26:00 -05004369 if (!quiet)
Len Brown7f5c2582015-12-01 01:36:39 -05004370 for_all_cpus(print_hwp, ODD_COUNTERS);
4371
Len Brown96e47152017-01-21 02:26:00 -05004372 if (!quiet)
Len Brown889facb2012-11-08 00:48:57 -05004373 for_all_cpus(print_epb, ODD_COUNTERS);
4374
Len Brown96e47152017-01-21 02:26:00 -05004375 if (!quiet)
Len Brown3a9a9412014-08-15 02:39:52 -04004376 for_all_cpus(print_perf_limit, ODD_COUNTERS);
4377
Len Brown96e47152017-01-21 02:26:00 -05004378 if (!quiet)
Len Brown889facb2012-11-08 00:48:57 -05004379 for_all_cpus(print_rapl, ODD_COUNTERS);
4380
4381 for_all_cpus(set_temperature_target, ODD_COUNTERS);
4382
Len Brown96e47152017-01-21 02:26:00 -05004383 if (!quiet)
Len Brown889facb2012-11-08 00:48:57 -05004384 for_all_cpus(print_thermal, ODD_COUNTERS);
Len Brown5a634262016-04-06 17:15:55 -04004385
Len Brown96e47152017-01-21 02:26:00 -05004386 if (!quiet && do_irtl_snb)
Len Brown5a634262016-04-06 17:15:55 -04004387 print_irtl();
Len Brown103a8fe2010-10-22 23:53:03 -04004388}
4389
4390int fork_it(char **argv)
4391{
Len Brown103a8fe2010-10-22 23:53:03 -04004392 pid_t child_pid;
Len Brownd91bb172012-11-01 00:08:19 -04004393 int status;
Len Brownd15cf7c2012-06-03 23:24:00 -04004394
Len Brown218f0e82017-02-14 22:07:52 -05004395 snapshot_proc_sysfs_files();
Len Brownd91bb172012-11-01 00:08:19 -04004396 status = for_all_cpus(get_counters, EVEN_COUNTERS);
4397 if (status)
4398 exit(status);
Len Brownc98d5d92012-06-04 00:56:40 -04004399 /* clear affinity side-effect of get_counters() */
4400 sched_setaffinity(0, cpu_present_setsize, cpu_present_set);
Len Brown103a8fe2010-10-22 23:53:03 -04004401 gettimeofday(&tv_even, (struct timezone *)NULL);
4402
4403 child_pid = fork();
4404 if (!child_pid) {
4405 /* child */
4406 execvp(argv[0], argv);
4407 } else {
Len Brown103a8fe2010-10-22 23:53:03 -04004408
4409 /* parent */
Josh Triplettb2c95d92013-08-20 17:20:18 -07004410 if (child_pid == -1)
4411 err(1, "fork");
Len Brown103a8fe2010-10-22 23:53:03 -04004412
4413 signal(SIGINT, SIG_IGN);
4414 signal(SIGQUIT, SIG_IGN);
Josh Triplettb2c95d92013-08-20 17:20:18 -07004415 if (waitpid(child_pid, &status, 0) == -1)
4416 err(status, "waitpid");
Len Brown103a8fe2010-10-22 23:53:03 -04004417 }
Len Brownc98d5d92012-06-04 00:56:40 -04004418 /*
4419 * n.b. fork_it() does not check for errors from for_all_cpus()
4420 * because re-starting is problematic when forking
4421 */
Len Brown218f0e82017-02-14 22:07:52 -05004422 snapshot_proc_sysfs_files();
Len Brownc98d5d92012-06-04 00:56:40 -04004423 for_all_cpus(get_counters, ODD_COUNTERS);
Len Brown103a8fe2010-10-22 23:53:03 -04004424 gettimeofday(&tv_odd, (struct timezone *)NULL);
Len Brown103a8fe2010-10-22 23:53:03 -04004425 timersub(&tv_odd, &tv_even, &tv_delta);
Len Brownba3dec92016-04-22 20:31:46 -04004426 if (for_all_cpus_2(delta_cpu, ODD_COUNTERS, EVEN_COUNTERS))
4427 fprintf(outf, "%s: Counter reset detected\n", progname);
4428 else {
4429 compute_average(EVEN_COUNTERS);
4430 format_all_counters(EVEN_COUNTERS);
4431 }
Len Brown103a8fe2010-10-22 23:53:03 -04004432
Len Brownb7d8c142016-02-13 23:36:17 -05004433 fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);
4434
4435 flush_output_stderr();
Len Brown103a8fe2010-10-22 23:53:03 -04004436
Len Brownd91bb172012-11-01 00:08:19 -04004437 return status;
Len Brown103a8fe2010-10-22 23:53:03 -04004438}
4439
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004440int get_and_dump_counters(void)
4441{
4442 int status;
4443
Len Brown218f0e82017-02-14 22:07:52 -05004444 snapshot_proc_sysfs_files();
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004445 status = for_all_cpus(get_counters, ODD_COUNTERS);
4446 if (status)
4447 return status;
4448
4449 status = for_all_cpus(dump_counters, ODD_COUNTERS);
4450 if (status)
4451 return status;
4452
Len Brownb7d8c142016-02-13 23:36:17 -05004453 flush_output_stdout();
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004454
4455 return status;
4456}
4457
Len Brownd8af6f52015-02-10 01:56:38 -05004458void print_version() {
Len Brown0539ba12017-02-10 00:27:20 -05004459 fprintf(outf, "turbostat version 4.17 10 Jan 2017"
Len Brownd8af6f52015-02-10 01:56:38 -05004460 " - Len Brown <lenb@kernel.org>\n");
4461}
4462
Len Brown495c76542017-02-08 02:41:51 -05004463int add_counter(unsigned int msr_num, char *path, char *name,
4464 unsigned int width, enum counter_scope scope,
Len Brown41618e62017-02-09 18:25:22 -05004465 enum counter_type type, enum counter_format format, int flags)
Len Brown388e9c82016-12-22 23:57:55 -05004466{
4467 struct msr_counter *msrp;
4468
4469 msrp = calloc(1, sizeof(struct msr_counter));
4470 if (msrp == NULL) {
4471 perror("calloc");
4472 exit(1);
4473 }
4474
4475 msrp->msr_num = msr_num;
4476 strncpy(msrp->name, name, NAME_BYTES);
Len Brown495c76542017-02-08 02:41:51 -05004477 if (path)
4478 strncpy(msrp->path, path, PATH_BYTES);
Len Brown388e9c82016-12-22 23:57:55 -05004479 msrp->width = width;
4480 msrp->type = type;
4481 msrp->format = format;
Len Brown41618e62017-02-09 18:25:22 -05004482 msrp->flags = flags;
Len Brown388e9c82016-12-22 23:57:55 -05004483
4484 switch (scope) {
4485
4486 case SCOPE_CPU:
Len Brown388e9c82016-12-22 23:57:55 -05004487 msrp->next = sys.tp;
4488 sys.tp = msrp;
Len Brown678a3bd2017-02-09 22:22:13 -05004489 sys.added_thread_counters++;
4490 if (sys.added_thread_counters > MAX_ADDED_COUNTERS) {
4491 fprintf(stderr, "exceeded max %d added thread counters\n",
4492 MAX_ADDED_COUNTERS);
4493 exit(-1);
4494 }
Len Brown388e9c82016-12-22 23:57:55 -05004495 break;
4496
4497 case SCOPE_CORE:
Len Brown388e9c82016-12-22 23:57:55 -05004498 msrp->next = sys.cp;
4499 sys.cp = msrp;
Len Brown678a3bd2017-02-09 22:22:13 -05004500 sys.added_core_counters++;
4501 if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
4502 fprintf(stderr, "exceeded max %d added core counters\n",
4503 MAX_ADDED_COUNTERS);
4504 exit(-1);
4505 }
Len Brown388e9c82016-12-22 23:57:55 -05004506 break;
4507
4508 case SCOPE_PACKAGE:
Len Brown388e9c82016-12-22 23:57:55 -05004509 msrp->next = sys.pp;
4510 sys.pp = msrp;
Len Brown678a3bd2017-02-09 22:22:13 -05004511 sys.added_package_counters++;
4512 if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
4513 fprintf(stderr, "exceeded max %d added package counters\n",
4514 MAX_ADDED_COUNTERS);
4515 exit(-1);
4516 }
Len Brown388e9c82016-12-22 23:57:55 -05004517 break;
4518 }
4519
4520 return 0;
4521}
4522
4523void parse_add_command(char *add_command)
4524{
4525 int msr_num = 0;
Len Brown495c76542017-02-08 02:41:51 -05004526 char *path = NULL;
Len Brown0f47c082017-01-27 00:50:45 -05004527 char name_buffer[NAME_BYTES] = "";
Len Brown388e9c82016-12-22 23:57:55 -05004528 int width = 64;
4529 int fail = 0;
4530 enum counter_scope scope = SCOPE_CPU;
4531 enum counter_type type = COUNTER_CYCLES;
4532 enum counter_format format = FORMAT_DELTA;
4533
4534 while (add_command) {
4535
4536 if (sscanf(add_command, "msr0x%x", &msr_num) == 1)
4537 goto next;
4538
4539 if (sscanf(add_command, "msr%d", &msr_num) == 1)
4540 goto next;
4541
Len Brown495c76542017-02-08 02:41:51 -05004542 if (*add_command == '/') {
4543 path = add_command;
4544 goto next;
4545 }
4546
Len Brown388e9c82016-12-22 23:57:55 -05004547 if (sscanf(add_command, "u%d", &width) == 1) {
4548 if ((width == 32) || (width == 64))
4549 goto next;
4550 width = 64;
4551 }
4552 if (!strncmp(add_command, "cpu", strlen("cpu"))) {
4553 scope = SCOPE_CPU;
4554 goto next;
4555 }
4556 if (!strncmp(add_command, "core", strlen("core"))) {
4557 scope = SCOPE_CORE;
4558 goto next;
4559 }
4560 if (!strncmp(add_command, "package", strlen("package"))) {
4561 scope = SCOPE_PACKAGE;
4562 goto next;
4563 }
4564 if (!strncmp(add_command, "cycles", strlen("cycles"))) {
4565 type = COUNTER_CYCLES;
4566 goto next;
4567 }
4568 if (!strncmp(add_command, "seconds", strlen("seconds"))) {
4569 type = COUNTER_SECONDS;
4570 goto next;
4571 }
Len Brown41618e62017-02-09 18:25:22 -05004572 if (!strncmp(add_command, "usec", strlen("usec"))) {
4573 type = COUNTER_USEC;
4574 goto next;
4575 }
Len Brown388e9c82016-12-22 23:57:55 -05004576 if (!strncmp(add_command, "raw", strlen("raw"))) {
4577 format = FORMAT_RAW;
4578 goto next;
4579 }
4580 if (!strncmp(add_command, "delta", strlen("delta"))) {
4581 format = FORMAT_DELTA;
4582 goto next;
4583 }
4584 if (!strncmp(add_command, "percent", strlen("percent"))) {
4585 format = FORMAT_PERCENT;
4586 goto next;
4587 }
4588
4589 if (sscanf(add_command, "%18s,%*s", name_buffer) == 1) { /* 18 < NAME_BYTES */
4590 char *eos;
4591
4592 eos = strchr(name_buffer, ',');
4593 if (eos)
4594 *eos = '\0';
4595 goto next;
4596 }
4597
4598next:
4599 add_command = strchr(add_command, ',');
Len Brown495c76542017-02-08 02:41:51 -05004600 if (add_command) {
4601 *add_command = '\0';
Len Brown388e9c82016-12-22 23:57:55 -05004602 add_command++;
Len Brown495c76542017-02-08 02:41:51 -05004603 }
Len Brown388e9c82016-12-22 23:57:55 -05004604
4605 }
Len Brown495c76542017-02-08 02:41:51 -05004606 if ((msr_num == 0) && (path == NULL)) {
4607 fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
Len Brown388e9c82016-12-22 23:57:55 -05004608 fail++;
4609 }
4610
4611 /* generate default column header */
4612 if (*name_buffer == '\0') {
4613 if (format == FORMAT_RAW) {
4614 if (width == 32)
4615 sprintf(name_buffer, "msr%d", msr_num);
4616 else
4617 sprintf(name_buffer, "MSR%d", msr_num);
4618 } else if (format == FORMAT_DELTA) {
4619 if (width == 32)
4620 sprintf(name_buffer, "cnt%d", msr_num);
4621 else
4622 sprintf(name_buffer, "CNT%d", msr_num);
4623 } else if (format == FORMAT_PERCENT) {
4624 if (width == 32)
4625 sprintf(name_buffer, "msr%d%%", msr_num);
4626 else
4627 sprintf(name_buffer, "MSR%d%%", msr_num);
4628 }
4629 }
4630
Len Brown41618e62017-02-09 18:25:22 -05004631 if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0))
Len Brown388e9c82016-12-22 23:57:55 -05004632 fail++;
4633
4634 if (fail) {
4635 help();
4636 exit(1);
4637 }
4638}
Len Brown41618e62017-02-09 18:25:22 -05004639
4640void probe_sysfs(void)
4641{
4642 char path[64];
4643 char name_buf[16];
4644 FILE *input;
4645 int state;
4646 char *sp;
4647
4648 if (!DO_BIC(BIC_sysfs))
4649 return;
4650
4651 for (state = 10; state > 0; --state) {
4652
4653 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
4654 base_cpu, state);
4655 input = fopen(path, "r");
4656 if (input == NULL)
4657 continue;
4658 fgets(name_buf, sizeof(name_buf), input);
4659
4660 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
4661 sp = strchr(name_buf, '-');
4662 if (!sp)
4663 sp = strchrnul(name_buf, '\n');
4664 *sp = '%';
4665 *(sp + 1) = '\0';
4666
4667 fclose(input);
4668
4669 sprintf(path, "cpuidle/state%d/time", state);
4670
4671 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC,
4672 FORMAT_PERCENT, SYSFS_PERCPU);
4673 }
4674
4675 for (state = 10; state > 0; --state) {
4676
4677 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
4678 base_cpu, state);
4679 input = fopen(path, "r");
4680 if (input == NULL)
4681 continue;
4682 fgets(name_buf, sizeof(name_buf), input);
4683 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
4684 sp = strchr(name_buf, '-');
4685 if (!sp)
4686 sp = strchrnul(name_buf, '\n');
4687 *sp = '\0';
4688 fclose(input);
4689
4690 sprintf(path, "cpuidle/state%d/usage", state);
4691
4692 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS,
4693 FORMAT_DELTA, SYSFS_PERCPU);
4694 }
4695
4696}
4697
Len Brown1ef7d212017-02-10 23:54:15 -05004698
4699/*
4700 * parse cpuset with following syntax
4701 * 1,2,4..6,8-10 and set bits in cpu_subset
4702 */
4703void parse_cpu_command(char *optarg)
4704{
4705 unsigned int start, end;
4706 char *next;
4707
4708 cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
4709 if (cpu_subset == NULL)
4710 err(3, "CPU_ALLOC");
4711 cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
4712
4713 CPU_ZERO_S(cpu_subset_size, cpu_subset);
4714
4715 next = optarg;
4716
4717 while (next && *next) {
4718
4719 if (*next == '-') /* no negative cpu numbers */
4720 goto error;
4721
4722 start = strtoul(next, &next, 10);
4723
4724 if (start >= CPU_SUBSET_MAXCPUS)
4725 goto error;
4726 CPU_SET_S(start, cpu_subset_size, cpu_subset);
4727
4728 if (*next == '\0')
4729 break;
4730
4731 if (*next == ',') {
4732 next += 1;
4733 continue;
4734 }
4735
4736 if (*next == '-') {
4737 next += 1; /* start range */
4738 } else if (*next == '.') {
4739 next += 1;
4740 if (*next == '.')
4741 next += 1; /* start range */
4742 else
4743 goto error;
4744 }
4745
4746 end = strtoul(next, &next, 10);
4747 if (end <= start)
4748 goto error;
4749
4750 while (++start <= end) {
4751 if (start >= CPU_SUBSET_MAXCPUS)
4752 goto error;
4753 CPU_SET_S(start, cpu_subset_size, cpu_subset);
4754 }
4755
4756 if (*next == ',')
4757 next += 1;
4758 else if (*next != '\0')
4759 goto error;
4760 }
4761
4762 return;
4763
4764error:
4765 fprintf(stderr, "'--cpu %s' malformed\n", optarg);
4766 exit(-1);
4767}
4768
Len Brown812db3f2017-02-10 00:25:41 -05004769/*
4770 * HIDE_LIST - hide this list of counters, show the rest [default]
4771 * SHOW_LIST - show this list of counters, hide the rest
4772 */
4773enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
4774
4775int shown;
4776/*
4777 * parse_show_hide() - process cmdline to set default counter action
4778 */
4779void parse_show_hide(char *optarg, enum show_hide_mode new_mode)
4780{
4781 /*
4782 * --show: show only those specified
4783 * The 1st invocation will clear and replace the enabled mask
4784 * subsequent invocations can add to it.
4785 */
4786 if (new_mode == SHOW_LIST) {
4787 if (shown == 0)
4788 bic_enabled = bic_lookup(optarg);
4789 else
4790 bic_enabled |= bic_lookup(optarg);
4791 shown = 1;
4792
4793 return;
4794 }
4795
4796 /*
4797 * --hide: do not show those specified
4798 * multiple invocations simply clear more bits in enabled mask
4799 */
4800 bic_enabled &= ~bic_lookup(optarg);
Len Brown41618e62017-02-09 18:25:22 -05004801
Len Brown812db3f2017-02-10 00:25:41 -05004802}
4803
Len Brown103a8fe2010-10-22 23:53:03 -04004804void cmdline(int argc, char **argv)
4805{
4806 int opt;
Len Brownd8af6f52015-02-10 01:56:38 -05004807 int option_index = 0;
4808 static struct option long_options[] = {
Len Brown388e9c82016-12-22 23:57:55 -05004809 {"add", required_argument, 0, 'a'},
Len Brown1ef7d212017-02-10 23:54:15 -05004810 {"cpu", required_argument, 0, 'c'},
Len Brownd8af6f52015-02-10 01:56:38 -05004811 {"Dump", no_argument, 0, 'D'},
Len Brown96e47152017-01-21 02:26:00 -05004812 {"debug", no_argument, 0, 'd'}, /* internal, not documented */
Len Brownd8af6f52015-02-10 01:56:38 -05004813 {"interval", required_argument, 0, 'i'},
4814 {"help", no_argument, 0, 'h'},
Len Brown812db3f2017-02-10 00:25:41 -05004815 {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help
Len Brownd8af6f52015-02-10 01:56:38 -05004816 {"Joules", no_argument, 0, 'J'},
Len Brownb7d8c142016-02-13 23:36:17 -05004817 {"out", required_argument, 0, 'o'},
Len Brownd8af6f52015-02-10 01:56:38 -05004818 {"Package", no_argument, 0, 'p'},
4819 {"processor", no_argument, 0, 'p'},
Len Brown96e47152017-01-21 02:26:00 -05004820 {"quiet", no_argument, 0, 'q'},
Len Brown812db3f2017-02-10 00:25:41 -05004821 {"show", required_argument, 0, 's'},
Len Brownd8af6f52015-02-10 01:56:38 -05004822 {"Summary", no_argument, 0, 'S'},
4823 {"TCC", required_argument, 0, 'T'},
4824 {"version", no_argument, 0, 'v' },
4825 {0, 0, 0, 0 }
4826 };
Len Brown103a8fe2010-10-22 23:53:03 -04004827
4828 progname = argv[0];
4829
Len Brown96e47152017-01-21 02:26:00 -05004830 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpqST:v",
Len Brownd8af6f52015-02-10 01:56:38 -05004831 long_options, &option_index)) != -1) {
Len Brown103a8fe2010-10-22 23:53:03 -04004832 switch (opt) {
Len Brown388e9c82016-12-22 23:57:55 -05004833 case 'a':
4834 parse_add_command(optarg);
4835 break;
Len Brown1ef7d212017-02-10 23:54:15 -05004836 case 'c':
4837 parse_cpu_command(optarg);
4838 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004839 case 'D':
4840 dump_only++;
Len Brown8e180f32012-09-22 01:25:08 -04004841 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004842 case 'd':
4843 debug++;
Len Brown2f32edf2012-09-21 23:45:46 -04004844 break;
Len Brown812db3f2017-02-10 00:25:41 -05004845 case 'H':
4846 parse_show_hide(optarg, HIDE_LIST);
4847 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004848 case 'h':
4849 default:
4850 help();
4851 exit(1);
4852 case 'i':
Len Brown2a0609c2016-02-12 22:44:48 -05004853 {
4854 double interval = strtod(optarg, NULL);
4855
4856 if (interval < 0.001) {
Len Brownb7d8c142016-02-13 23:36:17 -05004857 fprintf(outf, "interval %f seconds is too small\n",
Len Brown2a0609c2016-02-12 22:44:48 -05004858 interval);
4859 exit(2);
4860 }
4861
4862 interval_ts.tv_sec = interval;
4863 interval_ts.tv_nsec = (interval - interval_ts.tv_sec) * 1000000000;
4864 }
Len Brown889facb2012-11-08 00:48:57 -05004865 break;
Dirk Brandewie5c56be92013-12-16 10:23:41 -08004866 case 'J':
4867 rapl_joules++;
4868 break;
Len Brownb7d8c142016-02-13 23:36:17 -05004869 case 'o':
4870 outf = fopen_or_die(optarg, "w");
4871 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004872 case 'P':
4873 show_pkg_only++;
4874 break;
4875 case 'p':
4876 show_core_only++;
4877 break;
Len Brown96e47152017-01-21 02:26:00 -05004878 case 'q':
4879 quiet = 1;
4880 break;
Len Brown812db3f2017-02-10 00:25:41 -05004881 case 's':
4882 parse_show_hide(optarg, SHOW_LIST);
4883 break;
Len Brownd8af6f52015-02-10 01:56:38 -05004884 case 'S':
4885 summary_only++;
4886 break;
4887 case 'T':
4888 tcc_activation_temp_override = atoi(optarg);
4889 break;
4890 case 'v':
4891 print_version();
4892 exit(0);
4893 break;
Len Brown103a8fe2010-10-22 23:53:03 -04004894 }
4895 }
4896}
4897
4898int main(int argc, char **argv)
4899{
Len Brownb7d8c142016-02-13 23:36:17 -05004900 outf = stderr;
4901
Len Brown103a8fe2010-10-22 23:53:03 -04004902 cmdline(argc, argv);
4903
Len Brown96e47152017-01-21 02:26:00 -05004904 if (!quiet)
Len Brownd8af6f52015-02-10 01:56:38 -05004905 print_version();
Len Brown103a8fe2010-10-22 23:53:03 -04004906
Len Brown41618e62017-02-09 18:25:22 -05004907 probe_sysfs();
4908
Len Brown103a8fe2010-10-22 23:53:03 -04004909 turbostat_init();
4910
Andy Shevchenko3b4d5c72014-01-23 17:13:15 +02004911 /* dump counters and exit */
4912 if (dump_only)
4913 return get_and_dump_counters();
4914
Len Brown103a8fe2010-10-22 23:53:03 -04004915 /*
4916 * if any params left, it must be a command to fork
4917 */
4918 if (argc - optind)
4919 return fork_it(argv + optind);
4920 else
4921 turbostat_loop();
4922
4923 return 0;
4924}