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 cde12ec9612b7933d88544124965364239b821df..274c4329a0f9d33be022dc0b6cbe1db9f9bd5604 100644 |
--- a/build/android/pylib/perf/perf_control.py |
+++ b/build/android/pylib/perf/perf_control.py |
@@ -32,6 +32,7 @@ class PerfControl(object): |
def SetHighPerfMode(self): |
"""Sets the highest possible performance mode for the device.""" |
+ self._ForceAllCpusOnline(True) |
self._SetScalingGovernorInternal('performance') |
def SetDefaultPerfMode(self): |
@@ -45,10 +46,12 @@ class PerfControl(object): |
'Nexus 10': 'interactive' |
}.get(product_model, 'ondemand') |
self._SetScalingGovernorInternal(governor_mode) |
+ self._ForceAllCpusOnline(False) |
def RestoreOriginalPerfMode(self): |
"""Resets the original performance mode of the device.""" |
self._SetScalingGovernorInternal(self._original_scaling_governor) |
+ 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
|
def _SetScalingGovernorInternal(self, value): |
for cpu in range(self._kernel_max + 1): |
@@ -59,38 +62,35 @@ 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 _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 |
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
|
+ 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) |
- self._device.old_interface.RunShellCommandWithSU(script) |
- return self._device.old_interface.GetFileContents(online_path)[0] == '1' |
- |
- def ResetCpu(online_path): |
- self._device.old_interface.RunShellCommandWithSU( |
- 'chmod 644 %s' % online_path) |
- |
- def WaitFor(condition): |
- for _ in range(100): |
- if condition(): |
- return |
- time.sleep(0.1) |
- raise RuntimeError('Timed out') |
+ |
+ # This is a no-op if the SOC doesn't use mpdecision. |
+ script = 'stop mpdecision' if force_online else 'start mpdecision' |
+ 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
|
cpu_online_files = self._device.old_interface.RunShellCommand( |
'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
|
- for online_path in cpu_online_files: |
- if force_online: |
- WaitFor(lambda: ForceCpuOnline(online_path)) |
- else: |
- ResetCpu(online_path) |
+ 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.
|
+ for online_path in cpu_online_files: |
+ 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
|
+ self._device.old_interface.RunShellCommandWithSU(script) |
+ |
+ # Double check they all stayed online. |
+ time.sleep(0.25) |
+ for online_path in cpu_online_files: |
+ if self._device.old_interface.GetFileContents(online_path)[0] == '0': |
+ raise RuntimeError('Failed to force CPUs online') |
+ |