Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: build/android/pylib/perf/perf_control.py

Issue 338233003: Telemetry: Set scaling governor on all cpus (on all devices) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disable pylint warning. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/android/pylib/gtest/test_runner.py ('k') | build/android/pylib/perf/perf_control_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/pylib/perf/perf_control.py
diff --git a/build/android/pylib/perf/perf_control.py b/build/android/pylib/perf/perf_control.py
index 1c88945e2d19592203af90aeca57df9fef0c0382..e13c02adf8768d6560b2d8957bdae60c148da0ae 100644
--- a/build/android/pylib/perf/perf_control.py
+++ b/build/android/pylib/perf/perf_control.py
@@ -13,6 +13,7 @@ class PerfControl(object):
"""Provides methods for setting the performance mode of a device."""
_SCALING_GOVERNOR_FMT = (
'/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor')
+ _CPU_ONLINE_FMT = '/sys/devices/system/cpu/cpu%d/online'
_KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
def __init__(self, device):
@@ -25,13 +26,22 @@ class PerfControl(object):
assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX
self._kernel_max = int(kernel_max[0])
logging.info('Maximum CPU index: %d', self._kernel_max)
- self._original_scaling_governor = \
- self._device.old_interface.GetFileContents(
- PerfControl._SCALING_GOVERNOR_FMT % 0,
- log_result=False)[0]
+ self._have_mpdecision = self._device.old_interface.FileExistsOnDevice(
+ '/system/bin/mpdecision')
+
+ @property
+ def _NumCpuCores(self):
+ return self._kernel_max + 1
def SetHighPerfMode(self):
+ # TODO(epenner): Enable on all devices (http://crbug.com/383566)
+ if 'Nexus 4' == self._device.old_interface.GetProductModel():
+ self._ForceAllCpusOnline(True)
+ self._SetScalingGovernorInternal('performance')
+
+ def SetPerfProfilingMode(self):
"""Sets the highest possible performance mode for the device."""
+ self._ForceAllCpusOnline(True)
self._SetScalingGovernorInternal('performance')
def SetDefaultPerfMode(self):
@@ -45,13 +55,10 @@ class PerfControl(object):
'Nexus 10': 'interactive'
}.get(product_model, 'ondemand')
self._SetScalingGovernorInternal(governor_mode)
-
- def RestoreOriginalPerfMode(self):
- """Resets the original performance mode of the device."""
- self._SetScalingGovernorInternal(self._original_scaling_governor)
+ self._ForceAllCpusOnline(False)
def _SetScalingGovernorInternal(self, value):
- for cpu in range(self._kernel_max + 1):
+ for cpu in range(self._NumCpuCores):
scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu
if self._device.old_interface.FileExistsOnDevice(scaling_governor_file):
logging.info('Writing scaling governor mode \'%s\' -> %s',
@@ -59,37 +66,43 @@ class PerfControl(object):
self._device.old_interface.SetProtectedFileContents(
scaling_governor_file, value)
- def ForceAllCpusOnline(self, force_online):
- """Force all CPUs on a device to be online.
+ def _AllCpusAreOnline(self):
+ for cpu in range(self._NumCpuCores):
+ online_path = PerfControl._CPU_ONLINE_FMT % cpu
+ if self._device.old_interface.GetFileContents(online_path)[0] == '0':
+ return False
+ return True
+
+ def _ForceAllCpusOnline(self, force_online):
+ """Enable all CPUs on a device.
- Force every CPU core on an Android device to remain online, or return the
- cores under system power management control. This is needed to work around
- a bug in perf which makes it unable to record samples from CPUs that become
- online when recording is already underway.
+ Some vendors (or only Qualcomm?) hot-plug their CPUs, which can add noise
+ to measurements:
+ - In perf, samples are only taken for the CPUs that are online when the
+ measurement is started.
+ - The scaling governor can't be set for an offline CPU and frequency scaling
+ on newly enabled CPUs adds noise to both perf and tracing measurements.
+
+ It appears Qualcomm is the only vendor that hot-plugs CPUs, and on Qualcomm
+ this is done by "mpdecision".
- Args:
- force_online: True to set all CPUs online, False to return them under
- system power management control.
"""
- def ForceCpuOnline(online_path):
- script = 'chmod 644 {0}; echo 1 > {0}; chmod 444 {0}'.format(online_path)
+ if self._have_mpdecision:
+ script = 'stop mpdecision' if force_online else 'start mpdecision'
self._device.RunShellCommand(script, root=True)
- return self._device.old_interface.GetFileContents(online_path)[0] == '1'
-
- def ResetCpu(online_path):
- self._device.RunShellCommand('chmod 644 %s' % online_path, root=True)
-
- def WaitFor(condition):
- for _ in range(100):
- if condition():
- return
- time.sleep(0.1)
- raise RuntimeError('Timed out')
-
- cpu_online_files = self._device.RunShellCommand(
- 'ls -d /sys/devices/system/cpu/cpu[0-9]*/online')
- for online_path in cpu_online_files:
- if force_online:
- WaitFor(lambda: ForceCpuOnline(online_path))
- else:
- ResetCpu(online_path)
+
+ if not self._have_mpdecision and not self._AllCpusAreOnline():
+ logging.warning('Unexpected cpu hot plugging detected.')
+
+ if not force_online:
+ return
+
+ for cpu in range(self._NumCpuCores):
+ online_path = PerfControl._CPU_ONLINE_FMT % cpu
+ self._device.old_interface.SetProtectedFileContents(
+ online_path, '1')
+
+ # Double check all cores stayed online.
+ time.sleep(0.25)
+ if not self._AllCpusAreOnline():
+ raise RuntimeError('Failed to force CPUs online')
« no previous file with comments | « build/android/pylib/gtest/test_runner.py ('k') | build/android/pylib/perf/perf_control_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698