1# Copyright (c) 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import glob 6import logging 7import os 8 9from autotest_lib.client.bin import test, utils 10from autotest_lib.client.common_lib import error 11 12class kernel_Delay(test.test): 13 """ 14 Test to ensure that udelay() delays at least as long as requested 15 (as compared to ktime()). 16 17 Test a variety of delays at mininmum and maximum cpu frequencies. 18 19 """ 20 version = 1 21 22 MIN_KERNEL_VER = '3.8' 23 MODULE_NAME = 'udelay_test' 24 UDELAY_PATH = '/sys/kernel/debug/udelay_test' 25 QUIET_GOVERNOR_PATH = '/sys/devices/system/cpu/cpuquiet/current_governor' 26 GOVERNOR_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor' 27 SETSPEED_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_setspeed' 28 CUR_FREQ_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq' 29 CPUFREQ_AVAIL_PATH = ( 30 '/sys/devices/system/cpu/cpu0/cpufreq/' 31 'scaling_available_frequencies') 32 33 # Test a variety of delays 34 # 1..200, 200..500 (by 10), 500..2000 (by 100) 35 DELAYS = range(1, 200) + range(200, 500, 10) + range(500, 2001, 100) 36 ITERATIONS = 100 37 38 _governor_paths = [] 39 _setspeed_paths = [] 40 _cur_freq_paths = [] 41 42 def _set_file(self, contents, filename): 43 """ 44 Write a string to a file. 45 46 @param contents: the contents to write to the file 47 @param filename: the filename to use 48 49 """ 50 logging.debug('setting %s to %s', filename, contents) 51 with open(filename, 'w') as f: 52 f.write(contents) 53 54 55 def _get_file(self, filename): 56 """ 57 Read a string from a file. 58 59 @returns: the contents of the file (string) 60 61 """ 62 with open(filename, 'r') as f: 63 return f.read() 64 65 66 def _get_freqs(self): 67 """ 68 Get the current CPU frequencies. 69 70 @returns: the CPU frequencies of each CPU (list of int) 71 72 """ 73 return [int(self._get_file(p)) for p in self._cur_freq_paths] 74 75 76 def _get_freqs_string(self): 77 """ 78 Get the current CPU frequencies. 79 80 @returns: the CPU frequencies of each CPU (string) 81 82 """ 83 return ' '.join(str(x) for x in self._get_freqs()) 84 85 86 def _get_governors(self): 87 """ 88 Get the current CPU governors. 89 90 @returns: the CPU governors of each CPU (list of string) 91 92 """ 93 return [self._get_file(p).rstrip() for p in self._governor_paths] 94 95 96 def _get_quiet_governor(self): 97 """ 98 Get the current CPU quiet governor. 99 100 @returns: the CPU quiet governor or None if it does not exist (string) 101 102 """ 103 if os.path.isfile(self.QUIET_GOVERNOR_PATH): 104 return self._get_file(self.QUIET_GOVERNOR_PATH).rstrip() 105 else: 106 return None 107 108 109 def _reset_freq(self, initial_governors, initial_quiet_governor): 110 """ 111 Unlimit the CPU frequency. 112 113 @param initial_governors: list of initial governors to reset state to 114 @param initial_quiet_governor: initial quiet governor to reset state to 115 116 """ 117 for p, g in zip(self._governor_paths, initial_governors): 118 self._set_file(g, p) 119 if initial_quiet_governor and os.path.isfile(self.QUIET_GOVERNOR_PATH): 120 self._set_file(initial_quiet_governor, self.QUIET_GOVERNOR_PATH) 121 122 123 def _set_freq(self, freq): 124 """ 125 Set the CPU frequency. 126 127 @param freq: desired CPU frequency 128 129 """ 130 # Prevent CPUs from going up and down during the test if the option 131 # is available. 132 if os.path.isfile(self.QUIET_GOVERNOR_PATH): 133 logging.info('changing to userspace cpuquiet governor'); 134 self._set_file('userspace', self.QUIET_GOVERNOR_PATH) 135 136 for p in self._governor_paths: 137 self._set_file('userspace', p) 138 for p in self._setspeed_paths: 139 self._set_file(str(freq), p) 140 logging.info( 141 'cpu frequencies set to %s with userspace governor', 142 self._get_freqs_string()) 143 self._check_freq(freq) 144 145 146 def _check_freq(self, freq): 147 """ 148 Check the CPU frequencies are set as requested. 149 150 @param freq: desired CPU frequency 151 152 """ 153 for p in self._governor_paths: 154 governor = self._get_file(p).rstrip() 155 if governor != 'userspace': 156 raise error.TestFail('governor changed from userspace to %s' % ( 157 governor)) 158 for p in self._setspeed_paths: 159 speed = int(self._get_file(p)) 160 if speed != freq: 161 raise error.TestFail('setspeed changed from %s to %s' % ( 162 freq, speed)) 163 freqs = self._get_freqs() 164 for f in freqs: 165 if f != freq: 166 raise error.TestFail('frequency set to %s instead of %s' % ( 167 f, freq)) 168 169 170 def _test_udelay(self, usecs): 171 """ 172 Test udelay() for a given amount of time. 173 174 @param usecs: number of usecs to delay for each iteration 175 176 """ 177 self._set_file('%d %d' % (usecs, self.ITERATIONS), self.UDELAY_PATH) 178 with open(self.UDELAY_PATH, 'r') as f: 179 for line in f: 180 line = line.rstrip() 181 logging.info('result: %s', line) 182 if 'FAIL' in line: 183 raise error.TestFail('udelay failed: %s' % line) 184 185 186 def run_once(self): 187 kernel_ver = os.uname()[2] 188 if utils.compare_versions(kernel_ver, self.MIN_KERNEL_VER) < 0: 189 logging.info( 190 'skipping test: old kernel %s (min %s) missing module %s', 191 kernel_ver, self.MIN_KERNEL_VER, self.MODULE_NAME) 192 return 193 194 utils.load_module(self.MODULE_NAME) 195 196 self._governor_paths = glob.glob(self.GOVERNOR_GLOB) 197 self._setspeed_paths = glob.glob(self.SETSPEED_GLOB) 198 self._cur_freq_paths = glob.glob(self.CUR_FREQ_GLOB) 199 initial_governors = self._get_governors() 200 initial_quiet_governor = self._get_quiet_governor() 201 202 with open(self.CPUFREQ_AVAIL_PATH, 'r') as f: 203 available_freqs = [int(x) for x in f.readline().split()] 204 205 max_freq = max(available_freqs) 206 min_freq = min(available_freqs) 207 logging.info('cpu frequency max %d min %d', max_freq, min_freq) 208 209 freqs = [ min_freq, max_freq ] 210 try: 211 for freq in freqs: 212 self._set_freq(freq) 213 for usecs in self.DELAYS: 214 self._test_udelay(usecs) 215 self._check_freq(freq) 216 finally: 217 self._reset_freq(initial_governors, initial_quiet_governor) 218 utils.unload_module(self.MODULE_NAME) 219