1c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda# Use of this source code is governed by a BSD-style license that can be 3c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda# found in the LICENSE file. 4c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 5c21a372ca10358c41e840700c89be6f20505bda4Sameer Nandaimport glob, logging, os 6c21a372ca10358c41e840700c89be6f20505bda4Sameer Nandafrom autotest_lib.client.bin import test 7c21a372ca10358c41e840700c89be6f20505bda4Sameer Nandafrom autotest_lib.client.common_lib import error, utils 8c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 970824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny ChiuSYSFS_CPUQUIET_ENABLE = '/sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/enable' 103956655d260d169128da60006e69297db42d2a29Todd BrochSYSFS_INTEL_PSTATE_PATH = '/sys/devices/system/cpu/intel_pstate' 1170824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu 12c21a372ca10358c41e840700c89be6f20505bda4Sameer Nandaclass power_CPUFreq(test.test): 13c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda version = 1 14c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 1570824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu def initialize(self): 1670824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu # Store the setting if the system has CPUQuiet feature 1770824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu if os.path.exists(SYSFS_CPUQUIET_ENABLE): 1870824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu self.is_cpuquiet_enabled = utils.read_file(SYSFS_CPUQUIET_ENABLE) 1970824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu utils.write_one_line(SYSFS_CPUQUIET_ENABLE, '0') 2070824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu 21c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def run_once(self): 223956655d260d169128da60006e69297db42d2a29Todd Broch # TODO(crbug.com/485276) Revisit this exception once we've refactored 233956655d260d169128da60006e69297db42d2a29Todd Broch # test to account for intel_pstate cpufreq driver 243956655d260d169128da60006e69297db42d2a29Todd Broch if os.path.exists(SYSFS_INTEL_PSTATE_PATH): 253956655d260d169128da60006e69297db42d2a29Todd Broch raise error.TestNAError('Test does NOT support intel_pstate driver') 263956655d260d169128da60006e69297db42d2a29Todd Broch 27c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpufreq_path = '/sys/devices/system/cpu/cpu*/cpufreq' 28c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 29c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda dirs = glob.glob(cpufreq_path) 30c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda if not dirs: 31c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda raise error.TestFail('cpufreq not supported') 32c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 33f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que keyvals = {} 34f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que try: 35f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # First attempt to set all frequencies on each core before going 36f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # on to the next core. 37f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que self.test_cores_in_series(dirs) 38f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # Record that it was the first test that passed. 39f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que keyvals['test_cores_in_series'] = 1 40f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que except error.TestFail as exception: 41f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que if str(exception) == 'Unable to set frequency': 42f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # If test_cores_in_series fails, try to set each frequency for 43f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # all cores before moving on to the next frequency. 44f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 45f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que self.test_cores_in_parallel(dirs) 46f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # Record that it was the second test that passed. 47f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que keyvals['test_cores_in_parallel'] = 1 48f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que else: 49f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que raise exception 50f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 51f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que self.write_perf_keyval(keyvals); 52f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 53f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que def test_cores_in_series(self, dirs): 54c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda for dir in dirs: 55c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpu = cpufreq(dir) 56c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 57c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda if 'userspace' not in cpu.get_available_governors(): 58c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda raise error.TestError('userspace governor not supported') 59c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 60c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda available_frequencies = cpu.get_available_frequencies() 61c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda if len(available_frequencies) == 1: 62c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda raise error.TestFail('Not enough frequencies supported!') 63c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 64c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda # save cpufreq state so that it can be restored at the end 65c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda # of the test 66c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpu.save_state() 67c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 68c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda # set cpufreq governor to userspace 69c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpu.set_governor('userspace') 70c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 71c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda # cycle through all available frequencies 72c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda for freq in available_frequencies: 73c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpu.set_frequency(freq) 74c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda if freq != cpu.get_current_frequency(): 75c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpu.restore_state() 76c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda raise error.TestFail('Unable to set frequency') 77c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 78c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda # restore cpufreq state 79c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda cpu.restore_state() 80c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 81f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que def test_cores_in_parallel(self, dirs): 82f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpus = [cpufreq(dir) for dir in dirs] 83f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpu0 = cpus[0] 84f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 85f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # Use the first CPU's frequencies for all CPUs. Assume that they are 86f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # the same. 87f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que available_frequencies = cpu0.get_available_frequencies() 88f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que if len(available_frequencies) == 1: 89f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que raise error.TestFail('Not enough frequencies supported!') 90f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 91f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que for cpu in cpus: 92f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que if 'userspace' not in cpu.get_available_governors(): 93f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que raise error.TestError('userspace governor not supported') 94f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 95f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # save cpufreq state so that it can be restored at the end 96f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # of the test 97f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpu.save_state() 98f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 99f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # set cpufreq governor to userspace 100f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpu.set_governor('userspace') 101f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 102f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # cycle through all available frequencies 103f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que for freq in available_frequencies: 104f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que for cpu in cpus: 105f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpu.set_frequency(freq) 106f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que for cpu in cpus: 107f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que if freq != cpu.get_current_frequency(): 108f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpu.restore_state() 109f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que raise error.TestFail('Unable to set frequency') 110f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que 111f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que for cpu in cpus: 112f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # restore cpufreq state 113f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que cpu.restore_state() 114c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 11570824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu def cleanup(self): 11670824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu # Restore the original setting if system has CPUQuiet feature 11770824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu if os.path.exists(SYSFS_CPUQUIET_ENABLE): 11870824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu utils.open_write_close( 11970824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu SYSFS_CPUQUIET_ENABLE, self.is_cpuquiet_enabled) 12070824ac1a0fea6e7aab53b15cdbe30c45960dfd4Penny Chiu 121c21a372ca10358c41e840700c89be6f20505bda4Sameer Nandaclass cpufreq(object): 122c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def __init__(self, path): 123c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda self.__base_path = path 124c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda self.__save_files_list = ['scaling_max_freq', 'scaling_min_freq', 125c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 'scaling_governor'] 126c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 127c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 128c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def __write_file(self, file_name, data): 129c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda path = os.path.join(self.__base_path, file_name) 130c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda utils.open_write_close(path, data) 131c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 132c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 133c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def __read_file(self, file_name): 134c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda path = os.path.join(self.__base_path, file_name) 135c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda f = open(path, 'r') 136c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda data = f.read() 137c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda f.close() 138c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda return data 139c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 140c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 141c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def save_state(self): 142c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('saving state:') 143c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda for file in self.__save_files_list: 144c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda data = self.__read_file(file) 145c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda setattr(self, file, data) 146c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info(file + ': ' + data) 147c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 148c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 149c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def restore_state(self): 150c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('restoring state:') 151c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda for file in self.__save_files_list: 152f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # Sometimes a newline gets appended to a data string and it throws 153f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # an error when being written to a sysfs file. Call strip() to 154f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # eliminateextra whitespace characters so it can be written cleanly 155f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que # to the file. 156f8ed8a26b09ff82fc5e3a806f2865d63f84b3622Simon Que data = getattr(self, file).strip() 157c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info(file + ': ' + data) 158c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda self.__write_file(file, data) 159c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 160c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 161c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def get_available_governors(self): 162c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda governors = self.__read_file('scaling_available_governors') 163c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('available governors: %s' % governors) 164c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda return governors.split() 165c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 166c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 167c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def get_current_governor(self): 168c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda governor = self.__read_file('scaling_governor') 169c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('current governor: %s' % governor) 170c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda return governor.split()[0] 171c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 172c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 173c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def set_governor(self, governor): 174c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('setting governor to %s' % governor) 175c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda self.__write_file('scaling_governor', governor) 176c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 177c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 178c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def get_available_frequencies(self): 179c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda frequencies = self.__read_file('scaling_available_frequencies') 180c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('available frequencies: %s' % frequencies) 181c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda return [int(i) for i in frequencies.split()] 182c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 183c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 184c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def get_current_frequency(self): 185c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda freq = int(self.__read_file('scaling_cur_freq')) 186c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('current frequency: %s' % freq) 187c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda return freq 188c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 189c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 190c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda def set_frequency(self, frequency): 191c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda logging.info('setting frequency to %d' % frequency) 192c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda if frequency >= self.get_current_frequency(): 193c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda file_list = ['scaling_max_freq', 'scaling_min_freq', 194c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 'scaling_setspeed'] 195c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda else: 196c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda file_list = ['scaling_min_freq', 'scaling_max_freq', 197c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 'scaling_setspeed'] 198c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda 199c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda for file in file_list: 200c21a372ca10358c41e840700c89be6f20505bda4Sameer Nanda self.__write_file(file, str(frequency)) 201