Add graphics_PerfControl autotests.
This test exercises an empty performance test wrapped in the PerfControl
object. It essentially checks that we are able to
- read board temperatures
- read CPU frequencies
- read CPU utilization
- set the governor.
Finally it waits to obtain a cold, idle machine.
This change also cleans up site_utils.py to make reading these values more
robust.
BUG=chromium:357980
TEST=Runs locally on daisy and link. trybots no good.
test_that <ip> graphics_PerfControl graphics_GLMark2 graphics_GLBench
Change-Id: I727387a4a65be33b855b214e78846841b91a0aab
Reviewed-on: https://chromium-review.googlesource.com/192531
Tested-by: Ilja Friedel <ihf@chromium.org>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Reviewed-by: Ilja Friedel <ihf@chromium.org>
Commit-Queue: Ilja Friedel <ihf@chromium.org>
diff --git a/client/bin/site_utils.py b/client/bin/site_utils.py
index 293c64a..50b6c05 100644
--- a/client/bin/site_utils.py
+++ b/client/bin/site_utils.py
@@ -508,17 +508,9 @@
# System paths for machine performance state.
_CPUINFO = '/proc/cpuinfo'
-_CPUINFO_MAX_FREQ_FMT = '/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq'
-_CPUINFO_MIN_FREQ_FMT = '/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq'
_KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
_LSB_RELEASE = '/etc/lsb-release'
_MEMINFO = '/proc/meminfo'
-_SCALING_GOVERNOR_FMT = '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor'
-_TEMP_CRIT_FMT = '/sys/class/hwmon/hwmon0/temp%d_crit'
-_TEMP_INPUT_FMT = '/sys/class/hwmon/hwmon0/temp%d_input'
-# Same temperatures for daisy_spring.
-_TEMP_CRIT_VIRT = '/sys/devices/virtual/hwmon/hwmon1/temp1_crit'
-_TEMP_INPUT_VIRT = '/sys/devices/virtual/hwmon/hwmon1/temp1_input'
_TEMP_SENSOR_RE = 'Reading temperature...([0-9]*)'
@@ -569,17 +561,24 @@
return int(match, 16)
+def _get_hwmon_paths(file_pattern):
+ """
+ Returns a list of paths to the temperature sensors.
+ """
+ # Some systems like daisy_spring only have the virtual hwmon.
+ cmd = ('ls /sys/class/hwmon/hwmon*/' + file_pattern +
+ ' /sys/devices/virtual/hwmon/hwmon*/' + file_pattern)
+ paths = utils.run(cmd, verbose=False).stdout.splitlines()
+ return paths
+
+
def get_temperature_critical():
"""
Returns temperature at which we will see some throttling in the system.
"""
min_temperature = 1000.0
- cpus = _get_number_cpus()
- for cpu in range(1, cpus + 1):
- path = _TEMP_CRIT_FMT % cpu
- #TODO(ihf): Figure out a more consistent way to obtain temperatures.
- if 'spring' in get_board():
- path = _TEMP_CRIT_VIRT
+ paths = _get_hwmon_paths('temp*_crit')
+ for path in paths:
temperature = _get_float_from_file(path, 0, None, None) * 0.001
min_temperature = min(temperature, min_temperature)
# Sanity check for real world values.
@@ -593,12 +592,8 @@
Returns the maximum currently observed temperature.
"""
max_temperature = -1000.0
- cpus = _get_number_cpus()
- for cpu in range(1, cpus + 1):
- path = _TEMP_INPUT_FMT % cpu
- #TODO(ihf): Figure out a more consistent way to obtain temperatures.
- if 'spring' in get_board():
- path = _TEMP_INPUT_VIRT
+ paths = _get_hwmon_paths('temp*_input')
+ for path in paths:
temperature = _get_float_from_file(path, 0, None, None) * 0.001
max_temperature = max(temperature, max_temperature)
# Sanity check for real world values.
@@ -618,7 +613,7 @@
return temperatures
try:
full_cmd = 'ectool temps all'
- lines = utils.system_output(full_cmd).splitlines()
+ lines = utils.run(full_cmd, verbose=False).stdout.splitlines()
for line in lines:
temperature = int(line.split(': ')[1]) - 273
temperatures.append(temperature)
@@ -655,9 +650,8 @@
Returns the largest of the max CPU core frequencies. The unit is Hz.
"""
max_frequency = -1
- cpus = _get_number_cpus()
- for cpu in range(1, cpus + 1):
- path = _CPUINFO_MAX_FREQ_FMT % (cpu + 1)
+ paths = _get_cpufreq_paths('cpuinfo_max_freq')
+ for path in paths:
# Convert from kHz to Hz.
frequency = 1000 * _get_float_from_file(path, 0, None, None)
max_frequency = max(frequency, max_frequency)
@@ -671,9 +665,8 @@
Returns the smallest of the minimum CPU core frequencies.
"""
min_frequency = 1e20
- cpus = _get_number_cpus()
- for cpu in range(1, cpus + 1):
- path = _CPUINFO_MIN_FREQ_FMT % cpu
+ paths = _get_cpufreq_paths('cpuinfo_min_freq')
+ for path in paths:
frequency = _get_float_from_file(path, 0, None, None)
min_frequency = min(frequency, min_frequency)
# Sanity check.
@@ -753,17 +746,6 @@
return kernel_max
-def _get_number_cpus():
- """
- Returns the number of CPUs available.
- """
- # TODO(ihf): apparently get_kernel_max() + 1 is not right here due to
- # hyperthreading. We only need this right now to get sensible
- # temperature and frequency baselines. But to make the functions
- # more useful this needs to be fixed.
- return 1
-
-
def set_high_performance_mode():
"""
Sets the kernel governor mode to the highest setting.
@@ -779,20 +761,19 @@
Sets all scaling governor to string value.
Sample values: 'performance', 'interactive', 'ondemand', 'powersave'.
"""
- paths = _get_scaling_governor_paths()
+ paths = _get_cpufreq_paths('scaling_governor')
for path in paths:
cmd = 'sudo echo %s > %s' % (value, path)
logging.info('Writing scaling governor mode \'%s\' -> %s', value, path)
utils.system(cmd)
-def _get_scaling_governor_paths():
+def _get_cpufreq_paths(filename):
"""
Returns a list of paths to the governors.
"""
- cmd = 'ls /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor'
- paths = utils.system_output(cmd).splitlines()
- logging.info(paths)
+ cmd = 'ls /sys/devices/system/cpu/cpu*/cpufreq/' + filename
+ paths = utils.run(cmd, verbose=False).stdout.splitlines()
return paths
@@ -800,7 +781,7 @@
"""
Returns a list of (performance governor path, current state) tuples.
"""
- paths = _get_scaling_governor_paths()
+ paths = _get_cpufreq_paths('scaling_governor')
path_value_list = []
for path in paths:
value = _get_line_from_file(path, 0)