| 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 ede131789d70faca081d3810e5ccafb659adfb07..73cf95c53608591365b0335ff1aca2218f03d4d4 100644
|
| --- a/build/android/pylib/perf/perf_control.py
|
| +++ b/build/android/pylib/perf/perf_control.py
|
| @@ -10,9 +10,7 @@ from pylib.device import device_utils
|
|
|
| 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'
|
| + _CPU_PATH = '/sys/devices/system/cpu'
|
| _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
|
|
|
| def __init__(self, device):
|
| @@ -20,11 +18,12 @@ class PerfControl(object):
|
| if isinstance(device, android_commands.AndroidCommands):
|
| device = device_utils.DeviceUtils(device)
|
| self._device = device
|
| - cpu_files = self._device.RunShellCommand(
|
| - 'ls -d /sys/devices/system/cpu/cpu[0-9]*')
|
| - self._num_cpu_cores = len(cpu_files)
|
| - assert self._num_cpu_cores > 0, 'Failed to detect CPUs.'
|
| - logging.info('Number of CPUs: %d', self._num_cpu_cores)
|
| + # this will raise an AdbShellCommandFailedError if no CPU files are found
|
| + self._cpu_files = self._device.RunShellCommand(
|
| + 'ls -d cpu[0-9]*', cwd=self._CPU_PATH, check_return=True, as_root=True)
|
| + assert self._cpu_files, 'Failed to detect CPUs.'
|
| + self._cpu_file_list = ' '.join(self._cpu_files)
|
| + logging.info('CPUs found: %s', self._cpu_file_list)
|
| self._have_mpdecision = self._device.FileExists('/system/bin/mpdecision')
|
|
|
| def SetHighPerfMode(self):
|
| @@ -84,22 +83,41 @@ class PerfControl(object):
|
| self._SetScalingGovernorInternal(governor_mode)
|
| self._ForceAllCpusOnline(False)
|
|
|
| + def GetCpuInfo(self):
|
| + online = (output.rstrip() == '1' and status == 0
|
| + for (_, output, status) in self._ForEachCpu('cat "$CPU/online"'))
|
| + governor = (output.rstrip() if status == 0 else None
|
| + for (_, output, status)
|
| + in self._ForEachCpu('cat "$CPU/cpufreq/scaling_governor"'))
|
| + return zip(self._cpu_files, online, governor)
|
| +
|
| + def _ForEachCpu(self, cmd):
|
| + script = '; '.join([
|
| + 'for CPU in %s' % self._cpu_file_list,
|
| + 'do %s' % cmd,
|
| + 'echo -n "%~%$?%~%"',
|
| + 'done'
|
| + ])
|
| + output = self._device.RunShellCommand(
|
| + script, cwd=self._CPU_PATH, check_return=True, as_root=True)
|
| + output = '\n'.join(output).split('%~%')
|
| + return zip(self._cpu_files, output[0::2], (int(c) for c in output[1::2]))
|
| +
|
| + def _WriteEachCpuFile(self, path, value):
|
| + results = self._ForEachCpu(
|
| + 'test -e "$CPU/{path}" && echo {value} > "$CPU/{path}"'.format(
|
| + path=path, value=value))
|
| + cpus = ' '.join(cpu for (cpu, _, status) in results if status == 0)
|
| + if cpus:
|
| + logging.info('Successfully set %s to %r on: %s', path, value, cpus)
|
| + else:
|
| + logging.warning('Failed to set %s to %r on any cpus')
|
| +
|
| def _SetScalingGovernorInternal(self, value):
|
| - cpu_cores = ' '.join([str(x) for x in range(self._num_cpu_cores)])
|
| - script = ('for CPU in %s; do\n'
|
| - ' FILE="/sys/devices/system/cpu/cpu$CPU/cpufreq/scaling_governor"\n'
|
| - ' test -e $FILE && echo %s > $FILE\n'
|
| - 'done\n') % (cpu_cores, value)
|
| - logging.info('Setting scaling governor mode: %s', value)
|
| - self._device.RunShellCommand(script, as_root=True)
|
| + self._WriteEachCpuFile('cpufreq/scaling_governor', value)
|
|
|
| def _SetScalingMaxFreq(self, value):
|
| - cpu_cores = ' '.join([str(x) for x in range(self._num_cpu_cores)])
|
| - script = ('for CPU in %s; do\n'
|
| - ' FILE="/sys/devices/system/cpu/cpu$CPU/cpufreq/scaling_max_freq"\n'
|
| - ' test -e $FILE && echo %d > $FILE\n'
|
| - 'done\n') % (cpu_cores, value)
|
| - self._device.RunShellCommand(script, as_root=True)
|
| + self._WriteEachCpuFile('cpufreq/scaling_max_freq', '%d' % value)
|
|
|
| def _SetMaxGpuClock(self, value):
|
| self._device.WriteFile('/sys/class/kgsl/kgsl-3d0/max_gpuclk',
|
| @@ -107,14 +125,12 @@ class PerfControl(object):
|
| as_root=True)
|
|
|
| def _AllCpusAreOnline(self):
|
| - for cpu in range(1, self._num_cpu_cores):
|
| - online_path = PerfControl._CPU_ONLINE_FMT % cpu
|
| - # TODO(epenner): Investigate why file may be missing
|
| - # (http://crbug.com/397118)
|
| - if not self._device.FileExists(online_path) or \
|
| - self._device.ReadFile(online_path)[0] == '0':
|
| - return False
|
| - return True
|
| + results = self._ForEachCpu('cat "$CPU/online"')
|
| + # TODO(epenner): Investigate why file may be missing
|
| + # (http://crbug.com/397118)
|
| + return all(output.rstrip() == '1' and status == 0
|
| + for (cpu, output, status) in results
|
| + if cpu != 'cpu0')
|
|
|
| def _ForceAllCpusOnline(self, force_online):
|
| """Enable all CPUs on a device.
|
| @@ -132,15 +148,10 @@ class PerfControl(object):
|
| """
|
| if self._have_mpdecision:
|
| script = 'stop mpdecision' if force_online else 'start mpdecision'
|
| - self._device.RunShellCommand(script, as_root=True)
|
| + self._device.RunShellCommand(script, check_return=True, as_root=True)
|
|
|
| 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._num_cpu_cores):
|
| - online_path = PerfControl._CPU_ONLINE_FMT % cpu
|
| - self._device.WriteFile(online_path, '1', as_root=True)
|
| -
|
| + if force_online:
|
| + self._ForEachCpu('echo 1 > "$CPU/online"')
|
|
|