Home | History | Annotate | Download | only in kernel_CpufreqMinMax
      1 #!/usr/bin/python
      2 #
      3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 import logging
      8 
      9 from autotest_lib.client.bin import test, utils
     10 from autotest_lib.client.common_lib import error
     11 
     12 class kernel_CpufreqMinMax(test.test):
     13     """
     14     Test to ensure cpufreq user min/max limits can be set and reset.
     15 
     16     Test the kernel's ability to change the min and max cpufreq values
     17     in both directions.  I.e. we must be able to lower the max
     18     frequency and then raise it back up again, and raise the minimum
     19     frequency and lower it back again.  The test on the max is to make
     20     sure that thermal throttling will work correctly, and the test on
     21     the min is just for symmetry.
     22     """
     23     version = 1
     24 
     25     sys_cpufreq_path = '/sys/devices/system/cpu/cpu0/cpufreq/'
     26 
     27     def _test_freq_set(self, freqs, filename):
     28         """
     29         Iteratively write frequencies into a file and check the file.
     30 
     31         This is a helper function for testing the min and max
     32         given an ordered list, it sets each frequency in the list and
     33         then checks to make sure it really got set, and raises an
     34         error if it doesn't match.
     35 
     36         @param freqs: a list of frequencies to set
     37         @param filename: the filename in the cpufreq directory to use
     38         """
     39         for freq in freqs:
     40             logging.info('setting %s to %d' % (filename, freq))
     41             f = open(self.sys_cpufreq_path + filename, 'w')
     42             f.write(str(freq))
     43             f.close()
     44 
     45             f = open(self.sys_cpufreq_path + filename, 'r')
     46             cur_freq = int(f.readline())
     47             f.close()
     48 
     49             if (cur_freq != freq):
     50                 logging.info('%s was set to %d instead of %d' %
     51                              (filename, cur_freq, freq))
     52                 raise error.TestFail('unable to set %s to %d' %
     53                                      (filename, freq))
     54 
     55 
     56     def run_once(self):
     57         available_freqs = []
     58         # When the Intel P-state driver is used, the driver implements an
     59         # internal governer which selects the currect P-state automatically.
     60         # Any value between cpuinfo_min_freq and cpuinfo_max_freq is allowed
     61         # for scaling_max_freq and scaling_min_freq. Setting them is
     62         # equivalent to setting max_perf_pct and min_perf_pct under
     63         # /sys/devices/system/cpu/intel_pstate/.
     64         f = open(self.sys_cpufreq_path + 'scaling_driver', 'r')
     65         if ('intel_pstate\n' == f.read()):
     66             fmin = open(self.sys_cpufreq_path + 'cpuinfo_min_freq', 'r')
     67             fmax = open(self.sys_cpufreq_path + 'cpuinfo_max_freq', 'r')
     68             available_freqs = map(int, [fmin.read(), fmax.read()])
     69             fmin.close()
     70             fmax.close()
     71 
     72             # generate a list of frequencies between min and max
     73             step = (available_freqs[1] - available_freqs[0]) / 4
     74             if step:
     75                 available_freqs = range(available_freqs[0],
     76                                         available_freqs[1] + 1, step)
     77         f.close()
     78 
     79         if not available_freqs:
     80             f = open(self.sys_cpufreq_path + 'scaling_available_frequencies', 'r')
     81             available_freqs = sorted(map(int, f.readline().split()))
     82             f.close()
     83 
     84         # exit if there are not at least two frequencies
     85         if (len(available_freqs) < 2):
     86             return
     87 
     88         # get current maximum scaling frequency
     89         f = open(self.sys_cpufreq_path + 'scaling_max_freq', 'r')
     90         max_freq = int(f.readline())
     91         f.close()
     92 
     93         if max_freq < available_freqs[-1]:
     94             logging.info(
     95               'Current maximum frequency %d is lower than available maximum %d',
     96                 max_freq, available_freqs[-1])
     97             # Board is probably thermally throttled
     98             if not utils.wait_for_cool_machine():
     99                 raise error.TestFail('Could not get cold machine.')
    100 
    101         # set max to 2nd to highest frequency, then the highest
    102         self._test_freq_set(available_freqs[-2:], 'scaling_max_freq')
    103 
    104         # set to min 2nd to lowest frequency, then the lowest
    105         self._test_freq_set(reversed(available_freqs[:2]),
    106                            'scaling_min_freq')
    107