forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'turbostat' of git://git.kernel.org/pub/scm/linux/kernel…
…/git/lenb/linux Pull turbostat updates from Len Brown: "Update to turbostat v20.03.20. These patches unlock the full turbostat features for some new machines, plus a couple other minor tweaks" * 'turbostat' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: tools/power turbostat: update version tools/power turbostat: Print cpuidle information tools/power turbostat: Fix 32-bit capabilities warning tools/power turbostat: Fix missing SYS_LPI counter on some Chromebooks tools/power turbostat: Support Elkhart Lake tools/power turbostat: Support Jasper Lake tools/power turbostat: Support Ice Lake server tools/power turbostat: Support Tiger Lake tools/power turbostat: Fix gcc build warnings tools/power turbostat: Support Cometlake
- Loading branch information
Showing
2 changed files
with
114 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ | |
#include <sched.h> | ||
#include <time.h> | ||
#include <cpuid.h> | ||
#include <linux/capability.h> | ||
#include <sys/capability.h> | ||
#include <errno.h> | ||
#include <math.h> | ||
|
||
|
@@ -304,6 +304,10 @@ int *irqs_per_cpu; /* indexed by cpu_num */ | |
|
||
void setup_all_buffers(void); | ||
|
||
char *sys_lpi_file; | ||
char *sys_lpi_file_sysfs = "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us"; | ||
char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec"; | ||
|
||
int cpu_is_not_present(int cpu) | ||
{ | ||
return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); | ||
|
@@ -2916,8 +2920,6 @@ int snapshot_gfx_mhz(void) | |
* | ||
* record snapshot of | ||
* /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us | ||
* | ||
* return 1 if config change requires a restart, else return 0 | ||
*/ | ||
int snapshot_cpu_lpi_us(void) | ||
{ | ||
|
@@ -2941,17 +2943,14 @@ int snapshot_cpu_lpi_us(void) | |
/* | ||
* snapshot_sys_lpi() | ||
* | ||
* record snapshot of | ||
* /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us | ||
* | ||
* return 1 if config change requires a restart, else return 0 | ||
* record snapshot of sys_lpi_file | ||
*/ | ||
int snapshot_sys_lpi_us(void) | ||
{ | ||
FILE *fp; | ||
int retval; | ||
|
||
fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r"); | ||
fp = fopen_or_die(sys_lpi_file, "r"); | ||
|
||
retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); | ||
if (retval != 1) { | ||
|
@@ -3151,28 +3150,42 @@ void check_dev_msr() | |
err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); | ||
} | ||
|
||
void check_permissions() | ||
/* | ||
* check for CAP_SYS_RAWIO | ||
* return 0 on success | ||
* return 1 on fail | ||
*/ | ||
int check_for_cap_sys_rawio(void) | ||
{ | ||
struct __user_cap_header_struct cap_header_data; | ||
cap_user_header_t cap_header = &cap_header_data; | ||
struct __user_cap_data_struct cap_data_data; | ||
cap_user_data_t cap_data = &cap_data_data; | ||
extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); | ||
int do_exit = 0; | ||
char pathname[32]; | ||
cap_t caps; | ||
cap_flag_value_t cap_flag_value; | ||
|
||
/* check for CAP_SYS_RAWIO */ | ||
cap_header->pid = getpid(); | ||
cap_header->version = _LINUX_CAPABILITY_VERSION; | ||
if (capget(cap_header, cap_data) < 0) | ||
err(-6, "capget(2) failed"); | ||
caps = cap_get_proc(); | ||
if (caps == NULL) | ||
err(-6, "cap_get_proc\n"); | ||
|
||
if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { | ||
do_exit++; | ||
if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value)) | ||
err(-6, "cap_get\n"); | ||
|
||
if (cap_flag_value != CAP_SET) { | ||
warnx("capget(CAP_SYS_RAWIO) failed," | ||
" try \"# setcap cap_sys_rawio=ep %s\"", progname); | ||
return 1; | ||
} | ||
|
||
if (cap_free(caps) == -1) | ||
err(-6, "cap_free\n"); | ||
|
||
return 0; | ||
} | ||
void check_permissions(void) | ||
{ | ||
int do_exit = 0; | ||
char pathname[32]; | ||
|
||
/* check for CAP_SYS_RAWIO */ | ||
do_exit += check_for_cap_sys_rawio(); | ||
|
||
/* test file permissions */ | ||
sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); | ||
if (euidaccess(pathname, R_OK)) { | ||
|
@@ -3265,6 +3278,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) | |
case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ | ||
case INTEL_FAM6_ATOM_GOLDMONT_PLUS: | ||
case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ | ||
case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
pkg_cstate_limits = glm_pkg_cstate_limits; | ||
break; | ||
default: | ||
|
@@ -3336,6 +3350,17 @@ int is_skx(unsigned int family, unsigned int model) | |
} | ||
return 0; | ||
} | ||
int is_ehl(unsigned int family, unsigned int model) | ||
{ | ||
if (!genuine_intel) | ||
return 0; | ||
|
||
switch (model) { | ||
case INTEL_FAM6_ATOM_TREMONT: | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
int has_turbo_ratio_limit(unsigned int family, unsigned int model) | ||
{ | ||
|
@@ -3478,6 +3503,23 @@ dump_cstate_pstate_config_info(unsigned int family, unsigned int model) | |
dump_nhm_cst_cfg(); | ||
} | ||
|
||
static void dump_sysfs_file(char *path) | ||
{ | ||
FILE *input; | ||
char cpuidle_buf[64]; | ||
|
||
input = fopen(path, "r"); | ||
if (input == NULL) { | ||
if (debug) | ||
fprintf(outf, "NSFOD %s\n", path); | ||
return; | ||
} | ||
if (!fgets(cpuidle_buf, sizeof(cpuidle_buf), input)) | ||
err(1, "%s: failed to read file", path); | ||
fclose(input); | ||
|
||
fprintf(outf, "%s: %s", strrchr(path, '/') + 1, cpuidle_buf); | ||
} | ||
static void | ||
dump_sysfs_cstate_config(void) | ||
{ | ||
|
@@ -3491,6 +3533,15 @@ dump_sysfs_cstate_config(void) | |
if (!DO_BIC(BIC_sysfs)) | ||
return; | ||
|
||
if (access("/sys/devices/system/cpu/cpuidle", R_OK)) { | ||
fprintf(outf, "cpuidle not loaded\n"); | ||
return; | ||
} | ||
|
||
dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_driver"); | ||
dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor"); | ||
dump_sysfs_file("/sys/devices/system/cpu/cpuidle/current_governor_ro"); | ||
|
||
for (state = 0; state < 10; ++state) { | ||
|
||
sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", | ||
|
@@ -3894,6 +3945,20 @@ void rapl_probe_intel(unsigned int family, unsigned int model) | |
else | ||
BIC_PRESENT(BIC_PkgWatt); | ||
break; | ||
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; | ||
if (rapl_joules) { | ||
BIC_PRESENT(BIC_Pkg_J); | ||
BIC_PRESENT(BIC_Cor_J); | ||
BIC_PRESENT(BIC_RAM_J); | ||
BIC_PRESENT(BIC_GFX_J); | ||
} else { | ||
BIC_PRESENT(BIC_PkgWatt); | ||
BIC_PRESENT(BIC_CorWatt); | ||
BIC_PRESENT(BIC_RAMWatt); | ||
BIC_PRESENT(BIC_GFXWatt); | ||
} | ||
break; | ||
case INTEL_FAM6_SKYLAKE_L: /* SKL */ | ||
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; | ||
|
@@ -4295,6 +4360,7 @@ int has_snb_msrs(unsigned int family, unsigned int model) | |
case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ | ||
case INTEL_FAM6_ATOM_GOLDMONT_PLUS: | ||
case INTEL_FAM6_ATOM_GOLDMONT_D: /* DNV */ | ||
case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
return 1; | ||
} | ||
return 0; | ||
|
@@ -4324,6 +4390,7 @@ int has_c8910_msrs(unsigned int family, unsigned int model) | |
case INTEL_FAM6_CANNONLAKE_L: /* CNL */ | ||
case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ | ||
case INTEL_FAM6_ATOM_GOLDMONT_PLUS: | ||
case INTEL_FAM6_ATOM_TREMONT: /* EHL */ | ||
return 1; | ||
} | ||
return 0; | ||
|
@@ -4610,14 +4677,24 @@ unsigned int intel_model_duplicates(unsigned int model) | |
case INTEL_FAM6_SKYLAKE: | ||
case INTEL_FAM6_KABYLAKE_L: | ||
case INTEL_FAM6_KABYLAKE: | ||
case INTEL_FAM6_COMETLAKE_L: | ||
case INTEL_FAM6_COMETLAKE: | ||
return INTEL_FAM6_SKYLAKE_L; | ||
|
||
case INTEL_FAM6_ICELAKE_L: | ||
case INTEL_FAM6_ICELAKE_NNPI: | ||
case INTEL_FAM6_TIGERLAKE_L: | ||
case INTEL_FAM6_TIGERLAKE: | ||
return INTEL_FAM6_CANNONLAKE_L; | ||
|
||
case INTEL_FAM6_ATOM_TREMONT_D: | ||
return INTEL_FAM6_ATOM_GOLDMONT_D; | ||
|
||
case INTEL_FAM6_ATOM_TREMONT_L: | ||
return INTEL_FAM6_ATOM_TREMONT; | ||
|
||
case INTEL_FAM6_ICELAKE_X: | ||
return INTEL_FAM6_SKYLAKE_X; | ||
} | ||
return model; | ||
} | ||
|
@@ -4872,7 +4949,8 @@ void process_cpuid() | |
do_slm_cstates = is_slm(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)) | ||
BIC_NOT_PRESENT(BIC_CPU_c3); | ||
|
||
if (!quiet) | ||
|
@@ -4907,10 +4985,16 @@ void process_cpuid() | |
else | ||
BIC_NOT_PRESENT(BIC_CPU_LPI); | ||
|
||
if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", R_OK)) | ||
if (!access(sys_lpi_file_sysfs, R_OK)) { | ||
sys_lpi_file = sys_lpi_file_sysfs; | ||
BIC_PRESENT(BIC_SYS_LPI); | ||
else | ||
} else if (!access(sys_lpi_file_debugfs, R_OK)) { | ||
sys_lpi_file = sys_lpi_file_debugfs; | ||
BIC_PRESENT(BIC_SYS_LPI); | ||
} else { | ||
sys_lpi_file_sysfs = NULL; | ||
BIC_NOT_PRESENT(BIC_SYS_LPI); | ||
} | ||
|
||
if (!quiet) | ||
decode_misc_feature_control(); | ||
|
@@ -5306,7 +5390,7 @@ int get_and_dump_counters(void) | |
} | ||
|
||
void print_version() { | ||
fprintf(outf, "turbostat version 19.08.31" | ||
fprintf(outf, "turbostat version 20.03.20" | ||
" - Len Brown <[email protected]>\n"); | ||
} | ||
|
||
|
@@ -5323,9 +5407,9 @@ int add_counter(unsigned int msr_num, char *path, char *name, | |
} | ||
|
||
msrp->msr_num = msr_num; | ||
strncpy(msrp->name, name, NAME_BYTES); | ||
strncpy(msrp->name, name, NAME_BYTES - 1); | ||
if (path) | ||
strncpy(msrp->path, path, PATH_BYTES); | ||
strncpy(msrp->path, path, PATH_BYTES - 1); | ||
msrp->width = width; | ||
msrp->type = type; | ||
msrp->format = format; | ||
|