blob: 3ed2310d26d79f494da94053bf503c7caf2dfcd8 [file] [log] [blame]
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from time import sleep
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
class kernel_Delay(test.test):
"""
Test to ensure that udelay() delays at least as long as requested
(as compared to ktime()).
Test a variety of delays at mininmum and maximum cpu frequencies.
"""
version = 1
MODULE_NAME = 'udelay_test'
UDELAY_PATH = '/sys/kernel/debug/udelay_test'
CPUFREQ_CUR_PATH = '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq'
CPUFREQ_MIN_PATH = '/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq'
CPUFREQ_MAX_PATH = '/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq'
CPUFREQ_AVAIL_PATH = (
'/sys/devices/system/cpu/cpu0/cpufreq/'
'scaling_available_frequencies')
# Test a variety of delays
# 1..200, 200..500 (by 10), 500..2000 (by 100)
DELAYS = range(1, 200) + range(200, 500, 10) + range(500, 2001, 100)
ITERATIONS = 100
def _set_file(self, contents, filename):
"""
Write a string to a file.
@param contents: the contents to write to the file
@param filename: the filename to use
"""
logging.debug('setting %s to %s', filename, contents)
with open(filename, 'w') as f:
f.write(contents)
def _get_file(self, filename):
"""
Read a string from a file.
@returns: the contents of the file (string)
"""
with open(filename, 'r') as f:
return f.read()
def _get_freq(self):
"""
Get the current CPU frequency.
@returns: the CPU frequency (int)
"""
return int(self._get_file(self.CPUFREQ_CUR_PATH))
def _get_min_freq(self):
"""
Get the minimum CPU frequency.
@returns: the CPU frequency (int)
"""
return int(self._get_file(self.CPUFREQ_MIN_PATH))
def _get_max_freq(self):
"""
Get the maxium CPU frequency.
@returns: the CPU frequency (int)
"""
return int(self._get_file(self.CPUFREQ_MAX_PATH))
def _unlimit_freq(self, min_freq, max_freq):
"""
Unlimit the CPU frequency.
@param min_freq: minimum CPU frequency available
@param max_freq: maximum CPU frequency available
"""
# To ensure minimum < maximum at all times, unlimit first.
self._set_file(str(max_freq), self.CPUFREQ_MAX_PATH)
self._set_file(str(min_freq), self.CPUFREQ_MIN_PATH)
def _set_freq(self, freq, min_freq, max_freq):
"""
Set the CPU frequency.
@param freq: desired CPU frequency
@param min_freq: minimum CPU frequency available
@param max_freq: maximum CPU frequency available
"""
# To ensure minimum < maximum at all times, unlimit first.
self._unlimit_freq(min_freq, max_freq)
# Wait a moment for new scaling to take effect before setting.
sleep(0.2)
self._set_file(str(freq), self.CPUFREQ_MAX_PATH)
self._set_file(str(freq), self.CPUFREQ_MIN_PATH)
# Sometimes the frequency doesn't set right away, give it some time.
for x in range(0, 10):
cur_freq = self._get_freq()
logging.info('cpu freq set to %d', cur_freq)
if cur_freq == freq:
return
sleep(0.1)
raise error.TestFail('unable to set freq to %d' % freq)
def _test_udelay(self, usecs):
"""
Test udelay() for a given amount of time.
@param usecs: number of usecs to delay for each iteration
"""
self._set_file('%d %d' % (usecs, self.ITERATIONS), self.UDELAY_PATH)
with open(self.UDELAY_PATH, 'r') as f:
for line in f:
line = line.rstrip()
logging.info('result: %s', line)
if 'FAIL' in line:
raise error.TestFail('udelay failed: %s' % line)
def run_once(self):
utils.load_module(self.MODULE_NAME)
with open(self.CPUFREQ_AVAIL_PATH, 'r') as f:
available_freqs = [int(x) for x in f.readline().split()]
max_freq = max(available_freqs)
min_freq = min(available_freqs)
logging.info('cpu frequency max %d min %d', max_freq, min_freq)
freqs = [ min_freq, max_freq ]
for freq in freqs:
self._set_freq(freq, min_freq, max_freq)
for usecs in self.DELAYS:
self._test_udelay(usecs)
if freq != self._get_min_freq() or freq != self._get_max_freq():
raise error.TestFail(
'cpu frequency changed from %d to %d-%d' % (
freq, self._get_min_freq(), self._get_max_freq()))
self._unlimit_freq(min_freq, max_freq)
utils.unload_module(self.MODULE_NAME)