@@ -46,6 +46,7 @@
#include <errno.h>
char *proc_stat = "/proc/stat";
+char *TOPDIR = "/sys";
FILE *outf;
int *fd_percpu;
struct timeval interval_tv = {5, 0};
@@ -1653,8 +1654,8 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
char path[128 + PATH_BYTES];
if (mp->flags & SYSFS_PERCPU) {
- sprintf(path, "/sys/devices/system/cpu/cpu%d/%s",
- cpu, mp->path);
+ sprintf(path, "%s/devices/system/cpu/cpu%d/%s",
+ TOPDIR, cpu, mp->path);
*counterp = snapshot_sysfs_counter(path);
} else {
@@ -2456,17 +2457,22 @@ int parse_int_file(const char *fmt, ...)
*/
int cpu_is_first_core_in_package(int cpu)
{
- return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu);
+ return cpu == parse_int_file(
+ "%s/devices/system/cpu/cpu%d/topology/core_siblings_list",
+ TOPDIR, cpu);
}
int get_physical_package_id(int cpu)
{
- return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
+ return parse_int_file(
+ "%s/devices/system/cpu/cpu%d/topology/physical_package_id",
+ TOPDIR, cpu);
}
int get_core_id(int cpu)
{
- return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
+ return parse_int_file("%s/devices/system/cpu/cpu%d/topology/core_id",
+ TOPDIR, cpu);
}
void set_node_data(void)
@@ -2518,8 +2524,8 @@ int get_physical_node_id(struct cpu_topology *thiscpu)
int cpu = thiscpu->logical_cpu_id;
for (i = 0; i <= topo.max_cpu_num; i++) {
- sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist",
- cpu, i);
+ sprintf(path, "%s/devices/system/cpu/cpu%d/node%i/cpulist",
+ TOPDIR, cpu, i);
filep = fopen(path, "r");
if (!filep)
continue;
@@ -2550,7 +2556,8 @@ int get_thread_siblings(struct cpu_topology *thiscpu)
CPU_ZERO_S(size, thiscpu->put_ids);
sprintf(path,
- "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
+ "%s/devices/system/cpu/cpu%d/topology/thread_siblings",
+ TOPDIR, cpu);
filep = fopen_or_die(path, "r");
do {
offset -= BITMASK_SIZE;
@@ -2670,11 +2677,12 @@ void set_max_cpu_num(void)
{
FILE *filep;
unsigned long dummy;
+ char path[128 + PATH_BYTES];
topo.max_cpu_num = 0;
- filep = fopen_or_die(
- "/sys/devices/system/cpu/cpu0/topology/thread_siblings",
- "r");
+ sprintf(path, "%s/devices/system/cpu/cpu0/topology/thread_siblings",
+ TOPDIR);
+ filep = fopen_or_die(path, "r");
while (fscanf(filep, "%lx,", &dummy) == 1)
topo.max_cpu_num += BITMASK_SIZE;
fclose(filep);
@@ -2777,8 +2785,10 @@ int snapshot_gfx_rc6_ms(void)
{
FILE *fp;
int retval;
+ char path[128 + PATH_BYTES];
- fp = fopen_or_die("/sys/class/drm/card0/power/rc6_residency_ms", "r");
+ sprintf(path, "%s/class/drm/card0/power/rc6_residency_ms", TOPDIR);
+ fp = fopen_or_die(path, "r");
retval = fscanf(fp, "%lld", &gfx_cur_rc6_ms);
if (retval != 1)
@@ -2800,10 +2810,14 @@ int snapshot_gfx_mhz(void)
{
static FILE *fp;
int retval;
+ char path[128 + PATH_BYTES];
- if (fp == NULL)
- fp = fopen_or_die("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", "r");
- else {
+ if (fp == NULL) {
+ sprintf(path,
+ "%s/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz",
+ TOPDIR);
+ fp = fopen_or_die(path, "r");
+ } else {
rewind(fp);
fflush(fp);
}
@@ -2827,8 +2841,12 @@ int snapshot_cpu_lpi_us(void)
{
FILE *fp;
int retval;
+ char path[128 + PATH_BYTES];
- fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", "r");
+ sprintf(path,
+ "%s/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us",
+ TOPDIR);
+ fp = fopen_or_die(path, "r");
retval = fscanf(fp, "%lld", &cpuidle_cur_cpu_lpi_us);
if (retval != 1)
@@ -2850,8 +2868,12 @@ int snapshot_sys_lpi_us(void)
{
FILE *fp;
int retval;
+ char path[128 + PATH_BYTES];
- fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r");
+ sprintf(path,
+ "%s/devices/system/cpu/cpuidle/low_power_idle_system_residency_us",
+ TOPDIR);
+ fp = fopen_or_die(path, "r");
retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us);
if (retval != 1)
@@ -3402,8 +3424,9 @@ dump_sysfs_cstate_config(void)
for (state = 0; state < 10; ++state) {
- sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
- base_cpu, state);
+ sprintf(path,
+ "%s/devices/system/cpu/cpu%d/cpuidle/state%d/name",
+ TOPDIR, base_cpu, state);
input = fopen(path, "r");
if (input == NULL)
continue;
@@ -3417,8 +3440,9 @@ dump_sysfs_cstate_config(void)
fclose(input);
- sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
- base_cpu, state);
+ sprintf(path,
+ "%s/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
+ TOPDIR, base_cpu, state);
input = fopen(path, "r");
if (input == NULL)
continue;
@@ -3437,8 +3461,8 @@ dump_sysfs_pstate_config(void)
FILE *input;
int turbo;
- sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver",
- base_cpu);
+ sprintf(path, "%s/devices/system/cpu/cpu%d/cpufreq/scaling_driver",
+ TOPDIR, base_cpu);
input = fopen(path, "r");
if (input == NULL) {
fprintf(stderr, "NSFOD %s\n", path);
@@ -3447,8 +3471,8 @@ dump_sysfs_pstate_config(void)
fgets(driver_buf, sizeof(driver_buf), input);
fclose(input);
- sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
- base_cpu);
+ sprintf(path, "%s/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
+ TOPDIR, base_cpu);
input = fopen(path, "r");
if (input == NULL) {
fprintf(stderr, "NSFOD %s\n", path);
@@ -3460,7 +3484,7 @@ dump_sysfs_pstate_config(void)
fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf);
- sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
+ sprintf(path, "%s/devices/system/cpu/cpufreq/boost", TOPDIR);
input = fopen(path, "r");
if (input != NULL) {
fscanf(input, "%d", &turbo);
@@ -3468,7 +3492,7 @@ dump_sysfs_pstate_config(void)
fclose(input);
}
- sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
+ sprintf(path, "%s/devices/system/cpu/intel_pstate/no_turbo", TOPDIR);
input = fopen(path, "r");
if (input != NULL) {
fscanf(input, "%d", &turbo);
@@ -4441,6 +4465,7 @@ void process_cpuid()
unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
unsigned int fms, family, model, stepping;
unsigned int has_turbo;
+ char path[128 + PATH_BYTES];
eax = ebx = ecx = edx = 0;
@@ -4702,18 +4727,27 @@ void process_cpuid()
if (has_skl_msrs(family, model))
calculate_tsc_tweak();
- if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
+ sprintf(path, "%s/class/drm/card0/power/rc6_residency_ms", TOPDIR);
+ if (!access(path, R_OK))
BIC_PRESENT(BIC_GFX_rc6);
- if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
+ sprintf(path, "%s/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz",
+ TOPDIR);
+ if (!access(path, R_OK))
BIC_PRESENT(BIC_GFXMHz);
- if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us", R_OK))
+ sprintf(path,
+ "%s/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us",
+ TOPDIR);
+ if (!access(path, R_OK))
BIC_PRESENT(BIC_CPU_LPI);
else
BIC_NOT_PRESENT(BIC_CPU_LPI);
- if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", R_OK))
+ sprintf(path,
+ "%s/devices/system/cpu/cpuidle/low_power_idle_system_residency_us",
+ TOPDIR);
+ if (!access(path, R_OK))
BIC_PRESENT(BIC_SYS_LPI);
else
BIC_NOT_PRESENT(BIC_SYS_LPI);
@@ -5286,8 +5320,9 @@ void probe_sysfs(void)
for (state = 10; state >= 0; --state) {
- sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
- base_cpu, state);
+ sprintf(path,
+ "%s/devices/system/cpu/cpu%d/cpuidle/state%d/name",
+ TOPDIR, base_cpu, state);
input = fopen(path, "r");
if (input == NULL)
continue;
@@ -5313,8 +5348,9 @@ void probe_sysfs(void)
for (state = 10; state >= 0; --state) {
- sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
- base_cpu, state);
+ sprintf(path,
+ "%s/devices/system/cpu/cpu%d/cpuidle/state%d/name",
+ TOPDIR, base_cpu, state);
input = fopen(path, "r");
if (input == NULL)
continue;
@@ -5555,6 +5591,10 @@ int main(int argc, char **argv)
if (!quiet)
print_version();
+ if (strcmp(TOPDIR, "/sys/"))
+ fprintf(outf, "turbostat is examining %s, not /sys/.\n",
+ TOPDIR);
+
probe_sysfs();
turbostat_init();
It is difficult to get turbostat tested on unusual topologies due to a lack of hardware access. Typically it is enough to copy parts of /sys/devices/system/cpu and /sys/devices/system/node from a bug reporter's system to test. For example I can copy those directories to /tmp/test, and change "TOPDIR" to /tmp/test, compile, and run tests on that topology. Allow for a compile time modification to be made to turbostat to change the top-level directory. Signed-off-by: Prarit Bhargava <prarit@redhat.com> Cc: lenb@kernel.org --- tools/power/x86/turbostat/turbostat.c | 110 +++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 35 deletions(-)