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
This commit is contained in:
commit
6c1bae744d
@ -16,7 +16,7 @@ override CFLAGS += -D_FORTIFY_SOURCE=2
|
|||||||
|
|
||||||
%: %.c
|
%: %.c
|
||||||
@mkdir -p $(BUILD_OUTPUT)
|
@mkdir -p $(BUILD_OUTPUT)
|
||||||
$(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS)
|
$(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) -lcap
|
||||||
|
|
||||||
.PHONY : clean
|
.PHONY : clean
|
||||||
clean :
|
clean :
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
#include <linux/capability.h>
|
#include <sys/capability.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -304,6 +304,10 @@ int *irqs_per_cpu; /* indexed by cpu_num */
|
|||||||
|
|
||||||
void setup_all_buffers(void);
|
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)
|
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);
|
||||||
@ -2916,8 +2920,6 @@ int snapshot_gfx_mhz(void)
|
|||||||
*
|
*
|
||||||
* record snapshot of
|
* record snapshot of
|
||||||
* /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
|
* /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)
|
int snapshot_cpu_lpi_us(void)
|
||||||
{
|
{
|
||||||
@ -2941,17 +2943,14 @@ int snapshot_cpu_lpi_us(void)
|
|||||||
/*
|
/*
|
||||||
* snapshot_sys_lpi()
|
* snapshot_sys_lpi()
|
||||||
*
|
*
|
||||||
* record snapshot of
|
* record snapshot of sys_lpi_file
|
||||||
* /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us
|
|
||||||
*
|
|
||||||
* return 1 if config change requires a restart, else return 0
|
|
||||||
*/
|
*/
|
||||||
int snapshot_sys_lpi_us(void)
|
int snapshot_sys_lpi_us(void)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int retval;
|
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);
|
retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us);
|
||||||
if (retval != 1) {
|
if (retval != 1) {
|
||||||
@ -3151,27 +3150,41 @@ void check_dev_msr()
|
|||||||
err(-5, "no /dev/cpu/0/msr, Try \"# modprobe 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)
|
||||||
|
{
|
||||||
|
cap_t caps;
|
||||||
|
cap_flag_value_t cap_flag_value;
|
||||||
|
|
||||||
|
caps = cap_get_proc();
|
||||||
|
if (caps == NULL)
|
||||||
|
err(-6, "cap_get_proc\n");
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
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;
|
int do_exit = 0;
|
||||||
char pathname[32];
|
char pathname[32];
|
||||||
|
|
||||||
/* check for CAP_SYS_RAWIO */
|
/* check for CAP_SYS_RAWIO */
|
||||||
cap_header->pid = getpid();
|
do_exit += check_for_cap_sys_rawio();
|
||||||
cap_header->version = _LINUX_CAPABILITY_VERSION;
|
|
||||||
if (capget(cap_header, cap_data) < 0)
|
|
||||||
err(-6, "capget(2) failed");
|
|
||||||
|
|
||||||
if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
|
|
||||||
do_exit++;
|
|
||||||
warnx("capget(CAP_SYS_RAWIO) failed,"
|
|
||||||
" try \"# setcap cap_sys_rawio=ep %s\"", progname);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test file permissions */
|
/* test file permissions */
|
||||||
sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
|
sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
|
||||||
@ -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: /* 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 */
|
||||||
|
case INTEL_FAM6_ATOM_TREMONT: /* EHL */
|
||||||
pkg_cstate_limits = glm_pkg_cstate_limits;
|
pkg_cstate_limits = glm_pkg_cstate_limits;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -3336,6 +3350,17 @@ int is_skx(unsigned int family, unsigned int model)
|
|||||||
}
|
}
|
||||||
return 0;
|
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)
|
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();
|
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
|
static void
|
||||||
dump_sysfs_cstate_config(void)
|
dump_sysfs_cstate_config(void)
|
||||||
{
|
{
|
||||||
@ -3491,6 +3533,15 @@ dump_sysfs_cstate_config(void)
|
|||||||
if (!DO_BIC(BIC_sysfs))
|
if (!DO_BIC(BIC_sysfs))
|
||||||
return;
|
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) {
|
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",
|
||||||
@ -3894,6 +3945,20 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
|
|||||||
else
|
else
|
||||||
BIC_PRESENT(BIC_PkgWatt);
|
BIC_PRESENT(BIC_PkgWatt);
|
||||||
break;
|
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_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;
|
||||||
@ -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: /* 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 */
|
||||||
|
case INTEL_FAM6_ATOM_TREMONT: /* EHL */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
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_CANNONLAKE_L: /* CNL */
|
||||||
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_TREMONT: /* EHL */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -4610,14 +4677,24 @@ unsigned int intel_model_duplicates(unsigned int model)
|
|||||||
case INTEL_FAM6_SKYLAKE:
|
case INTEL_FAM6_SKYLAKE:
|
||||||
case INTEL_FAM6_KABYLAKE_L:
|
case INTEL_FAM6_KABYLAKE_L:
|
||||||
case INTEL_FAM6_KABYLAKE:
|
case INTEL_FAM6_KABYLAKE:
|
||||||
|
case INTEL_FAM6_COMETLAKE_L:
|
||||||
|
case INTEL_FAM6_COMETLAKE:
|
||||||
return INTEL_FAM6_SKYLAKE_L;
|
return INTEL_FAM6_SKYLAKE_L;
|
||||||
|
|
||||||
case INTEL_FAM6_ICELAKE_L:
|
case INTEL_FAM6_ICELAKE_L:
|
||||||
case INTEL_FAM6_ICELAKE_NNPI:
|
case INTEL_FAM6_ICELAKE_NNPI:
|
||||||
|
case INTEL_FAM6_TIGERLAKE_L:
|
||||||
|
case INTEL_FAM6_TIGERLAKE:
|
||||||
return INTEL_FAM6_CANNONLAKE_L;
|
return INTEL_FAM6_CANNONLAKE_L;
|
||||||
|
|
||||||
case INTEL_FAM6_ATOM_TREMONT_D:
|
case INTEL_FAM6_ATOM_TREMONT_D:
|
||||||
return INTEL_FAM6_ATOM_GOLDMONT_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;
|
return model;
|
||||||
}
|
}
|
||||||
@ -4872,7 +4949,8 @@ 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))
|
||||||
BIC_NOT_PRESENT(BIC_CPU_c3);
|
BIC_NOT_PRESENT(BIC_CPU_c3);
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
@ -4907,10 +4985,16 @@ void process_cpuid()
|
|||||||
else
|
else
|
||||||
BIC_NOT_PRESENT(BIC_CPU_LPI);
|
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);
|
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);
|
BIC_NOT_PRESENT(BIC_SYS_LPI);
|
||||||
|
}
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
decode_misc_feature_control();
|
decode_misc_feature_control();
|
||||||
@ -5306,7 +5390,7 @@ int get_and_dump_counters(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void print_version() {
|
void print_version() {
|
||||||
fprintf(outf, "turbostat version 19.08.31"
|
fprintf(outf, "turbostat version 20.03.20"
|
||||||
" - Len Brown <lenb@kernel.org>\n");
|
" - Len Brown <lenb@kernel.org>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5323,9 +5407,9 @@ int add_counter(unsigned int msr_num, char *path, char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
msrp->msr_num = msr_num;
|
msrp->msr_num = msr_num;
|
||||||
strncpy(msrp->name, name, NAME_BYTES);
|
strncpy(msrp->name, name, NAME_BYTES - 1);
|
||||||
if (path)
|
if (path)
|
||||||
strncpy(msrp->path, path, PATH_BYTES);
|
strncpy(msrp->path, path, PATH_BYTES - 1);
|
||||||
msrp->width = width;
|
msrp->width = width;
|
||||||
msrp->type = type;
|
msrp->type = type;
|
||||||
msrp->format = format;
|
msrp->format = format;
|
||||||
|
Loading…
Reference in New Issue
Block a user