Author: gnichols
Date: 2011-03-08 13:51:50 +0000 (Tue, 08 Mar 2011)
New Revision: 795
Modified:
trunk/tests/cpuscaling/cpuscaling.py
Log:
579498 - RH cert suite cpuscaling test fails Nehalem-EX procs
Modified: trunk/tests/cpuscaling/cpuscaling.py
===================================================================
--- trunk/tests/cpuscaling/cpuscaling.py 2011-03-08 13:08:47 UTC (rev 794)
+++ trunk/tests/cpuscaling/cpuscaling.py 2011-03-08 13:51:50 UTC (rev 795)
@@ -22,6 +22,7 @@
import time
import dbus
import decimal
+import signal
from v7.tags import Constants, DeviceClass, TestTag
from v7.test import Test
@@ -38,79 +39,83 @@
self.retryTolerance = 5.0 # percent
self.sysCPUDirectory = "/sys/devices/system/cpu"
self.idaFlag = "ida"
- self.idaSpeedupFactor = 8.0 # percent
+ self.idaSpeedupFactor = 8.0 # percent
+ self.turboSpeedupTolerance = 5.0 # percent - test expects turbo/ida to increase performance by more than this
self.selfTestData = [10.0, 10.0, 10.0, 10.0] # min, max, ondemand, performance
self.selfTestStep = 0
self.deviceClass = DeviceClass.processor
+ self.cpuNumbers = None
+ self.cpuToPackage = None
+ self.packageToCpus = None
+ self.workloads = ["minimum", "maximum", "ondemand", "performance"]
+ self.workloadTime = dict() # workload run time list indexed by [workload][cpu]
+
+ def setWorkloadTime(self, workload, cpu, time):
+ if not workload in self.workloadTime:
+ self.workloadTime[workload] = dict()
+ if not cpu in self.workloadTime[workload]:
+ self.workloadTime[workload][cpu] = list()
+ self.workloadTime[workload][cpu].append(time)
+ def getWorkloadTime(self, workload, cpu):
+ try:
+ return self.workloadTime[workload][cpu][-1] # get the last time
+ except KeyError:
+ return None
+
+ def getWorkloadTimes(self, workload, cpu):
+ try:
+ return self.workloadTime[workload][cpu] # get the whole list of times
+ except KeyError:
+ return None
+ def getWorkloadTimesLength(self, workload):
+ """ return the max number of entries of any cpu """
+ max = 0
+ for cpu in self.workloadTime[workload]:
+ if len(self.workloadTime[workload][cpu]) > max:
+ max = len(self.workloadTime[workload][cpu])
+ return max
+
+ def speedup(self, cpu):
+ return self.getWorkloadTime("minimum", cpu)/self.getWorkloadTime("maximum", cpu)
+
+ def speedupMargin(self, cpu):
+ return (abs(self.speedup(cpu)-self.predictedSpeedup)/self.predictedSpeedup)*100
+
+ def margin(self, cpu, workload):
+ return (abs(self.getWorkloadTime(workload,cpu)-self.getWorkloadTime("maximum",cpu))/self.getWorkloadTime("maximum",cpu))*100
+
def tags(self):
return [TestTag.noninteractive, TestTag.certification]
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
-
- # if no "can_throttle", check the /sys file system
+ # check the /sys file system to see if scaling looks possible
self.getCPUFreqDirectories()
- if not canThrottle and self.cpufreqDirectories:
- for directory in self.cpufreqDirectories:
+ cpuScalingSupported = False
+ if self.cpufreqDirectories:
+ for directory in self.cpufreqDirectories.values():
availableFreq = os.path.join(directory, "scaling_available_frequencies")
if os.path.exists(availableFreq):
# if there's more than one frequency, then schedule the tests
freqs = open(availableFreq)
line = freqs.readline()
if line and len(line.split()) > 1:
- canThrottle = True
+ cpuScalingSupported = True
freqs.close()
+ # if cpu scaling is supported, just schedule one test.
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)
+ if cpuScalingSupported:
+ test = self.makeCopy()
+ tests.append(test)
return tests
def verify(self):
- if not self.getLogicalDeviceName():
- while True:
- cpuNumber = self.prompt("Please enter the cpu number to be tested:")
- try:
- int(cpuNumber)
- self.setLogicalDeviceName(cpuNumber)
- self.parameters.set(Constants.DEVICE, cpuNumber)
- break
- except ValueError:
- print "Please enter just the integer cpu number."
-
- # do a quick test to see if the cpu number is usable
- cpuDirectories = self.getCPUFreqDirectories()
- for directory in cpuDirectories:
- if ("cpu" + self.getLogicalDeviceName()) in directory:
- return True
- # otherwise
- print "Error: there is no cpufreq directory for cpu" + self.getLogicalDeviceName()
- return False
-
-
-
-
+ # disable for now
+ return True
def getCPUFreqDirectories(self):
- self.cpufreqDirectory = "%s/cpu%s/cpufreq" % (self.sysCPUDirectory, self.getLogicalDeviceName())
-
if not os.path.exists(self.sysCPUDirectory):
print "Error: no file %s" % self.sysCPUDirectory
return None
@@ -120,18 +125,22 @@
for subdirectory in os.listdir(self.sysCPUDirectory):
match = pattern.search(subdirectory)
if match and match.group("cpuNumber"):
+ cpuNumber = match.group("cpuNumber")
+ if not self.cpuNumbers:
+ self.cpuNumbers = list()
+ self.cpuNumbers.append(cpuNumber)
cpufreqDirectory = "%s/%s/cpufreq" % (self.sysCPUDirectory, subdirectory)
if not os.path.exists(cpufreqDirectory):
continue
# otherwise
if not self.cpufreqDirectories:
- self.cpufreqDirectories = list()
- self.cpufreqDirectories.append(cpufreqDirectory)
+ self.cpufreqDirectories = dict()
+ self.cpufreqDirectories[cpuNumber] = cpufreqDirectory
return self.cpufreqDirectories
def checkParameters(self, file):
current = None
- for cpufreqDirectory in self.cpufreqDirectories:
+ for cpufreqDirectory in self.cpufreqDirectories.values():
parameters = self.getParameters(cpufreqDirectory, file)
if not parameters:
print "Error: could not determine cpu parameters from %s/%s" % (cpufreqDirectory, file)
@@ -156,11 +165,18 @@
return line.strip().split()
return None
- def setParameter(self, switch, setFile, readFile, value):
- # try the command for all cpus
+ def setPackageParameter(self, switch, setFile, readFile, value):
+ # try the command for all cpus in the package
result = True
+ for cpu in self.packageToCpus[self.currentPackage]:
+ if not self.setParameter(cpu, switch, setFile, readFile, value):
+ result = False
+ return result
+
+ def setParameter(self, cpu, switch, setFile, readFile, value):
+ result = True
try:
- command = Command("cpufreq-selector -c %s -%s %s" % (self.getLogicalDeviceName(), switch, value))
+ command = Command("cpufreq-selector -c %s -%s %s" % (cpu, switch, value))
command.echo()
except V7CommandException, exception:
print "Note: command failed: %s" % exception.command
@@ -169,7 +185,7 @@
if not result:
print "Trying alternate method."
try:
- command = Command("echo \"%s\" > %s/%s" % (value, self.cpufreqDirectory, setFile))
+ command = Command("echo \"%s\" > %s/%s" % (value, cpu, setFile))
command.echo()
except V7CommandException, exception:
print "Error: command failed:"
@@ -177,10 +193,10 @@
return False
# verify it has changed
- parameterFile = open("%s/%s" % (self.cpufreqDirectory, readFile))
+ parameterFile = open("%s/%s" % (self.cpufreqDirectories[cpu], 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)
+ print "Error: could not verify that %s/%s was set to %s" % (self.cpufreqDirectories[cpu], readFile, value)
if line:
print "Actual Value: %s" % line
else:
@@ -190,20 +206,30 @@
return True
def setFrequency(self, frequency):
- return self.setParameter("f", "scaling_setspeed", "scaling_cur_freq", frequency)
+ return self.setPackageParameter("f", "scaling_setspeed", "scaling_cur_freq", frequency)
def setGovernor(self, governor):
- return self.setParameter("g", "scaling_governor", "scaling_governor", governor)
+ return self.setPackageParameter("g", "scaling_governor", "scaling_governor", governor)
-
- def getParameter(self, parameter):
+ def getPackageParameter(self, parameter):
+ packageParameterValue = None
+ for cpu in self.packageToCpus[self.currentPackage]:
+ value = self.getParameter(cpu, parameter)
+ if value and not packageParameterValue:
+ packageParameterValue = value
+ elif value != packageParameterValue:
+ print "Error: cpu%s in package %s has the value %s which differs from other cpus in the package" % (cpu, self.currentPackage, value)
+ return None
+ return packageParameterValue
+
+ def getParameter(self, cpu, parameter):
value = None
- parameterFilePath = "%s/%s" % (self.cpufreqDirectory, parameter)
+ parameterFilePath = "%s/%s" % (self.cpufreqDirectories[cpu], parameter)
try:
parameterFile = open(parameterFilePath)
line = parameterFile.readline()
if not line:
- print "Error: failed to get %s for %s" % (parameter, cpufreqDirectory)
+ print "Error: failed to get %s for %s" % (parameter, self.cpufreqDirectories[cpu])
return None
value = line.strip()
return value
@@ -215,7 +241,7 @@
def getParameterList(self, parameter):
values = list()
- for cpufreqDirectory in self.cpufreqDirectories:
+ for cpufreqDirectory in self.cpufreqDirectories.values():
parameterFile = open("%s/%s" % (cpufreqDirectory, parameter))
line = parameterFile.readline()
if not line:
@@ -225,31 +251,23 @@
return values
- def _runLoadTest(self):
+ def runLoadTest(self, cpu=None):
+ """ run package load test, cpu default None means for all cpus """
print "Running CPU load test..."
- sys.stdout.flush()
- try:
- Command("taskset -pc %s %s" % (self.getLogicalDeviceName(), os.getpid())).echo()
- except V7CommandException, 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()
+ averageProcessTime = self.__runSubprocessLoadTest(cpu)
+ print "average worker process time: %.2f seconds" % averageProcessTime
if not runTime:
- runTime = stop_elapsed_time - start_elapsed_time
+ runTime = averageProcessTime
else:
- thisTime = stop_elapsed_time - start_elapsed_time
+ thisTime = averageProcessTime
# print "comparing %.2f" % (abs(thisTime-runTime)/runTime)
if (abs(thisTime-runTime)/runTime)*100 < self.retryTolerance:
- return runTime
+ return thisTime
else:
runTime = thisTime
tries += 1
@@ -258,39 +276,59 @@
print "Error: could not repeat load test times within %.1f%%" % self.retryTolerance
return None
- def runLoadTest(self):
- result = self._runLoadTest()
- print "CPU Load finished."
- sys.stdout.flush()
- if self.getMode() == Constants.self:
- print "Warning: in self-test mode, returning face data"
- result = self.selfTestData[self.selfTestStep]
- self.selfTestStep = self.selfTestStep + 1
- return result
+ def __runSubprocessLoadTest(self, cpu=None):
+ print "Running load test for package " + self.currentPackage
+ self.loadProcesses = dict()
-
- 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
+ # if cpu is set, just load that one
+ if cpu:
+ loadProcess = LoadProcess(self, cpu)
+ loadProcess.start()
+ self.loadProcesses[cpu] = loadProcess
+ else: # load all cpus in the package
+ for cpu in self.packageToCpus[self.currentPackage]:
+ loadProcess = LoadProcess(self, cpu)
+ loadProcess.start()
+ self.loadProcesses[cpu] = loadProcess
+
+ print "waiting for load processes..."
+ totalProcessTime = 0
+ numberOfProcesses = len(self.loadProcesses)
+ while len(self.loadProcesses) > 0 :
+ for (cpu, process) in self.loadProcesses.items():
+ if process.isDone():
+ if process.returnCode is not 0:
+ print "Error: load process terminated with return code " + process.returnCode
+ return None
+ runTime = process.getRunTime()
+ if not runTime:
+ print "Error: could not find process run time"
+ return None
+ # otherwise - collect info
+ print "process for cpu %s is done in %.2f seconds" % (cpu, runTime)
+ self.setWorkloadTime(self.currentWorkload, cpu, runTime)
+ totalProcessTime += runTime
+ del self.loadProcesses[cpu]
+
+ time.sleep(1) # poll once per second
+ print "processes complete"
+ return totalProcessTime/numberOfProcesses
+ def done(self, cpu):
+ print "process for cpu %s is done. (caught SIGCHLD)" % cpu
+ try:
+ del self.loadProcesses[cpu]
+ except KeyError:
+ print "Error: no cpu %s in load processes" % cpu
+
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")
+ minimumFrequency = self.getPackageParameter("scaling_min_freq")
+ currentFrequency = self.getPackageParameter("scaling_cur_freq")
if not minimumFrequency or not currentFrequency or (minimumFrequency != currentFrequency):
return False
@@ -301,7 +339,6 @@
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
@@ -309,8 +346,35 @@
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
+
+ # 1.5 get core/package topology
+ if self.cpuNumbers:
+ for cpuNumber in self.cpuNumbers:
+ sys.stdout.flush()
+ parameters = self.getParameters(os.path.join(self.sysCPUDirectory, ("cpu" + cpuNumber), "topology"), "physical_package_id")
+ if parameters and len(parameters) == 1:
+ packageNumber = parameters[0]
+ if not self.cpuToPackage:
+ self.cpuToPackage = dict()
+ self.cpuToPackage[cpuNumber] = packageNumber
+ if not self.packageToCpus:
+ self.packageToCpus = dict()
+ if not packageNumber in self.packageToCpus:
+ self.packageToCpus[packageNumber] = list()
+ if cpuNumber not in self.packageToCpus[packageNumber]:
+ self.packageToCpus[packageNumber].append(cpuNumber)
+ else:
+ print "Warning: could not determine cpu topology: no package ID for cpu " + cpuNumber
+ # print them out
+ for package in self.packageToCpus.keys():
+ sys.stdout.write("package %s has cpus: " % package)
+ sys.stdout.write(", ".join(self.packageToCpus[package]))
+ print ""
+ print ""
+
+ # 2. Check ~/cpu[*]/scaling_available_freq files to ensure that all cpu's scale the same amount; if not bail
+ print "Checking freguencies"
+ sys.stdout.flush()
freqFileName = "scaling_available_frequencies"
frequencies = self.checkParameters(freqFileName)
if not frequencies:
@@ -351,6 +415,8 @@
print "Error: could not determine current governor settings"
return False
+
+
self.getCPUFlags()
sys.stdout.flush()
@@ -366,6 +432,16 @@
print "Warning: could not read CPU flags"
print exception
+ def turboBoostSupported(self):
+ # if "ida" turbo thing, increase the expectation by 8%
+ if self.cpuFlags and self.idaFlag in self.cpuFlags:
+ return True
+ #otherwise
+ return False
+
+ # print "Note: found %s flag, increasing expected speedup by %.1f%%" % (self.idaFlag, self.idaSpeedupFactor)
+ # self.predictedSpeedup = self.predictedSpeedup*(1.0/(1.0-(self.idaSpeedupFactor/100.0)))
+
def runUserSpaceTests(self):
print ""
@@ -375,8 +451,11 @@
# 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
+ # calculate predicted (theoretical) speed up based on scaling frequencies
+ maximumFrequency = self.getPackageParameter("scaling_max_freq")
+ minimumFrequency = self.getPackageParameter("scaling_min_freq")
+ self.predictedSpeedup = string.atof(maximumFrequency)/string.atof(minimumFrequency)
+
success = True
governor = "userspace"
if governor in self.governors:
@@ -386,15 +465,18 @@
# 7. Set the the cpu speed to it's lowest value
frequency = self.frequencies[0]
- currentFrequency = self.getParameter("scaling_cur_freq")
- print "Changing cpu frequency from %u to %u MHz" % (int(currentFrequency)/1000, (frequency/1000))
+ currentFrequency = self.getPackageParameter("scaling_cur_freq")
+ if currentFrequency:
+ print "Changing cpu frequency from %u to %u MHz" % (int(currentFrequency)/1000, (frequency/1000))
+ else:
+ print "Setting cpu frequency to %u MHz" % (frequency/1000)
if not self.setFrequency("%u" % frequency):
success = False
+ self.currentWorkload = "minimum"
sys.stdout.flush()
# 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")
+ currentFrequency = self.getPackageParameter("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 of %s" % minimumFrequency
success = False
@@ -405,17 +487,17 @@
self.minimumFrequencyTestTime = self.runLoadTest()
if not self.minimumFrequencyTestTime:
return False
- print "Minumum frequency load test time: %.2f" % self.minimumFrequencyTestTime
+ print "Minumum frequency average load test time: %.2f" % self.minimumFrequencyTestTime
# 11. Set the cpu speed to it's highest value as above.
frequency = self.frequencies[-1]
- currentFrequency = self.getParameter("scaling_cur_freq")
+ currentFrequency = self.getPackageParameter("scaling_cur_freq")
print "Changing cpu frequency from %u to %u MHz" % (int(currentFrequency)/1000, (frequency/1000))
if not self.setFrequency("%u" % frequency):
success = False
+ self.currentWorkload = "maximum"
- maximumFrequency = self.getParameter("scaling_max_freq")
- currentFrequency = self.getParameter("scaling_cur_freq")
+ currentFrequency = self.getPackageParameter("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 of %s" % maximumFrequency
success = False
@@ -424,26 +506,23 @@
self.maximumFrequencyTestTime = self.runLoadTest()
if not self.maximumFrequencyTestTime:
return False
- print "Maximum frequency load test time: %.2f" % self.maximumFrequencyTestTime
+ print "Maximum frequency average 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)
+
- # if "ida" turbo thing, increase the expectation by 8%
- if self.cpuFlags and self.idaFlag in self.cpuFlags:
- print "Note: found %s flag, increasing expected speedup by %.1f%%" % (self.idaFlag, self.idaSpeedupFactor)
- predictedSpeedup = predictedSpeedup*(1.0/(1.0-(self.idaSpeedupFactor/100.0)))
-
- measuredSpeedup = self.minimumFrequencyTestTime/self.maximumFrequencyTestTime
- print ""
- print "CPU Frequency Speed Up: %.2f" % predictedSpeedup
- print "Measured Speed Up: %.2f" % measuredSpeedup
- self.differenceSpeedUp = (abs(measuredSpeedup-predictedSpeedup)/predictedSpeedup)*100
- print "Percentage Difference %.1f%%" % self.differenceSpeedUp
- if self.differenceSpeedUp > self.speedUpTolerance:
- print "Error: measured speedup vs expected speedup is %.1f%% and is not within %.1f%% margin. " % (self.differenceSpeedUp, self.speedUpTolerance)
- success = False
+ # for each cpu in the package
+ for cpu in self.packageToCpus[self.currentPackage]:
+ measuredSpeedup = self.speedup(cpu)
+ print ""
+ print "CPU Frequency Speed Up: %.2f" % self.predictedSpeedup
+ print "CPU %s Measured Speed Up: %.2f" % (cpu, measuredSpeedup)
+ self.differenceSpeedUp = self.speedupMargin(cpu)
+ print "Percentage Difference %.1f%%" % self.differenceSpeedUp
+ if self.differenceSpeedUp > self.speedUpTolerance:
+ print "Error: measured speedup vs expected speedup is %.1f%% and is not within %.1f%% margin. " % (self.differenceSpeedUp, self.speedUpTolerance)
+ success = False
else:
print "Note: %s governor not supported" % governor
@@ -463,6 +542,7 @@
print "Setting governor to %s" % governor
if not self.setGovernor(governor):
success = False
+ self.currentWorkload = "ondemand"
# 16. Wait a fixed period of time, then verify current speed is the slowest in as before
if not self.verifyMinimumFrequency():
@@ -476,15 +556,17 @@
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
- if self.maximumFrequencyTestTime:
- self.differenceOnDemandVsMaximum = (abs(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 vs maximum of %.1f%% is not within %.1f%% margin" % (self.differenceOnDemandVsMaximum, self.speedUpTolerance)
+ # for each cpu in the package
+ for cpu in self.packageToCpus[self.currentPackage]:
+ if self.getWorkloadTime("maximum", cpu):
+ self.differenceOnDemandVsMaximum = self.margin(cpu, "ondemand")
+ print "Percentage Difference vs. maximum frequency: %.1f%%" % self.differenceOnDemandVsMaximum
+ if self.differenceOnDemandVsMaximum > self.speedUpTolerance:
+ print "Error: on demand performance vs maximum of %.1f%% is not within %.1f%% margin" % (self.differenceOnDemandVsMaximum, self.speedUpTolerance)
+ success = False
+ else:
+ print "No maximum frequency test data to compare"
success = False
- else:
- print "No maximum frequency test data to compare"
- success = False
# 19. Verify the current speed has returned to the lowest speed as before
if not self.verifyMinimumFrequency():
@@ -508,10 +590,11 @@
print "Setting governor to %s" % governor
if not self.setGovernor(governor):
success = False
+ self.currentWorkload = "performance"
# 21. Verify the current speed is the same as scaling_max_freq
- maximumFrequency = self.getParameter("scaling_max_freq")
- currentFrequency = self.getParameter("scaling_cur_freq")
+ maximumFrequency = self.getPackageParameter("scaling_max_freq")
+ currentFrequency = self.getPackageParameter("scaling_cur_freq")
if not maximumFrequency or not currentFrequency or (maximumFrequency != currentFrequency):
print "Error: Current cpu frequency of %.2f is not set to the maximum value of %.2f" % (currentFrequency, maximumFrequency)
return False
@@ -524,45 +607,162 @@
print "Performance load test time: %.2f" % self.performanceTestTime
# 23. Compare the timing to the max results for a self.speedUpTolerance delta
- self.differencePerformanceVsMaximum = (abs(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 vs maximum of %.1f%% is not within %.1f%% margin" % (self.differencePerformanceVsMaximum, self.speedUpTolerance)
- success = False
+ for cpu in self.packageToCpus[self.currentPackage]:
+ self.differencePerformanceVsMaximum = self.margin(cpu, "performance")
+ print "Percentage Difference vs. maximum frequency: %.1f%%" % self.differencePerformanceVsMaximum
+ if self.differencePerformanceVsMaximum > self.speedUpTolerance:
+ print "Error: performance setting vs maximum of %.1f%% is not within %.1f%% margin" % (self.differencePerformanceVsMaximum, self.speedUpTolerance)
+ success = False
else:
print "Note: %s governor not supported" % governor
return success
+ def runTurboBoostTest(self):
+ """ test one cpu in the package while others are idle, and verify that its speedup is greater than when all
+ cpus in the package are loaded """
+ print ""
+ print "Turbo Boost Test:"
+ print "-------------------------------------------------"
+ self.differenceTurboVsMaximum = None
+ # 30. Set and verify the govr. to "performance"
+ governor = "ondemand"
+ success = True
+ if governor in self.governors:
+ print "Setting governor to %s" % governor
+ if not self.setGovernor(governor):
+ success = False
+ self.currentWorkload = "turbo"
+
+ # 32 Pick a cpu other than cpu0 to load
+ turboCpu = self.getTurboCpu()
+ print "Using cpu %s to test Turbo/IDA performance" % turboCpu
+
+
+ # 33. Repeat workload test, loading a single cpu
+ self.turboTestTime = self.runLoadTest(cpu=turboCpu)
+ if not self.turboTestTime:
+ return False
+ # otherwise
+ print "Turbo/IDA load test time: %.2f" % self.turboTestTime
+
+ # 23. Compare the timing to the max results for a self.speedUpTolerance delta
+ self.differenceTurboVsMaximum = self.margin(turboCpu, "turbo")
+ print "Percentage Difference vs. maximum frequency: %.1f%%" % self.differenceTurboVsMaximum
+ if self.differenceTurboVsMaximum < self.turboSpeedupTolerance:
+ print "Error: turbo/IDA setting vs maximum of %.1f%% is not within %.1f%% margin" % (self.differenceTurboVsMaximum, self.turboSpeedupTolerance)
+ success = False
+
+ else:
+ print "Error: %s governor not supported" % governor
+ success = False
+
+ return success
+
+ def getTurboCpu(self):
+ # 32 Pick a cpu other than cpu0 to load
+ for turboCpu in self.packageToCpus[self.currentPackage]:
+ if turboCpu != "0":
+ break
+ return turboCpu
+
def restoreGovernors(self):
print "Restoring original governor to %s" % (self.originalGovernors[0])
self.setGovernor(self.originalGovernors[0])
+ def runSummary(self):
+ for package in self.packageToCpus.keys():
+ self.printSummary(package)
+
+ for package in self.packageToCpus.keys():
+ self.printWorkloadTimeSummary(package)
+
+ return True
+
- def printSummary(self):
+ def printSummary(self, package):
+ """ tables: row title is 13 characters, each cpu cell is 9 characters """
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 "Summary for Package %s:" % package
+ self.__printBorder(package)
+ sys.stdout.write("Workload ")
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write(" cpu %-3s " % cpu)
print ""
+ self.__printBorder(package)
+ for workload in self.workloads:
+ if workload in self.workloadTime:
+ sys.stdout.write("%-13s" % workload)
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write("%9.2f" % self.getWorkloadTime(workload, cpu))
+ print ""
+ print "\n"
+
+ sys.stdout.write("Speedup ")
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write(" cpu %-3s " % cpu)
+ print ""
+ self.__printBorder(package)
+ sys.stdout.write("expected ")
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write("%9.2f" % self.predictedSpeedup)
+ print ""
+ sys.stdout.write("actual ")
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write("%9.2f" % self.speedup(cpu))
+ print ""
+ sys.stdout.write("margin ")
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write("%8.2f%%" % self.speedupMargin(cpu))
+ print ""
+ for workload in ["ondemand", "performance"]:
+ if workload in self.workloadTime.keys(): # iterate over logged workloads
+ sys.stdout.write("%-13s" % workload)
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write("%8.2f%%" % self.margin(cpu, workload))
+ print ""
+ if "turbo" in self.workloadTime:
+ sys.stdout.write("%-13s" % "turbo")
+ turboCpu = self.getTurboCpu()
+ for cpu in self.packageToCpus[package]:
+ if cpu == turboCpu:
+ sys.stdout.write("%8.2f%%" % self.margin(cpu, "turbo"))
+ else:
+ sys.stdout.write(" - ")
+ print ""
+ print "\n"
+
+ def printWorkloadTimeSummary(self, package):
+ sys.stdout.write("Workload run times for package %s:\n" % package)
+ sys.stdout.write("-------------------\n")
+ workloads = self.workloads
+ workloads.append("turbo")
+ for workload in workloads:
+ if workload in self.workloadTime:
+ sys.stdout.write("%-13s" % workload)
+ run = 1
+ for run in range(1, self.getWorkloadTimesLength(workload)+1):
+ sys.stdout.write(" %7u " % run)
+ run += 1
+ sys.stdout.write("\n")
+ for cpu in self.packageToCpus[package]:
+ if self.getWorkloadTimes(workload, cpu):
+ sys.stdout.write(" cpu %3s: " % cpu)
+ for time in self.getWorkloadTimes(workload, cpu):
+ if time:
+ sys.stdout.write("%9.2f" % time)
+ else:
+ sys.stdout.write(" - ")
+ print ""
+ print ""
+ print "\n"
+
+ def __printBorder(self, package):
+ sys.stdout.write("-------------") # 13 for row title
+ for cpu in self.packageToCpus[package]:
+ sys.stdout.write(" --------") # 9 for cpu cell ( 1 space, 8 -)
+ sys.stdout.write("\n")
def run(self):
PASSED = 0
@@ -570,28 +770,121 @@
if not self.runSubTest(self.getSystemCapabilities, "Capabilities"):
return FAILED
-
- self.waitForLull()
- result = PASSED
+ for package in self.packageToCpus.keys():
+
+ print "Testing CPU Package " + package
+ self.currentPackage = package
+
+ self.waitForLull()
+
+ result = PASSED
+
+ if not self.runSubTest(self.runUserSpaceTests, "User Space, package %s" % package):
+ result = FAILED
+
+
+ if not self.runSubTest(self.runOnDemandTests, "On Demand, package %s" % package):
+ result = FAILED
+
+ if not self.runSubTest(self.runPerformanceTests, "Performance, package %s" % package):
+ result = FAILED
+
+ if self.turboBoostSupported():
+ if not self.runSubTest(self.runTurboBoostTest, "Turbo Boost/IDA, package %s" % package):
+ result = FAILED
+
- if not self.runSubTest(self.runUserSpaceTests, "User Space"):
- result = FAILED
+ self.restoreGovernors()
+
+ if not self.runSubTest(self.runSummary, "Summary"):
+ result = FAILED
+
+
- if not self.runSubTest(self.runOnDemandTests, "On Demand"):
- result = FAILED
-
- if not self.runSubTest(self.runPerformanceTests, "Performance"):
- result = FAILED
- self.printSummary()
+ return result
+
+class LoadProcess:
+ def __init__(self, owner, cpu):
+ self.owner = owner
+ self.cpu = cpu
+ self.workProcess = None
+ self.returnCode = None
+ self.start_elapsed_time = None
+ self.runTime = None
+ # signal.signal(signal.SIGCHLD, self.sigChldHandler)
+
+ def start(self):
+ try:
+ print "starting process for cpu %s" % self.cpu
+ self.workProcess = Command("./cpuscaling.py work %s" % self.cpu)
+ self.workProcess.start()
+ taskset = Command("taskset -pc %s %s" % (self.cpu, self.workProcess.getPID()))
+ if self.owner.debug != Constants.off:
+ taskset.echo()
+ else:
+ taskset.run()
+ except V7CommandException, exception:
+ print "Error: could not start load process"
+ print exception
+ print exception.command.printErrors()
+ return False
+ return True
+
+ def getRunTime(self):
+ return self.runTime
+
+ def sigChldHandler(self, signalNumber, stackFrame):
+ print "Got signal %d" % signalNumber
+ self.__stopTimer()
+ self.owner.done(self.cpu)
- self.restoreGovernors()
+ def isDone(self):
+ if self.workProcess and self.workProcess.poll() is not None:
+ self.returnCode = self.workProcess.poll()
+ while True:
+ line = self.workProcess.readline()
+ if line:
+ try:
+ self.runTime = float(line)
+ return True
+ except ValueError:
+ pass # keep trying
+ else:
+ print "Error: could not determine process run time"
+ break
+ return True
+ # otherwise
+ return False
+
+ def getReturnCode(self):
+ return self.returnCode
+
+def pi():
+ 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
- return result
-
-
if __name__ == "__main__":
+
+ if "work" in sys.argv:
+ (start_utime, start_stime, start_cutime, start_cstime, start_elapsed_time) = os.times()
+ pi()
+ (stop_utime, stop_stime, stop_cutime, stop_cstime, stop_elapsed_time) = os.times()
+ runTime = stop_elapsed_time - start_elapsed_time
+ print runTime
+ sys.exit(0)
+
test = CPUScalingTest()
returnValue = test.do(sys.argv)
sys.exit(returnValue)