Commit d8cb379c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'turbostat' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux

Pull turbostat updates from Len Brown:
 "Bug fixes and a smattering of features"

* 'turbostat' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: (21 commits)
  tools/power turbostat: version 2021.05.04
  tools/power turbostat: Support "turbostat --hide idle"
  tools/power turbostat: elevate priority of interval mode
  tools/power turbostat: formatting
  tools/power turbostat: rename tcc variables
  tools/power turbostat: add TCC Offset support
  tools/power turbostat: save original CPU model
  tools/power turbostat: Fix Core C6 residency on Atom CPUs
  tools/power turbostat: Print the C-state Pre-wake settings
  tools/power turbostat: Enable tsc_tweak for Elkhart Lake and Jasper Lake
  tools/power turbostat: unmark non-kernel-doc comment
  tools/power/turbostat: Remove Package C6 Retention on Ice Lake Server
  tools/power turbostat: Fix offset overflow issue in index converting
  tools/power/turbostat: Fix turbostat for AMD Zen CPUs
  tools/power turbostat: update version number
  tools/power turbostat: Fix DRAM Energy Unit on SKX
  Revert "tools/power turbostat: adjust for temperature offset"
  tools/power turbostat: Support Ice Lake D
  tools/power turbostat: Support Alder Lake Mobile
  tools/power turbostat: print microcode patch level
  ...
parents dd8c86c6 3c070b2a
...@@ -54,12 +54,14 @@ name as necessary to disambiguate it from others is necessary. Note that option ...@@ -54,12 +54,14 @@ name as necessary to disambiguate it from others is necessary. Note that option
.PP .PP
\fB--cpu cpu-set\fP limit output to system summary plus the specified cpu-set. If cpu-set is the string "core", then the system summary plus the first CPU in each core are printed -- eg. subsequent HT siblings are not printed. Or if cpu-set is the string "package", then the system summary plus the first CPU in each package is printed. Otherwise, the system summary plus the specified set of CPUs are printed. The cpu-set is ordered from low to high, comma delimited with ".." and "-" permitted to denote a range. eg. 1,2,8,14..17,21-44 \fB--cpu cpu-set\fP limit output to system summary plus the specified cpu-set. If cpu-set is the string "core", then the system summary plus the first CPU in each core are printed -- eg. subsequent HT siblings are not printed. Or if cpu-set is the string "package", then the system summary plus the first CPU in each package is printed. Otherwise, the system summary plus the specified set of CPUs are printed. The cpu-set is ordered from low to high, comma delimited with ".." and "-" permitted to denote a range. eg. 1,2,8,14..17,21-44
.PP .PP
\fB--hide column\fP do not show the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--hide sysfs" to hide the sysfs statistics columns as a group. \fB--hide column\fP do not show the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names.
.PP .PP
\fB--enable column\fP show the specified built-in columns, which are otherwise disabled, by default. Currently the only built-in counters disabled by default are "usec", "Time_Of_Day_Seconds", "APIC" and "X2APIC". \fB--enable column\fP show the specified built-in columns, which are otherwise disabled, by default. Currently the only built-in counters disabled by default are "usec", "Time_Of_Day_Seconds", "APIC" and "X2APIC".
The column name "all" can be used to enable all disabled-by-default built-in counters. The column name "all" can be used to enable all disabled-by-default built-in counters.
.PP .PP
\fB--show column\fP show only the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--show sysfs" to show the sysfs statistics columns as a group. \fB--show column\fP show only the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names.
.PP
\fB--show CATEGORY --hide CATEGORY\fP Show and hide also accept a single CATEGORY of columns: "all", "topology", "idle", "frequency", "power", "sysfs", "other".
.PP .PP
\fB--Dump\fP displays the raw counter values. \fB--Dump\fP displays the raw counter values.
.PP .PP
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* turbostat -- show CPU frequency and C-state residency * turbostat -- show CPU frequency and C-state residency
* on modern Intel and AMD processors. * on modern Intel and AMD processors.
* *
* Copyright (c) 2013 Intel Corporation. * Copyright (c) 2021 Intel Corporation.
* Len Brown <len.brown@intel.com> * Len Brown <len.brown@intel.com>
*/ */
...@@ -33,12 +33,20 @@ ...@@ -33,12 +33,20 @@
#include <sys/capability.h> #include <sys/capability.h>
#include <errno.h> #include <errno.h>
#include <math.h> #include <math.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#include <stdbool.h>
char *proc_stat = "/proc/stat"; char *proc_stat = "/proc/stat";
FILE *outf; FILE *outf;
int *fd_percpu; int *fd_percpu;
struct timeval interval_tv = {5, 0}; int *fd_instr_count_percpu;
struct timespec interval_ts = {5, 0}; struct timeval interval_tv = { 5, 0 };
struct timespec interval_ts = { 5, 0 };
/* Save original CPU model */
unsigned int model_orig;
unsigned int num_iterations; unsigned int num_iterations;
unsigned int debug; unsigned int debug;
unsigned int quiet; unsigned int quiet;
...@@ -75,18 +83,21 @@ char *output_buffer, *outp; ...@@ -75,18 +83,21 @@ char *output_buffer, *outp;
unsigned int do_rapl; unsigned int do_rapl;
unsigned int do_dts; unsigned int do_dts;
unsigned int do_ptm; unsigned int do_ptm;
unsigned int do_ipc;
unsigned long long gfx_cur_rc6_ms; unsigned long long gfx_cur_rc6_ms;
unsigned long long cpuidle_cur_cpu_lpi_us; unsigned long long cpuidle_cur_cpu_lpi_us;
unsigned long long cpuidle_cur_sys_lpi_us; unsigned long long cpuidle_cur_sys_lpi_us;
unsigned int gfx_cur_mhz; unsigned int gfx_cur_mhz;
unsigned int gfx_act_mhz; unsigned int gfx_act_mhz;
unsigned int tcc_activation_temp; unsigned int tj_max;
unsigned int tcc_activation_temp_override; unsigned int tj_max_override;
int tcc_offset_bits;
double rapl_power_units, rapl_time_units; double rapl_power_units, rapl_time_units;
double rapl_dram_energy_units, rapl_energy_units; double rapl_dram_energy_units, rapl_energy_units;
double rapl_joule_counter_range; double rapl_joule_counter_range;
unsigned int do_core_perf_limit_reasons; unsigned int do_core_perf_limit_reasons;
unsigned int has_automatic_cstate_conversion; unsigned int has_automatic_cstate_conversion;
unsigned int dis_cstate_prewake;
unsigned int do_gfx_perf_limit_reasons; unsigned int do_gfx_perf_limit_reasons;
unsigned int do_ring_perf_limit_reasons; unsigned int do_ring_perf_limit_reasons;
unsigned int crystal_hz; unsigned int crystal_hz;
...@@ -173,12 +184,14 @@ struct thread_data { ...@@ -173,12 +184,14 @@ struct thread_data {
unsigned long long aperf; unsigned long long aperf;
unsigned long long mperf; unsigned long long mperf;
unsigned long long c1; unsigned long long c1;
unsigned long long instr_count;
unsigned long long irq_count; unsigned long long irq_count;
unsigned int smi_count; unsigned int smi_count;
unsigned int cpu_id; unsigned int cpu_id;
unsigned int apic_id; unsigned int apic_id;
unsigned int x2apic_id; unsigned int x2apic_id;
unsigned int flags; unsigned int flags;
bool is_atom;
#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 #define CPU_IS_FIRST_THREAD_IN_CORE 0x2
#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
unsigned long long counter[MAX_ADDED_THREAD_COUNTERS]; unsigned long long counter[MAX_ADDED_THREAD_COUNTERS];
...@@ -240,12 +253,11 @@ struct pkg_data { ...@@ -240,12 +253,11 @@ struct pkg_data {
((node_no) * topo.cores_per_node) + \ ((node_no) * topo.cores_per_node) + \
(core_no)) (core_no))
#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no) #define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE}; enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
enum counter_type {COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC}; enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC };
enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT}; enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT };
struct msr_counter { struct msr_counter {
unsigned int msr_num; unsigned int msr_num;
...@@ -281,9 +293,9 @@ int get_msr_sum(int cpu, off_t offset, unsigned long long *msr); ...@@ -281,9 +293,9 @@ int get_msr_sum(int cpu, off_t offset, unsigned long long *msr);
struct msr_sum_array { struct msr_sum_array {
/* get_msr_sum() = sum + (get_msr() - last) */ /* get_msr_sum() = sum + (get_msr() - last) */
struct { struct {
/*The accumulated MSR value is updated by the timer*/ /*The accumulated MSR value is updated by the timer */
unsigned long long sum; unsigned long long sum;
/*The MSR footprint recorded in last timer*/ /*The MSR footprint recorded in last timer */
unsigned long long last; unsigned long long last;
} entries[IDX_COUNT]; } entries[IDX_COUNT];
}; };
...@@ -291,12 +303,15 @@ struct msr_sum_array { ...@@ -291,12 +303,15 @@ struct msr_sum_array {
/* The percpu MSR sum array.*/ /* The percpu MSR sum array.*/
struct msr_sum_array *per_cpu_msr_sum; struct msr_sum_array *per_cpu_msr_sum;
int idx_to_offset(int idx) off_t idx_to_offset(int idx)
{ {
int offset; off_t offset;
switch (idx) { switch (idx) {
case IDX_PKG_ENERGY: case IDX_PKG_ENERGY:
if (do_rapl & RAPL_AMD_F17H)
offset = MSR_PKG_ENERGY_STAT;
else
offset = MSR_PKG_ENERGY_STATUS; offset = MSR_PKG_ENERGY_STATUS;
break; break;
case IDX_DRAM_ENERGY: case IDX_DRAM_ENERGY:
...@@ -320,12 +335,13 @@ int idx_to_offset(int idx) ...@@ -320,12 +335,13 @@ int idx_to_offset(int idx)
return offset; return offset;
} }
int offset_to_idx(int offset) int offset_to_idx(off_t offset)
{ {
int idx; int idx;
switch (offset) { switch (offset) {
case MSR_PKG_ENERGY_STATUS: case MSR_PKG_ENERGY_STATUS:
case MSR_PKG_ENERGY_STAT:
idx = IDX_PKG_ENERGY; idx = IDX_PKG_ENERGY;
break; break;
case MSR_DRAM_ENERGY_STATUS: case MSR_DRAM_ENERGY_STATUS:
...@@ -353,7 +369,7 @@ int idx_valid(int idx) ...@@ -353,7 +369,7 @@ int idx_valid(int idx)
{ {
switch (idx) { switch (idx) {
case IDX_PKG_ENERGY: case IDX_PKG_ENERGY:
return do_rapl & RAPL_PKG; return do_rapl & (RAPL_PKG | RAPL_AMD_F17H);
case IDX_DRAM_ENERGY: case IDX_DRAM_ENERGY:
return do_rapl & RAPL_DRAM; return do_rapl & RAPL_DRAM;
case IDX_PP0_ENERGY: case IDX_PP0_ENERGY:
...@@ -368,6 +384,7 @@ int idx_valid(int idx) ...@@ -368,6 +384,7 @@ int idx_valid(int idx)
return 0; return 0;
} }
} }
struct sys_counters { struct sys_counters {
unsigned int added_thread_counters; unsigned int added_thread_counters;
unsigned int added_core_counters; unsigned int added_core_counters;
...@@ -421,12 +438,13 @@ int cpu_is_not_present(int cpu) ...@@ -421,12 +438,13 @@ int cpu_is_not_present(int cpu)
{ {
return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
} }
/* /*
* run func(thread, core, package) in topology order * run func(thread, core, package) in topology order
* skip non-present cpus * skip non-present cpus
*/ */
int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *), int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *),
struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base) struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
{ {
int retval, pkg_no, core_no, thread_no, node_no; int retval, pkg_no, core_no, thread_no, node_no;
...@@ -434,21 +452,17 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg ...@@ -434,21 +452,17 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg
for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) { for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) {
for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
for (thread_no = 0; thread_no < for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) {
topo.threads_per_core; ++thread_no) {
struct thread_data *t; struct thread_data *t;
struct core_data *c; struct core_data *c;
struct pkg_data *p; struct pkg_data *p;
t = GET_THREAD(thread_base, thread_no, t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no);
core_no, node_no,
pkg_no);
if (cpu_is_not_present(t->cpu_id)) if (cpu_is_not_present(t->cpu_id))
continue; continue;
c = GET_CORE(core_base, core_no, c = GET_CORE(core_base, core_no, node_no, pkg_no);
node_no, pkg_no);
p = GET_PKG(pkg_base, pkg_no); p = GET_PKG(pkg_base, pkg_no);
retval = func(t, c, p); retval = func(t, c, p);
...@@ -470,6 +484,7 @@ int cpu_migrate(int cpu) ...@@ -470,6 +484,7 @@ int cpu_migrate(int cpu)
else else
return 0; return 0;
} }
int get_msr_fd(int cpu) int get_msr_fd(int cpu)
{ {
char pathname[32]; char pathname[32];
...@@ -490,6 +505,39 @@ int get_msr_fd(int cpu) ...@@ -490,6 +505,39 @@ int get_msr_fd(int cpu)
return fd; return fd;
} }
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
{
return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
}
static int perf_instr_count_open(int cpu_num)
{
struct perf_event_attr pea;
int fd;
memset(&pea, 0, sizeof(struct perf_event_attr));
pea.type = PERF_TYPE_HARDWARE;
pea.size = sizeof(struct perf_event_attr);
pea.config = PERF_COUNT_HW_INSTRUCTIONS;
/* counter for cpu_num, including user + kernel and all processes */
fd = perf_event_open(&pea, -1, cpu_num, -1, 0);
if (fd == -1)
err(-1, "cpu%d: perf instruction counter\n", cpu_num);
return fd;
}
int get_instr_count_fd(int cpu)
{
if (fd_instr_count_percpu[cpu])
return fd_instr_count_percpu[cpu];
fd_instr_count_percpu[cpu] = perf_instr_count_open(cpu);
return fd_instr_count_percpu[cpu];
}
int get_msr(int cpu, off_t offset, unsigned long long *msr) int get_msr(int cpu, off_t offset, unsigned long long *msr)
{ {
ssize_t retval; ssize_t retval;
...@@ -518,7 +566,7 @@ struct msr_counter bic[] = { ...@@ -518,7 +566,7 @@ struct msr_counter bic[] = {
{ 0x0, "Bzy_MHz" }, { 0x0, "Bzy_MHz" },
{ 0x0, "TSC_MHz" }, { 0x0, "TSC_MHz" },
{ 0x0, "IRQ" }, { 0x0, "IRQ" },
{ 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL}, { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL },
{ 0x0, "sysfs" }, { 0x0, "sysfs" },
{ 0x0, "CPU%c1" }, { 0x0, "CPU%c1" },
{ 0x0, "CPU%c3" }, { 0x0, "CPU%c3" },
...@@ -561,6 +609,7 @@ struct msr_counter bic[] = { ...@@ -561,6 +609,7 @@ struct msr_counter bic[] = {
{ 0x0, "X2APIC" }, { 0x0, "X2APIC" },
{ 0x0, "Die" }, { 0x0, "Die" },
{ 0x0, "GFXAMHz" }, { 0x0, "GFXAMHz" },
{ 0x0, "IPC" },
}; };
#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
...@@ -616,6 +665,13 @@ struct msr_counter bic[] = { ...@@ -616,6 +665,13 @@ struct msr_counter bic[] = {
#define BIC_X2APIC (1ULL << 49) #define BIC_X2APIC (1ULL << 49)
#define BIC_Die (1ULL << 50) #define BIC_Die (1ULL << 50)
#define BIC_GFXACTMHz (1ULL << 51) #define BIC_GFXACTMHz (1ULL << 51)
#define BIC_IPC (1ULL << 52)
#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die )
#define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__)
#define BIC_FREQUENCY ( BIC_Avg_MHz | BIC_Busy | BIC_Bzy_MHz | BIC_TSC_MHz | BIC_GFXMHz | BIC_GFXACTMHz )
#define BIC_IDLE ( BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX)
#define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
...@@ -627,7 +683,7 @@ unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC ...@@ -627,7 +683,7 @@ unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC
#define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT) #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT) #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
#define BIC_IS_ENABLED(COUNTER_BIT) (bic_enabled & COUNTER_BIT)
#define MAX_DEFERRED 16 #define MAX_DEFERRED 16
char *deferred_skip_names[MAX_DEFERRED]; char *deferred_skip_names[MAX_DEFERRED];
...@@ -675,9 +731,7 @@ void help(void) ...@@ -675,9 +731,7 @@ void help(void)
" sets the Thermal Control Circuit temperature in\n" " sets the Thermal Control Circuit temperature in\n"
" degrees Celsius\n" " degrees Celsius\n"
" -h, --help print this help message\n" " -h, --help print this help message\n"
" -v, --version print version information\n" " -v, --version print version information\n" "\n" "For more help, run \"man turbostat\"\n");
"\n"
"For more help, run \"man turbostat\"\n");
} }
/* /*
...@@ -700,6 +754,18 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode) ...@@ -700,6 +754,18 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
if (!strcmp(name_list, "all")) if (!strcmp(name_list, "all"))
return ~0; return ~0;
if (!strcmp(name_list, "topology"))
return BIC_TOPOLOGY;
if (!strcmp(name_list, "power"))
return BIC_THERMAL_PWR;
if (!strcmp(name_list, "idle"))
return BIC_IDLE;
if (!strcmp(name_list, "frequency"))
return BIC_FREQUENCY;
if (!strcmp(name_list, "other"))
return BIC_OTHER;
if (!strcmp(name_list, "all"))
return 0;
for (i = 0; i < MAX_BIC; ++i) { for (i = 0; i < MAX_BIC; ++i) {
if (!strcmp(name_list, bic[i].name)) { if (!strcmp(name_list, bic[i].name)) {
...@@ -731,7 +797,6 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode) ...@@ -731,7 +797,6 @@ unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
return retval; return retval;
} }
void print_header(char *delim) void print_header(char *delim)
{ {
struct msr_counter *mp; struct msr_counter *mp;
...@@ -764,6 +829,9 @@ void print_header(char *delim) ...@@ -764,6 +829,9 @@ void print_header(char *delim)
if (DO_BIC(BIC_TSC_MHz)) if (DO_BIC(BIC_TSC_MHz))
outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : "")); outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : ""));
if (DO_BIC(BIC_IPC))
outp += sprintf(outp, "%sIPC", (printed++ ? delim : ""));
if (DO_BIC(BIC_IRQ)) { if (DO_BIC(BIC_IRQ)) {
if (sums_need_wide_columns) if (sums_need_wide_columns)
outp += sprintf(outp, "%s IRQ", (printed++ ? delim : "")); outp += sprintf(outp, "%s IRQ", (printed++ ? delim : ""));
...@@ -910,8 +978,7 @@ void print_header(char *delim) ...@@ -910,8 +978,7 @@ void print_header(char *delim)
outp += sprintf(outp, "\n"); outp += sprintf(outp, "\n");
} }
int dump_counters(struct thread_data *t, struct core_data *c, int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
struct pkg_data *p)
{ {
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
...@@ -919,21 +986,22 @@ int dump_counters(struct thread_data *t, struct core_data *c, ...@@ -919,21 +986,22 @@ int dump_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p); outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
if (t) { if (t) {
outp += sprintf(outp, "CPU: %d flags 0x%x\n", outp += sprintf(outp, "CPU: %d flags 0x%x\n", t->cpu_id, t->flags);
t->cpu_id, t->flags);
outp += sprintf(outp, "TSC: %016llX\n", t->tsc); outp += sprintf(outp, "TSC: %016llX\n", t->tsc);
outp += sprintf(outp, "aperf: %016llX\n", t->aperf); outp += sprintf(outp, "aperf: %016llX\n", t->aperf);
outp += sprintf(outp, "mperf: %016llX\n", t->mperf); outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
outp += sprintf(outp, "c1: %016llX\n", t->c1); outp += sprintf(outp, "c1: %016llX\n", t->c1);
if (DO_BIC(BIC_IPC))
outp += sprintf(outp, "IPC: %lld\n", t->instr_count);
if (DO_BIC(BIC_IRQ)) if (DO_BIC(BIC_IRQ))
outp += sprintf(outp, "IRQ: %lld\n", t->irq_count); outp += sprintf(outp, "IRQ: %lld\n", t->irq_count);
if (DO_BIC(BIC_SMI)) if (DO_BIC(BIC_SMI))
outp += sprintf(outp, "SMI: %d\n", t->smi_count); outp += sprintf(outp, "SMI: %d\n", t->smi_count);
for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n", outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n", i, mp->msr_num, t->counter[i]);
i, mp->msr_num, t->counter[i]);
} }
} }
...@@ -946,8 +1014,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, ...@@ -946,8 +1014,7 @@ int dump_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "Joules: %0X\n", c->core_energy); outp += sprintf(outp, "Joules: %0X\n", c->core_energy);
for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", i, mp->msr_num, c->counter[i]);
i, mp->msr_num, c->counter[i]);
} }
outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us); outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
} }
...@@ -976,15 +1043,12 @@ int dump_counters(struct thread_data *t, struct core_data *c, ...@@ -976,15 +1043,12 @@ int dump_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores); outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores);
outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx); outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx);
outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram); outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram);
outp += sprintf(outp, "Throttle PKG: %0llX\n", outp += sprintf(outp, "Throttle PKG: %0llX\n", p->rapl_pkg_perf_status);
p->rapl_pkg_perf_status); outp += sprintf(outp, "Throttle RAM: %0llX\n", p->rapl_dram_perf_status);
outp += sprintf(outp, "Throttle RAM: %0llX\n",
p->rapl_dram_perf_status);
outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c); outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n", outp += sprintf(outp, "pADDED [%d] msr0x%x: %08llX\n", i, mp->msr_num, p->counter[i]);
i, mp->msr_num, p->counter[i]);
} }
} }
...@@ -996,8 +1060,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, ...@@ -996,8 +1060,7 @@ int dump_counters(struct thread_data *t, struct core_data *c,
/* /*
* column formatting convention & formats * column formatting convention & formats
*/ */
int format_counters(struct thread_data *t, struct core_data *c, int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
struct pkg_data *p)
{ {
double interval_float, tsc; double interval_float, tsc;
char *fmt8; char *fmt8;
...@@ -1015,8 +1078,7 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1015,8 +1078,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
return 0; return 0;
/*if not summary line and --cpu is used */ /*if not summary line and --cpu is used */
if ((t != &average.threads) && if ((t != &average.threads) && (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
(cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
return 0; return 0;
if (DO_BIC(BIC_USEC)) { if (DO_BIC(BIC_USEC)) {
...@@ -1031,7 +1093,7 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1031,7 +1093,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
if (DO_BIC(BIC_TOD)) if (DO_BIC(BIC_TOD))
outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec); outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec/1000000.0; interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec / 1000000.0;
tsc = t->tsc * tsc_tweak; tsc = t->tsc * tsc_tweak;
...@@ -1067,11 +1129,9 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1067,11 +1129,9 @@ int format_counters(struct thread_data *t, struct core_data *c,
if (DO_BIC(BIC_Node)) { if (DO_BIC(BIC_Node)) {
if (t) if (t)
outp += sprintf(outp, "%s%d", outp += sprintf(outp, "%s%d",
(printed++ ? delim : ""), (printed++ ? delim : ""), cpus[t->cpu_id].physical_node_id);
cpus[t->cpu_id].physical_node_id);
else else
outp += sprintf(outp, "%s-", outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
(printed++ ? delim : ""));
} }
if (DO_BIC(BIC_Core)) { if (DO_BIC(BIC_Core)) {
if (c) if (c)
...@@ -1088,22 +1148,25 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1088,22 +1148,25 @@ int format_counters(struct thread_data *t, struct core_data *c,
} }
if (DO_BIC(BIC_Avg_MHz)) if (DO_BIC(BIC_Avg_MHz))
outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float);
1.0 / units * t->aperf / interval_float);
if (DO_BIC(BIC_Busy)) if (DO_BIC(BIC_Busy))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->mperf/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->mperf / tsc);
if (DO_BIC(BIC_Bzy_MHz)) { if (DO_BIC(BIC_Bzy_MHz)) {
if (has_base_hz) if (has_base_hz)
outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf); outp +=
sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf);
else else
outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
tsc / units * t->aperf / t->mperf / interval_float); tsc / units * t->aperf / t->mperf / interval_float);
} }
if (DO_BIC(BIC_TSC_MHz)) if (DO_BIC(BIC_TSC_MHz))
outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc/units/interval_float); outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc / units / interval_float);
if (DO_BIC(BIC_IPC))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 1.0 * t->instr_count / t->aperf);
/* IRQ */ /* IRQ */
if (DO_BIC(BIC_IRQ)) { if (DO_BIC(BIC_IRQ)) {
...@@ -1121,7 +1184,8 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1121,7 +1184,8 @@ int format_counters(struct thread_data *t, struct core_data *c,
for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
if (mp->format == FORMAT_RAW) { if (mp->format == FORMAT_RAW) {
if (mp->width == 32) if (mp->width == 32)
outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) t->counter[i]); outp +=
sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)t->counter[i]);
else else
outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]); outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]);
} else if (mp->format == FORMAT_DELTA) { } else if (mp->format == FORMAT_DELTA) {
...@@ -1131,27 +1195,28 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1131,27 +1195,28 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->counter[i]); outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->counter[i]);
} else if (mp->format == FORMAT_PERCENT) { } else if (mp->format == FORMAT_PERCENT) {
if (mp->type == COUNTER_USEC) if (mp->type == COUNTER_USEC)
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), t->counter[i]/interval_float/10000); outp +=
sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
t->counter[i] / interval_float / 10000);
else else
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->counter[i]/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->counter[i] / tsc);
} }
} }
/* C1 */ /* C1 */
if (DO_BIC(BIC_CPU_c1)) if (DO_BIC(BIC_CPU_c1))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->c1/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->c1 / tsc);
/* print per-core data only for 1st thread in core */ /* print per-core data only for 1st thread in core */
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
goto done; goto done;
if (DO_BIC(BIC_CPU_c3)) if (DO_BIC(BIC_CPU_c3))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3 / tsc);
if (DO_BIC(BIC_CPU_c6)) if (DO_BIC(BIC_CPU_c6))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6 / tsc);
if (DO_BIC(BIC_CPU_c7)) if (DO_BIC(BIC_CPU_c7))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c7/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c7 / tsc);
/* Mod%c6 */ /* Mod%c6 */
if (DO_BIC(BIC_Mod_c6)) if (DO_BIC(BIC_Mod_c6))
...@@ -1163,7 +1228,8 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1163,7 +1228,8 @@ int format_counters(struct thread_data *t, struct core_data *c,
for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
if (mp->format == FORMAT_RAW) { if (mp->format == FORMAT_RAW) {
if (mp->width == 32) if (mp->width == 32)
outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) c->counter[i]); outp +=
sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)c->counter[i]);
else else
outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]); outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]);
} else if (mp->format == FORMAT_DELTA) { } else if (mp->format == FORMAT_DELTA) {
...@@ -1172,14 +1238,15 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1172,14 +1238,15 @@ int format_counters(struct thread_data *t, struct core_data *c,
else else
outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->counter[i]); outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->counter[i]);
} else if (mp->format == FORMAT_PERCENT) { } else if (mp->format == FORMAT_PERCENT) {
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->counter[i]/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->counter[i] / tsc);
} }
} }
fmt8 = "%s%.2f"; fmt8 = "%s%.2f";
if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY)) if (DO_BIC(BIC_CorWatt) && (do_rapl & RAPL_PER_CORE_ENERGY))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units / interval_float);
if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY)) if (DO_BIC(BIC_Cor_J) && (do_rapl & RAPL_PER_CORE_ENERGY))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units); outp += sprintf(outp, fmt8, (printed++ ? delim : ""), c->core_energy * rapl_energy_units);
...@@ -1211,42 +1278,49 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1211,42 +1278,49 @@ int format_counters(struct thread_data *t, struct core_data *c,
/* Totl%C0, Any%C0 GFX%C0 CPUGFX% */ /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
if (DO_BIC(BIC_Totl_c0)) if (DO_BIC(BIC_Totl_c0))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0 / tsc);
if (DO_BIC(BIC_Any_c0)) if (DO_BIC(BIC_Any_c0))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0 / tsc);
if (DO_BIC(BIC_GFX_c0)) if (DO_BIC(BIC_GFX_c0))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0 / tsc);
if (DO_BIC(BIC_CPUGFX)) if (DO_BIC(BIC_CPUGFX))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0 / tsc);
if (DO_BIC(BIC_Pkgpc2)) if (DO_BIC(BIC_Pkgpc2))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2 / tsc);
if (DO_BIC(BIC_Pkgpc3)) if (DO_BIC(BIC_Pkgpc3))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc3/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc3 / tsc);
if (DO_BIC(BIC_Pkgpc6)) if (DO_BIC(BIC_Pkgpc6))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc6/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc6 / tsc);
if (DO_BIC(BIC_Pkgpc7)) if (DO_BIC(BIC_Pkgpc7))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc7/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc7 / tsc);
if (DO_BIC(BIC_Pkgpc8)) if (DO_BIC(BIC_Pkgpc8))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc8/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc8 / tsc);
if (DO_BIC(BIC_Pkgpc9)) if (DO_BIC(BIC_Pkgpc9))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc9/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc9 / tsc);
if (DO_BIC(BIC_Pkgpc10)) if (DO_BIC(BIC_Pkgpc10))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10 / tsc);
if (DO_BIC(BIC_CPU_LPI)) if (DO_BIC(BIC_CPU_LPI))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->cpu_lpi / 1000000.0 / interval_float); outp +=
sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->cpu_lpi / 1000000.0 / interval_float);
if (DO_BIC(BIC_SYS_LPI)) if (DO_BIC(BIC_SYS_LPI))
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float); outp +=
sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->sys_lpi / 1000000.0 / interval_float);
if (DO_BIC(BIC_PkgWatt)) if (DO_BIC(BIC_PkgWatt))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);
if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY)) if (DO_BIC(BIC_CorWatt) && !(do_rapl & RAPL_PER_CORE_ENERGY))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
if (DO_BIC(BIC_GFXWatt)) if (DO_BIC(BIC_GFXWatt))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float);
if (DO_BIC(BIC_RAMWatt)) if (DO_BIC(BIC_RAMWatt))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""),
p->energy_dram * rapl_dram_energy_units / interval_float);
if (DO_BIC(BIC_Pkg_J)) if (DO_BIC(BIC_Pkg_J))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units); outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units);
if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY)) if (DO_BIC(BIC_Cor_J) && !(do_rapl & RAPL_PER_CORE_ENERGY))
...@@ -1256,14 +1330,19 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1256,14 +1330,19 @@ int format_counters(struct thread_data *t, struct core_data *c,
if (DO_BIC(BIC_RAM_J)) if (DO_BIC(BIC_RAM_J))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units); outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units);
if (DO_BIC(BIC_PKG__)) if (DO_BIC(BIC_PKG__))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""),
100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
if (DO_BIC(BIC_RAM__)) if (DO_BIC(BIC_RAM__))
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); outp +=
sprintf(outp, fmt8, (printed++ ? delim : ""),
100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
if (mp->format == FORMAT_RAW) { if (mp->format == FORMAT_RAW) {
if (mp->width == 32) if (mp->width == 32)
outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) p->counter[i]); outp +=
sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)p->counter[i]);
else else
outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), p->counter[i]); outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), p->counter[i]);
} else if (mp->format == FORMAT_DELTA) { } else if (mp->format == FORMAT_DELTA) {
...@@ -1272,7 +1351,7 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -1272,7 +1351,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
else else
outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), p->counter[i]); outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), p->counter[i]);
} else if (mp->format == FORMAT_PERCENT) { } else if (mp->format == FORMAT_PERCENT) {
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->counter[i]/tsc); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->counter[i] / tsc);
} }
} }
...@@ -1297,12 +1376,14 @@ void flush_output_stdout(void) ...@@ -1297,12 +1376,14 @@ void flush_output_stdout(void)
outp = output_buffer; outp = output_buffer;
} }
void flush_output_stderr(void) void flush_output_stderr(void)
{ {
fputs(output_buffer, outf); fputs(output_buffer, outf);
fflush(outf); fflush(outf);
outp = output_buffer; outp = output_buffer;
} }
void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{ {
static int printed; static int printed;
...@@ -1323,13 +1404,11 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_ ...@@ -1323,13 +1404,11 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_
#define DELTA_WRAP32(new, old) \ #define DELTA_WRAP32(new, old) \
old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32); old = ((((unsigned long long)new << 32) - ((unsigned long long)old << 32)) >> 32);
int int delta_package(struct pkg_data *new, struct pkg_data *old)
delta_package(struct pkg_data *new, struct pkg_data *old)
{ {
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
if (DO_BIC(BIC_Totl_c0)) if (DO_BIC(BIC_Totl_c0))
old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0; old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0;
if (DO_BIC(BIC_Any_c0)) if (DO_BIC(BIC_Any_c0))
...@@ -1379,8 +1458,7 @@ delta_package(struct pkg_data *new, struct pkg_data *old) ...@@ -1379,8 +1458,7 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
return 0; return 0;
} }
void void delta_core(struct core_data *new, struct core_data *old)
delta_core(struct core_data *new, struct core_data *old)
{ {
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
...@@ -1412,9 +1490,7 @@ int soft_c1_residency_display(int bic) ...@@ -1412,9 +1490,7 @@ int soft_c1_residency_display(int bic)
/* /*
* old = new - old * old = new - old
*/ */
int int delta_thread(struct thread_data *new, struct thread_data *old, struct core_data *core_delta)
delta_thread(struct thread_data *new, struct thread_data *old,
struct core_data *core_delta)
{ {
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
...@@ -1445,8 +1521,7 @@ delta_thread(struct thread_data *new, struct thread_data *old, ...@@ -1445,8 +1521,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
old->c1 = new->c1 - old->c1; old->c1 = new->c1 - old->c1;
if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || soft_c1_residency_display(BIC_Avg_MHz)) {
soft_c1_residency_display(BIC_Avg_MHz)) {
if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
old->aperf = new->aperf - old->aperf; old->aperf = new->aperf - old->aperf;
old->mperf = new->mperf - old->mperf; old->mperf = new->mperf - old->mperf;
...@@ -1455,7 +1530,6 @@ delta_thread(struct thread_data *new, struct thread_data *old, ...@@ -1455,7 +1530,6 @@ delta_thread(struct thread_data *new, struct thread_data *old,
} }
} }
if (use_c1_residency_msr) { if (use_c1_residency_msr) {
/* /*
* Some models have a dedicated C1 residency MSR, * Some models have a dedicated C1 residency MSR,
...@@ -1482,6 +1556,9 @@ delta_thread(struct thread_data *new, struct thread_data *old, ...@@ -1482,6 +1556,9 @@ delta_thread(struct thread_data *new, struct thread_data *old,
old->mperf = 1; /* divide by 0 protection */ old->mperf = 1; /* divide by 0 protection */
} }
if (DO_BIC(BIC_IPC))
old->instr_count = new->instr_count - old->instr_count;
if (DO_BIC(BIC_IRQ)) if (DO_BIC(BIC_IRQ))
old->irq_count = new->irq_count - old->irq_count; old->irq_count = new->irq_count - old->irq_count;
...@@ -1498,8 +1575,7 @@ delta_thread(struct thread_data *new, struct thread_data *old, ...@@ -1498,8 +1575,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
} }
int delta_cpu(struct thread_data *t, struct core_data *c, int delta_cpu(struct thread_data *t, struct core_data *c,
struct pkg_data *p, struct thread_data *t2, struct pkg_data *p, struct thread_data *t2, struct core_data *c2, struct pkg_data *p2)
struct core_data *c2, struct pkg_data *p2)
{ {
int retval = 0; int retval = 0;
...@@ -1536,6 +1612,8 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -1536,6 +1612,8 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
t->mperf = 0; t->mperf = 0;
t->c1 = 0; t->c1 = 0;
t->instr_count = 0;
t->irq_count = 0; t->irq_count = 0;
t->smi_count = 0; t->smi_count = 0;
...@@ -1587,8 +1665,8 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -1587,8 +1665,8 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) for (i = 0, mp = sys.pp; mp; i++, mp = mp->next)
p->counter[i] = 0; p->counter[i] = 0;
} }
int sum_counters(struct thread_data *t, struct core_data *c,
struct pkg_data *p) int sum_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{ {
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
...@@ -1611,6 +1689,8 @@ int sum_counters(struct thread_data *t, struct core_data *c, ...@@ -1611,6 +1689,8 @@ int sum_counters(struct thread_data *t, struct core_data *c,
average.threads.mperf += t->mperf; average.threads.mperf += t->mperf;
average.threads.c1 += t->c1; average.threads.c1 += t->c1;
average.threads.instr_count += t->instr_count;
average.threads.irq_count += t->irq_count; average.threads.irq_count += t->irq_count;
average.threads.smi_count += t->smi_count; average.threads.smi_count += t->smi_count;
...@@ -1687,12 +1767,12 @@ int sum_counters(struct thread_data *t, struct core_data *c, ...@@ -1687,12 +1767,12 @@ int sum_counters(struct thread_data *t, struct core_data *c,
} }
return 0; return 0;
} }
/* /*
* sum the counters for all cpus in the system * sum the counters for all cpus in the system
* compute the weighted average * compute the weighted average
*/ */
void compute_average(struct thread_data *t, struct core_data *c, void compute_average(struct thread_data *t, struct core_data *c, struct pkg_data *p)
struct pkg_data *p)
{ {
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
...@@ -1707,6 +1787,7 @@ void compute_average(struct thread_data *t, struct core_data *c, ...@@ -1707,6 +1787,7 @@ void compute_average(struct thread_data *t, struct core_data *c,
average.threads.tsc /= topo.num_cpus; average.threads.tsc /= topo.num_cpus;
average.threads.aperf /= topo.num_cpus; average.threads.aperf /= topo.num_cpus;
average.threads.mperf /= topo.num_cpus; average.threads.mperf /= topo.num_cpus;
average.threads.instr_count /= topo.num_cpus;
average.threads.c1 /= topo.num_cpus; average.threads.c1 /= topo.num_cpus;
if (average.threads.irq_count > 9999999) if (average.threads.irq_count > 9999999)
...@@ -1772,7 +1853,7 @@ static unsigned long long rdtsc(void) ...@@ -1772,7 +1853,7 @@ static unsigned long long rdtsc(void)
{ {
unsigned int low, high; unsigned int low, high;
asm volatile("rdtsc" : "=a" (low), "=d" (high)); asm volatile ("rdtsc":"=a" (low), "=d"(high));
return low | ((unsigned long long)high) << 32; return low | ((unsigned long long)high) << 32;
} }
...@@ -1788,6 +1869,7 @@ FILE *fopen_or_die(const char *path, const char *mode) ...@@ -1788,6 +1869,7 @@ FILE *fopen_or_die(const char *path, const char *mode)
err(1, "%s: open failed", path); err(1, "%s: open failed", path);
return filep; return filep;
} }
/* /*
* snapshot_sysfs_counter() * snapshot_sysfs_counter()
* *
...@@ -1819,8 +1901,7 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp) ...@@ -1819,8 +1901,7 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
char path[128 + PATH_BYTES]; char path[128 + PATH_BYTES];
if (mp->flags & SYSFS_PERCPU) { if (mp->flags & SYSFS_PERCPU) {
sprintf(path, "/sys/devices/system/cpu/cpu%d/%s", sprintf(path, "/sys/devices/system/cpu/cpu%d/%s", cpu, mp->path);
cpu, mp->path);
*counterp = snapshot_sysfs_counter(path); *counterp = snapshot_sysfs_counter(path);
} else { } else {
...@@ -1903,8 +1984,7 @@ void get_apic_id(struct thread_data *t) ...@@ -1903,8 +1984,7 @@ void get_apic_id(struct thread_data *t)
t->x2apic_id = edx; t->x2apic_id = edx;
if (debug && (t->apic_id != (t->x2apic_id & 0xff))) if (debug && (t->apic_id != (t->x2apic_id & 0xff)))
fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);
t->cpu_id, t->apic_id, t->x2apic_id);
} }
/* /*
...@@ -1932,8 +2012,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -1932,8 +2012,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
retry: retry:
t->tsc = rdtsc(); /* we are running on local CPU of interest */ t->tsc = rdtsc(); /* we are running on local CPU of interest */
if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) || soft_c1_residency_display(BIC_Avg_MHz)) {
soft_c1_residency_display(BIC_Avg_MHz)) {
unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time; unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
/* /*
...@@ -1980,8 +2059,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -1980,8 +2059,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (aperf_mperf_retry_count < 5) if (aperf_mperf_retry_count < 5)
goto retry; goto retry;
else else
warnx("cpu%d jitter %lld %lld", warnx("cpu%d jitter %lld %lld", cpu, aperf_time, mperf_time);
cpu, aperf_time, mperf_time);
} }
aperf_mperf_retry_count = 0; aperf_mperf_retry_count = 0;
...@@ -1989,6 +2067,10 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -1989,6 +2067,10 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
t->mperf = t->mperf * aperf_mperf_multiplier; t->mperf = t->mperf * aperf_mperf_multiplier;
} }
if (DO_BIC(BIC_IPC))
if (read(get_instr_count_fd(cpu), &t->instr_count, sizeof(long long)) != sizeof(long long))
return -4;
if (DO_BIC(BIC_IRQ)) if (DO_BIC(BIC_IRQ))
t->irq_count = irqs_per_cpu[cpu]; t->irq_count = irqs_per_cpu[cpu];
if (DO_BIC(BIC_SMI)) { if (DO_BIC(BIC_SMI)) {
...@@ -2023,9 +2105,19 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -2023,9 +2105,19 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return -7; return -7;
} }
if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7)) if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7)) {
if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7)) if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
return -8; return -8;
else if (t->is_atom) {
/*
* For Atom CPUs that has core cstate deeper than c6,
* MSR_CORE_C6_RESIDENCY returns residency of cc6 and deeper.
* Minus CC7 (and deeper cstates) residency to get
* accturate cc6 residency.
*/
c->c6 -= c->c7;
}
}
if (DO_BIC(BIC_Mod_c6)) if (DO_BIC(BIC_Mod_c6))
if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us)) if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
...@@ -2034,7 +2126,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -2034,7 +2126,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (DO_BIC(BIC_CoreTmp)) { if (DO_BIC(BIC_CoreTmp)) {
if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr)) if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
return -9; return -9;
c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); c->core_temp_c = tj_max - ((msr >> 16) & 0x7F);
} }
if (do_rapl & RAPL_AMD_F17H) { if (do_rapl & RAPL_AMD_F17H) {
...@@ -2140,7 +2232,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -2140,7 +2232,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (DO_BIC(BIC_PkgTmp)) { if (DO_BIC(BIC_PkgTmp)) {
if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
return -17; return -17;
p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); p->pkg_temp_c = tj_max - ((msr >> 16) & 0x7F);
} }
if (DO_BIC(BIC_GFX_rc6)) if (DO_BIC(BIC_GFX_rc6))
...@@ -2187,26 +2279,62 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -2187,26 +2279,62 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
int pkg_cstate_limit = PCLUKN; int pkg_cstate_limit = PCLUKN;
char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2", char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
"pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"}; "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"
};
int nhm_pkg_cstate_limits[16] =
{ PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
int snb_pkg_cstate_limits[16] =
{ PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
int hsw_pkg_cstate_limits[16] =
{ PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
int slv_pkg_cstate_limits[16] =
{ PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCL__6, PCL__7
};
int amt_pkg_cstate_limits[16] =
{ PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
int phi_pkg_cstate_limits[16] =
{ PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
int glm_pkg_cstate_limits[16] =
{ PCLUNL, PCL__1, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCL_10, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int skx_pkg_cstate_limits[16] =
int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; { PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; PCLRSV, PCLRSV
int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7}; };
int amt_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int glm_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCL_10, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
int icx_pkg_cstate_limits[16] =
{ PCL__0, PCL__2, PCL__6, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV,
PCLRSV, PCLRSV
};
static void static void calculate_tsc_tweak()
calculate_tsc_tweak()
{ {
tsc_tweak = base_hz / tsc_hz; tsc_tweak = base_hz / tsc_hz;
} }
static void void prewake_cstate_probe(unsigned int family, unsigned int model);
dump_nhm_platform_info(void)
static void dump_nhm_platform_info(void)
{ {
unsigned long long msr; unsigned long long msr;
unsigned int ratio; unsigned int ratio;
...@@ -2216,22 +2344,23 @@ dump_nhm_platform_info(void) ...@@ -2216,22 +2344,23 @@ dump_nhm_platform_info(void)
fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr); fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
ratio = (msr >> 40) & 0xFF; ratio = (msr >> 40) & 0xFF;
fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n", fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 8) & 0xFF; ratio = (msr >> 8) & 0xFF;
fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr); get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
base_cpu, msr, msr & 0x2 ? "EN" : "DIS"); base_cpu, msr, msr & 0x2 ? "EN" : "DIS");
/* C-state Pre-wake Disable (CSTATE_PREWAKE_DISABLE) */
if (dis_cstate_prewake)
fprintf(outf, "C-state Pre-wake: %sabled\n", msr & 0x40000000 ? "DIS" : "EN");
return; return;
} }
static void static void dump_hsw_turbo_ratio_limits(void)
dump_hsw_turbo_ratio_limits(void)
{ {
unsigned long long msr; unsigned long long msr;
unsigned int ratio; unsigned int ratio;
...@@ -2242,18 +2371,15 @@ dump_hsw_turbo_ratio_limits(void) ...@@ -2242,18 +2371,15 @@ dump_hsw_turbo_ratio_limits(void)
ratio = (msr >> 8) & 0xFF; ratio = (msr >> 8) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 0) & 0xFF; ratio = (msr >> 0) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
return; return;
} }
static void static void dump_ivt_turbo_ratio_limits(void)
dump_ivt_turbo_ratio_limits(void)
{ {
unsigned long long msr; unsigned long long msr;
unsigned int ratio; unsigned int ratio;
...@@ -2264,45 +2390,38 @@ dump_ivt_turbo_ratio_limits(void) ...@@ -2264,45 +2390,38 @@ dump_ivt_turbo_ratio_limits(void)
ratio = (msr >> 56) & 0xFF; ratio = (msr >> 56) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 48) & 0xFF; ratio = (msr >> 48) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 40) & 0xFF; ratio = (msr >> 40) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 32) & 0xFF; ratio = (msr >> 32) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 24) & 0xFF; ratio = (msr >> 24) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 16) & 0xFF; ratio = (msr >> 16) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 8) & 0xFF; ratio = (msr >> 8) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 0) & 0xFF; ratio = (msr >> 0) & 0xFF;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
return; return;
} }
int has_turbo_ratio_group_limits(int family, int model) int has_turbo_ratio_group_limits(int family, int model)
{ {
...@@ -2312,6 +2431,7 @@ int has_turbo_ratio_group_limits(int family, int model) ...@@ -2312,6 +2431,7 @@ int has_turbo_ratio_group_limits(int family, int model)
switch (model) { switch (model) {
case INTEL_FAM6_ATOM_GOLDMONT: case INTEL_FAM6_ATOM_GOLDMONT:
case INTEL_FAM6_SKYLAKE_X: case INTEL_FAM6_SKYLAKE_X:
case INTEL_FAM6_ICELAKE_X:
case INTEL_FAM6_ATOM_GOLDMONT_D: case INTEL_FAM6_ATOM_GOLDMONT_D:
case INTEL_FAM6_ATOM_TREMONT_D: case INTEL_FAM6_ATOM_TREMONT_D:
return 1; return 1;
...@@ -2319,8 +2439,7 @@ int has_turbo_ratio_group_limits(int family, int model) ...@@ -2319,8 +2439,7 @@ int has_turbo_ratio_group_limits(int family, int model)
return 0; return 0;
} }
static void static void dump_turbo_ratio_limits(int family, int model)
dump_turbo_ratio_limits(int family, int model)
{ {
unsigned long long msr, core_counts; unsigned long long msr, core_counts;
unsigned int ratio, group_size; unsigned int ratio, group_size;
...@@ -2385,8 +2504,7 @@ dump_turbo_ratio_limits(int family, int model) ...@@ -2385,8 +2504,7 @@ dump_turbo_ratio_limits(int family, int model)
return; return;
} }
static void static void dump_atom_turbo_ratio_limits(void)
dump_atom_turbo_ratio_limits(void)
{ {
unsigned long long msr; unsigned long long msr;
unsigned int ratio; unsigned int ratio;
...@@ -2396,45 +2514,37 @@ dump_atom_turbo_ratio_limits(void) ...@@ -2396,45 +2514,37 @@ dump_atom_turbo_ratio_limits(void)
ratio = (msr >> 0) & 0x3F; ratio = (msr >> 0) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n", fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 8) & 0x3F; ratio = (msr >> 8) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n", fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 16) & 0x3F; ratio = (msr >> 16) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr); get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF); fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
ratio = (msr >> 24) & 0x3F; ratio = (msr >> 24) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 16) & 0x3F; ratio = (msr >> 16) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 8) & 0x3F; ratio = (msr >> 8) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
ratio = (msr >> 0) & 0x3F; ratio = (msr >> 0) & 0x3F;
if (ratio) if (ratio)
fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n", fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n", ratio, bclk, ratio * bclk);
ratio, bclk, ratio * bclk);
} }
static void static void dump_knl_turbo_ratio_limits(void)
dump_knl_turbo_ratio_limits(void)
{ {
const unsigned int buckets_no = 7; const unsigned int buckets_no = 7;
...@@ -2446,8 +2556,7 @@ dump_knl_turbo_ratio_limits(void) ...@@ -2446,8 +2556,7 @@ dump_knl_turbo_ratio_limits(void)
get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr); get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
base_cpu, msr);
/* /*
* Turbo encoding in KNL is as follows: * Turbo encoding in KNL is as follows:
...@@ -2492,8 +2601,7 @@ dump_knl_turbo_ratio_limits(void) ...@@ -2492,8 +2601,7 @@ dump_knl_turbo_ratio_limits(void)
ratio[i], bclk, ratio[i] * bclk, cores[i]); ratio[i], bclk, ratio[i] * bclk, cores[i]);
} }
static void static void dump_nhm_cst_cfg(void)
dump_nhm_cst_cfg(void)
{ {
unsigned long long msr; unsigned long long msr;
...@@ -2506,14 +2614,11 @@ dump_nhm_cst_cfg(void) ...@@ -2506,14 +2614,11 @@ dump_nhm_cst_cfg(void)
(msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "", (msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
(msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "", (msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
(msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "", (msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
(msr & (1 << 15)) ? "" : "UN", (msr & (1 << 15)) ? "" : "UN", (unsigned int)msr & 0xF, pkg_cstate_limit_strings[pkg_cstate_limit]);
(unsigned int)msr & 0xF,
pkg_cstate_limit_strings[pkg_cstate_limit]);
#define AUTOMATIC_CSTATE_CONVERSION (1UL << 16) #define AUTOMATIC_CSTATE_CONVERSION (1UL << 16)
if (has_automatic_cstate_conversion) { if (has_automatic_cstate_conversion) {
fprintf(outf, ", automatic c-state conversion=%s", fprintf(outf, ", automatic c-state conversion=%s", (msr & AUTOMATIC_CSTATE_CONVERSION) ? "on" : "off");
(msr & AUTOMATIC_CSTATE_CONVERSION) ? "on" : "off");
} }
fprintf(outf, ")\n"); fprintf(outf, ")\n");
...@@ -2521,8 +2626,7 @@ dump_nhm_cst_cfg(void) ...@@ -2521,8 +2626,7 @@ dump_nhm_cst_cfg(void)
return; return;
} }
static void static void dump_config_tdp(void)
dump_config_tdp(void)
{ {
unsigned long long msr; unsigned long long msr;
...@@ -2564,7 +2668,7 @@ dump_config_tdp(void) ...@@ -2564,7 +2668,7 @@ dump_config_tdp(void)
fprintf(outf, ")\n"); fprintf(outf, ")\n");
} }
unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 }; unsigned int irtl_time_units[] = { 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
void print_irtl(void) void print_irtl(void)
{ {
...@@ -2604,6 +2708,7 @@ void print_irtl(void) ...@@ -2604,6 +2708,7 @@ void print_irtl(void)
(msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
} }
void free_fd_percpu(void) void free_fd_percpu(void)
{ {
int i; int i;
...@@ -2660,7 +2765,6 @@ void free_all_buffers(void) ...@@ -2660,7 +2765,6 @@ void free_all_buffers(void)
free(cpus); free(cpus);
} }
/* /*
* Parse a file containing a single int. * Parse a file containing a single int.
* Return 0 if file can not be opened * Return 0 if file can not be opened
...@@ -2735,8 +2839,7 @@ void set_node_data(void) ...@@ -2735,8 +2839,7 @@ void set_node_data(void)
* the logical_node_id * the logical_node_id
*/ */
for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) { for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) {
if ((cpus[cpux].physical_package_id == pkg) && if ((cpus[cpux].physical_package_id == pkg) && (cpus[cpux].physical_node_id == node)) {
(cpus[cpux].physical_node_id == node)) {
cpus[cpux].logical_node_id = lnode; cpus[cpux].logical_node_id = lnode;
cpu_count++; cpu_count++;
} }
...@@ -2758,8 +2861,7 @@ int get_physical_node_id(struct cpu_topology *thiscpu) ...@@ -2758,8 +2861,7 @@ int get_physical_node_id(struct cpu_topology *thiscpu)
int cpu = thiscpu->logical_cpu_id; int cpu = thiscpu->logical_cpu_id;
for (i = 0; i <= topo.max_cpu_num; i++) { for (i = 0; i <= topo.max_cpu_num; i++) {
sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist", sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist", cpu, i);
cpu, i);
filep = fopen(path, "r"); filep = fopen(path, "r");
if (!filep) if (!filep)
continue; continue;
...@@ -2789,8 +2891,7 @@ int get_thread_siblings(struct cpu_topology *thiscpu) ...@@ -2789,8 +2891,7 @@ int get_thread_siblings(struct cpu_topology *thiscpu)
size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
CPU_ZERO_S(size, thiscpu->put_ids); CPU_ZERO_S(size, thiscpu->put_ids);
sprintf(path, sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
"/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
filep = fopen(path, "r"); filep = fopen(path, "r");
if (!filep) { if (!filep) {
...@@ -2807,10 +2908,8 @@ int get_thread_siblings(struct cpu_topology *thiscpu) ...@@ -2807,10 +2908,8 @@ int get_thread_siblings(struct cpu_topology *thiscpu)
sib_core = get_core_id(so); sib_core = get_core_id(so);
if (sib_core == thiscpu->physical_core_id) { if (sib_core == thiscpu->physical_core_id) {
CPU_SET_S(so, size, thiscpu->put_ids); CPU_SET_S(so, size, thiscpu->put_ids);
if ((so != cpu) && if ((so != cpu) && (cpus[so].thread_id < 0))
(cpus[so].thread_id < 0)) cpus[so].thread_id = thread_id++;
cpus[so].thread_id =
thread_id++;
} }
} }
} }
...@@ -2825,41 +2924,31 @@ int get_thread_siblings(struct cpu_topology *thiscpu) ...@@ -2825,41 +2924,31 @@ int get_thread_siblings(struct cpu_topology *thiscpu)
* skip non-present cpus * skip non-present cpus
*/ */
int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *, int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
struct pkg_data *, struct thread_data *, struct core_data *, struct pkg_data *, struct thread_data *, struct core_data *,
struct pkg_data *), struct thread_data *thread_base, struct pkg_data *), struct thread_data *thread_base,
struct core_data *core_base, struct pkg_data *pkg_base, struct core_data *core_base, struct pkg_data *pkg_base,
struct thread_data *thread_base2, struct core_data *core_base2, struct thread_data *thread_base2, struct core_data *core_base2, struct pkg_data *pkg_base2)
struct pkg_data *pkg_base2)
{ {
int retval, pkg_no, node_no, core_no, thread_no; int retval, pkg_no, node_no, core_no, thread_no;
for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) {
for (node_no = 0; node_no < topo.nodes_per_pkg; ++node_no) { for (node_no = 0; node_no < topo.nodes_per_pkg; ++node_no) {
for (core_no = 0; core_no < topo.cores_per_node; for (core_no = 0; core_no < topo.cores_per_node; ++core_no) {
++core_no) { for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) {
for (thread_no = 0; thread_no <
topo.threads_per_core; ++thread_no) {
struct thread_data *t, *t2; struct thread_data *t, *t2;
struct core_data *c, *c2; struct core_data *c, *c2;
struct pkg_data *p, *p2; struct pkg_data *p, *p2;
t = GET_THREAD(thread_base, thread_no, t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no);
core_no, node_no,
pkg_no);
if (cpu_is_not_present(t->cpu_id)) if (cpu_is_not_present(t->cpu_id))
continue; continue;
t2 = GET_THREAD(thread_base2, thread_no, t2 = GET_THREAD(thread_base2, thread_no, core_no, node_no, pkg_no);
core_no, node_no,
pkg_no);
c = GET_CORE(core_base, core_no, c = GET_CORE(core_base, core_no, node_no, pkg_no);
node_no, pkg_no); c2 = GET_CORE(core_base2, core_no, node_no, pkg_no);
c2 = GET_CORE(core_base2, core_no,
node_no,
pkg_no);
p = GET_PKG(pkg_base, pkg_no); p = GET_PKG(pkg_base, pkg_no);
p2 = GET_PKG(pkg_base2, pkg_no); p2 = GET_PKG(pkg_base2, pkg_no);
...@@ -2878,7 +2967,7 @@ int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *, ...@@ -2878,7 +2967,7 @@ int for_all_cpus_2(int (func)(struct thread_data *, struct core_data *,
* run func(cpu) on every cpu in /proc/stat * run func(cpu) on every cpu in /proc/stat
* return max_cpu number * return max_cpu number
*/ */
int for_all_proc_cpus(int (func)(int)) int for_all_proc_cpus(int (func) (int))
{ {
FILE *fp; FILE *fp;
int cpu_num; int cpu_num;
...@@ -2898,7 +2987,7 @@ int for_all_proc_cpus(int (func)(int)) ...@@ -2898,7 +2987,7 @@ int for_all_proc_cpus(int (func)(int))
retval = func(cpu_num); retval = func(cpu_num);
if (retval) { if (retval) {
fclose(fp); fclose(fp);
return(retval); return (retval);
} }
} }
fclose(fp); fclose(fp);
...@@ -2922,9 +3011,7 @@ void set_max_cpu_num(void) ...@@ -2922,9 +3011,7 @@ void set_max_cpu_num(void)
base_cpu = sched_getcpu(); base_cpu = sched_getcpu();
if (base_cpu < 0) if (base_cpu < 0)
err(1, "cannot find calling cpu ID"); err(1, "cannot find calling cpu ID");
sprintf(pathname, sprintf(pathname, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", base_cpu);
"/sys/devices/system/cpu/cpu%d/topology/thread_siblings",
base_cpu);
filep = fopen_or_die(pathname, "r"); filep = fopen_or_die(pathname, "r");
topo.max_cpu_num = 0; topo.max_cpu_num = 0;
...@@ -2943,6 +3030,7 @@ int count_cpus(int cpu) ...@@ -2943,6 +3030,7 @@ int count_cpus(int cpu)
topo.num_cpus++; topo.num_cpus++;
return 0; return 0;
} }
int mark_cpu_present(int cpu) int mark_cpu_present(int cpu)
{ {
CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set); CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
...@@ -3012,12 +3100,12 @@ int snapshot_proc_interrupts(void) ...@@ -3012,12 +3100,12 @@ int snapshot_proc_interrupts(void)
} }
while (getc(fp) != '\n') while (getc(fp) != '\n') ; /* flush interrupt description */
; /* flush interrupt description */
} }
return 0; return 0;
} }
/* /*
* snapshot_gfx_rc6_ms() * snapshot_gfx_rc6_ms()
* *
...@@ -3041,6 +3129,7 @@ int snapshot_gfx_rc6_ms(void) ...@@ -3041,6 +3129,7 @@ int snapshot_gfx_rc6_ms(void)
return 0; return 0;
} }
/* /*
* snapshot_gfx_mhz() * snapshot_gfx_mhz()
* *
...@@ -3120,6 +3209,7 @@ int snapshot_cpu_lpi_us(void) ...@@ -3120,6 +3209,7 @@ int snapshot_cpu_lpi_us(void)
return 0; return 0;
} }
/* /*
* snapshot_sys_lpi() * snapshot_sys_lpi()
* *
...@@ -3143,6 +3233,7 @@ int snapshot_sys_lpi_us(void) ...@@ -3143,6 +3233,7 @@ int snapshot_sys_lpi_us(void)
return 0; return 0;
} }
/* /*
* snapshot /proc and /sys files * snapshot /proc and /sys files
* *
...@@ -3174,7 +3265,7 @@ int snapshot_proc_sysfs_files(void) ...@@ -3174,7 +3265,7 @@ int snapshot_proc_sysfs_files(void)
int exit_requested; int exit_requested;
static void signal_handler (int signal) static void signal_handler(int signal)
{ {
switch (signal) { switch (signal) {
case SIGINT: case SIGINT:
...@@ -3272,7 +3363,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg ...@@ -3272,7 +3363,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg
for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) { for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) {
unsigned long long msr_cur, msr_last; unsigned long long msr_cur, msr_last;
int offset; off_t offset;
if (!idx_valid(i)) if (!idx_valid(i))
continue; continue;
...@@ -3281,7 +3372,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg ...@@ -3281,7 +3372,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg
continue; continue;
ret = get_msr(cpu, offset, &msr_cur); ret = get_msr(cpu, offset, &msr_cur);
if (ret) { if (ret) {
fprintf(outf, "Can not update msr(0x%x)\n", offset); fprintf(outf, "Can not update msr(0x%llx)\n", (unsigned long long)offset);
continue; continue;
} }
...@@ -3294,8 +3385,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg ...@@ -3294,8 +3385,7 @@ static int update_msr_sum(struct thread_data *t, struct core_data *c, struct pkg
return 0; return 0;
} }
static void static void msr_record_handler(union sigval v)
msr_record_handler(union sigval v)
{ {
for_all_cpus(update_msr_sum, EVEN_COUNTERS); for_all_cpus(update_msr_sum, EVEN_COUNTERS);
} }
...@@ -3340,12 +3430,38 @@ void msr_sum_record(void) ...@@ -3340,12 +3430,38 @@ void msr_sum_record(void)
} }
return; return;
release_timer: release_timer:
timer_delete(timerid); timer_delete(timerid);
release_msr: release_msr:
free(per_cpu_msr_sum); free(per_cpu_msr_sum);
} }
/*
* set_my_sched_priority(pri)
* return previous
*/
int set_my_sched_priority(int priority)
{
int retval;
int original_priority;
errno = 0;
original_priority = getpriority(PRIO_PROCESS, 0);
if (errno && (original_priority == -1))
err(errno, "getpriority");
retval = setpriority(PRIO_PROCESS, 0, priority);
if (retval)
err(retval, "setpriority(%d)", priority);
errno = 0;
retval = getpriority(PRIO_PROCESS, 0);
if (retval != priority)
err(-1, "getpriority(%d) != setpriority(%d)", retval, priority);
return original_priority;
}
void turbostat_loop() void turbostat_loop()
{ {
int retval; int retval;
...@@ -3354,6 +3470,11 @@ void turbostat_loop() ...@@ -3354,6 +3470,11 @@ void turbostat_loop()
setup_signal_handler(); setup_signal_handler();
/*
* elevate own priority for interval mode
*/
set_my_sched_priority(-20);
restart: restart:
restarted++; restarted++;
...@@ -3456,8 +3577,7 @@ int check_for_cap_sys_rawio(void) ...@@ -3456,8 +3577,7 @@ int check_for_cap_sys_rawio(void)
err(-6, "cap_get\n"); err(-6, "cap_get\n");
if (cap_flag_value != CAP_SET) { if (cap_flag_value != CAP_SET) {
warnx("capget(CAP_SYS_RAWIO) failed," warnx("capget(CAP_SYS_RAWIO) failed," " try \"# setcap cap_sys_rawio=ep %s\"", progname);
" try \"# setcap cap_sys_rawio=ep %s\"", progname);
return 1; return 1;
} }
...@@ -3466,6 +3586,7 @@ int check_for_cap_sys_rawio(void) ...@@ -3466,6 +3586,7 @@ int check_for_cap_sys_rawio(void)
return 0; return 0;
} }
void check_permissions(void) void check_permissions(void)
{ {
int do_exit = 0; int do_exit = 0;
...@@ -3551,6 +3672,10 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) ...@@ -3551,6 +3672,10 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
pkg_cstate_limits = skx_pkg_cstate_limits; pkg_cstate_limits = skx_pkg_cstate_limits;
has_misc_feature_control = 1; has_misc_feature_control = 1;
break; break;
case INTEL_FAM6_ICELAKE_X: /* ICX */
pkg_cstate_limits = icx_pkg_cstate_limits;
has_misc_feature_control = 1;
break;
case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */ case INTEL_FAM6_ATOM_SILVERMONT: /* BYT */
no_MSR_MISC_PWR_MGMT = 1; no_MSR_MISC_PWR_MGMT = 1;
case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */ case INTEL_FAM6_ATOM_SILVERMONT_D: /* AVN */
...@@ -3583,6 +3708,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) ...@@ -3583,6 +3708,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
has_base_hz = 1; has_base_hz = 1;
return 1; return 1;
} }
/* /*
* SLV client has support for unique MSRs: * SLV client has support for unique MSRs:
* *
...@@ -3603,6 +3729,7 @@ int has_slv_msrs(unsigned int family, unsigned int model) ...@@ -3603,6 +3729,7 @@ int has_slv_msrs(unsigned int family, unsigned int model)
} }
return 0; return 0;
} }
int is_dnv(unsigned int family, unsigned int model) int is_dnv(unsigned int family, unsigned int model)
{ {
...@@ -3615,6 +3742,7 @@ int is_dnv(unsigned int family, unsigned int model) ...@@ -3615,6 +3742,7 @@ int is_dnv(unsigned int family, unsigned int model)
} }
return 0; return 0;
} }
int is_bdx(unsigned int family, unsigned int model) int is_bdx(unsigned int family, unsigned int model)
{ {
...@@ -3627,6 +3755,7 @@ int is_bdx(unsigned int family, unsigned int model) ...@@ -3627,6 +3755,7 @@ int is_bdx(unsigned int family, unsigned int model)
} }
return 0; return 0;
} }
int is_skx(unsigned int family, unsigned int model) int is_skx(unsigned int family, unsigned int model)
{ {
...@@ -3639,6 +3768,20 @@ int is_skx(unsigned int family, unsigned int model) ...@@ -3639,6 +3768,20 @@ int is_skx(unsigned int family, unsigned int model)
} }
return 0; return 0;
} }
int is_icx(unsigned int family, unsigned int model)
{
if (!genuine_intel)
return 0;
switch (model) {
case INTEL_FAM6_ICELAKE_X:
return 1;
}
return 0;
}
int is_ehl(unsigned int family, unsigned int model) int is_ehl(unsigned int family, unsigned int model)
{ {
if (!genuine_intel) if (!genuine_intel)
...@@ -3650,6 +3793,7 @@ int is_ehl(unsigned int family, unsigned int model) ...@@ -3650,6 +3793,7 @@ int is_ehl(unsigned int family, unsigned int model)
} }
return 0; return 0;
} }
int is_jvl(unsigned int family, unsigned int model) int is_jvl(unsigned int family, unsigned int model)
{ {
if (!genuine_intel) if (!genuine_intel)
...@@ -3676,6 +3820,7 @@ int has_turbo_ratio_limit(unsigned int family, unsigned int model) ...@@ -3676,6 +3820,7 @@ int has_turbo_ratio_limit(unsigned int family, unsigned int model)
return 1; return 1;
} }
} }
int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model) int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
{ {
if (has_slv_msrs(family, model)) if (has_slv_msrs(family, model))
...@@ -3683,6 +3828,7 @@ int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model) ...@@ -3683,6 +3828,7 @@ int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
return 0; return 0;
} }
int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
{ {
if (!genuine_intel) if (!genuine_intel)
...@@ -3699,6 +3845,7 @@ int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) ...@@ -3699,6 +3845,7 @@ int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
return 0; return 0;
} }
} }
int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model) int has_hsw_turbo_ratio_limit(unsigned int family, unsigned int model)
{ {
if (!genuine_intel) if (!genuine_intel)
...@@ -3730,6 +3877,7 @@ int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model) ...@@ -3730,6 +3877,7 @@ int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
return 0; return 0;
} }
} }
int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model) int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
{ {
if (!genuine_intel) if (!genuine_intel)
...@@ -3741,11 +3889,13 @@ int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model) ...@@ -3741,11 +3889,13 @@ int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
switch (model) { switch (model) {
case INTEL_FAM6_ATOM_GOLDMONT: case INTEL_FAM6_ATOM_GOLDMONT:
case INTEL_FAM6_SKYLAKE_X: case INTEL_FAM6_SKYLAKE_X:
case INTEL_FAM6_ICELAKE_X:
return 1; return 1;
default: default:
return 0; return 0;
} }
} }
int has_config_tdp(unsigned int family, unsigned int model) int has_config_tdp(unsigned int family, unsigned int model)
{ {
if (!genuine_intel) if (!genuine_intel)
...@@ -3766,6 +3916,7 @@ int has_config_tdp(unsigned int family, unsigned int model) ...@@ -3766,6 +3916,7 @@ int has_config_tdp(unsigned int family, unsigned int model)
case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_SKYLAKE_L: /* SKL */
case INTEL_FAM6_CANNONLAKE_L: /* CNL */ case INTEL_FAM6_CANNONLAKE_L: /* CNL */
case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_SKYLAKE_X: /* SKX */
case INTEL_FAM6_ICELAKE_X: /* ICX */
case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */
return 1; return 1;
...@@ -3774,8 +3925,41 @@ int has_config_tdp(unsigned int family, unsigned int model) ...@@ -3774,8 +3925,41 @@ int has_config_tdp(unsigned int family, unsigned int model)
} }
} }
static void /*
remove_underbar(char *s) * tcc_offset_bits:
* 0: Tcc Offset not supported (Default)
* 6: Bit 29:24 of MSR_PLATFORM_INFO
* 4: Bit 27:24 of MSR_PLATFORM_INFO
*/
void check_tcc_offset(int model)
{
unsigned long long msr;
if (!genuine_intel)
return;
switch (model) {
case INTEL_FAM6_SKYLAKE_L:
case INTEL_FAM6_SKYLAKE:
case INTEL_FAM6_KABYLAKE_L:
case INTEL_FAM6_KABYLAKE:
case INTEL_FAM6_ICELAKE_L:
case INTEL_FAM6_ICELAKE:
case INTEL_FAM6_TIGERLAKE_L:
case INTEL_FAM6_TIGERLAKE:
case INTEL_FAM6_COMETLAKE:
if (!get_msr(base_cpu, MSR_PLATFORM_INFO, &msr)) {
msr = (msr >> 30) & 1;
if (msr)
tcc_offset_bits = 6;
}
return;
default:
return;
}
}
static void remove_underbar(char *s)
{ {
char *to = s; char *to = s;
...@@ -3788,8 +3972,7 @@ remove_underbar(char *s) ...@@ -3788,8 +3972,7 @@ remove_underbar(char *s)
*to = 0; *to = 0;
} }
static void static void dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
{ {
if (!do_nhm_platform_info) if (!do_nhm_platform_info)
return; return;
...@@ -3834,8 +4017,8 @@ static void dump_sysfs_file(char *path) ...@@ -3834,8 +4017,8 @@ static void dump_sysfs_file(char *path)
fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf); fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf);
} }
static void
dump_sysfs_cstate_config(void) static void dump_sysfs_cstate_config(void)
{ {
char path[64]; char path[64];
char name_buf[16]; char name_buf[16];
...@@ -3855,8 +4038,7 @@ dump_sysfs_cstate_config(void) ...@@ -3855,8 +4038,7 @@ dump_sysfs_cstate_config(void)
for (state = 0; state < 10; ++state) { for (state = 0; state < 10; ++state) {
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
base_cpu, state);
input = fopen(path, "r"); input = fopen(path, "r");
if (input == NULL) if (input == NULL)
continue; continue;
...@@ -3872,8 +4054,7 @@ dump_sysfs_cstate_config(void) ...@@ -3872,8 +4054,7 @@ dump_sysfs_cstate_config(void)
remove_underbar(name_buf); remove_underbar(name_buf);
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", base_cpu, state);
base_cpu, state);
input = fopen(path, "r"); input = fopen(path, "r");
if (input == NULL) if (input == NULL)
continue; continue;
...@@ -3884,8 +4065,8 @@ dump_sysfs_cstate_config(void) ...@@ -3884,8 +4065,8 @@ dump_sysfs_cstate_config(void)
fclose(input); fclose(input);
} }
} }
static void
dump_sysfs_pstate_config(void) static void dump_sysfs_pstate_config(void)
{ {
char path[64]; char path[64];
char driver_buf[64]; char driver_buf[64];
...@@ -3893,8 +4074,7 @@ dump_sysfs_pstate_config(void) ...@@ -3893,8 +4074,7 @@ dump_sysfs_pstate_config(void)
FILE *input; FILE *input;
int turbo; int turbo;
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver", sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver", base_cpu);
base_cpu);
input = fopen(path, "r"); input = fopen(path, "r");
if (input == NULL) { if (input == NULL) {
fprintf(outf, "NSFOD %s\n", path); fprintf(outf, "NSFOD %s\n", path);
...@@ -3904,8 +4084,7 @@ dump_sysfs_pstate_config(void) ...@@ -3904,8 +4084,7 @@ dump_sysfs_pstate_config(void)
err(1, "%s: failed to read file", path); err(1, "%s: failed to read file", path);
fclose(input); fclose(input);
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", base_cpu);
base_cpu);
input = fopen(path, "r"); input = fopen(path, "r");
if (input == NULL) { if (input == NULL) {
fprintf(outf, "NSFOD %s\n", path); fprintf(outf, "NSFOD %s\n", path);
...@@ -3937,7 +4116,6 @@ dump_sysfs_pstate_config(void) ...@@ -3937,7 +4116,6 @@ dump_sysfs_pstate_config(void)
} }
} }
/* /*
* print_epb() * print_epb()
* Decode the ENERGY_PERF_BIAS MSR * Decode the ENERGY_PERF_BIAS MSR
...@@ -3983,6 +4161,7 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -3983,6 +4161,7 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return 0; return 0;
} }
/* /*
* print_hwp() * print_hwp()
* Decode the MSR_HWP_CAPABILITIES * Decode the MSR_HWP_CAPABILITIES
...@@ -4009,8 +4188,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4009,8 +4188,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (get_msr(cpu, MSR_PM_ENABLE, &msr)) if (get_msr(cpu, MSR_PM_ENABLE, &msr))
return 0; return 0;
fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n", fprintf(outf, "cpu%d: MSR_PM_ENABLE: 0x%08llx (%sHWP)\n", cpu, msr, (msr & (1 << 0)) ? "" : "No-");
cpu, msr, (msr & (1 << 0)) ? "" : "No-");
/* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */ /* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
if ((msr & (1 << 0)) == 0) if ((msr & (1 << 0)) == 0)
...@@ -4024,8 +4202,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4024,8 +4202,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
cpu, msr, cpu, msr,
(unsigned int)HWP_HIGHEST_PERF(msr), (unsigned int)HWP_HIGHEST_PERF(msr),
(unsigned int)HWP_GUARANTEED_PERF(msr), (unsigned int)HWP_GUARANTEED_PERF(msr),
(unsigned int)HWP_MOSTEFFICIENT_PERF(msr), (unsigned int)HWP_MOSTEFFICIENT_PERF(msr), (unsigned int)HWP_LOWEST_PERF(msr));
(unsigned int)HWP_LOWEST_PERF(msr));
if (get_msr(cpu, MSR_HWP_REQUEST, &msr)) if (get_msr(cpu, MSR_HWP_REQUEST, &msr))
return 0; return 0;
...@@ -4037,8 +4214,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4037,8 +4214,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
(unsigned int)(((msr) >> 8) & 0xff), (unsigned int)(((msr) >> 8) & 0xff),
(unsigned int)(((msr) >> 16) & 0xff), (unsigned int)(((msr) >> 16) & 0xff),
(unsigned int)(((msr) >> 24) & 0xff), (unsigned int)(((msr) >> 24) & 0xff),
(unsigned int)(((msr) >> 32) & 0xff3), (unsigned int)(((msr) >> 32) & 0xff3), (unsigned int)(((msr) >> 42) & 0x1));
(unsigned int)(((msr) >> 42) & 0x1));
if (has_hwp_pkg) { if (has_hwp_pkg) {
if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr)) if (get_msr(cpu, MSR_HWP_REQUEST_PKG, &msr))
...@@ -4050,8 +4226,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4050,8 +4226,7 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
(unsigned int)(((msr) >> 0) & 0xff), (unsigned int)(((msr) >> 0) & 0xff),
(unsigned int)(((msr) >> 8) & 0xff), (unsigned int)(((msr) >> 8) & 0xff),
(unsigned int)(((msr) >> 16) & 0xff), (unsigned int)(((msr) >> 16) & 0xff),
(unsigned int)(((msr) >> 24) & 0xff), (unsigned int)(((msr) >> 24) & 0xff), (unsigned int)(((msr) >> 32) & 0xff3));
(unsigned int)(((msr) >> 32) & 0xff3));
} }
if (has_hwp_notify) { if (has_hwp_notify) {
if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr)) if (get_msr(cpu, MSR_HWP_INTERRUPT, &msr))
...@@ -4059,18 +4234,14 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4059,18 +4234,14 @@ int print_hwp(struct thread_data *t, struct core_data *c, struct pkg_data *p)
fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx " fprintf(outf, "cpu%d: MSR_HWP_INTERRUPT: 0x%08llx "
"(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n", "(%s_Guaranteed_Perf_Change, %s_Excursion_Min)\n",
cpu, msr, cpu, msr, ((msr) & 0x1) ? "EN" : "Dis", ((msr) & 0x2) ? "EN" : "Dis");
((msr) & 0x1) ? "EN" : "Dis",
((msr) & 0x2) ? "EN" : "Dis");
} }
if (get_msr(cpu, MSR_HWP_STATUS, &msr)) if (get_msr(cpu, MSR_HWP_STATUS, &msr))
return 0; return 0;
fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx " fprintf(outf, "cpu%d: MSR_HWP_STATUS: 0x%08llx "
"(%sGuaranteed_Perf_Change, %sExcursion_Min)\n", "(%sGuaranteed_Perf_Change, %sExcursion_Min)\n",
cpu, msr, cpu, msr, ((msr) & 0x1) ? "" : "No-", ((msr) & 0x2) ? "" : "No-");
((msr) & 0x1) ? "" : "No-",
((msr) & 0x2) ? "" : "No-");
return 0; return 0;
} }
...@@ -4110,8 +4281,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -4110,8 +4281,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data
(msr & 1 << 5) ? "Auto-HWP, " : "", (msr & 1 << 5) ? "Auto-HWP, " : "",
(msr & 1 << 4) ? "Graphics, " : "", (msr & 1 << 4) ? "Graphics, " : "",
(msr & 1 << 2) ? "bit2, " : "", (msr & 1 << 2) ? "bit2, " : "",
(msr & 1 << 1) ? "ThermStatus, " : "", (msr & 1 << 1) ? "ThermStatus, " : "", (msr & 1 << 0) ? "PROCHOT, " : "");
(msr & 1 << 0) ? "PROCHOT, " : "");
fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
(msr & 1 << 31) ? "bit31, " : "", (msr & 1 << 31) ? "bit31, " : "",
(msr & 1 << 30) ? "bit30, " : "", (msr & 1 << 30) ? "bit30, " : "",
...@@ -4125,8 +4295,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -4125,8 +4295,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data
(msr & 1 << 21) ? "Auto-HWP, " : "", (msr & 1 << 21) ? "Auto-HWP, " : "",
(msr & 1 << 20) ? "Graphics, " : "", (msr & 1 << 20) ? "Graphics, " : "",
(msr & 1 << 18) ? "bit18, " : "", (msr & 1 << 18) ? "bit18, " : "",
(msr & 1 << 17) ? "ThermStatus, " : "", (msr & 1 << 17) ? "ThermStatus, " : "", (msr & 1 << 16) ? "PROCHOT, " : "");
(msr & 1 << 16) ? "PROCHOT, " : "");
} }
if (do_gfx_perf_limit_reasons) { if (do_gfx_perf_limit_reasons) {
...@@ -4139,8 +4308,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -4139,8 +4308,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data
(msr & 1 << 6) ? "VR-Therm, " : "", (msr & 1 << 6) ? "VR-Therm, " : "",
(msr & 1 << 8) ? "Amps, " : "", (msr & 1 << 8) ? "Amps, " : "",
(msr & 1 << 9) ? "GFXPwr, " : "", (msr & 1 << 9) ? "GFXPwr, " : "",
(msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 11) ? "PkgPwrL2, " : "");
(msr & 1 << 11) ? "PkgPwrL2, " : "");
fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n", fprintf(outf, " (Logged: %s%s%s%s%s%s%s%s)\n",
(msr & 1 << 16) ? "PROCHOT, " : "", (msr & 1 << 16) ? "PROCHOT, " : "",
(msr & 1 << 17) ? "ThermStatus, " : "", (msr & 1 << 17) ? "ThermStatus, " : "",
...@@ -4148,8 +4316,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -4148,8 +4316,7 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data
(msr & 1 << 22) ? "VR-Therm, " : "", (msr & 1 << 22) ? "VR-Therm, " : "",
(msr & 1 << 24) ? "Amps, " : "", (msr & 1 << 24) ? "Amps, " : "",
(msr & 1 << 25) ? "GFXPwr, " : "", (msr & 1 << 25) ? "GFXPwr, " : "",
(msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 27) ? "PkgPwrL2, " : "");
(msr & 1 << 27) ? "PkgPwrL2, " : "");
} }
if (do_ring_perf_limit_reasons) { if (do_ring_perf_limit_reasons) {
get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr); get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
...@@ -4159,15 +4326,13 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data ...@@ -4159,15 +4326,13 @@ int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data
(msr & 1 << 1) ? "ThermStatus, " : "", (msr & 1 << 1) ? "ThermStatus, " : "",
(msr & 1 << 6) ? "VR-Therm, " : "", (msr & 1 << 6) ? "VR-Therm, " : "",
(msr & 1 << 8) ? "Amps, " : "", (msr & 1 << 8) ? "Amps, " : "",
(msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 10) ? "PkgPwrL1, " : "", (msr & 1 << 11) ? "PkgPwrL2, " : "");
(msr & 1 << 11) ? "PkgPwrL2, " : "");
fprintf(outf, " (Logged: %s%s%s%s%s%s)\n", fprintf(outf, " (Logged: %s%s%s%s%s%s)\n",
(msr & 1 << 16) ? "PROCHOT, " : "", (msr & 1 << 16) ? "PROCHOT, " : "",
(msr & 1 << 17) ? "ThermStatus, " : "", (msr & 1 << 17) ? "ThermStatus, " : "",
(msr & 1 << 22) ? "VR-Therm, " : "", (msr & 1 << 22) ? "VR-Therm, " : "",
(msr & 1 << 24) ? "Amps, " : "", (msr & 1 << 24) ? "Amps, " : "",
(msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 26) ? "PkgPwrL1, " : "", (msr & 1 << 27) ? "PkgPwrL2, " : "");
(msr & 1 << 27) ? "PkgPwrL2, " : "");
} }
return 0; return 0;
} }
...@@ -4202,14 +4367,14 @@ double get_tdp_amd(unsigned int family) ...@@ -4202,14 +4367,14 @@ double get_tdp_amd(unsigned int family)
* rapl_dram_energy_units_probe() * rapl_dram_energy_units_probe()
* Energy units are either hard-coded, or come from RAPL Energy Unit MSR. * Energy units are either hard-coded, or come from RAPL Energy Unit MSR.
*/ */
static double static double rapl_dram_energy_units_probe(int model, double rapl_energy_units)
rapl_dram_energy_units_probe(int model, double rapl_energy_units)
{ {
/* only called for genuine_intel, family 6 */ /* only called for genuine_intel, family 6 */
switch (model) { switch (model) {
case INTEL_FAM6_HASWELL_X: /* HSX */ case INTEL_FAM6_HASWELL_X: /* HSX */
case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_BROADWELL_X: /* BDX */
case INTEL_FAM6_SKYLAKE_X: /* SKX */
case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
return (rapl_dram_energy_units = 15.3 / 1000000); return (rapl_dram_energy_units = 15.3 / 1000000);
default: default:
...@@ -4254,7 +4419,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model) ...@@ -4254,7 +4419,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
BIC_PRESENT(BIC_PkgWatt); BIC_PRESENT(BIC_PkgWatt);
break; break;
case INTEL_FAM6_ATOM_TREMONT: /* EHL */ case INTEL_FAM6_ATOM_TREMONT: /* EHL */
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; do_rapl =
RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS
| RAPL_GFX | RAPL_PKG_POWER_INFO;
if (rapl_joules) { if (rapl_joules) {
BIC_PRESENT(BIC_Pkg_J); BIC_PRESENT(BIC_Pkg_J);
BIC_PRESENT(BIC_Cor_J); BIC_PRESENT(BIC_Cor_J);
...@@ -4277,7 +4444,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model) ...@@ -4277,7 +4444,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
break; break;
case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_SKYLAKE_L: /* SKL */
case INTEL_FAM6_CANNONLAKE_L: /* CNL */ case INTEL_FAM6_CANNONLAKE_L: /* CNL */
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; do_rapl =
RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS
| RAPL_GFX | RAPL_PKG_POWER_INFO;
BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_PKG__);
BIC_PRESENT(BIC_RAM__); BIC_PRESENT(BIC_RAM__);
if (rapl_joules) { if (rapl_joules) {
...@@ -4295,8 +4464,11 @@ void rapl_probe_intel(unsigned int family, unsigned int model) ...@@ -4295,8 +4464,11 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
case INTEL_FAM6_HASWELL_X: /* HSX */ case INTEL_FAM6_HASWELL_X: /* HSX */
case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_BROADWELL_X: /* BDX */
case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_SKYLAKE_X: /* SKX */
case INTEL_FAM6_ICELAKE_X: /* ICX */
case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; do_rapl =
RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS |
RAPL_PKG_POWER_INFO;
BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_PKG__);
BIC_PRESENT(BIC_RAM__); BIC_PRESENT(BIC_RAM__);
if (rapl_joules) { if (rapl_joules) {
...@@ -4309,7 +4481,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model) ...@@ -4309,7 +4481,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
break; break;
case INTEL_FAM6_SANDYBRIDGE_X: case INTEL_FAM6_SANDYBRIDGE_X:
case INTEL_FAM6_IVYBRIDGE_X: case INTEL_FAM6_IVYBRIDGE_X:
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; 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;
BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_PKG__);
BIC_PRESENT(BIC_RAM__); BIC_PRESENT(BIC_RAM__);
if (rapl_joules) { if (rapl_joules) {
...@@ -4334,7 +4508,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model) ...@@ -4334,7 +4508,9 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
} }
break; break;
case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */
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; 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;
BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_PKG__);
BIC_PRESENT(BIC_RAM__); BIC_PRESENT(BIC_RAM__);
if (rapl_joules) { if (rapl_joules) {
...@@ -4451,10 +4627,16 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) ...@@ -4451,10 +4627,16 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model)
void automatic_cstate_conversion_probe(unsigned int family, unsigned int model) void automatic_cstate_conversion_probe(unsigned int family, unsigned int model)
{ {
if (is_skx(family, model) || is_bdx(family, model)) if (is_skx(family, model) || is_bdx(family, model) || is_icx(family, model))
has_automatic_cstate_conversion = 1; has_automatic_cstate_conversion = 1;
} }
void prewake_cstate_probe(unsigned int family, unsigned int model)
{
if (is_icx(family, model))
dis_cstate_prewake = 1;
}
int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p) int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{ {
unsigned long long msr; unsigned long long msr;
...@@ -4480,8 +4662,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p ...@@ -4480,8 +4662,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
return 0; return 0;
dts = (msr >> 16) & 0x7F; dts = (msr >> 16) & 0x7F;
fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n", fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_STATUS: 0x%08llx (%d C)\n", cpu, msr, tj_max - dts);
cpu, msr, tcc_activation_temp - dts);
if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr)) if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &msr))
return 0; return 0;
...@@ -4489,10 +4670,9 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p ...@@ -4489,10 +4670,9 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
dts = (msr >> 16) & 0x7F; dts = (msr >> 16) & 0x7F;
dts2 = (msr >> 8) & 0x7F; dts2 = (msr >> 8) & 0x7F;
fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n", fprintf(outf, "cpu%d: MSR_IA32_PACKAGE_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2); cpu, msr, tj_max - dts, tj_max - dts2);
} }
if (do_dts && debug) { if (do_dts && debug) {
unsigned int resolution; unsigned int resolution;
...@@ -4502,7 +4682,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p ...@@ -4502,7 +4682,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
dts = (msr >> 16) & 0x7F; dts = (msr >> 16) & 0x7F;
resolution = (msr >> 27) & 0xF; resolution = (msr >> 27) & 0xF;
fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n", fprintf(outf, "cpu%d: MSR_IA32_THERM_STATUS: 0x%08llx (%d C +/- %d)\n",
cpu, msr, tcc_activation_temp - dts, resolution); cpu, msr, tj_max - dts, resolution);
if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr)) if (get_msr(cpu, MSR_IA32_THERM_INTERRUPT, &msr))
return 0; return 0;
...@@ -4510,7 +4690,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p ...@@ -4510,7 +4690,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p
dts = (msr >> 16) & 0x7F; dts = (msr >> 16) & 0x7F;
dts2 = (msr >> 8) & 0x7F; dts2 = (msr >> 8) & 0x7F;
fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n", fprintf(outf, "cpu%d: MSR_IA32_THERM_INTERRUPT: 0x%08llx (%d C, %d C)\n",
cpu, msr, tcc_activation_temp - dts, tcc_activation_temp - dts2); cpu, msr, tj_max - dts, tj_max - dts2);
} }
return 0; return 0;
...@@ -4522,7 +4702,7 @@ void print_power_limit_msr(int cpu, unsigned long long msr, char *label) ...@@ -4522,7 +4702,7 @@ void print_power_limit_msr(int cpu, unsigned long long msr, char *label)
cpu, label, cpu, label,
((msr >> 15) & 1) ? "EN" : "DIS", ((msr >> 15) & 1) ? "EN" : "DIS",
((msr >> 0) & 0x7FFF) * rapl_power_units, ((msr >> 0) & 0x7FFF) * rapl_power_units,
(1.0 + (((msr >> 22) & 0x3)/4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units, (1.0 + (((msr >> 22) & 0x3) / 4.0)) * (1 << ((msr >> 17) & 0x1F)) * rapl_time_units,
(((msr >> 16) & 1) ? "EN" : "DIS")); (((msr >> 16) & 1) ? "EN" : "DIS"));
return; return;
...@@ -4565,7 +4745,6 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4565,7 +4745,6 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
return -5; return -5;
fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n", fprintf(outf, "cpu%d: MSR_PKG_POWER_INFO: 0x%08llx (%.0f W TDP, RAPL %.0f - %.0f W, %f sec.)\n",
cpu, msr, cpu, msr,
((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units, ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units,
...@@ -4587,7 +4766,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -4587,7 +4766,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
cpu, cpu,
((msr >> 47) & 1) ? "EN" : "DIS", ((msr >> 47) & 1) ? "EN" : "DIS",
((msr >> 32) & 0x7FFF) * rapl_power_units, ((msr >> 32) & 0x7FFF) * rapl_power_units,
(1.0 + (((msr >> 54) & 0x3)/4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units, (1.0 + (((msr >> 54) & 0x3) / 4.0)) * (1 << ((msr >> 49) & 0x1F)) * rapl_time_units,
((msr >> 48) & 1) ? "EN" : "DIS"); ((msr >> 48) & 1) ? "EN" : "DIS");
} }
...@@ -4666,6 +4845,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) ...@@ -4666,6 +4845,7 @@ int has_snb_msrs(unsigned int family, unsigned int model)
case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_SKYLAKE_L: /* SKL */
case INTEL_FAM6_CANNONLAKE_L: /* CNL */ case INTEL_FAM6_CANNONLAKE_L: /* CNL */
case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_SKYLAKE_X: /* SKX */
case INTEL_FAM6_ICELAKE_X: /* ICX */
case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
case INTEL_FAM6_ATOM_GOLDMONT_PLUS: case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */
...@@ -4771,7 +4951,7 @@ unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model) ...@@ -4771,7 +4951,7 @@ unsigned int get_aperf_mperf_multiplier(unsigned int family, unsigned int model)
} }
#define SLM_BCLK_FREQS 5 #define SLM_BCLK_FREQS 5
double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0}; double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0 };
double slm_bclk(void) double slm_bclk(void)
{ {
...@@ -4805,6 +4985,28 @@ double discover_bclk(unsigned int family, unsigned int model) ...@@ -4805,6 +4985,28 @@ double discover_bclk(unsigned int family, unsigned int model)
return 133.33; return 133.33;
} }
int get_cpu_type(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{
unsigned int eax, ebx, ecx, edx;
if (!genuine_intel)
return 0;
if (cpu_migrate(t->cpu_id)) {
fprintf(outf, "Could not migrate to CPU %d\n", t->cpu_id);
return -1;
}
if (max_level < 0x1a)
return 0;
__cpuid(0x1a, eax, ebx, ecx, edx);
eax = (eax >> 24) & 0xFF;
if (eax == 0x20)
t->is_atom = true;
return 0;
}
/* /*
* MSR_IA32_TEMPERATURE_TARGET indicates the temperature where * MSR_IA32_TEMPERATURE_TARGET indicates the temperature where
* the Thermal Control Circuit (TCC) activates. * the Thermal Control Circuit (TCC) activates.
...@@ -4817,53 +5019,69 @@ double discover_bclk(unsigned int family, unsigned int model) ...@@ -4817,53 +5019,69 @@ double discover_bclk(unsigned int family, unsigned int model)
* below this value, including the Digital Thermal Sensor (DTS), * below this value, including the Digital Thermal Sensor (DTS),
* Package Thermal Management Sensor (PTM), and thermal event thresholds. * Package Thermal Management Sensor (PTM), and thermal event thresholds.
*/ */
int read_tcc_activation_temp() int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{ {
unsigned long long msr; unsigned long long msr;
unsigned int tcc, target_c, offset_c; unsigned int tcc_default, tcc_offset;
int cpu;
/* Temperature Target MSR is Nehalem and newer only */ /* tj_max is used only for dts or ptm */
if (!do_nhm_platform_info) if (!(do_dts || do_ptm))
return 0; return 0;
if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr)) /* this is a per-package concept */
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
return 0; return 0;
target_c = (msr >> 16) & 0xFF; cpu = t->cpu_id;
if (cpu_migrate(cpu)) {
fprintf(outf, "Could not migrate to CPU %d\n", cpu);
return -1;
}
offset_c = (msr >> 24) & 0xF; if (tj_max_override != 0) {
tj_max = tj_max_override;
fprintf(outf, "cpu%d: Using cmdline TCC Target (%d C)\n", cpu, tj_max);
return 0;
}
tcc = target_c - offset_c; /* Temperature Target MSR is Nehalem and newer only */
if (!do_nhm_platform_info)
goto guess;
if (!quiet) if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr))
fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C) (%d default - %d offset)\n", goto guess;
base_cpu, msr, tcc, target_c, offset_c);
return tcc; tcc_default = (msr >> 16) & 0xFF;
}
int set_temperature_target(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (!quiet) {
{ switch (tcc_offset_bits) {
/* tcc_activation_temp is used only for dts or ptm */ case 4:
if (!(do_dts || do_ptm)) tcc_offset = (msr >> 24) & 0xF;
return 0; fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C) (%d default - %d offset)\n",
cpu, msr, tcc_default - tcc_offset, tcc_default, tcc_offset);
break;
case 6:
tcc_offset = (msr >> 24) & 0x3F;
fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C) (%d default - %d offset)\n",
cpu, msr, tcc_default - tcc_offset, tcc_default, tcc_offset);
break;
default:
fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", cpu, msr, tcc_default);
break;
}
}
/* this is a per-package concept */ if (!tcc_default)
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) goto guess;
return 0;
if (tcc_activation_temp_override != 0) { tj_max = tcc_default;
tcc_activation_temp = tcc_activation_temp_override;
fprintf(outf, "Using cmdline TCC Target (%d C)\n", tcc_activation_temp);
return 0;
}
tcc_activation_temp = read_tcc_activation_temp();
if (tcc_activation_temp)
return 0; return 0;
tcc_activation_temp = TJMAX_DEFAULT; guess:
fprintf(outf, "Guessing tjMax %d C, Please use -T to specify\n", tcc_activation_temp); tj_max = TJMAX_DEFAULT;
fprintf(outf, "cpu%d: Guessing tjMax %d C, Please use -T to specify\n", cpu, tj_max);
return 0; return 0;
} }
...@@ -4874,9 +5092,7 @@ void decode_feature_control_msr(void) ...@@ -4874,9 +5092,7 @@ void decode_feature_control_msr(void)
if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr)) if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr))
fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n", fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n",
base_cpu, msr, base_cpu, msr, msr & FEAT_CTL_LOCKED ? "" : "UN-", msr & (1 << 18) ? "SGX" : "");
msr & FEAT_CTL_LOCKED ? "" : "UN-",
msr & (1 << 18) ? "SGX" : "");
} }
void decode_misc_enable_msr(void) void decode_misc_enable_msr(void)
...@@ -4904,13 +5120,12 @@ void decode_misc_feature_control(void) ...@@ -4904,13 +5120,12 @@ void decode_misc_feature_control(void)
return; return;
if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr)) if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n", fprintf(outf,
base_cpu, msr, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
msr & (0 << 0) ? "No-" : "", base_cpu, msr, msr & (0 << 0) ? "No-" : "", msr & (1 << 0) ? "No-" : "",
msr & (1 << 0) ? "No-" : "", msr & (2 << 0) ? "No-" : "", msr & (3 << 0) ? "No-" : "");
msr & (2 << 0) ? "No-" : "",
msr & (3 << 0) ? "No-" : "");
} }
/* /*
* Decode MSR_MISC_PWR_MGMT * Decode MSR_MISC_PWR_MGMT
* *
...@@ -4931,10 +5146,9 @@ void decode_misc_pwr_mgmt_msr(void) ...@@ -4931,10 +5146,9 @@ void decode_misc_pwr_mgmt_msr(void)
if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr)) if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n", fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
base_cpu, msr, base_cpu, msr,
msr & (1 << 0) ? "DIS" : "EN", msr & (1 << 0) ? "DIS" : "EN", msr & (1 << 1) ? "EN" : "DIS", msr & (1 << 8) ? "EN" : "DIS");
msr & (1 << 1) ? "EN" : "DIS",
msr & (1 << 8) ? "EN" : "DIS");
} }
/* /*
* Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
* *
...@@ -4960,7 +5174,7 @@ void decode_c6_demotion_policy_msr(void) ...@@ -4960,7 +5174,7 @@ void decode_c6_demotion_policy_msr(void)
unsigned int intel_model_duplicates(unsigned int model) unsigned int intel_model_duplicates(unsigned int model)
{ {
switch(model) { switch (model) {
case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
case 0x1F: /* Core i7 and i5 Processor - Nehalem */ case 0x1F: /* Core i7 and i5 Processor - Nehalem */
...@@ -4994,14 +5208,15 @@ unsigned int intel_model_duplicates(unsigned int model) ...@@ -4994,14 +5208,15 @@ unsigned int intel_model_duplicates(unsigned int model)
case INTEL_FAM6_ROCKETLAKE: case INTEL_FAM6_ROCKETLAKE:
case INTEL_FAM6_LAKEFIELD: case INTEL_FAM6_LAKEFIELD:
case INTEL_FAM6_ALDERLAKE: case INTEL_FAM6_ALDERLAKE:
case INTEL_FAM6_ALDERLAKE_L:
return INTEL_FAM6_CANNONLAKE_L; return INTEL_FAM6_CANNONLAKE_L;
case INTEL_FAM6_ATOM_TREMONT_L: case INTEL_FAM6_ATOM_TREMONT_L:
return INTEL_FAM6_ATOM_TREMONT; return INTEL_FAM6_ATOM_TREMONT;
case INTEL_FAM6_ICELAKE_X: case INTEL_FAM6_ICELAKE_D:
case INTEL_FAM6_SAPPHIRERAPIDS_X: case INTEL_FAM6_SAPPHIRERAPIDS_X:
return INTEL_FAM6_SKYLAKE_X; return INTEL_FAM6_ICELAKE_X;
} }
return model; return model;
} }
...@@ -5025,17 +5240,36 @@ void print_dev_latency(void) ...@@ -5025,17 +5240,36 @@ void print_dev_latency(void)
close(fd); close(fd);
return; return;
} }
fprintf(outf, "/dev/cpu_dma_latency: %d usec (%s)\n", fprintf(outf, "/dev/cpu_dma_latency: %d usec (%s)\n", value, value == 2000000000 ? "default" : "constrained");
value, value == 2000000000 ? "default" : "constrained");
close(fd); close(fd);
} }
/*
* Linux-perf manages the the HW instructions-retired counter
* by enabling when requested, and hiding rollover
*/
void linux_perf_init(void)
{
if (!BIC_IS_ENABLED(BIC_IPC))
return;
if (access("/proc/sys/kernel/perf_event_paranoid", F_OK))
return;
fd_instr_count_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
if (fd_instr_count_percpu == NULL)
err(-1, "calloc fd_instr_count_percpu");
BIC_PRESENT(BIC_IPC);
}
void process_cpuid() void process_cpuid()
{ {
unsigned int eax, ebx, ecx, edx; unsigned int eax, ebx, ecx, edx;
unsigned int fms, family, model, stepping, ecx_flags, edx_flags; unsigned int fms, family, model, stepping, ecx_flags, edx_flags;
unsigned int has_turbo; unsigned int has_turbo;
unsigned long long ucode_patch = 0;
eax = ebx = ecx = edx = 0; eax = ebx = ecx = edx = 0;
...@@ -5049,8 +5283,8 @@ void process_cpuid() ...@@ -5049,8 +5283,8 @@ void process_cpuid()
hygon_genuine = 1; hygon_genuine = 1;
if (!quiet) if (!quiet)
fprintf(outf, "CPUID(0): %.4s%.4s%.4s ", fprintf(outf, "CPUID(0): %.4s%.4s%.4s 0x%x CPUID levels\n",
(char *)&ebx, (char *)&edx, (char *)&ecx); (char *)&ebx, (char *)&edx, (char *)&ecx, max_level);
__cpuid(1, fms, ebx, ecx, edx); __cpuid(1, fms, ebx, ecx, edx);
family = (fms >> 8) & 0xf; family = (fms >> 8) & 0xf;
...@@ -5063,6 +5297,9 @@ void process_cpuid() ...@@ -5063,6 +5297,9 @@ void process_cpuid()
ecx_flags = ecx; ecx_flags = ecx;
edx_flags = edx; edx_flags = edx;
if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch))
warnx("get_msr(UCODE)\n");
/* /*
* check max extended function levels of CPUID. * check max extended function levels of CPUID.
* This is needed to check for invariant TSC. * This is needed to check for invariant TSC.
...@@ -5072,8 +5309,10 @@ void process_cpuid() ...@@ -5072,8 +5309,10 @@ void process_cpuid()
__cpuid(0x80000000, max_extended_level, ebx, ecx, edx); __cpuid(0x80000000, max_extended_level, ebx, ecx, edx);
if (!quiet) { if (!quiet) {
fprintf(outf, "0x%x CPUID levels; 0x%x xlevels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", fprintf(outf, "CPUID(1): family:model:stepping 0x%x:%x:%x (%d:%d:%d) microcode 0x%x\n",
max_level, max_extended_level, family, model, stepping, family, model, stepping); family, model, stepping, family, model, stepping,
(unsigned int)((ucode_patch >> 32) & 0xFFFFFFFF));
fprintf(outf, "CPUID(0x80000000): max_extended_levels: 0x%x\n", max_extended_level);
fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n", fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n",
ecx_flags & (1 << 0) ? "SSE3" : "-", ecx_flags & (1 << 0) ? "SSE3" : "-",
ecx_flags & (1 << 3) ? "MONITOR" : "-", ecx_flags & (1 << 3) ? "MONITOR" : "-",
...@@ -5083,11 +5322,12 @@ void process_cpuid() ...@@ -5083,11 +5322,12 @@ void process_cpuid()
edx_flags & (1 << 4) ? "TSC" : "-", edx_flags & (1 << 4) ? "TSC" : "-",
edx_flags & (1 << 5) ? "MSR" : "-", edx_flags & (1 << 5) ? "MSR" : "-",
edx_flags & (1 << 22) ? "ACPI-TM" : "-", edx_flags & (1 << 22) ? "ACPI-TM" : "-",
edx_flags & (1 << 28) ? "HT" : "-", edx_flags & (1 << 28) ? "HT" : "-", edx_flags & (1 << 29) ? "TM" : "-");
edx_flags & (1 << 29) ? "TM" : "-");
} }
if (genuine_intel) if (genuine_intel) {
model_orig = model;
model = intel_model_duplicates(model); model = intel_model_duplicates(model);
}
if (!(edx_flags & (1 << 5))) if (!(edx_flags & (1 << 5)))
errx(1, "CPUID: no MSR"); errx(1, "CPUID: no MSR");
...@@ -5138,14 +5378,11 @@ void process_cpuid() ...@@ -5138,14 +5378,11 @@ void process_cpuid()
has_hwp ? "" : "No-", has_hwp ? "" : "No-",
has_hwp_notify ? "" : "No-", has_hwp_notify ? "" : "No-",
has_hwp_activity_window ? "" : "No-", has_hwp_activity_window ? "" : "No-",
has_hwp_epp ? "" : "No-", has_hwp_epp ? "" : "No-", has_hwp_pkg ? "" : "No-", has_epb ? "" : "No-");
has_hwp_pkg ? "" : "No-",
has_epb ? "" : "No-");
if (!quiet) if (!quiet)
decode_misc_enable_msr(); decode_misc_enable_msr();
if (max_level >= 0x7 && !quiet) { if (max_level >= 0x7 && !quiet) {
int has_sgx; int has_sgx;
...@@ -5177,7 +5414,7 @@ void process_cpuid() ...@@ -5177,7 +5414,7 @@ void process_cpuid()
eax_crystal, ebx_tsc, crystal_hz); eax_crystal, ebx_tsc, crystal_hz);
if (crystal_hz == 0) if (crystal_hz == 0)
switch(model) { switch (model) {
case INTEL_FAM6_SKYLAKE_L: /* SKL */ case INTEL_FAM6_SKYLAKE_L: /* SKL */
crystal_hz = 24000000; /* 24.0 MHz */ crystal_hz = 24000000; /* 24.0 MHz */
break; break;
...@@ -5193,7 +5430,7 @@ void process_cpuid() ...@@ -5193,7 +5430,7 @@ void process_cpuid()
} }
if (crystal_hz) { if (crystal_hz) {
tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal; tsc_hz = (unsigned long long)crystal_hz *ebx_tsc / eax_crystal;
if (!quiet) if (!quiet)
fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n", fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal); tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
...@@ -5265,7 +5502,7 @@ void process_cpuid() ...@@ -5265,7 +5502,7 @@ void process_cpuid()
BIC_NOT_PRESENT(BIC_Pkgpc7); BIC_NOT_PRESENT(BIC_Pkgpc7);
use_c1_residency_msr = 1; use_c1_residency_msr = 1;
} }
if (is_skx(family, model)) { if (is_skx(family, model) || is_icx(family, model)) {
BIC_NOT_PRESENT(BIC_CPU_c3); BIC_NOT_PRESENT(BIC_CPU_c3);
BIC_NOT_PRESENT(BIC_Pkgpc3); BIC_NOT_PRESENT(BIC_Pkgpc3);
BIC_NOT_PRESENT(BIC_CPU_c7); BIC_NOT_PRESENT(BIC_CPU_c7);
...@@ -5293,8 +5530,7 @@ void process_cpuid() ...@@ -5293,8 +5530,7 @@ void process_cpuid()
do_slm_cstates = is_slm(family, model); do_slm_cstates = is_slm(family, model);
do_knl_cstates = is_knl(family, model); do_knl_cstates = is_knl(family, model);
if (do_slm_cstates || do_knl_cstates || is_cnl(family, model) || if (do_slm_cstates || do_knl_cstates || is_cnl(family, model) || is_ehl(family, model))
is_ehl(family, model))
BIC_NOT_PRESENT(BIC_CPU_c3); BIC_NOT_PRESENT(BIC_CPU_c3);
if (!quiet) if (!quiet)
...@@ -5307,6 +5543,8 @@ void process_cpuid() ...@@ -5307,6 +5543,8 @@ void process_cpuid()
perf_limit_reasons_probe(family, model); perf_limit_reasons_probe(family, model);
automatic_cstate_conversion_probe(family, model); automatic_cstate_conversion_probe(family, model);
check_tcc_offset(model_orig);
if (!quiet) if (!quiet)
dump_cstate_pstate_config_info(family, model); dump_cstate_pstate_config_info(family, model);
...@@ -5317,7 +5555,7 @@ void process_cpuid() ...@@ -5317,7 +5555,7 @@ void process_cpuid()
if (!quiet) if (!quiet)
dump_sysfs_pstate_config(); dump_sysfs_pstate_config();
if (has_skl_msrs(family, model)) if (has_skl_msrs(family, model) || is_ehl(family, model))
calculate_tsc_tweak(); calculate_tsc_tweak();
if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK)) if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
...@@ -5465,22 +5703,19 @@ void topology_probe() ...@@ -5465,22 +5703,19 @@ void topology_probe()
topo.cores_per_node = max_core_id + 1; topo.cores_per_node = max_core_id + 1;
if (debug > 1) if (debug > 1)
fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node);
max_core_id, topo.cores_per_node);
if (!summary_only && topo.cores_per_node > 1) if (!summary_only && topo.cores_per_node > 1)
BIC_PRESENT(BIC_Core); BIC_PRESENT(BIC_Core);
topo.num_die = max_die_id + 1; topo.num_die = max_die_id + 1;
if (debug > 1) if (debug > 1)
fprintf(outf, "max_die_id %d, sizing for %d die\n", fprintf(outf, "max_die_id %d, sizing for %d die\n", max_die_id, topo.num_die);
max_die_id, topo.num_die);
if (!summary_only && topo.num_die > 1) if (!summary_only && topo.num_die > 1)
BIC_PRESENT(BIC_Die); BIC_PRESENT(BIC_Die);
topo.num_packages = max_package_id + 1; topo.num_packages = max_package_id + 1;
if (debug > 1) if (debug > 1)
fprintf(outf, "max_package_id %d, sizing for %d packages\n", fprintf(outf, "max_package_id %d, sizing for %d packages\n", max_package_id, topo.num_packages);
max_package_id, topo.num_packages);
if (!summary_only && topo.num_packages > 1) if (!summary_only && topo.num_packages > 1)
BIC_PRESENT(BIC_Package); BIC_PRESENT(BIC_Package);
...@@ -5503,21 +5738,15 @@ void topology_probe() ...@@ -5503,21 +5738,15 @@ void topology_probe()
fprintf(outf, fprintf(outf,
"cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n", "cpu %d pkg %d die %d node %d lnode %d core %d thread %d\n",
i, cpus[i].physical_package_id, cpus[i].die_id, i, cpus[i].physical_package_id, cpus[i].die_id,
cpus[i].physical_node_id, cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].physical_core_id, cpus[i].thread_id);
cpus[i].logical_node_id,
cpus[i].physical_core_id,
cpus[i].thread_id);
} }
} }
void void allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p)
allocate_counters(struct thread_data **t, struct core_data **c,
struct pkg_data **p)
{ {
int i; int i;
int num_cores = topo.cores_per_node * topo.nodes_per_pkg * int num_cores = topo.cores_per_node * topo.nodes_per_pkg * topo.num_packages;
topo.num_packages;
int num_threads = topo.threads_per_core * num_cores; int num_threads = topo.threads_per_core * num_cores;
*t = calloc(num_threads, sizeof(struct thread_data)); *t = calloc(num_threads, sizeof(struct thread_data));
...@@ -5545,13 +5774,13 @@ allocate_counters(struct thread_data **t, struct core_data **c, ...@@ -5545,13 +5774,13 @@ allocate_counters(struct thread_data **t, struct core_data **c,
error: error:
err(1, "calloc counters"); err(1, "calloc counters");
} }
/* /*
* init_counter() * init_counter()
* *
* set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE
*/ */
void init_counter(struct thread_data *thread_base, struct core_data *core_base, void init_counter(struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base, int cpu_id)
struct pkg_data *pkg_base, int cpu_id)
{ {
int pkg_id = cpus[cpu_id].physical_package_id; int pkg_id = cpus[cpu_id].physical_package_id;
int node_id = cpus[cpu_id].logical_node_id; int node_id = cpus[cpu_id].logical_node_id;
...@@ -5561,7 +5790,6 @@ void init_counter(struct thread_data *thread_base, struct core_data *core_base, ...@@ -5561,7 +5790,6 @@ void init_counter(struct thread_data *thread_base, struct core_data *core_base,
struct core_data *c; struct core_data *c;
struct pkg_data *p; struct pkg_data *p;
/* Workaround for systems where physical_node_id==-1 /* Workaround for systems where physical_node_id==-1
* and logical_node_id==(-1 - topo.num_cpus) * and logical_node_id==(-1 - topo.num_cpus)
*/ */
...@@ -5583,7 +5811,6 @@ void init_counter(struct thread_data *thread_base, struct core_data *core_base, ...@@ -5583,7 +5811,6 @@ void init_counter(struct thread_data *thread_base, struct core_data *core_base,
p->package_id = pkg_id; p->package_id = pkg_id;
} }
int initialize_counters(int cpu_id) int initialize_counters(int cpu_id)
{ {
init_counter(EVEN_COUNTERS, cpu_id); init_counter(EVEN_COUNTERS, cpu_id);
...@@ -5598,12 +5825,14 @@ void allocate_output_buffer() ...@@ -5598,12 +5825,14 @@ void allocate_output_buffer()
if (outp == NULL) if (outp == NULL)
err(-1, "calloc output buffer"); err(-1, "calloc output buffer");
} }
void allocate_fd_percpu(void) void allocate_fd_percpu(void)
{ {
fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int)); fd_percpu = calloc(topo.max_cpu_num + 1, sizeof(int));
if (fd_percpu == NULL) if (fd_percpu == NULL)
err(-1, "calloc fd_percpu"); err(-1, "calloc fd_percpu");
} }
void allocate_irq_buffers(void) void allocate_irq_buffers(void)
{ {
irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int)); irq_column_2_cpu = calloc(topo.num_cpus, sizeof(int));
...@@ -5614,6 +5843,7 @@ void allocate_irq_buffers(void) ...@@ -5614,6 +5843,7 @@ void allocate_irq_buffers(void)
if (irqs_per_cpu == NULL) if (irqs_per_cpu == NULL)
err(-1, "calloc %d", topo.max_cpu_num + 1); err(-1, "calloc %d", topo.max_cpu_num + 1);
} }
void setup_all_buffers(void) void setup_all_buffers(void)
{ {
topology_probe(); topology_probe();
...@@ -5642,7 +5872,7 @@ void turbostat_init() ...@@ -5642,7 +5872,7 @@ void turbostat_init()
check_dev_msr(); check_dev_msr();
check_permissions(); check_permissions();
process_cpuid(); process_cpuid();
linux_perf_init();
if (!quiet) if (!quiet)
for_all_cpus(print_hwp, ODD_COUNTERS); for_all_cpus(print_hwp, ODD_COUNTERS);
...@@ -5658,6 +5888,9 @@ void turbostat_init() ...@@ -5658,6 +5888,9 @@ void turbostat_init()
for_all_cpus(set_temperature_target, ODD_COUNTERS); for_all_cpus(set_temperature_target, ODD_COUNTERS);
for_all_cpus(get_cpu_type, ODD_COUNTERS);
for_all_cpus(get_cpu_type, EVEN_COUNTERS);
if (!quiet) if (!quiet)
for_all_cpus(print_thermal, ODD_COUNTERS); for_all_cpus(print_thermal, ODD_COUNTERS);
...@@ -5713,7 +5946,7 @@ int fork_it(char **argv) ...@@ -5713,7 +5946,7 @@ int fork_it(char **argv)
format_all_counters(EVEN_COUNTERS); format_all_counters(EVEN_COUNTERS);
} }
fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); fprintf(outf, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec / 1000000.0);
flush_output_stderr(); flush_output_stderr();
...@@ -5738,9 +5971,9 @@ int get_and_dump_counters(void) ...@@ -5738,9 +5971,9 @@ int get_and_dump_counters(void)
return status; return status;
} }
void print_version() { void print_version()
fprintf(outf, "turbostat version 20.09.30" {
" - Len Brown <lenb@kernel.org>\n"); fprintf(outf, "turbostat version 21.05.04" " - Len Brown <lenb@kernel.org>\n");
} }
int add_counter(unsigned int msr_num, char *path, char *name, int add_counter(unsigned int msr_num, char *path, char *name,
...@@ -5771,8 +6004,7 @@ int add_counter(unsigned int msr_num, char *path, char *name, ...@@ -5771,8 +6004,7 @@ int add_counter(unsigned int msr_num, char *path, char *name,
sys.tp = msrp; sys.tp = msrp;
sys.added_thread_counters++; sys.added_thread_counters++;
if (sys.added_thread_counters > MAX_ADDED_THREAD_COUNTERS) { if (sys.added_thread_counters > MAX_ADDED_THREAD_COUNTERS) {
fprintf(stderr, "exceeded max %d added thread counters\n", fprintf(stderr, "exceeded max %d added thread counters\n", MAX_ADDED_COUNTERS);
MAX_ADDED_COUNTERS);
exit(-1); exit(-1);
} }
break; break;
...@@ -5782,8 +6014,7 @@ int add_counter(unsigned int msr_num, char *path, char *name, ...@@ -5782,8 +6014,7 @@ int add_counter(unsigned int msr_num, char *path, char *name,
sys.cp = msrp; sys.cp = msrp;
sys.added_core_counters++; sys.added_core_counters++;
if (sys.added_core_counters > MAX_ADDED_COUNTERS) { if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
fprintf(stderr, "exceeded max %d added core counters\n", fprintf(stderr, "exceeded max %d added core counters\n", MAX_ADDED_COUNTERS);
MAX_ADDED_COUNTERS);
exit(-1); exit(-1);
} }
break; break;
...@@ -5793,8 +6024,7 @@ int add_counter(unsigned int msr_num, char *path, char *name, ...@@ -5793,8 +6024,7 @@ int add_counter(unsigned int msr_num, char *path, char *name,
sys.pp = msrp; sys.pp = msrp;
sys.added_package_counters++; sys.added_package_counters++;
if (sys.added_package_counters > MAX_ADDED_COUNTERS) { if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
fprintf(stderr, "exceeded max %d added package counters\n", fprintf(stderr, "exceeded max %d added package counters\n", MAX_ADDED_COUNTERS);
MAX_ADDED_COUNTERS);
exit(-1); exit(-1);
} }
break; break;
...@@ -5931,8 +6161,7 @@ void probe_sysfs(void) ...@@ -5931,8 +6161,7 @@ void probe_sysfs(void)
for (state = 10; state >= 0; --state) { for (state = 10; state >= 0; --state) {
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
base_cpu, state);
input = fopen(path, "r"); input = fopen(path, "r");
if (input == NULL) if (input == NULL)
continue; continue;
...@@ -5955,14 +6184,12 @@ void probe_sysfs(void) ...@@ -5955,14 +6184,12 @@ void probe_sysfs(void)
if (is_deferred_skip(name_buf)) if (is_deferred_skip(name_buf))
continue; continue;
add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC, add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC, FORMAT_PERCENT, SYSFS_PERCPU);
FORMAT_PERCENT, SYSFS_PERCPU);
} }
for (state = 10; state >= 0; --state) { for (state = 10; state >= 0; --state) {
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state);
base_cpu, state);
input = fopen(path, "r"); input = fopen(path, "r");
if (input == NULL) if (input == NULL)
continue; continue;
...@@ -5982,13 +6209,11 @@ void probe_sysfs(void) ...@@ -5982,13 +6209,11 @@ void probe_sysfs(void)
if (is_deferred_skip(name_buf)) if (is_deferred_skip(name_buf))
continue; continue;
add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS, FORMAT_DELTA, SYSFS_PERCPU);
FORMAT_DELTA, SYSFS_PERCPU);
} }
} }
/* /*
* parse cpuset with following syntax * parse cpuset with following syntax
* 1,2,4..6,8-10 and set bits in cpu_subset * 1,2,4..6,8-10 and set bits in cpu_subset
...@@ -6075,36 +6300,35 @@ void parse_cpu_command(char *optarg) ...@@ -6075,36 +6300,35 @@ void parse_cpu_command(char *optarg)
exit(-1); exit(-1);
} }
void cmdline(int argc, char **argv) void cmdline(int argc, char **argv)
{ {
int opt; int opt;
int option_index = 0; int option_index = 0;
static struct option long_options[] = { static struct option long_options[] = {
{"add", required_argument, 0, 'a'}, { "add", required_argument, 0, 'a' },
{"cpu", required_argument, 0, 'c'}, { "cpu", required_argument, 0, 'c' },
{"Dump", no_argument, 0, 'D'}, { "Dump", no_argument, 0, 'D' },
{"debug", no_argument, 0, 'd'}, /* internal, not documented */ { "debug", no_argument, 0, 'd' }, /* internal, not documented */
{"enable", required_argument, 0, 'e'}, { "enable", required_argument, 0, 'e' },
{"interval", required_argument, 0, 'i'}, { "interval", required_argument, 0, 'i' },
{"num_iterations", required_argument, 0, 'n'}, { "IPC", no_argument, 0, 'I' },
{"help", no_argument, 0, 'h'}, { "num_iterations", required_argument, 0, 'n' },
{"hide", required_argument, 0, 'H'}, // meh, -h taken by --help { "help", no_argument, 0, 'h' },
{"Joules", no_argument, 0, 'J'}, { "hide", required_argument, 0, 'H' }, // meh, -h taken by --help
{"list", no_argument, 0, 'l'}, { "Joules", no_argument, 0, 'J' },
{"out", required_argument, 0, 'o'}, { "list", no_argument, 0, 'l' },
{"quiet", no_argument, 0, 'q'}, { "out", required_argument, 0, 'o' },
{"show", required_argument, 0, 's'}, { "quiet", no_argument, 0, 'q' },
{"Summary", no_argument, 0, 'S'}, { "show", required_argument, 0, 's' },
{"TCC", required_argument, 0, 'T'}, { "Summary", no_argument, 0, 'S' },
{"version", no_argument, 0, 'v' }, { "TCC", required_argument, 0, 'T' },
{0, 0, 0, 0 } { "version", no_argument, 0, 'v' },
{ 0, 0, 0, 0 }
}; };
progname = argv[0]; progname = argv[0];
while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qST:v", while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qST:v", long_options, &option_index)) != -1) {
long_options, &option_index)) != -1) {
switch (opt) { switch (opt) {
case 'a': case 'a':
parse_add_command(optarg); parse_add_command(optarg);
...@@ -6139,8 +6363,7 @@ void cmdline(int argc, char **argv) ...@@ -6139,8 +6363,7 @@ void cmdline(int argc, char **argv)
double interval = strtod(optarg, NULL); double interval = strtod(optarg, NULL);
if (interval < 0.001) { if (interval < 0.001) {
fprintf(outf, "interval %f seconds is too small\n", fprintf(outf, "interval %f seconds is too small\n", interval);
interval);
exit(2); exit(2);
} }
...@@ -6167,8 +6390,7 @@ void cmdline(int argc, char **argv) ...@@ -6167,8 +6390,7 @@ void cmdline(int argc, char **argv)
num_iterations = strtod(optarg, NULL); num_iterations = strtod(optarg, NULL);
if (num_iterations <= 0) { if (num_iterations <= 0) {
fprintf(outf, "iterations %d should be positive number\n", fprintf(outf, "iterations %d should be positive number\n", num_iterations);
num_iterations);
exit(2); exit(2);
} }
break; break;
...@@ -6188,7 +6410,7 @@ void cmdline(int argc, char **argv) ...@@ -6188,7 +6410,7 @@ void cmdline(int argc, char **argv)
summary_only++; summary_only++;
break; break;
case 'T': case 'T':
tcc_activation_temp_override = atoi(optarg); tj_max_override = atoi(optarg);
break; break;
case 'v': case 'v':
print_version(); print_version();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment