Home | History | Annotate | Download | only in kernel_Delay
      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 
      5 import glob
      6 import logging
      7 import os
      8 
      9 from autotest_lib.client.bin import test, utils
     10 from autotest_lib.client.common_lib import error
     11 
     12 class 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