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

Side by Side 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 unified diff | Download patch
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import logging 5 import logging
6 import time 6 import time
7 7
8 from pylib import android_commands 8 from pylib import android_commands
9 from pylib.device import device_utils 9 from pylib.device import device_utils
10 10
11 11
12 class PerfControl(object): 12 class PerfControl(object):
13 """Provides methods for setting the performance mode of a device.""" 13 """Provides methods for setting the performance mode of a device."""
14 _SCALING_GOVERNOR_FMT = ( 14 _SCALING_GOVERNOR_FMT = (
15 '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor') 15 '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor')
16 _CPU_ONLINE_FMT = '/sys/devices/system/cpu/cpu%d/online'
16 _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max' 17 _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
17 18
18 def __init__(self, device): 19 def __init__(self, device):
19 # TODO(jbudorick) Remove once telemetry gets switched over. 20 # TODO(jbudorick) Remove once telemetry gets switched over.
20 if isinstance(device, android_commands.AndroidCommands): 21 if isinstance(device, android_commands.AndroidCommands):
21 device = device_utils.DeviceUtils(device) 22 device = device_utils.DeviceUtils(device)
22 self._device = device 23 self._device = device
23 kernel_max = self._device.old_interface.GetFileContents( 24 kernel_max = self._device.old_interface.GetFileContents(
24 PerfControl._KERNEL_MAX, log_result=False) 25 PerfControl._KERNEL_MAX, log_result=False)
25 assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX 26 assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX
26 self._kernel_max = int(kernel_max[0]) 27 self._kernel_max = int(kernel_max[0])
27 logging.info('Maximum CPU index: %d', self._kernel_max) 28 logging.info('Maximum CPU index: %d', self._kernel_max)
28 self._original_scaling_governor = \ 29 self._have_mpdecision = self._device.old_interface.FileExistsOnDevice(
29 self._device.old_interface.GetFileContents( 30 '/system/bin/mpdecision')
30 PerfControl._SCALING_GOVERNOR_FMT % 0, 31
31 log_result=False)[0] 32 @property
33 def _NumCpuCores(self):
34 return self._kernel_max + 1
32 35
33 def SetHighPerfMode(self): 36 def SetHighPerfMode(self):
37 # TODO(epenner): Enable on all devices (http://crbug.com/383566)
38 if 'Nexus 4' == self._device.old_interface.GetProductModel():
39 self._ForceAllCpusOnline(True)
40 self._SetScalingGovernorInternal('performance')
41
42 def SetPerfProfilingMode(self):
34 """Sets the highest possible performance mode for the device.""" 43 """Sets the highest possible performance mode for the device."""
44 self._ForceAllCpusOnline(True)
35 self._SetScalingGovernorInternal('performance') 45 self._SetScalingGovernorInternal('performance')
36 46
37 def SetDefaultPerfMode(self): 47 def SetDefaultPerfMode(self):
38 """Sets the performance mode for the device to its default mode.""" 48 """Sets the performance mode for the device to its default mode."""
39 product_model = self._device.old_interface.GetProductModel() 49 product_model = self._device.old_interface.GetProductModel()
40 governor_mode = { 50 governor_mode = {
41 'GT-I9300': 'pegasusq', 51 'GT-I9300': 'pegasusq',
42 'Galaxy Nexus': 'interactive', 52 'Galaxy Nexus': 'interactive',
43 'Nexus 4': 'ondemand', 53 'Nexus 4': 'ondemand',
44 'Nexus 7': 'interactive', 54 'Nexus 7': 'interactive',
45 'Nexus 10': 'interactive' 55 'Nexus 10': 'interactive'
46 }.get(product_model, 'ondemand') 56 }.get(product_model, 'ondemand')
47 self._SetScalingGovernorInternal(governor_mode) 57 self._SetScalingGovernorInternal(governor_mode)
48 58 self._ForceAllCpusOnline(False)
49 def RestoreOriginalPerfMode(self):
50 """Resets the original performance mode of the device."""
51 self._SetScalingGovernorInternal(self._original_scaling_governor)
52 59
53 def _SetScalingGovernorInternal(self, value): 60 def _SetScalingGovernorInternal(self, value):
54 for cpu in range(self._kernel_max + 1): 61 for cpu in range(self._NumCpuCores):
55 scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu 62 scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu
56 if self._device.old_interface.FileExistsOnDevice(scaling_governor_file): 63 if self._device.old_interface.FileExistsOnDevice(scaling_governor_file):
57 logging.info('Writing scaling governor mode \'%s\' -> %s', 64 logging.info('Writing scaling governor mode \'%s\' -> %s',
58 value, scaling_governor_file) 65 value, scaling_governor_file)
59 self._device.old_interface.SetProtectedFileContents( 66 self._device.old_interface.SetProtectedFileContents(
60 scaling_governor_file, value) 67 scaling_governor_file, value)
61 68
62 def ForceAllCpusOnline(self, force_online): 69 def _AllCpusAreOnline(self):
63 """Force all CPUs on a device to be online. 70 for cpu in range(self._NumCpuCores):
71 online_path = PerfControl._CPU_ONLINE_FMT % cpu
72 if self._device.old_interface.GetFileContents(online_path)[0] == '0':
73 return False
74 return True
64 75
65 Force every CPU core on an Android device to remain online, or return the 76 def _ForceAllCpusOnline(self, force_online):
66 cores under system power management control. This is needed to work around 77 """Enable all CPUs on a device.
67 a bug in perf which makes it unable to record samples from CPUs that become
68 online when recording is already underway.
69 78
70 Args: 79 Some vendors (or only Qualcomm?) hot-plug their CPUs, which can add noise
71 force_online: True to set all CPUs online, False to return them under 80 to measurements:
72 system power management control. 81 - In perf, samples are only taken for the CPUs that are online when the
82 measurement is started.
83 - The scaling governor can't be set for an offline CPU and frequency scaling
84 on newly enabled CPUs adds noise to both perf and tracing measurements.
85
86 It appears Qualcomm is the only vendor that hot-plugs CPUs, and on Qualcomm
87 this is done by "mpdecision".
88
73 """ 89 """
74 def ForceCpuOnline(online_path): 90 if self._have_mpdecision:
75 script = 'chmod 644 {0}; echo 1 > {0}; chmod 444 {0}'.format(online_path) 91 script = 'stop mpdecision' if force_online else 'start mpdecision'
76 self._device.RunShellCommand(script, root=True) 92 self._device.RunShellCommand(script, root=True)
77 return self._device.old_interface.GetFileContents(online_path)[0] == '1'
78 93
79 def ResetCpu(online_path): 94 if not self._have_mpdecision and not self._AllCpusAreOnline():
80 self._device.RunShellCommand('chmod 644 %s' % online_path, root=True) 95 logging.warning('Unexpected cpu hot plugging detected.')
81 96
82 def WaitFor(condition): 97 if not force_online:
83 for _ in range(100): 98 return
84 if condition():
85 return
86 time.sleep(0.1)
87 raise RuntimeError('Timed out')
88 99
89 cpu_online_files = self._device.RunShellCommand( 100 for cpu in range(self._NumCpuCores):
90 'ls -d /sys/devices/system/cpu/cpu[0-9]*/online') 101 online_path = PerfControl._CPU_ONLINE_FMT % cpu
91 for online_path in cpu_online_files: 102 self._device.old_interface.SetProtectedFileContents(
92 if force_online: 103 online_path, '1')
93 WaitFor(lambda: ForceCpuOnline(online_path)) 104
94 else: 105 # Double check all cores stayed online.
95 ResetCpu(online_path) 106 time.sleep(0.25)
107 if not self._AllCpusAreOnline():
108 raise RuntimeError('Failed to force CPUs online')
OLDNEW
« 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