Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 318602 Details for
Bug 463354
FEAT: cpuscaling test should be run separately for each cpu
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
cpuscaling.py patch
cpuscaling.py (text/plain), 20.64 KB, created by
Greg Nichols
on 2008-10-01 16:24:35 UTC
(
hide
)
Description:
cpuscaling.py patch
Filename:
MIME Type:
Creator:
Greg Nichols
Created:
2008-10-01 16:24:35 UTC
Size:
20.64 KB
patch
obsolete
>#!/usr/bin/python ># Copyright (c) 2008 Red Hat, Inc. All rights reserved. This copyrighted material ># is made available to anyone wishing to use, modify, copy, or ># redistribute it subject to the terms and conditions of the GNU General ># Public License v.2. ># ># This program is distributed in the hope that it will be useful, but WITHOUT ANY ># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A ># PARTICULAR PURPOSE. See the GNU General Public License for more details. ># ># You should have received a copy of the GNU General Public License ># along with this program; if not, write to the Free Software ># Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ># ># Author: Greg Nichols <gnichols@redhat.com> > >import os >import string >import sys >import commands >import re >import time >import dbus >import decimal > >from hts.tags import Constants >from hts.test import Test >from hts.device import Device >from hts.command import Command, HTSCommandException > > >class CPUScalingTest(Test): > > def __init__(self): > Test.__init__(self, name="cpuscaling") > self.interactive = False > self.speedUpTolerance = 10.0 # percent > self.retryLimit = 5 > self.retryTolerance = 5.0 # percent > self.sysCPUDirectory = "/sys/devices/system/cpu" > self.cpufreqDirectory = "%s/cpu%s/cpufreq" % (self.sysCPUDirectory, self.getLogicalDeviceName()) > > > > def plan(self, devices): > cpuDevices = list() > canThrottle = False > for device in devices: > # plan a separate test for each cpu > # if any of the cpus appear to support it. > if 'processor' in device.getProperty("info.category"): > cpuDevices.append(device) > if device.getProperty("processor.can_throttle"): > canThrottle = True > > tests = list() > if canThrottle: > for cpuDevice in cpuDevices: > test = self.makeCopy() > test.setDevice(cpuDevice) > cpuNumber = cpuDevice.getProperty("processor.number") > if not cpuNumber: > cpuNumber = "0" > test.setLogicalDeviceName("%s" % cpuNumber) > tests.append(test) > > return tests > > def getCPUFreqDirectories(self): > > if not os.path.exists(self.sysCPUDirectory): > print "Error: no file %s" % self.sysCPUDirectory > return None > # look for cpu subdirectories > pattern = re.compile("cpu(?P<cpuNumber>[0-9]+)") > self.cpufreqDirectories = list() > for subdirectory in os.listdir(self.sysCPUDirectory): > match = pattern.search(subdirectory) > if match and match.group("cpuNumber"): > cpufreqDirectory = "%s/%s/cpufreq" % (self.sysCPUDirectory, subdirectory) > if not os.path.exists(cpufreqDirectory): > print "Error: cpu %s has no cpufreq directory %s" % (match.group("cpuNumber"), cpufreqDirectory) > return None > # otherwise > self.cpufreqDirectories.append(cpufreqDirectory) > if len(self.cpufreqDirectories) is 0: > return None > # otherwise > return self.cpufreqDirectories > > def checkParameters(self, file): > current = None > for cpufreqDirectory in self.cpufreqDirectories: > parameters = self.getParameters(cpufreqDirectory, file) > if not parameters: > print "Error: could not determine cpu parameters from %s/%s" % (cpufreqDirectory, file) > return None > # otherwise > if not current: > current = parameters > elif not current == parameters: > return None > > return current > > > > def getParameters(self, cpufreqDirectory, file): > file = open("%s/%s" % (cpufreqDirectory, file)) > while 1: > line = file.readline() > if not line: > break > if len(line.strip()) > 0: > return line.strip().split() > return None > > def setParameter(self, switch, setFile, readFile, value): > # try the command for all cpus > result = True > try: > command = Command("cpufreq-selector -c %s -%s %s" % (self.getLogicalDeviceName(), switch, value)) > command.echo() > except HTSCommandException, exception: > print "Note: command failed: %s" % exception.command > result = False > > if not result: > print "Trying alternate method." > try: > command = Command("echo \"%s\" > %s/%s" % (value, self.cpufreqDirectory, setFile)) > command.echo() > except HTSCommandException, exception: > print "Error: command failed:" > print exception > return False > > # verify it has changed > parameterFile = open("%s/%s" % (self.cpufreqDirectory, readFile)) > line = parameterFile.readline() > if not line or line.strip() != value: > print "Error: could not verify that %s/%s was set to %s" % (self.cpufreqDirectory, readFile, value) > if line: > print "Actual Value: %s" % line > else: > print "parameter file was empty" > return False > > return True > > def setFrequency(self, frequency): > return self.setParameter("f", "scaling_setspeed", "scaling_cur_freq", frequency) > > def setGovernor(self, governor): > return self.setParameter("g", "scaling_governor", "scaling_governor", governor) > > > def getParameter(self, parameter): > value = None > parameterFile = open("%s/%s" % (self.cpufreqDirectory, parameter)) > line = parameterFile.readline() > if not line: > print "Error: failed to get %s for %s" % (parameter, cpufreqDirectory) > return None > value = line.strip() > return value > > def getParameterList(self, parameter): > values = list() > for cpufreqDirectory in self.cpufreqDirectories: > parameterFile = open("%s/%s" % (cpufreqDirectory, parameter)) > line = parameterFile.readline() > if not line: > print "Error: failed to get %s for %s" % (parameter, cpufreqDirectory) > return None > values.append(line.strip()) > > return values > > def runLoadTest(self): > print "Running CPU load test..." > try: > Command("taskset -pc %s %s" % (self.getLogicalDeviceName(), os.getpid())).echo() > except HTSCommandException, exception: > print "Error: could not set task affinity" > print exception > return None > > runTime = None > tries = 0 > while tries < self.retryLimit: > sys.stdout.flush() > (start_utime, start_stime, start_cutime, start_cstime, start_elapsed_time) = os.times() > # os.system("echo \"scale=2^12; 4*a(1)\" | bc -l > /dev/null") > self.pi() > (stop_utime, stop_stime, stop_cutime, stop_cstime, stop_elapsed_time) = os.times() > if not runTime: > runTime = stop_elapsed_time - start_elapsed_time > else: > thisTime = stop_elapsed_time - start_elapsed_time > print "comparing %.2f" % (abs(thisTime-runTime)/runTime) > if (abs(thisTime-runTime)/runTime)*100 < self.retryTolerance: > return runTime > else: > runTime = thisTime > tries += 1 > print "try %u - %.2f sec" % (tries, runTime) > > print "Error: could not repeat load test times within %.1f%%" % self.retryTolerance > return None > > def pi(self): > decimal.getcontext().prec = 500 > s = decimal.Decimal(1) > h = decimal.Decimal(3).sqrt()/2 > n = 6 > for i in range(170): > A = n*h*s/2 # A ... area of polygon > s2 = ((1-h)**2+s**2/4) > s = s2.sqrt() > h = (1-s2/4).sqrt() > n = 2*n > # print i,":",A > return True > > def verifyMinimumFrequency(self): > waitTime = 5 > sys.stdout.write("Waiting %d seconds..." % waitTime) > sys.stdout.flush() > time.sleep(waitTime) > sys.stdout.write(" done.\n") > minimumFrequency = self.getParameter("scaling_min_freq") > currentFrequency = self.getParameter("scaling_cur_freq") > if not minimumFrequency or not currentFrequency or (minimumFrequency != currentFrequency): > return False > > # otherwise > return True > > def getSystemCapabilities(self): > print "" > print "System Capabilites:" > print "-------------------------------------------------" > print "Testing cpu %s" % self.getLogicalDeviceName() > > # 1. Determine if the cpu's support scaling using presense or lack there of ~/cpufreq in sysfs > > if not self.getCPUFreqDirectories(): > return False > if len (self.cpufreqDirectories) > 1: > print "System has %u cpus"% len(self.cpufreqDirectories) > > # 2. Check ~/cpu[*]/scaling_available_freq files to ensure that all cpu's scale the same ammount; if not bail > freqFileName = "scaling_available_frequencies" > self.frequencies = self.checkParameters(freqFileName) > if not self.frequencies: > return False > > print "" > print "Supported CPU Frequencies: " > for freq in self.frequencies: > f = string.atoi(freq)/1000 > print " %u MHz" % f > print "" > > # 3. Check ~/cpu[*]/scaling_available_governors files to verify all cpu's support the same control methods > governorFileName = "scaling_available_governors" > self.governors = self.checkParameters(governorFileName) > if not self.governors: > return False > > # 4. Log the testable govs. which I suggest to be "ondemand", "userspace", and "performance"; each test below is as applicable > print "" > print "Supported Governors: " > comma = False > for governor in self.governors: > print " %s" % governor > > self.originalGovernors = self.getParameterList("scaling_governor") > if self.originalGovernors: > print "" > print "Current governors:" > i = 0 > for g in self.originalGovernors: > sys.stdout.write(" cpu%u: %s\n" % (i, g)) > i += 1 > else: > print "Error: could not determine current governor settings" > return False > > return True > > def runUserSpaceTests(self): > print "" > print "On Userspace Governor Test:" > print "-------------------------------------------------" > # 5. Set the govr.(*) to "userspace" for each cpu via a command similar to: > # 6. Verify the govr. setting took by checking ~/scaling_governor > self.differenceSpeedUp = None > self.minimumFrequencyTestTime = None > self.maximumFrequencyTestTime = None > success = True > governor = "userspace" > if governor in self.governors: > print "Setting governor to %s" % governor > if not self.setGovernor(governor): > success = False > > # 7. Set the the cpu speed to it's lowest value > frequency = self.frequencies[-1] > print "Setting cpu frequency to %u MHz" % (string.atoi(frequency)/1000) > if not self.setFrequency(frequency): > success = False > > # 8. Verify the speed is set to the lowest value by comparing ~/scaling_min_freq to ~/scaling_cur_freq > minimumFrequency = self.getParameter("scaling_min_freq") > currentFrequency = self.getParameter("scaling_cur_freq") > if not minimumFrequency or not currentFrequency or (minimumFrequency != currentFrequency): > print "Error: Could not verify that cpu frequency is set to the minimum value" > success = False > > # 9. Run and time non-cacheable work(?) test for each CPU > # 10. Repeat and time until execution times are within self.retryTolerance of each other > # run to verify the base line execution time, bail if self.retryTolerance margin cannot be acheived in self.retryLimit runs. > self.minimumFrequencyTestTime = self.runLoadTest() > if not self.minimumFrequencyTestTime: > success = False > print "Minumum frequency load test time: %.2f" % self.minimumFrequencyTestTime > > # 11. Set the cpu speed to it's highest value as above. > frequency = self.frequencies[0] > print "Setting cpu frequency to %u MHz" % (string.atoi(frequency)/1000) > if not self.setFrequency(frequency): > success = False > > maximumFrequency = self.getParameter("scaling_max_freq") > currentFrequency = self.getParameter("scaling_cur_freq") > if not maximumFrequency or not currentFrequency or (maximumFrequency != currentFrequency): > print "Error: Could not verify that cpu frequency is set to the maximum value" > success = False > > # 12. Repeat workload test, record timing > self.maximumFrequencyTestTime = self.runLoadTest() > if not self.maximumFrequencyTestTime: > success = False > print "Maximum frequency load test time: %.2f" % self.maximumFrequencyTestTime > > # 13. Verify MHz increase is comparable to time % decrease( eg. slow MHz/fast MHz ~= fast time/slow time; > # again with self.speedUpTolerance margin) > predictedSpeedup = string.atof(maximumFrequency)/string.atof(minimumFrequency) > measuredSpeedup = self.minimumFrequencyTestTime/self.maximumFrequencyTestTime > print "" > print "CPU Frequency Speed Up: %.2f" % predictedSpeedup > print "Measured Speed Up: %.2f" % measuredSpeedup > self.differenceSpeedUp = ((measuredSpeedup-predictedSpeedup)/predictedSpeedup)*100 > print "Percentage Difference %.1f%%" % self.differenceSpeedUp > if self.differenceSpeedUp > self.speedUpTolerance: > print "Error: measured speedup is not within %.1f%% margin." % self.speedUpTolerance > success = False > else: > print "Note: %s governor not supported" % governor > > return success > > def runOnDemandTests(self): > print "" > print "On Demand Governor Test:" > print "-------------------------------------------------" > self.differenceOnDemandVsMaximum = None > self.onDemandTestTime = None > governor = "ondemand" > success = True > if governor in self.governors: > # 14. Set the govr. to "ondemand" > #15. Verify the govr. is set as above > print "Setting governor to %s" % governor > if not self.setGovernor(governor): > success = False > > # 16. Wait a fixed period of time, then verify current speed is the slowest in as before > if not self.verifyMinimumFrequency(): > print "Error: Could not verify that cpu frequency has settled to the minimum value" > success = False > > # 17. Repeat workload test, record timing; also during testing verify the ~scaling_cur_freq reaches ~scaling_max_freq > self.onDemandTestTime = self.runLoadTest() > if not self.onDemandTestTime: > success = False > print "On Demand load test time: %.2f" % self.onDemandTestTime > > # 18. Compare the timing to the max results from earlier, again time should be within self.speedUpTolerance > self.differenceOnDemandVsMaximum = ((self.onDemandTestTime-self.maximumFrequencyTestTime)/self.maximumFrequencyTestTime)*100 > print "Percentage Difference vs. maximum frequency: %.1f%%" % self.differenceOnDemandVsMaximum > if self.differenceOnDemandVsMaximum > self.speedUpTolerance: > print "Error: on demand performance is not within %.1f%% margin" % self.speedUpTolerance > success = False > > # 19. Verify the current speed has returned to the lowest speed as before > if not self.verifyMinimumFrequency(): > print "Error: Could not verify that cpu frequency has settled to the minimum value" > success = False > else: > print "Note: %s governor not supported" % governor > > return success > > def runPerformanceTests(self): > > print "" > print "Performance Governor Test:" > print "-------------------------------------------------" > self.differencePerformanceVsMaximum = None > # 20. Set and verify the govr. to "performance" > governor = "performance" > success = True > if governor in self.governors: > print "Setting governor to %s" % governor > if not self.setGovernor(governor): > success = False > > # 21. Verify the current speed is the same as scaling_max_freq > maximumFrequency = self.getParameter("scaling_max_freq") > currentFrequency = self.getParameter("scaling_cur_freq") > if not maximumFrequency or not currentFrequency or (maximumFrequency != currentFrequency): > print "Error: Could not verify that cpu frequency is set to the maximum value" > success = False > > # 22. Repeat workload test, record timing, also verify frequency does not drop during run > self.performanceTestTime = self.runLoadTest() > if not self.performanceTestTime: > success = False > print "Performance load test time: %.2f" % self.performanceTestTime > > # 23. Compare the timing to the max results for a self.speedUpTolerance delta > self.differencePerformanceVsMaximum = ((self.performanceTestTime-self.maximumFrequencyTestTime)/self.maximumFrequencyTestTime)*100 > print "Percentage Difference vs. maximum frequency: %.1f%%" % self.differencePerformanceVsMaximum > if self.differencePerformanceVsMaximum > self.speedUpTolerance: > print "Error: performance setting is not within %.1f%% margin" % self.speedUpTolerance > success = False > > else: > print "Note: %s governor not supported" % governor > > return success > > def restoreGovernors(self): > print "Restoring original governor to %s" % (self.originalGovernors[0]) > self.setGovernor(self.originalGovernors[0]) > > > def printSummary(self): > print "" > print "Summary:" > print "-------------------------------------------------" > print "Load Test Times:" > if self.minimumFrequencyTestTime: > print " Minimum: %.2f" % self.minimumFrequencyTestTime > if self.maximumFrequencyTestTime: > print " Maximum: %.2f" % self.maximumFrequencyTestTime > if self.onDemandTestTime: > print " On Demand: %.2f" % self.onDemandTestTime > if self.performanceTestTime: > print " Performance: %.2f" % self.performanceTestTime > > print "Margins:" > if self.differenceSpeedUp: > print " Speed Up: %.1f%%" % self.differenceSpeedUp > if self.differenceOnDemandVsMaximum: > print " On Demand: %.1f%%" % self.differenceOnDemandVsMaximum > if self.differencePerformanceVsMaximum: > print " Performance: %.1f%%" % self.differencePerformanceVsMaximum > > print "" > > def run(self): > PASSED = 0 > FAILED = 1 > > > if not self.getSystemCapabilities(): > return FAILED > > result = PASSED > > if not self.runUserSpaceTests(): > result = FAILED > > if not self.runOnDemandTests(): > result = FAILED > > if not self.runPerformanceTests(): > result = FAILED > > self.printSummary() > > self.restoreGovernors() > > return result > > >if __name__ == "__main__": > test = CPUScalingTest() > returnValue = test.do(sys.argv) > sys.exit(returnValue)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 463354
:
317490
| 318602