summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/power/cpupower/Makefile6
-rw-r--r--tools/power/cpupower/utils/cpufreq-info.c11
-rw-r--r--tools/power/cpupower/utils/helpers/cppc.c56
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h2
-rw-r--r--tools/power/cpupower/utils/powercap-info.c2
-rwxr-xr-xtools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py18
-rwxr-xr-xtools/testing/selftests/cpufreq/governor.sh26
-rwxr-xr-xtools/testing/selftests/cpufreq/special-tests.sh18
8 files changed, 114 insertions, 25 deletions
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index 969716dfe8de..ab428e336d87 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -131,7 +131,7 @@ override CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \
UTIL_OBJS = utils/helpers/amd.o utils/helpers/msr.o \
utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \
- utils/helpers/pci.o utils/helpers/bitmask.o \
+ utils/helpers/pci.o utils/helpers/bitmask.o utils/helpers/cppc.o \
utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \
utils/idle_monitor/hsw_ext_idle.o \
utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \
@@ -236,9 +236,9 @@ $(OUTPUT)%.o: %.c
$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)$(LIBCPUPOWER)
$(ECHO) " CC " $@
ifeq ($(strip $(STATIC)),true)
- $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lrt -lpci -L$(OUTPUT) -o $@
+ $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lm -lrt -lpci -L$(OUTPUT) -o $@
else
- $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
+ $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lm -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
endif
$(QUIET) $(STRIPCMD) $@
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index 5a242b491a9d..11629ae49f98 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -270,10 +270,10 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human)
{
unsigned long freq;
- if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
+ freq = cpufreq_get_freq_hardware(cpu);
+ if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF) && !freq)
return -EINVAL;
- freq = cpufreq_get_freq_hardware(cpu);
printf(_(" current CPU frequency: "));
if (!freq) {
printf("Unable to call hardware\n");
@@ -477,12 +477,13 @@ static int get_latency(unsigned int cpu, unsigned int human)
}
/* --performance / -c */
-
static int get_perf_cap(unsigned int cpu)
{
if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE)
amd_pstate_show_perf_and_freq(cpu, no_rounding);
+ else
+ cppc_show_perf_and_freq(cpu, no_rounding);
return 0;
}
@@ -513,8 +514,8 @@ static void debug_output_one(unsigned int cpu)
get_available_governors(cpu);
get_policy(cpu);
- if (get_freq_hardware(cpu, 1) < 0)
- get_freq_kernel(cpu, 1);
+ get_freq_hardware(cpu, 1);
+ get_freq_kernel(cpu, 1);
get_boost_mode(cpu);
get_perf_cap(cpu);
}
diff --git a/tools/power/cpupower/utils/helpers/cppc.c b/tools/power/cpupower/utils/helpers/cppc.c
new file mode 100644
index 000000000000..3493ce8551ea
--- /dev/null
+++ b/tools/power/cpupower/utils/helpers/cppc.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "helpers/helpers.h"
+#include "cpufreq.h"
+#include "acpi_cppc.h"
+
+#define cppc_to_frequency(perf) (roundf(slope * (perf) + intercept))
+
+void cppc_show_perf_and_freq(unsigned int cpu, int no_rounding)
+{
+ int64_t nominal = acpi_cppc_get_data(cpu, NOMINAL_PERF);
+ int64_t nominal_freq = acpi_cppc_get_data(cpu, NOMINAL_FREQ) * 1000;
+ int64_t lowest = acpi_cppc_get_data(cpu, LOWEST_PERF);
+ int64_t lowest_freq = acpi_cppc_get_data(cpu, LOWEST_FREQ) * 1000;
+ unsigned long non_linear = acpi_cppc_get_data(cpu, LOWEST_NONLINEAR_PERF);
+ unsigned long highest = acpi_cppc_get_data(cpu, HIGHEST_PERF);
+ float slope, intercept;
+
+ /* do the optional freq fields look invalid? */
+ if (!nominal_freq || !lowest_freq || nominal == lowest)
+ return;
+
+ slope = (float)(nominal_freq - lowest_freq) / (nominal - lowest);
+ intercept = lowest_freq - slope * lowest;
+
+ printf(_(" CPPC limits:\n"));
+ printf(_(" Highest Performance: %lu. Maximum Frequency: "),
+ highest);
+ /*
+ * If boost isn't active, the cpuinfo_max doesn't indicate real max
+ * frequency.
+ */
+ print_speed(cppc_to_frequency(highest), no_rounding);
+ printf(".\n");
+
+ printf(_(" Nominal Performance: %lu. Nominal Frequency: "),
+ acpi_cppc_get_data(cpu, NOMINAL_PERF));
+ print_speed(nominal_freq, no_rounding);
+ printf(".\n");
+
+ printf(_(" Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "),
+ non_linear);
+ print_speed(cppc_to_frequency(non_linear), no_rounding);
+ printf(".\n");
+
+ printf(_(" Lowest Performance: %lu. Lowest Frequency: "),
+ acpi_cppc_get_data(cpu, LOWEST_PERF));
+ print_speed(lowest_freq, no_rounding);
+ printf(".\n");
+}
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index a3ad80b9c2c2..9c5126b63966 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -221,4 +221,6 @@ void print_online_cpus(void);
void print_offline_cpus(void);
void print_speed(unsigned long speed, int no_rounding);
+void cppc_show_perf_and_freq(unsigned int cpu, int no_rounding);
+
#endif /* __CPUPOWERUTILS_HELPERS__ */
diff --git a/tools/power/cpupower/utils/powercap-info.c b/tools/power/cpupower/utils/powercap-info.c
index e53033488218..88a5edb76315 100644
--- a/tools/power/cpupower/utils/powercap-info.c
+++ b/tools/power/cpupower/utils/powercap-info.c
@@ -47,8 +47,6 @@ static int powercap_print_one_zone(struct powercap_zone *zone)
printf("\n");
- if (ret != 0)
- return ret;
return ret;
}
diff --git a/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py b/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
index 38cfbdcdedb7..64001bc80f68 100755
--- a/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
+++ b/tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
@@ -32,8 +32,6 @@ import re
import signal
import sys
import getopt
-import Gnuplot
-from numpy import *
from decimal import *
__author__ = "Srinivas Pandruvada"
@@ -88,8 +86,8 @@ def print_help(driver_name):
print(' kbytes: Kilo bytes of memory per CPU to allocate to the trace buffer. Default: 10240')
print(' Output:')
print(' If not already present, creates a "results/test_name" folder in the current working directory with:')
- print(' cpu.csv - comma seperated values file with trace contents and some additional calculations.')
- print(' cpu???.csv - comma seperated values file for CPU number ???.')
+ print(' cpu.csv - comma separated values file with trace contents and some additional calculations.')
+ print(' cpu???.csv - comma separated values file for CPU number ???.')
print(' *.png - a variety of PNG format plot files created from the trace contents and the additional calculations.')
print(' Notes:')
print(' Avoid the use of _ (underscore) in test names, because in gnuplot it is a subscript directive.')
@@ -295,6 +293,8 @@ def common_all_gnuplot_settings(output_png):
def common_gnuplot_settings():
""" common gnuplot settings. """
+ import Gnuplot
+
g_plot = Gnuplot.Gnuplot(persist=1)
# The following line is for rigor only. It seems to be assumed for .csv files
g_plot('set datafile separator \",\"')
@@ -343,7 +343,7 @@ def store_csv(cpu_int, time_pre_dec, time_post_dec, core_busy, scaled, _from, _t
graph_data_present = True;
def split_csv(current_max_cpu, cpu_mask):
- """ seperate the all csv file into per CPU csv files. """
+ """ separate the main csv file into per CPU csv files. """
if os.path.exists('cpu.csv'):
for index in range(0, current_max_cpu + 1):
@@ -482,7 +482,7 @@ def read_trace_data(filename, cpu_mask):
if cpu_int > current_max_cpu:
current_max_cpu = cpu_int
# End of for each trace line loop
-# Now seperate the main overall csv file into per CPU csv files.
+# Now separate the main overall csv file into per CPU csv files.
split_csv(current_max_cpu, cpu_mask)
def signal_handler(signal, frame):
@@ -508,8 +508,6 @@ if __name__ == "__main__":
valid1 = False
valid2 = False
- cpu_mask = zeros((MAX_CPUS,), dtype=int)
-
try:
opts, args = getopt.getopt(sys.argv[1:],"ht:i:c:n:m:",["help","trace_file=","interval=","cpu=","name=","memory="])
except getopt.GetoptError:
@@ -538,6 +536,10 @@ if __name__ == "__main__":
print_help('intel_pstate')
sys.exit()
+ from numpy import zeros
+
+ cpu_mask = zeros((MAX_CPUS,), dtype=int)
+
if cpu_list:
for p in re.split("[,]", cpu_list):
if int(p) < MAX_CPUS :
diff --git a/tools/testing/selftests/cpufreq/governor.sh b/tools/testing/selftests/cpufreq/governor.sh
index fe37df79c087..cf59e63f8e14 100755
--- a/tools/testing/selftests/cpufreq/governor.sh
+++ b/tools/testing/selftests/cpufreq/governor.sh
@@ -16,6 +16,12 @@ source cpufreq.sh
CUR_GOV=
CUR_FREQ=
+# Per-policy backup, keyed by policy so multiple policies can be saved at once
+# (backup_governor/restore_governor also keep CUR_GOV/CUR_FREQ for callers that
+# read them directly).
+declare -A SAVED_GOVERNORS
+declare -A SAVED_FREQS
+
# Find governor's directory path
# $1: policy, $2: governor
find_gov_directory()
@@ -39,11 +45,13 @@ find_current_governor()
backup_governor()
{
CUR_GOV=$(find_current_governor $1)
+ SAVED_GOVERNORS[$1]=$CUR_GOV
printf "Governor backup done for $1: $CUR_GOV\n"
if [ $CUR_GOV == "userspace" ]; then
CUR_FREQ=$(find_current_freq $1)
+ SAVED_FREQS[$1]=$CUR_FREQ
printf "Governor frequency backup done for $1: $CUR_FREQ\n"
fi
@@ -53,11 +61,13 @@ backup_governor()
# $1: policy
restore_governor()
{
+ CUR_GOV=${SAVED_GOVERNORS[$1]}
__switch_governor $1 $CUR_GOV
printf "Governor restored for $1 to $CUR_GOV\n"
if [ $CUR_GOV == "userspace" ]; then
+ CUR_FREQ=${SAVED_FREQS[$1]}
set_cpu_frequency $1 $CUR_FREQ
printf "Governor frequency restored for $1: $CUR_FREQ\n"
fi
@@ -65,6 +75,17 @@ restore_governor()
printf "\n"
}
+# Save/restore governors for every policy at once
+save_all_governors()
+{
+ for_each_policy backup_governor
+}
+
+restore_all_governors()
+{
+ for_each_policy restore_governor
+}
+
# param:
# $1: policy, $2: governor
__switch_governor()
@@ -100,11 +121,6 @@ switch_governor()
# $1: policy, $2: governor
switch_show_governor()
{
- cur_gov=find_current_governor
- if [ $cur_gov == "userspace" ]; then
- cur_freq=find_current_freq
- fi
-
# switch governor
__switch_governor $1 $2
diff --git a/tools/testing/selftests/cpufreq/special-tests.sh b/tools/testing/selftests/cpufreq/special-tests.sh
index 8d40505dc468..e87ed7c8e5e5 100755
--- a/tools/testing/selftests/cpufreq/special-tests.sh
+++ b/tools/testing/selftests/cpufreq/special-tests.sh
@@ -40,7 +40,9 @@ simple_lockdep()
{
printf "** Test: Running ${FUNCNAME[0]} **\n"
+ save_all_governors
for_each_policy __simple_lockdep
+ restore_all_governors
}
# Test 2
@@ -56,7 +58,10 @@ concurrent_lockdep()
{
printf "** Test: Running ${FUNCNAME[0]} **\n"
+ save_all_governors
for_each_policy_concurrent __concurrent_lockdep
+ wait
+ restore_all_governors
}
# Test 3
@@ -65,20 +70,26 @@ quick_shuffle()
# this is called concurrently from governor_race
for I in `seq 1000`
do
- echo ondemand | sudo tee $CPUFREQROOT/policy*/scaling_governor &
- echo userspace | sudo tee $CPUFREQROOT/policy*/scaling_governor &
+ echo ondemand | tee $CPUFREQROOT/policy*/scaling_governor &
+ echo userspace | tee $CPUFREQROOT/policy*/scaling_governor &
done
+ wait
}
governor_race()
{
printf "** Test: Running ${FUNCNAME[0]} **\n"
+ save_all_governors
+
# run 8 concurrent instances
for I in `seq 8`
do
quick_shuffle &
done
+ wait
+
+ restore_all_governors
}
# Test 4
@@ -112,5 +123,8 @@ hotplug_with_updates_cpu()
hotplug_with_updates()
{
+ save_all_governors
for_each_non_boot_cpu hotplug_with_updates_cpu
+ wait
+ restore_all_governors
}