Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX | 25 assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX |
| 26 self._kernel_max = int(kernel_max[0]) | 26 self._kernel_max = int(kernel_max[0]) |
| 27 logging.info('Maximum CPU index: %d', self._kernel_max) | 27 logging.info('Maximum CPU index: %d', self._kernel_max) |
| 28 self._original_scaling_governor = \ | 28 self._original_scaling_governor = \ |
| 29 self._device.old_interface.GetFileContents( | 29 self._device.old_interface.GetFileContents( |
| 30 PerfControl._SCALING_GOVERNOR_FMT % 0, | 30 PerfControl._SCALING_GOVERNOR_FMT % 0, |
| 31 log_result=False)[0] | 31 log_result=False)[0] |
| 32 | 32 |
| 33 def SetHighPerfMode(self): | 33 def SetHighPerfMode(self): |
| 34 """Sets the highest possible performance mode for the device.""" | 34 """Sets the highest possible performance mode for the device.""" |
| 35 self._ForceAllCpusOnline(True) | |
| 35 self._SetScalingGovernorInternal('performance') | 36 self._SetScalingGovernorInternal('performance') |
| 36 | 37 |
| 37 def SetDefaultPerfMode(self): | 38 def SetDefaultPerfMode(self): |
| 38 """Sets the performance mode for the device to its default mode.""" | 39 """Sets the performance mode for the device to its default mode.""" |
| 39 product_model = self._device.old_interface.GetProductModel() | 40 product_model = self._device.old_interface.GetProductModel() |
| 40 governor_mode = { | 41 governor_mode = { |
| 41 'GT-I9300': 'pegasusq', | 42 'GT-I9300': 'pegasusq', |
| 42 'Galaxy Nexus': 'interactive', | 43 'Galaxy Nexus': 'interactive', |
| 43 'Nexus 4': 'ondemand', | 44 'Nexus 4': 'ondemand', |
| 44 'Nexus 7': 'interactive', | 45 'Nexus 7': 'interactive', |
| 45 'Nexus 10': 'interactive' | 46 'Nexus 10': 'interactive' |
| 46 }.get(product_model, 'ondemand') | 47 }.get(product_model, 'ondemand') |
| 47 self._SetScalingGovernorInternal(governor_mode) | 48 self._SetScalingGovernorInternal(governor_mode) |
| 49 self._ForceAllCpusOnline(False) | |
| 48 | 50 |
| 49 def RestoreOriginalPerfMode(self): | 51 def RestoreOriginalPerfMode(self): |
| 50 """Resets the original performance mode of the device.""" | 52 """Resets the original performance mode of the device.""" |
| 51 self._SetScalingGovernorInternal(self._original_scaling_governor) | 53 self._SetScalingGovernorInternal(self._original_scaling_governor) |
| 54 self._ForceAllCpusOnline(False) | |
|
pasko
2014/06/17 11:48:30
All this function does fithe False is 'start mpdec
Sami
2014/06/17 13:04:07
We could always reboot the devices after running t
pasko
2014/06/17 15:12:37
Maybe we should just remove the RestoreOriginalPer
Sami
2014/06/17 15:46:35
Hmm, this is called from various front-ends -- not
pasko
2014/06/17 17:02:22
OK, I just don't understand the contract we are ma
epenner
2014/06/17 22:10:55
My thinking was that this only only different if m
pasko
2014/06/18 10:59:49
The issue is that we cannot really divide our curr
| |
| 52 | 55 |
| 53 def _SetScalingGovernorInternal(self, value): | 56 def _SetScalingGovernorInternal(self, value): |
| 54 for cpu in range(self._kernel_max + 1): | 57 for cpu in range(self._kernel_max + 1): |
| 55 scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu | 58 scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu |
| 56 if self._device.old_interface.FileExistsOnDevice(scaling_governor_file): | 59 if self._device.old_interface.FileExistsOnDevice(scaling_governor_file): |
| 57 logging.info('Writing scaling governor mode \'%s\' -> %s', | 60 logging.info('Writing scaling governor mode \'%s\' -> %s', |
| 58 value, scaling_governor_file) | 61 value, scaling_governor_file) |
| 59 self._device.old_interface.SetProtectedFileContents( | 62 self._device.old_interface.SetProtectedFileContents( |
| 60 scaling_governor_file, value) | 63 scaling_governor_file, value) |
| 61 | 64 |
| 62 def ForceAllCpusOnline(self, force_online): | 65 def _ForceAllCpusOnline(self, force_online): |
| 63 """Force all CPUs on a device to be online. | 66 """Enable all CPUs on a device. |
| 64 | 67 |
| 65 Force every CPU core on an Android device to remain online, or return the | 68 Some vendors (or only Qualcomm?) hot-plug their CPUs, which can add noise |
|
pasko
2014/06/17 11:48:30
It seems Tegra and OMAP4 support hotplug, they jus
Sami
2014/06/17 13:04:07
I think such a list would quickly become unmaintan
pasko
2014/06/17 15:12:37
Yes, I would prefer a real no-op :) If we check fo
epenner
2014/06/17 22:10:56
Okay I buy it's good to check for mpdecision first
pasko
2014/06/18 10:59:49
You are right, we are deciding whether to trade sm
| |
| 66 cores under system power management control. This is needed to work around | 69 to measurements: |
| 67 a bug in perf which makes it unable to record samples from CPUs that become | 70 - In perf, samples are only taken for the CPUs that are online when the |
| 68 online when recording is already underway. | 71 measurement is started. |
| 72 - The scaling governor can't be set for an offline CPU and frequency scaling | |
| 73 on newly enabled CPUs adds noise to both perf and tracing measurements. | |
| 69 | 74 |
| 70 Args: | 75 It appears Qualcomm is the only vendor that hot-plugs CPUs, and on Qualcomm |
| 71 force_online: True to set all CPUs online, False to return them under | 76 this is done by "mpdecision". |
| 72 system power management control. | 77 |
| 73 """ | 78 """ |
| 74 def ForceCpuOnline(online_path): | |
| 75 script = 'chmod 644 {0}; echo 1 > {0}; chmod 444 {0}'.format(online_path) | |
| 76 self._device.old_interface.RunShellCommandWithSU(script) | |
| 77 return self._device.old_interface.GetFileContents(online_path)[0] == '1' | |
| 78 | 79 |
| 79 def ResetCpu(online_path): | 80 # This is a no-op if the SOC doesn't use mpdecision. |
| 80 self._device.old_interface.RunShellCommandWithSU( | 81 script = 'stop mpdecision' if force_online else 'start mpdecision' |
| 81 'chmod 644 %s' % online_path) | 82 self._device.old_interface.RunShellCommandWithSU(script) |
|
pasko
2014/06/17 11:48:30
SU is not available on some devices. Here we can a
Sami
2014/06/17 13:04:07
Can we really assume that for all callers? At leas
pasko
2014/06/17 15:12:37
Yes, let's do it separately.
I am absolutely sure
Sami
2014/06/17 15:46:35
Right, again, this affects more than just the perf
epenner
2014/06/17 22:10:56
Can I take away this okay for now? Will these comm
pasko
2014/06/18 10:59:49
Yeah, I think it will fail silently if adb is not
| |
| 82 | |
| 83 def WaitFor(condition): | |
| 84 for _ in range(100): | |
| 85 if condition(): | |
| 86 return | |
| 87 time.sleep(0.1) | |
| 88 raise RuntimeError('Timed out') | |
| 89 | 83 |
| 90 cpu_online_files = self._device.old_interface.RunShellCommand( | 84 cpu_online_files = self._device.old_interface.RunShellCommand( |
| 91 'ls -d /sys/devices/system/cpu/cpu[0-9]*/online') | 85 'ls -d /sys/devices/system/cpu/cpu[0-9]*/online') |
|
pasko
2014/06/17 11:48:30
Please use a constant like _CPU_DIR_FMT? there is
| |
| 92 for online_path in cpu_online_files: | 86 if force_online: |
|
Sami
2014/06/17 04:16:43
nit: This could be moved to line 83 to early out b
epenner
2014/06/17 22:10:55
Nice. Done.
| |
| 93 if force_online: | 87 for online_path in cpu_online_files: |
| 94 WaitFor(lambda: ForceCpuOnline(online_path)) | 88 script = 'echo 1 > {0};'.format(online_path) |
|
pasko
2014/06/17 11:48:30
There is android_commands.SetProtectedFileContents
Sami
2014/06/17 13:04:07
Right, we should use that. FWIW it wasn't used her
epenner
2014/06/17 22:10:56
Ahh good point, yeah it needed the && before to wi
| |
| 95 else: | 89 self._device.old_interface.RunShellCommandWithSU(script) |
| 96 ResetCpu(online_path) | 90 |
| 91 # Double check they all stayed online. | |
| 92 time.sleep(0.25) | |
| 93 for online_path in cpu_online_files: | |
| 94 if self._device.old_interface.GetFileContents(online_path)[0] == '0': | |
| 95 raise RuntimeError('Failed to force CPUs online') | |
| 96 | |
| OLD | NEW |