Commit e3e2ffdc authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge back earlier power management tools updates for v5.4.

parents a41f7f0a 42161483
p m - g r a p h p m - g r a p h
pm-graph: suspend/resume/boot timing analysis tools pm-graph: suspend/resume/boot timing analysis tools
Version: 5.4 Version: 5.5
Author: Todd Brandt <todd.e.brandt@intel.com> Author: Todd Brandt <todd.e.brandt@intel.com>
Home Page: https://01.org/pm-graph Home Page: https://01.org/pm-graph
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
- upstream version in git: - upstream version in git:
https://github.com/intel/pm-graph/ https://github.com/intel/pm-graph/
Requirements:
- runs with python2 or python3, choice is made by /usr/bin/python link
- python2 now requires python-configparser be installed
Table of Contents Table of Contents
- Overview - Overview
- Setup - Setup
......
#!/usr/bin/python2 #!/usr/bin/python
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# #
# Tool for analyzing boot timing # Tool for analyzing boot timing
# Copyright (c) 2013, Intel Corporation. # Copyright (c) 2013, Intel Corporation.
# #
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope 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.
#
# Authors: # Authors:
# Todd Brandt <todd.e.brandt@linux.intel.com> # Todd Brandt <todd.e.brandt@linux.intel.com>
# #
...@@ -81,7 +90,7 @@ class SystemValues(aslib.SystemValues): ...@@ -81,7 +90,7 @@ class SystemValues(aslib.SystemValues):
cmdline = 'initcall_debug log_buf_len=32M' cmdline = 'initcall_debug log_buf_len=32M'
if self.useftrace: if self.useftrace:
if self.cpucount > 0: if self.cpucount > 0:
bs = min(self.memtotal / 2, 2*1024*1024) / self.cpucount bs = min(self.memtotal // 2, 2*1024*1024) // self.cpucount
else: else:
bs = 131072 bs = 131072
cmdline += ' trace_buf_size=%dK trace_clock=global '\ cmdline += ' trace_buf_size=%dK trace_clock=global '\
...@@ -137,13 +146,13 @@ class SystemValues(aslib.SystemValues): ...@@ -137,13 +146,13 @@ class SystemValues(aslib.SystemValues):
if arg in ['-h', '-v', '-cronjob', '-reboot', '-verbose']: if arg in ['-h', '-v', '-cronjob', '-reboot', '-verbose']:
continue continue
elif arg in ['-o', '-dmesg', '-ftrace', '-func']: elif arg in ['-o', '-dmesg', '-ftrace', '-func']:
args.next() next(args)
continue continue
elif arg == '-result': elif arg == '-result':
cmdline += ' %s "%s"' % (arg, os.path.abspath(args.next())) cmdline += ' %s "%s"' % (arg, os.path.abspath(next(args)))
continue continue
elif arg == '-cgskip': elif arg == '-cgskip':
file = self.configFile(args.next()) file = self.configFile(next(args))
cmdline += ' %s "%s"' % (arg, os.path.abspath(file)) cmdline += ' %s "%s"' % (arg, os.path.abspath(file))
continue continue
cmdline += ' '+arg cmdline += ' '+arg
...@@ -292,11 +301,11 @@ def parseKernelLog(): ...@@ -292,11 +301,11 @@ def parseKernelLog():
tp = aslib.TestProps() tp = aslib.TestProps()
devtemp = dict() devtemp = dict()
if(sysvals.dmesgfile): if(sysvals.dmesgfile):
lf = open(sysvals.dmesgfile, 'r') lf = open(sysvals.dmesgfile, 'rb')
else: else:
lf = Popen('dmesg', stdout=PIPE).stdout lf = Popen('dmesg', stdout=PIPE).stdout
for line in lf: for line in lf:
line = line.replace('\r\n', '') line = aslib.ascii(line).replace('\r\n', '')
# grab the stamp and sysinfo # grab the stamp and sysinfo
if re.match(tp.stampfmt, line): if re.match(tp.stampfmt, line):
tp.stamp = line tp.stamp = line
...@@ -649,7 +658,7 @@ def createBootGraph(data): ...@@ -649,7 +658,7 @@ def createBootGraph(data):
statinfo += '\t"%s": [\n\t\t"%s",\n' % (n, devstats[n]['info']) statinfo += '\t"%s": [\n\t\t"%s",\n' % (n, devstats[n]['info'])
if 'fstat' in devstats[n]: if 'fstat' in devstats[n]:
funcs = devstats[n]['fstat'] funcs = devstats[n]['fstat']
for f in sorted(funcs, key=funcs.get, reverse=True): for f in sorted(funcs, key=lambda k:(funcs[k], k), reverse=True):
if funcs[f][0] < 0.01 and len(funcs) > 10: if funcs[f][0] < 0.01 and len(funcs) > 10:
break break
statinfo += '\t\t"%f|%s|%d",\n' % (funcs[f][0], f, funcs[f][1]) statinfo += '\t\t"%f|%s|%d",\n' % (funcs[f][0], f, funcs[f][1])
...@@ -729,7 +738,7 @@ def updateCron(restore=False): ...@@ -729,7 +738,7 @@ def updateCron(restore=False):
op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) op.write('@reboot python %s\n' % sysvals.cronjobCmdString())
op.close() op.close()
res = call([cmd, cronfile]) res = call([cmd, cronfile])
except Exception, e: except Exception as e:
pprint('Exception: %s' % str(e)) pprint('Exception: %s' % str(e))
shutil.move(backfile, cronfile) shutil.move(backfile, cronfile)
res = -1 res = -1
...@@ -745,7 +754,7 @@ def updateGrub(restore=False): ...@@ -745,7 +754,7 @@ def updateGrub(restore=False):
try: try:
call(sysvals.blexec, stderr=PIPE, stdout=PIPE, call(sysvals.blexec, stderr=PIPE, stdout=PIPE,
env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'})
except Exception, e: except Exception as e:
pprint('Exception: %s\n' % str(e)) pprint('Exception: %s\n' % str(e))
return return
# extract the option and create a grub config without it # extract the option and create a grub config without it
...@@ -792,7 +801,7 @@ def updateGrub(restore=False): ...@@ -792,7 +801,7 @@ def updateGrub(restore=False):
op.close() op.close()
res = call(sysvals.blexec) res = call(sysvals.blexec)
os.remove(grubfile) os.remove(grubfile)
except Exception, e: except Exception as e:
pprint('Exception: %s' % str(e)) pprint('Exception: %s' % str(e))
res = -1 res = -1
# cleanup # cleanup
...@@ -866,6 +875,7 @@ def printHelp(): ...@@ -866,6 +875,7 @@ def printHelp():
'Other commands:\n'\ 'Other commands:\n'\
' -flistall Print all functions capable of being captured in ftrace\n'\ ' -flistall Print all functions capable of being captured in ftrace\n'\
' -sysinfo Print out system info extracted from BIOS\n'\ ' -sysinfo Print out system info extracted from BIOS\n'\
' -which exec Print an executable path, should function even without PATH\n'\
' [redo]\n'\ ' [redo]\n'\
' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\ ' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\
' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\ ' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\
...@@ -907,13 +917,13 @@ if __name__ == '__main__': ...@@ -907,13 +917,13 @@ if __name__ == '__main__':
sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0)
elif(arg == '-cgfilter'): elif(arg == '-cgfilter'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No callgraph functions supplied', True) doError('No callgraph functions supplied', True)
sysvals.setCallgraphFilter(val) sysvals.setCallgraphFilter(val)
elif(arg == '-cgskip'): elif(arg == '-cgskip'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No file supplied', True) doError('No file supplied', True)
if val.lower() in switchoff: if val.lower() in switchoff:
...@@ -924,7 +934,7 @@ if __name__ == '__main__': ...@@ -924,7 +934,7 @@ if __name__ == '__main__':
doError('%s does not exist' % cgskip) doError('%s does not exist' % cgskip)
elif(arg == '-bl'): elif(arg == '-bl'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No boot loader name supplied', True) doError('No boot loader name supplied', True)
if val.lower() not in ['grub']: if val.lower() not in ['grub']:
...@@ -937,7 +947,7 @@ if __name__ == '__main__': ...@@ -937,7 +947,7 @@ if __name__ == '__main__':
sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000)
elif(arg == '-func'): elif(arg == '-func'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No filter functions supplied', True) doError('No filter functions supplied', True)
sysvals.useftrace = True sysvals.useftrace = True
...@@ -946,7 +956,7 @@ if __name__ == '__main__': ...@@ -946,7 +956,7 @@ if __name__ == '__main__':
sysvals.setGraphFilter(val) sysvals.setGraphFilter(val)
elif(arg == '-ftrace'): elif(arg == '-ftrace'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No ftrace file supplied', True) doError('No ftrace file supplied', True)
if(os.path.exists(val) == False): if(os.path.exists(val) == False):
...@@ -959,7 +969,7 @@ if __name__ == '__main__': ...@@ -959,7 +969,7 @@ if __name__ == '__main__':
sysvals.cgexp = True sysvals.cgexp = True
elif(arg == '-dmesg'): elif(arg == '-dmesg'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No dmesg file supplied', True) doError('No dmesg file supplied', True)
if(os.path.exists(val) == False): if(os.path.exists(val) == False):
...@@ -968,13 +978,13 @@ if __name__ == '__main__': ...@@ -968,13 +978,13 @@ if __name__ == '__main__':
sysvals.dmesgfile = val sysvals.dmesgfile = val
elif(arg == '-o'): elif(arg == '-o'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No subdirectory name supplied', True) doError('No subdirectory name supplied', True)
sysvals.testdir = sysvals.setOutputFolder(val) sysvals.testdir = sysvals.setOutputFolder(val)
elif(arg == '-result'): elif(arg == '-result'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No result file supplied', True) doError('No result file supplied', True)
sysvals.result = val sysvals.result = val
...@@ -986,6 +996,17 @@ if __name__ == '__main__': ...@@ -986,6 +996,17 @@ if __name__ == '__main__':
# remaining options are only for cron job use # remaining options are only for cron job use
elif(arg == '-cronjob'): elif(arg == '-cronjob'):
sysvals.iscronjob = True sysvals.iscronjob = True
elif(arg == '-which'):
try:
val = next(args)
except:
doError('No executable supplied', True)
out = sysvals.getExec(val)
if not out:
print('%s not found' % val)
sys.exit(1)
print(out)
sys.exit(0)
else: else:
doError('Invalid argument: '+arg, True) doError('Invalid argument: '+arg, True)
......
...@@ -53,10 +53,10 @@ disable rtcwake and require a user keypress to resume. ...@@ -53,10 +53,10 @@ disable rtcwake and require a user keypress to resume.
Add the dmesg and ftrace logs to the html output. They will be viewable by Add the dmesg and ftrace logs to the html output. They will be viewable by
clicking buttons in the timeline. clicking buttons in the timeline.
.TP .TP
\fB-turbostat\fR \fB-noturbostat\fR
Use turbostat to execute the command in freeze mode (default: disabled). This By default, if turbostat is found and the requested mode is freeze, sleepgraph
will provide turbostat output in the log which will tell you which actual will execute the suspend via turbostat and collect data in the timeline log.
power modes were entered. This option disables the use of turbostat.
.TP .TP
\fB-result \fIfile\fR \fB-result \fIfile\fR
Export a results table to a text file for parsing. Export a results table to a text file for parsing.
......
#!/usr/bin/python2 #!/usr/bin/python
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# #
# Tool for analyzing suspend/resume timing # Tool for analyzing suspend/resume timing
# Copyright (c) 2013, Intel Corporation. # Copyright (c) 2013, Intel Corporation.
# #
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope 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.
#
# Authors: # Authors:
# Todd Brandt <todd.e.brandt@linux.intel.com> # Todd Brandt <todd.e.brandt@linux.intel.com>
# #
...@@ -48,9 +57,10 @@ import string ...@@ -48,9 +57,10 @@ import string
import re import re
import platform import platform
import signal import signal
import codecs
from datetime import datetime from datetime import datetime
import struct import struct
import ConfigParser import configparser
import gzip import gzip
from threading import Thread from threading import Thread
from subprocess import call, Popen, PIPE from subprocess import call, Popen, PIPE
...@@ -60,6 +70,9 @@ def pprint(msg): ...@@ -60,6 +70,9 @@ def pprint(msg):
print(msg) print(msg)
sys.stdout.flush() sys.stdout.flush()
def ascii(text):
return text.decode('ascii', 'ignore')
# ----------------- CLASSES -------------------- # ----------------- CLASSES --------------------
# Class: SystemValues # Class: SystemValues
...@@ -68,7 +81,7 @@ def pprint(msg): ...@@ -68,7 +81,7 @@ def pprint(msg):
# store system values and test parameters # store system values and test parameters
class SystemValues: class SystemValues:
title = 'SleepGraph' title = 'SleepGraph'
version = '5.4' version = '5.5'
ansi = False ansi = False
rs = 0 rs = 0
display = '' display = ''
...@@ -78,7 +91,7 @@ class SystemValues: ...@@ -78,7 +91,7 @@ class SystemValues:
testlog = True testlog = True
dmesglog = True dmesglog = True
ftracelog = False ftracelog = False
tstat = False tstat = True
mindevlen = 0.0 mindevlen = 0.0
mincglen = 0.0 mincglen = 0.0
cgphase = '' cgphase = ''
...@@ -147,6 +160,7 @@ class SystemValues: ...@@ -147,6 +160,7 @@ class SystemValues:
devdump = False devdump = False
mixedphaseheight = True mixedphaseheight = True
devprops = dict() devprops = dict()
platinfo = []
predelay = 0 predelay = 0
postdelay = 0 postdelay = 0
pmdebug = '' pmdebug = ''
...@@ -323,13 +337,20 @@ class SystemValues: ...@@ -323,13 +337,20 @@ class SystemValues:
sys.exit(1) sys.exit(1)
return False return False
def getExec(self, cmd): def getExec(self, cmd):
dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin', try:
'/usr/local/sbin', '/usr/local/bin'] fp = Popen(['which', cmd], stdout=PIPE, stderr=PIPE).stdout
for path in dirlist: out = ascii(fp.read()).strip()
fp.close()
except:
out = ''
if out:
return out
for path in ['/sbin', '/bin', '/usr/sbin', '/usr/bin',
'/usr/local/sbin', '/usr/local/bin']:
cmdfull = os.path.join(path, cmd) cmdfull = os.path.join(path, cmd)
if os.path.exists(cmdfull): if os.path.exists(cmdfull):
return cmdfull return cmdfull
return '' return out
def setPrecision(self, num): def setPrecision(self, num):
if num < 0 or num > 6: if num < 0 or num > 6:
return return
...@@ -455,7 +476,7 @@ class SystemValues: ...@@ -455,7 +476,7 @@ class SystemValues:
fp = Popen('dmesg', stdout=PIPE).stdout fp = Popen('dmesg', stdout=PIPE).stdout
ktime = '0' ktime = '0'
for line in fp: for line in fp:
line = line.replace('\r\n', '') line = ascii(line).replace('\r\n', '')
idx = line.find('[') idx = line.find('[')
if idx > 1: if idx > 1:
line = line[idx:] line = line[idx:]
...@@ -469,7 +490,7 @@ class SystemValues: ...@@ -469,7 +490,7 @@ class SystemValues:
# store all new dmesg lines since initdmesg was called # store all new dmesg lines since initdmesg was called
fp = Popen('dmesg', stdout=PIPE).stdout fp = Popen('dmesg', stdout=PIPE).stdout
for line in fp: for line in fp:
line = line.replace('\r\n', '') line = ascii(line).replace('\r\n', '')
idx = line.find('[') idx = line.find('[')
if idx > 1: if idx > 1:
line = line[idx:] line = line[idx:]
...@@ -501,7 +522,7 @@ class SystemValues: ...@@ -501,7 +522,7 @@ class SystemValues:
call('cat '+self.tpath+'available_filter_functions', shell=True) call('cat '+self.tpath+'available_filter_functions', shell=True)
return return
master = self.listFromFile(self.tpath+'available_filter_functions') master = self.listFromFile(self.tpath+'available_filter_functions')
for i in self.tracefuncs: for i in sorted(self.tracefuncs):
if 'func' in self.tracefuncs[i]: if 'func' in self.tracefuncs[i]:
i = self.tracefuncs[i]['func'] i = self.tracefuncs[i]['func']
if i in master: if i in master:
...@@ -628,7 +649,7 @@ class SystemValues: ...@@ -628,7 +649,7 @@ class SystemValues:
self.fsetVal(kprobeevents, 'kprobe_events') self.fsetVal(kprobeevents, 'kprobe_events')
if output: if output:
check = self.fgetVal('kprobe_events') check = self.fgetVal('kprobe_events')
linesack = (len(check.split('\n')) - 1) / 2 linesack = (len(check.split('\n')) - 1) // 2
pprint(' kprobe functions enabled: %d/%d' % (linesack, linesout)) pprint(' kprobe functions enabled: %d/%d' % (linesack, linesout))
self.fsetVal('1', 'events/kprobes/enable') self.fsetVal('1', 'events/kprobes/enable')
def testKprobe(self, kname, kprobe): def testKprobe(self, kname, kprobe):
...@@ -646,19 +667,19 @@ class SystemValues: ...@@ -646,19 +667,19 @@ class SystemValues:
if linesack < linesout: if linesack < linesout:
return False return False
return True return True
def setVal(self, val, file, mode='w'): def setVal(self, val, file):
if not os.path.exists(file): if not os.path.exists(file):
return False return False
try: try:
fp = open(file, mode, 0) fp = open(file, 'wb', 0)
fp.write(val) fp.write(val.encode())
fp.flush() fp.flush()
fp.close() fp.close()
except: except:
return False return False
return True return True
def fsetVal(self, val, path, mode='w'): def fsetVal(self, val, path):
return self.setVal(val, self.tpath+path, mode) return self.setVal(val, self.tpath+path)
def getVal(self, file): def getVal(self, file):
res = '' res = ''
if not os.path.exists(file): if not os.path.exists(file):
...@@ -719,7 +740,7 @@ class SystemValues: ...@@ -719,7 +740,7 @@ class SystemValues:
tgtsize = min(self.memfree, bmax) tgtsize = min(self.memfree, bmax)
else: else:
tgtsize = 65536 tgtsize = 65536
while not self.fsetVal('%d' % (tgtsize / cpus), 'buffer_size_kb'): while not self.fsetVal('%d' % (tgtsize // cpus), 'buffer_size_kb'):
# if the size failed to set, lower it and keep trying # if the size failed to set, lower it and keep trying
tgtsize -= 65536 tgtsize -= 65536
if tgtsize < 65536: if tgtsize < 65536:
...@@ -863,14 +884,23 @@ class SystemValues: ...@@ -863,14 +884,23 @@ class SystemValues:
isgz = self.gzip isgz = self.gzip
if mode == 'r': if mode == 'r':
try: try:
with gzip.open(filename, mode+'b') as fp: with gzip.open(filename, mode+'t') as fp:
test = fp.read(64) test = fp.read(64)
isgz = True isgz = True
except: except:
isgz = False isgz = False
if isgz: if isgz:
return gzip.open(filename, mode+'b') return gzip.open(filename, mode+'t')
return open(filename, mode) return open(filename, mode)
def b64unzip(self, data):
try:
out = codecs.decode(base64.b64decode(data), 'zlib').decode()
except:
out = data
return out
def b64zip(self, data):
out = base64.b64encode(codecs.encode(data.encode(), 'zlib')).decode()
return out
def mcelog(self, clear=False): def mcelog(self, clear=False):
cmd = self.getExec('mcelog') cmd = self.getExec('mcelog')
if not cmd: if not cmd:
...@@ -878,12 +908,124 @@ class SystemValues: ...@@ -878,12 +908,124 @@ class SystemValues:
if clear: if clear:
call(cmd+' > /dev/null 2>&1', shell=True) call(cmd+' > /dev/null 2>&1', shell=True)
return '' return ''
fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout try:
out = fp.read().strip() fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout
fp.close() out = ascii(fp.read()).strip()
fp.close()
except:
return ''
if not out: if not out:
return '' return ''
return base64.b64encode(out.encode('zlib')) return self.b64zip(out)
def platforminfo(self):
# add platform info on to a completed ftrace file
if not os.path.exists(self.ftracefile):
return False
footer = '#\n'
# add test command string line if need be
if self.suspendmode == 'command' and self.testcommand:
footer += '# platform-testcmd: %s\n' % (self.testcommand)
# get a list of target devices from the ftrace file
props = dict()
tp = TestProps()
tf = self.openlog(self.ftracefile, 'r')
for line in tf:
# determine the trace data type (required for further parsing)
m = re.match(tp.tracertypefmt, line)
if(m):
tp.setTracerType(m.group('t'))
continue
# parse only valid lines, if this is not one move on
m = re.match(tp.ftrace_line_fmt, line)
if(not m or 'device_pm_callback_start' not in line):
continue
m = re.match('.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg'));
if(not m):
continue
dev = m.group('d')
if dev not in props:
props[dev] = DevProps()
tf.close()
# now get the syspath for each target device
for dirname, dirnames, filenames in os.walk('/sys/devices'):
if(re.match('.*/power', dirname) and 'async' in filenames):
dev = dirname.split('/')[-2]
if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)):
props[dev].syspath = dirname[:-6]
# now fill in the properties for our target devices
for dev in sorted(props):
dirname = props[dev].syspath
if not dirname or not os.path.exists(dirname):
continue
with open(dirname+'/power/async') as fp:
text = fp.read()
props[dev].isasync = False
if 'enabled' in text:
props[dev].isasync = True
fields = os.listdir(dirname)
if 'product' in fields:
with open(dirname+'/product', 'rb') as fp:
props[dev].altname = ascii(fp.read())
elif 'name' in fields:
with open(dirname+'/name', 'rb') as fp:
props[dev].altname = ascii(fp.read())
elif 'model' in fields:
with open(dirname+'/model', 'rb') as fp:
props[dev].altname = ascii(fp.read())
elif 'description' in fields:
with open(dirname+'/description', 'rb') as fp:
props[dev].altname = ascii(fp.read())
elif 'id' in fields:
with open(dirname+'/id', 'rb') as fp:
props[dev].altname = ascii(fp.read())
elif 'idVendor' in fields and 'idProduct' in fields:
idv, idp = '', ''
with open(dirname+'/idVendor', 'rb') as fp:
idv = ascii(fp.read()).strip()
with open(dirname+'/idProduct', 'rb') as fp:
idp = ascii(fp.read()).strip()
props[dev].altname = '%s:%s' % (idv, idp)
if props[dev].altname:
out = props[dev].altname.strip().replace('\n', ' ')\
.replace(',', ' ').replace(';', ' ')
props[dev].altname = out
# add a devinfo line to the bottom of ftrace
out = ''
for dev in sorted(props):
out += props[dev].out(dev)
footer += '# platform-devinfo: %s\n' % self.b64zip(out)
# add a line for each of these commands with their outputs
cmds = [
['pcidevices', 'lspci', '-tv'],
['interrupts', 'cat', '/proc/interrupts'],
['gpecounts', 'sh', '-c', 'grep -v invalid /sys/firmware/acpi/interrupts/gpe*'],
]
for cargs in cmds:
name = cargs[0]
cmdline = ' '.join(cargs[1:])
cmdpath = self.getExec(cargs[1])
if not cmdpath:
continue
cmd = [cmdpath] + cargs[2:]
try:
fp = Popen(cmd, stdout=PIPE, stderr=PIPE).stdout
info = ascii(fp.read()).strip()
fp.close()
except:
continue
if not info:
continue
footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
with self.openlog(self.ftracefile, 'a') as fp:
fp.write(footer)
return True
def haveTurbostat(self): def haveTurbostat(self):
if not self.tstat: if not self.tstat:
return False return False
...@@ -891,31 +1033,40 @@ class SystemValues: ...@@ -891,31 +1033,40 @@ class SystemValues:
if not cmd: if not cmd:
return False return False
fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr
out = fp.read().strip() out = ascii(fp.read()).strip()
fp.close() fp.close()
return re.match('turbostat version [0-9\.]* .*', out) if re.match('turbostat version [0-9\.]* .*', out):
sysvals.vprint(out)
return True
return False
def turbostat(self): def turbostat(self):
cmd = self.getExec('turbostat') cmd = self.getExec('turbostat')
if not cmd: rawout = keyline = valline = ''
return 'missing turbostat executable'
text = []
fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile) fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile)
fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr
for line in fp: for line in fp:
if re.match('[0-9.]* sec', line): line = ascii(line)
rawout += line
if keyline and valline:
continue continue
text.append(line.split()) if re.match('(?i)Avg_MHz.*', line):
keyline = line.strip().split()
elif keyline:
valline = line.strip().split()
fp.close() fp.close()
if len(text) < 2: if not keyline or not valline or len(keyline) != len(valline):
return 'turbostat output format error' errmsg = 'unrecognized turbostat output:\n'+rawout.strip()
sysvals.vprint(errmsg)
if not sysvals.verbose:
pprint(errmsg)
return ''
if sysvals.verbose:
pprint(rawout.strip())
out = [] out = []
for key in text[0]: for key in keyline:
values = [] idx = keyline.index(key)
idx = text[0].index(key) val = valline[idx]
for line in text[1:]: out.append('%s=%s' % (key, val))
if len(line) > idx:
values.append(line[idx])
out.append('%s=%s' % (key, ','.join(values)))
return '|'.join(out) return '|'.join(out)
def checkWifi(self): def checkWifi(self):
out = dict() out = dict()
...@@ -924,7 +1075,7 @@ class SystemValues: ...@@ -924,7 +1075,7 @@ class SystemValues:
return out return out
fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout
for line in fp: for line in fp:
m = re.match('(?P<dev>\S*) .* ESSID:(?P<ess>\S*)', line) m = re.match('(?P<dev>\S*) .* ESSID:(?P<ess>\S*)', ascii(line))
if not m: if not m:
continue continue
out['device'] = m.group('dev') out['device'] = m.group('dev')
...@@ -935,7 +1086,7 @@ class SystemValues: ...@@ -935,7 +1086,7 @@ class SystemValues:
if 'device' in out: if 'device' in out:
fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout
for line in fp: for line in fp:
m = re.match('.* inet (?P<ip>[0-9\.]*)', line) m = re.match('.* inet (?P<ip>[0-9\.]*)', ascii(line))
if m: if m:
out['ip'] = m.group('ip') out['ip'] = m.group('ip')
break break
...@@ -990,13 +1141,13 @@ class DevProps: ...@@ -990,13 +1141,13 @@ class DevProps:
def __init__(self): def __init__(self):
self.syspath = '' self.syspath = ''
self.altname = '' self.altname = ''
self.async = True self.isasync = True
self.xtraclass = '' self.xtraclass = ''
self.xtrainfo = '' self.xtrainfo = ''
def out(self, dev): def out(self, dev):
return '%s,%s,%d;' % (dev, self.altname, self.async) return '%s,%s,%d;' % (dev, self.altname, self.isasync)
def debug(self, dev): def debug(self, dev):
pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.async)) pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.isasync))
def altName(self, dev): def altName(self, dev):
if not self.altname or self.altname == dev: if not self.altname or self.altname == dev:
return dev return dev
...@@ -1004,13 +1155,13 @@ class DevProps: ...@@ -1004,13 +1155,13 @@ class DevProps:
def xtraClass(self): def xtraClass(self):
if self.xtraclass: if self.xtraclass:
return ' '+self.xtraclass return ' '+self.xtraclass
if not self.async: if not self.isasync:
return ' sync' return ' sync'
return '' return ''
def xtraInfo(self): def xtraInfo(self):
if self.xtraclass: if self.xtraclass:
return ' '+self.xtraclass return ' '+self.xtraclass
if self.async: if self.isasync:
return ' async_device' return ' async_device'
return ' sync_device' return ' sync_device'
...@@ -1108,7 +1259,7 @@ class Data: ...@@ -1108,7 +1259,7 @@ class Data:
return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order']) return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order'])
def initDevicegroups(self): def initDevicegroups(self):
# called when phases are all finished being added # called when phases are all finished being added
for phase in self.dmesg.keys(): for phase in sorted(self.dmesg.keys()):
if '*' in phase: if '*' in phase:
p = phase.split('*') p = phase.split('*')
pnew = '%s%d' % (p[0], len(p)) pnew = '%s%d' % (p[0], len(p))
...@@ -1430,16 +1581,7 @@ class Data: ...@@ -1430,16 +1581,7 @@ class Data:
return phase return phase
def sortedDevices(self, phase): def sortedDevices(self, phase):
list = self.dmesg[phase]['list'] list = self.dmesg[phase]['list']
slist = [] return sorted(list, key=lambda k:list[k]['start'])
tmp = dict()
for devname in list:
dev = list[devname]
if dev['length'] == 0:
continue
tmp[dev['start']] = devname
for t in sorted(tmp):
slist.append(tmp[t])
return slist
def fixupInitcalls(self, phase): def fixupInitcalls(self, phase):
# if any calls never returned, clip them at system resume end # if any calls never returned, clip them at system resume end
phaselist = self.dmesg[phase]['list'] phaselist = self.dmesg[phase]['list']
...@@ -1576,7 +1718,7 @@ class Data: ...@@ -1576,7 +1718,7 @@ class Data:
maxname = '%d' % self.maxDeviceNameSize(phase) maxname = '%d' % self.maxDeviceNameSize(phase)
fmt = '%3d) %'+maxname+'s - %f - %f' fmt = '%3d) %'+maxname+'s - %f - %f'
c = 1 c = 1
for name in devlist: for name in sorted(devlist):
s = devlist[name]['start'] s = devlist[name]['start']
e = devlist[name]['end'] e = devlist[name]['end']
sysvals.vprint(fmt % (c, name, s, e)) sysvals.vprint(fmt % (c, name, s, e))
...@@ -1588,7 +1730,7 @@ class Data: ...@@ -1588,7 +1730,7 @@ class Data:
devlist = [] devlist = []
for phase in self.sortedPhases(): for phase in self.sortedPhases():
list = self.deviceChildren(devname, phase) list = self.deviceChildren(devname, phase)
for dev in list: for dev in sorted(list):
if dev not in devlist: if dev not in devlist:
devlist.append(dev) devlist.append(dev)
return devlist return devlist
...@@ -1628,16 +1770,16 @@ class Data: ...@@ -1628,16 +1770,16 @@ class Data:
def rootDeviceList(self): def rootDeviceList(self):
# list of devices graphed # list of devices graphed
real = [] real = []
for phase in self.dmesg: for phase in self.sortedPhases():
list = self.dmesg[phase]['list'] list = self.dmesg[phase]['list']
for dev in list: for dev in sorted(list):
if list[dev]['pid'] >= 0 and dev not in real: if list[dev]['pid'] >= 0 and dev not in real:
real.append(dev) real.append(dev)
# list of top-most root devices # list of top-most root devices
rootlist = [] rootlist = []
for phase in self.dmesg: for phase in self.sortedPhases():
list = self.dmesg[phase]['list'] list = self.dmesg[phase]['list']
for dev in list: for dev in sorted(list):
pdev = list[dev]['par'] pdev = list[dev]['par']
pid = list[dev]['pid'] pid = list[dev]['pid']
if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)): if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)):
...@@ -1718,9 +1860,9 @@ class Data: ...@@ -1718,9 +1860,9 @@ class Data:
def createProcessUsageEvents(self): def createProcessUsageEvents(self):
# get an array of process names # get an array of process names
proclist = [] proclist = []
for t in self.pstl: for t in sorted(self.pstl):
pslist = self.pstl[t] pslist = self.pstl[t]
for ps in pslist: for ps in sorted(pslist):
if ps not in proclist: if ps not in proclist:
proclist.append(ps) proclist.append(ps)
# get a list of data points for suspend and resume # get a list of data points for suspend and resume
...@@ -1765,7 +1907,7 @@ class Data: ...@@ -1765,7 +1907,7 @@ class Data:
def debugPrint(self): def debugPrint(self):
for p in self.sortedPhases(): for p in self.sortedPhases():
list = self.dmesg[p]['list'] list = self.dmesg[p]['list']
for devname in list: for devname in sorted(list):
dev = list[devname] dev = list[devname]
if 'ftrace' in dev: if 'ftrace' in dev:
dev['ftrace'].debugPrint(' [%s]' % devname) dev['ftrace'].debugPrint(' [%s]' % devname)
...@@ -2466,7 +2608,7 @@ class Timeline: ...@@ -2466,7 +2608,7 @@ class Timeline:
# if there is 1 line per row, draw them the standard way # if there is 1 line per row, draw them the standard way
for t, p in standardphases: for t, p in standardphases:
for i in sorted(self.rowheight[t][p]): for i in sorted(self.rowheight[t][p]):
self.rowheight[t][p][i] = self.bodyH/len(self.rowlines[t][p]) self.rowheight[t][p][i] = float(self.bodyH)/len(self.rowlines[t][p])
def createZoomBox(self, mode='command', testcount=1): def createZoomBox(self, mode='command', testcount=1):
# Create bounding box, add buttons # Create bounding box, add buttons
html_zoombox = '<center><button id="zoomin">ZOOM IN +</button><button id="zoomout">ZOOM OUT -</button><button id="zoomdef">ZOOM 1:1</button></center>\n' html_zoombox = '<center><button id="zoomin">ZOOM IN +</button><button id="zoomout">ZOOM OUT -</button><button id="zoomdef">ZOOM 1:1</button></center>\n'
...@@ -2537,6 +2679,7 @@ class TestProps: ...@@ -2537,6 +2679,7 @@ class TestProps:
cmdlinefmt = '^# command \| (?P<cmd>.*)' cmdlinefmt = '^# command \| (?P<cmd>.*)'
kparamsfmt = '^# kparams \| (?P<kp>.*)' kparamsfmt = '^# kparams \| (?P<kp>.*)'
devpropfmt = '# Device Properties: .*' devpropfmt = '# Device Properties: .*'
pinfofmt = '# platform-(?P<val>[a-z,A-Z,0-9]*): (?P<info>.*)'
tracertypefmt = '# tracer: (?P<t>.*)' tracertypefmt = '# tracer: (?P<t>.*)'
firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$' firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$'
procexecfmt = 'ps - (?P<ps>.*)$' procexecfmt = 'ps - (?P<ps>.*)$'
...@@ -2571,12 +2714,6 @@ class TestProps: ...@@ -2571,12 +2714,6 @@ class TestProps:
self.ftrace_line_fmt = self.ftrace_line_fmt_nop self.ftrace_line_fmt = self.ftrace_line_fmt_nop
else: else:
doError('Invalid tracer format: [%s]' % tracer) doError('Invalid tracer format: [%s]' % tracer)
def decode(self, data):
try:
out = base64.b64decode(data).decode('zlib')
except:
out = data
return out
def stampInfo(self, line): def stampInfo(self, line):
if re.match(self.stampfmt, line): if re.match(self.stampfmt, line):
self.stamp = line self.stamp = line
...@@ -2660,7 +2797,7 @@ class TestProps: ...@@ -2660,7 +2797,7 @@ class TestProps:
if len(self.mcelog) > data.testnumber: if len(self.mcelog) > data.testnumber:
m = re.match(self.mcelogfmt, self.mcelog[data.testnumber]) m = re.match(self.mcelogfmt, self.mcelog[data.testnumber])
if m: if m:
data.mcelog = self.decode(m.group('m')) data.mcelog = sv.b64unzip(m.group('m'))
# turbostat data # turbostat data
if len(self.turbostat) > data.testnumber: if len(self.turbostat) > data.testnumber:
m = re.match(self.tstatfmt, self.turbostat[data.testnumber]) m = re.match(self.tstatfmt, self.turbostat[data.testnumber])
...@@ -2681,6 +2818,46 @@ class TestProps: ...@@ -2681,6 +2818,46 @@ class TestProps:
m = re.match(self.testerrfmt, self.testerror[data.testnumber]) m = re.match(self.testerrfmt, self.testerror[data.testnumber])
if m: if m:
data.enterfail = m.group('e') data.enterfail = m.group('e')
def devprops(self, data):
props = dict()
devlist = data.split(';')
for dev in devlist:
f = dev.split(',')
if len(f) < 3:
continue
dev = f[0]
props[dev] = DevProps()
props[dev].altname = f[1]
if int(f[2]):
props[dev].isasync = True
else:
props[dev].isasync = False
return props
def parseDevprops(self, line, sv):
idx = line.index(': ') + 2
if idx >= len(line):
return
props = self.devprops(line[idx:])
if sv.suspendmode == 'command' and 'testcommandstring' in props:
sv.testcommand = props['testcommandstring'].altname
sv.devprops = props
def parsePlatformInfo(self, line, sv):
m = re.match(self.pinfofmt, line)
if not m:
return
name, info = m.group('val'), m.group('info')
if name == 'devinfo':
sv.devprops = self.devprops(sv.b64unzip(info))
return
elif name == 'testcmd':
sv.testcommand = info
return
field = info.split('|')
if len(field) < 2:
return
cmdline = field[0].strip()
output = sv.b64unzip(field[1].strip())
sv.platinfo.append([name, cmdline, output])
# Class: TestRun # Class: TestRun
# Description: # Description:
...@@ -2701,7 +2878,7 @@ class ProcessMonitor: ...@@ -2701,7 +2878,7 @@ class ProcessMonitor:
process = Popen(c, shell=True, stdout=PIPE) process = Popen(c, shell=True, stdout=PIPE)
running = dict() running = dict()
for line in process.stdout: for line in process.stdout:
data = line.split() data = ascii(line).split()
pid = data[0] pid = data[0]
name = re.sub('[()]', '', data[1]) name = re.sub('[()]', '', data[1])
user = int(data[13]) user = int(data[13])
...@@ -2805,7 +2982,11 @@ def appendIncompleteTraceLog(testruns): ...@@ -2805,7 +2982,11 @@ def appendIncompleteTraceLog(testruns):
continue continue
# device properties line # device properties line
if(re.match(tp.devpropfmt, line)): if(re.match(tp.devpropfmt, line)):
devProps(line) tp.parseDevprops(line, sysvals)
continue
# platform info line
if(re.match(tp.pinfofmt, line)):
tp.parsePlatformInfo(line, sysvals)
continue continue
# parse only valid lines, if this is not one move on # parse only valid lines, if this is not one move on
m = re.match(tp.ftrace_line_fmt, line) m = re.match(tp.ftrace_line_fmt, line)
...@@ -2902,7 +3083,7 @@ def parseTraceLog(live=False): ...@@ -2902,7 +3083,7 @@ def parseTraceLog(live=False):
sysvals.setupAllKprobes() sysvals.setupAllKprobes()
ksuscalls = ['pm_prepare_console'] ksuscalls = ['pm_prepare_console']
krescalls = ['pm_restore_console'] krescalls = ['pm_restore_console']
tracewatch = [] tracewatch = ['irq_wakeup']
if sysvals.usekprobes: if sysvals.usekprobes:
tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend', tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend',
'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON', 'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON',
...@@ -2928,7 +3109,11 @@ def parseTraceLog(live=False): ...@@ -2928,7 +3109,11 @@ def parseTraceLog(live=False):
continue continue
# device properties line # device properties line
if(re.match(tp.devpropfmt, line)): if(re.match(tp.devpropfmt, line)):
devProps(line) tp.parseDevprops(line, sysvals)
continue
# platform info line
if(re.match(tp.pinfofmt, line)):
tp.parsePlatformInfo(line, sysvals)
continue continue
# ignore all other commented lines # ignore all other commented lines
if line[0] == '#': if line[0] == '#':
...@@ -3001,16 +3186,11 @@ def parseTraceLog(live=False): ...@@ -3001,16 +3186,11 @@ def parseTraceLog(live=False):
isbegin = False isbegin = False
else: else:
continue continue
m = re.match('(?P<name>.*)\[(?P<val>[0-9]*)\] .*', t.name) if '[' in t.name:
if(m): m = re.match('(?P<name>.*)\[.*', t.name)
val = m.group('val')
if val == '0':
name = m.group('name')
else:
name = m.group('name')+'['+val+']'
else: else:
m = re.match('(?P<name>.*) .*', t.name) m = re.match('(?P<name>.*) .*', t.name)
name = m.group('name') name = m.group('name')
# ignore these events # ignore these events
if(name.split('[')[0] in tracewatch): if(name.split('[')[0] in tracewatch):
continue continue
...@@ -3045,6 +3225,8 @@ def parseTraceLog(live=False): ...@@ -3045,6 +3225,8 @@ def parseTraceLog(live=False):
elif(re.match('machine_suspend\[.*', t.name)): elif(re.match('machine_suspend\[.*', t.name)):
if(isbegin): if(isbegin):
lp = data.lastPhase() lp = data.lastPhase()
if lp == 'resume_machine':
data.dmesg[lp]['end'] = t.time
phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True) phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True)
data.setPhase(phase, t.time, False) data.setPhase(phase, t.time, False)
if data.tSuspended == 0: if data.tSuspended == 0:
...@@ -3213,11 +3395,11 @@ def parseTraceLog(live=False): ...@@ -3213,11 +3395,11 @@ def parseTraceLog(live=False):
# add the traceevent data to the device hierarchy # add the traceevent data to the device hierarchy
if(sysvals.usetraceevents): if(sysvals.usetraceevents):
# add actual trace funcs # add actual trace funcs
for name in test.ttemp: for name in sorted(test.ttemp):
for event in test.ttemp[name]: for event in test.ttemp[name]:
data.newActionGlobal(name, event['begin'], event['end'], event['pid']) data.newActionGlobal(name, event['begin'], event['end'], event['pid'])
# add the kprobe based virtual tracefuncs as actual devices # add the kprobe based virtual tracefuncs as actual devices
for key in tp.ktemp: for key in sorted(tp.ktemp):
name, pid = key name, pid = key
if name not in sysvals.tracefuncs: if name not in sysvals.tracefuncs:
continue continue
...@@ -3231,7 +3413,7 @@ def parseTraceLog(live=False): ...@@ -3231,7 +3413,7 @@ def parseTraceLog(live=False):
data.newActionGlobal(e['name'], kb, ke, pid, color) data.newActionGlobal(e['name'], kb, ke, pid, color)
# add config base kprobes and dev kprobes # add config base kprobes and dev kprobes
if sysvals.usedevsrc: if sysvals.usedevsrc:
for key in tp.ktemp: for key in sorted(tp.ktemp):
name, pid = key name, pid = key
if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs: if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs:
continue continue
...@@ -3244,7 +3426,7 @@ def parseTraceLog(live=False): ...@@ -3244,7 +3426,7 @@ def parseTraceLog(live=False):
if sysvals.usecallgraph: if sysvals.usecallgraph:
# add the callgraph data to the device hierarchy # add the callgraph data to the device hierarchy
sortlist = dict() sortlist = dict()
for key in test.ftemp: for key in sorted(test.ftemp):
proc, pid = key proc, pid = key
for cg in test.ftemp[key]: for cg in test.ftemp[key]:
if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0): if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0):
...@@ -3582,7 +3764,7 @@ def parseKernelLog(data): ...@@ -3582,7 +3764,7 @@ def parseKernelLog(data):
# if trace events are not available, these are better than nothing # if trace events are not available, these are better than nothing
if(not sysvals.usetraceevents): if(not sysvals.usetraceevents):
# look for known actions # look for known actions
for a in at: for a in sorted(at):
if(re.match(at[a]['smsg'], msg)): if(re.match(at[a]['smsg'], msg)):
if(a not in actions): if(a not in actions):
actions[a] = [] actions[a] = []
...@@ -3641,7 +3823,7 @@ def parseKernelLog(data): ...@@ -3641,7 +3823,7 @@ def parseKernelLog(data):
data.tResumed = data.tSuspended data.tResumed = data.tSuspended
# fill in any actions we've found # fill in any actions we've found
for name in actions: for name in sorted(actions):
for event in actions[name]: for event in actions[name]:
data.newActionGlobal(name, event['begin'], event['end']) data.newActionGlobal(name, event['begin'], event['end'])
...@@ -3761,7 +3943,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): ...@@ -3761,7 +3943,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
if lastmode and lastmode != mode and num > 0: if lastmode and lastmode != mode and num > 0:
for i in range(2): for i in range(2):
s = sorted(tMed[i]) s = sorted(tMed[i])
list[lastmode]['med'][i] = s[int(len(s)/2)] list[lastmode]['med'][i] = s[int(len(s)//2)]
iMed[i] = tMed[i][list[lastmode]['med'][i]] iMed[i] = tMed[i][list[lastmode]['med'][i]]
list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num]
list[lastmode]['min'] = tMin list[lastmode]['min'] = tMin
...@@ -3803,7 +3985,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): ...@@ -3803,7 +3985,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
if lastmode and num > 0: if lastmode and num > 0:
for i in range(2): for i in range(2):
s = sorted(tMed[i]) s = sorted(tMed[i])
list[lastmode]['med'][i] = s[int(len(s)/2)] list[lastmode]['med'][i] = s[int(len(s)//2)]
iMed[i] = tMed[i][list[lastmode]['med'][i]] iMed[i] = tMed[i][list[lastmode]['med'][i]]
list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num]
list[lastmode]['min'] = tMin list[lastmode]['min'] = tMin
...@@ -3845,7 +4027,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): ...@@ -3845,7 +4027,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
'</tr>\n' '</tr>\n'
headnone = '<tr class="head"><td>{0}</td><td>{1}</td><td colspan='+\ headnone = '<tr class="head"><td>{0}</td><td>{1}</td><td colspan='+\
colspan+'></td></tr>\n' colspan+'></td></tr>\n'
for mode in list: for mode in sorted(list):
# header line for each suspend mode # header line for each suspend mode
num = 0 num = 0
tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\ tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\
...@@ -3944,7 +4126,8 @@ def createHTMLDeviceSummary(testruns, htmlfile, title): ...@@ -3944,7 +4126,8 @@ def createHTMLDeviceSummary(testruns, htmlfile, title):
th.format('Average Time') + th.format('Count') +\ th.format('Average Time') + th.format('Count') +\
th.format('Worst Time') + th.format('Host (worst time)') +\ th.format('Worst Time') + th.format('Host (worst time)') +\
th.format('Link (worst time)') + '</tr>\n' th.format('Link (worst time)') + '</tr>\n'
for name in sorted(devlist, key=lambda k:devlist[k]['worst'], reverse=True): for name in sorted(devlist, key=lambda k:(devlist[k]['worst'], \
devlist[k]['total'], devlist[k]['name']), reverse=True):
data = devall[type][name] data = devall[type][name]
data['average'] = data['total'] / data['count'] data['average'] = data['total'] / data['count']
if data['average'] < limit: if data['average'] < limit:
...@@ -4085,7 +4268,7 @@ def createHTML(testruns, testfail): ...@@ -4085,7 +4268,7 @@ def createHTML(testruns, testfail):
if(tTotal == 0): if(tTotal == 0):
doError('No timeline data') doError('No timeline data')
if(len(data.tLow) > 0): if(len(data.tLow) > 0):
low_time = '|'.join(data.tLow) low_time = '+'.join(data.tLow)
if sysvals.suspendmode == 'command': if sysvals.suspendmode == 'command':
run_time = '%.0f'%((data.end-data.start)*1000) run_time = '%.0f'%((data.end-data.start)*1000)
if sysvals.testcommand: if sysvals.testcommand:
...@@ -4151,7 +4334,7 @@ def createHTML(testruns, testfail): ...@@ -4151,7 +4334,7 @@ def createHTML(testruns, testfail):
for group in data.devicegroups: for group in data.devicegroups:
devlist = [] devlist = []
for phase in group: for phase in group:
for devname in data.tdevlist[phase]: for devname in sorted(data.tdevlist[phase]):
d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname]) d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname])
devlist.append(d) devlist.append(d)
if d.isa('kth'): if d.isa('kth'):
...@@ -4230,7 +4413,7 @@ def createHTML(testruns, testfail): ...@@ -4230,7 +4413,7 @@ def createHTML(testruns, testfail):
for b in phases[dir]: for b in phases[dir]:
# draw the devices for this phase # draw the devices for this phase
phaselist = data.dmesg[b]['list'] phaselist = data.dmesg[b]['list']
for d in data.tdevlist[b]: for d in sorted(data.tdevlist[b]):
name = d name = d
drv = '' drv = ''
dev = phaselist[d] dev = phaselist[d]
...@@ -4971,13 +5154,9 @@ def executeSuspend(): ...@@ -4971,13 +5154,9 @@ def executeSuspend():
if mode == 'freeze' and sysvals.haveTurbostat(): if mode == 'freeze' and sysvals.haveTurbostat():
# execution will pause here # execution will pause here
turbo = sysvals.turbostat() turbo = sysvals.turbostat()
if '|' in turbo: if turbo:
tdata['turbo'] = turbo tdata['turbo'] = turbo
else:
tdata['error'] = turbo
else: else:
if sysvals.haveTurbostat():
sysvals.vprint('WARNING: ignoring turbostat in mode "%s"' % mode)
pf = open(sysvals.powerfile, 'w') pf = open(sysvals.powerfile, 'w')
pf.write(mode) pf.write(mode)
# execution will pause here # execution will pause here
...@@ -5024,7 +5203,7 @@ def executeSuspend(): ...@@ -5024,7 +5203,7 @@ def executeSuspend():
op.write(line) op.write(line)
op.close() op.close()
sysvals.fsetVal('', 'trace') sysvals.fsetVal('', 'trace')
devProps() sysvals.platforminfo()
return testdata return testdata
def readFile(file): def readFile(file):
...@@ -5040,9 +5219,9 @@ def readFile(file): ...@@ -5040,9 +5219,9 @@ def readFile(file):
# The time string, e.g. "1901m16s" # The time string, e.g. "1901m16s"
def ms2nice(val): def ms2nice(val):
val = int(val) val = int(val)
h = val / 3600000 h = val // 3600000
m = (val / 60000) % 60 m = (val // 60000) % 60
s = (val / 1000) % 60 s = (val // 1000) % 60
if h > 0: if h > 0:
return '%d:%02d:%02d' % (h, m, s) return '%d:%02d:%02d' % (h, m, s)
if m > 0: if m > 0:
...@@ -5115,127 +5294,6 @@ def deviceInfo(output=''): ...@@ -5115,127 +5294,6 @@ def deviceInfo(output=''):
print(lines[i]) print(lines[i])
return res return res
# Function: devProps
# Description:
# Retrieve a list of properties for all devices in the trace log
def devProps(data=0):
props = dict()
if data:
idx = data.index(': ') + 2
if idx >= len(data):
return
devlist = data[idx:].split(';')
for dev in devlist:
f = dev.split(',')
if len(f) < 3:
continue
dev = f[0]
props[dev] = DevProps()
props[dev].altname = f[1]
if int(f[2]):
props[dev].async = True
else:
props[dev].async = False
sysvals.devprops = props
if sysvals.suspendmode == 'command' and 'testcommandstring' in props:
sysvals.testcommand = props['testcommandstring'].altname
return
if(os.path.exists(sysvals.ftracefile) == False):
doError('%s does not exist' % sysvals.ftracefile)
# first get the list of devices we need properties for
msghead = 'Additional data added by AnalyzeSuspend'
alreadystamped = False
tp = TestProps()
tf = sysvals.openlog(sysvals.ftracefile, 'r')
for line in tf:
if msghead in line:
alreadystamped = True
continue
# determine the trace data type (required for further parsing)
m = re.match(tp.tracertypefmt, line)
if(m):
tp.setTracerType(m.group('t'))
continue
# parse only valid lines, if this is not one move on
m = re.match(tp.ftrace_line_fmt, line)
if(not m or 'device_pm_callback_start' not in line):
continue
m = re.match('.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg'));
if(not m):
continue
dev = m.group('d')
if dev not in props:
props[dev] = DevProps()
tf.close()
if not alreadystamped and sysvals.suspendmode == 'command':
out = '#\n# '+msghead+'\n# Device Properties: '
out += 'testcommandstring,%s,0;' % (sysvals.testcommand)
with sysvals.openlog(sysvals.ftracefile, 'a') as fp:
fp.write(out+'\n')
sysvals.devprops = props
return
# now get the syspath for each of our target devices
for dirname, dirnames, filenames in os.walk('/sys/devices'):
if(re.match('.*/power', dirname) and 'async' in filenames):
dev = dirname.split('/')[-2]
if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)):
props[dev].syspath = dirname[:-6]
# now fill in the properties for our target devices
for dev in props:
dirname = props[dev].syspath
if not dirname or not os.path.exists(dirname):
continue
with open(dirname+'/power/async') as fp:
text = fp.read()
props[dev].async = False
if 'enabled' in text:
props[dev].async = True
fields = os.listdir(dirname)
if 'product' in fields:
with open(dirname+'/product') as fp:
props[dev].altname = fp.read()
elif 'name' in fields:
with open(dirname+'/name') as fp:
props[dev].altname = fp.read()
elif 'model' in fields:
with open(dirname+'/model') as fp:
props[dev].altname = fp.read()
elif 'description' in fields:
with open(dirname+'/description') as fp:
props[dev].altname = fp.read()
elif 'id' in fields:
with open(dirname+'/id') as fp:
props[dev].altname = fp.read()
elif 'idVendor' in fields and 'idProduct' in fields:
idv, idp = '', ''
with open(dirname+'/idVendor') as fp:
idv = fp.read().strip()
with open(dirname+'/idProduct') as fp:
idp = fp.read().strip()
props[dev].altname = '%s:%s' % (idv, idp)
if props[dev].altname:
out = props[dev].altname.strip().replace('\n', ' ')
out = out.replace(',', ' ')
out = out.replace(';', ' ')
props[dev].altname = out
# and now write the data to the ftrace file
if not alreadystamped:
out = '#\n# '+msghead+'\n# Device Properties: '
for dev in sorted(props):
out += props[dev].out(dev)
with sysvals.openlog(sysvals.ftracefile, 'a') as fp:
fp.write(out+'\n')
sysvals.devprops = props
# Function: getModes # Function: getModes
# Description: # Description:
# Determine the supported power modes on this system # Determine the supported power modes on this system
...@@ -5339,11 +5397,11 @@ def dmidecode(mempath, fatal=False): ...@@ -5339,11 +5397,11 @@ def dmidecode(mempath, fatal=False):
# search for either an SM table or DMI table # search for either an SM table or DMI table
i = base = length = num = 0 i = base = length = num = 0
while(i < memsize): while(i < memsize):
if buf[i:i+4] == '_SM_' and i < memsize - 16: if buf[i:i+4] == b'_SM_' and i < memsize - 16:
length = struct.unpack('H', buf[i+22:i+24])[0] length = struct.unpack('H', buf[i+22:i+24])[0]
base, num = struct.unpack('IH', buf[i+24:i+30]) base, num = struct.unpack('IH', buf[i+24:i+30])
break break
elif buf[i:i+5] == '_DMI_': elif buf[i:i+5] == b'_DMI_':
length = struct.unpack('H', buf[i+6:i+8])[0] length = struct.unpack('H', buf[i+6:i+8])[0]
base, num = struct.unpack('IH', buf[i+8:i+14]) base, num = struct.unpack('IH', buf[i+8:i+14])
break break
...@@ -5376,15 +5434,15 @@ def dmidecode(mempath, fatal=False): ...@@ -5376,15 +5434,15 @@ def dmidecode(mempath, fatal=False):
if 0 == struct.unpack('H', buf[n:n+2])[0]: if 0 == struct.unpack('H', buf[n:n+2])[0]:
break break
n += 1 n += 1
data = buf[i+size:n+2].split('\0') data = buf[i+size:n+2].split(b'\0')
for name in info: for name in info:
itype, idxadr = info[name] itype, idxadr = info[name]
if itype == type: if itype == type:
idx = struct.unpack('B', buf[i+idxadr])[0] idx = struct.unpack('B', buf[i+idxadr:i+idxadr+1])[0]
if idx > 0 and idx < len(data) - 1: if idx > 0 and idx < len(data) - 1:
s = data[idx-1].strip() s = data[idx-1].decode('utf-8')
if s and s.lower() != 'to be filled by o.e.m.': if s.strip() and s.strip().lower() != 'to be filled by o.e.m.':
out[name] = data[idx-1] out[name] = s
i = n + 2 i = n + 2
count += 1 count += 1
return out return out
...@@ -5409,7 +5467,7 @@ def getBattery(): ...@@ -5409,7 +5467,7 @@ def getBattery():
return (ac, charge) return (ac, charge)
def displayControl(cmd): def displayControl(cmd):
xset, ret = 'xset -d :0.0 {0}', 0 xset, ret = 'timeout 10 xset -d :0.0 {0}', 0
if sysvals.sudouser: if sysvals.sudouser:
xset = 'sudo -u %s %s' % (sysvals.sudouser, xset) xset = 'sudo -u %s %s' % (sysvals.sudouser, xset)
if cmd == 'init': if cmd == 'init':
...@@ -5433,7 +5491,7 @@ def displayControl(cmd): ...@@ -5433,7 +5491,7 @@ def displayControl(cmd):
fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout
ret = 'unknown' ret = 'unknown'
for line in fp: for line in fp:
m = re.match('[\s]*Monitor is (?P<m>.*)', line) m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line))
if(m and len(m.group('m')) >= 2): if(m and len(m.group('m')) >= 2):
out = m.group('m').lower() out = m.group('m').lower()
ret = out[3:] if out[0:2] == 'in' else out ret = out[3:] if out[0:2] == 'in' else out
...@@ -5495,10 +5553,11 @@ def getFPDT(output): ...@@ -5495,10 +5553,11 @@ def getFPDT(output):
' OEM Revision : %u\n'\ ' OEM Revision : %u\n'\
' Creator ID : %s\n'\ ' Creator ID : %s\n'\
' Creator Revision : 0x%x\n'\ ' Creator Revision : 0x%x\n'\
'' % (table[0], table[0], table[1], table[2], table[3], '' % (ascii(table[0]), ascii(table[0]), table[1], table[2],
table[4], table[5], table[6], table[7], table[8])) table[3], ascii(table[4]), ascii(table[5]), table[6],
ascii(table[7]), table[8]))
if(table[0] != 'FPDT'): if(table[0] != b'FPDT'):
if(output): if(output):
doError('Invalid FPDT table') doError('Invalid FPDT table')
return False return False
...@@ -5530,8 +5589,8 @@ def getFPDT(output): ...@@ -5530,8 +5589,8 @@ def getFPDT(output):
return [0, 0] return [0, 0]
rechead = struct.unpack('4sI', first) rechead = struct.unpack('4sI', first)
recdata = fp.read(rechead[1]-8) recdata = fp.read(rechead[1]-8)
if(rechead[0] == 'FBPT'): if(rechead[0] == b'FBPT'):
record = struct.unpack('HBBIQQQQQ', recdata) record = struct.unpack('HBBIQQQQQ', recdata[:48])
if(output): if(output):
pprint('%s (%s)\n'\ pprint('%s (%s)\n'\
' Reset END : %u ns\n'\ ' Reset END : %u ns\n'\
...@@ -5539,11 +5598,11 @@ def getFPDT(output): ...@@ -5539,11 +5598,11 @@ def getFPDT(output):
' OS Loader StartImage Start : %u ns\n'\ ' OS Loader StartImage Start : %u ns\n'\
' ExitBootServices Entry : %u ns\n'\ ' ExitBootServices Entry : %u ns\n'\
' ExitBootServices Exit : %u ns'\ ' ExitBootServices Exit : %u ns'\
'' % (rectype[header[0]], rechead[0], record[4], record[5], '' % (rectype[header[0]], ascii(rechead[0]), record[4], record[5],
record[6], record[7], record[8])) record[6], record[7], record[8]))
elif(rechead[0] == 'S3PT'): elif(rechead[0] == b'S3PT'):
if(output): if(output):
pprint('%s (%s)' % (rectype[header[0]], rechead[0])) pprint('%s (%s)' % (rectype[header[0]], ascii(rechead[0])))
j = 0 j = 0
while(j < len(recdata)): while(j < len(recdata)):
prechead = struct.unpack('HBB', recdata[j:j+4]) prechead = struct.unpack('HBB', recdata[j:j+4])
...@@ -5689,7 +5748,7 @@ def doError(msg, help=False): ...@@ -5689,7 +5748,7 @@ def doError(msg, help=False):
def getArgInt(name, args, min, max, main=True): def getArgInt(name, args, min, max, main=True):
if main: if main:
try: try:
arg = args.next() arg = next(args)
except: except:
doError(name+': no argument supplied', True) doError(name+': no argument supplied', True)
else: else:
...@@ -5708,7 +5767,7 @@ def getArgInt(name, args, min, max, main=True): ...@@ -5708,7 +5767,7 @@ def getArgInt(name, args, min, max, main=True):
def getArgFloat(name, args, min, max, main=True): def getArgFloat(name, args, min, max, main=True):
if main: if main:
try: try:
arg = args.next() arg = next(args)
except: except:
doError(name+': no argument supplied', True) doError(name+': no argument supplied', True)
else: else:
...@@ -5737,9 +5796,12 @@ def processData(live=False): ...@@ -5737,9 +5796,12 @@ def processData(live=False):
parseKernelLog(data) parseKernelLog(data)
if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)): if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)):
appendIncompleteTraceLog(testruns) appendIncompleteTraceLog(testruns)
shown = ['bios', 'biosdate', 'cpu', 'host', 'kernel', 'man', 'memfr',
'memsz', 'mode', 'numcpu', 'plat', 'time']
sysvals.vprint('System Info:') sysvals.vprint('System Info:')
for key in sorted(sysvals.stamp): for key in sorted(sysvals.stamp):
sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) if key in shown:
sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key]))
if sysvals.kparams: if sysvals.kparams:
sysvals.vprint('Kparams:\n %s' % sysvals.kparams) sysvals.vprint('Kparams:\n %s' % sysvals.kparams)
sysvals.vprint('Command:\n %s' % sysvals.cmdline) sysvals.vprint('Command:\n %s' % sysvals.cmdline)
...@@ -5768,6 +5830,12 @@ def processData(live=False): ...@@ -5768,6 +5830,12 @@ def processData(live=False):
(w[0], w[1]) (w[0], w[1])
sysvals.vprint(s) sysvals.vprint(s)
data.printDetails() data.printDetails()
if len(sysvals.platinfo) > 0:
sysvals.vprint('\nPlatform Info:')
for info in sysvals.platinfo:
sysvals.vprint(info[0]+' - '+info[1])
sysvals.vprint(info[2])
sysvals.vprint('')
if sysvals.cgdump: if sysvals.cgdump:
for data in testruns: for data in testruns:
data.debugPrint() data.debugPrint()
...@@ -5951,7 +6019,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): ...@@ -5951,7 +6019,7 @@ def data_from_html(file, outpath, issues, fulldetail=False):
worst[d] = {'name':'', 'time': 0.0} worst[d] = {'name':'', 'time': 0.0}
dev = devices[d] if d in devices else 0 dev = devices[d] if d in devices else 0
if dev and len(dev.keys()) > 0: if dev and len(dev.keys()) > 0:
n = sorted(dev, key=dev.get, reverse=True)[0] n = sorted(dev, key=lambda k:(dev[k], k), reverse=True)[0]
worst[d]['name'], worst[d]['time'] = n, dev[n] worst[d]['name'], worst[d]['time'] = n, dev[n]
data = { data = {
'mode': stmp[2], 'mode': stmp[2],
...@@ -5976,7 +6044,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): ...@@ -5976,7 +6044,7 @@ def data_from_html(file, outpath, issues, fulldetail=False):
data['funclist'] = find_in_html(html, '<div title="', '" class="traceevent"', False) data['funclist'] = find_in_html(html, '<div title="', '" class="traceevent"', False)
return data return data
def genHtml(subdir): def genHtml(subdir, force=False):
for dirname, dirnames, filenames in os.walk(subdir): for dirname, dirnames, filenames in os.walk(subdir):
sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = '' sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = ''
for filename in filenames: for filename in filenames:
...@@ -5986,7 +6054,7 @@ def genHtml(subdir): ...@@ -5986,7 +6054,7 @@ def genHtml(subdir):
sysvals.ftracefile = os.path.join(dirname, filename) sysvals.ftracefile = os.path.join(dirname, filename)
sysvals.setOutputFile() sysvals.setOutputFile()
if sysvals.ftracefile and sysvals.htmlfile and \ if sysvals.ftracefile and sysvals.htmlfile and \
not os.path.exists(sysvals.htmlfile): (force or not os.path.exists(sysvals.htmlfile)):
pprint('FTRACE: %s' % sysvals.ftracefile) pprint('FTRACE: %s' % sysvals.ftracefile)
if sysvals.dmesgfile: if sysvals.dmesgfile:
pprint('DMESG : %s' % sysvals.dmesgfile) pprint('DMESG : %s' % sysvals.dmesgfile)
...@@ -6042,7 +6110,7 @@ def checkArgBool(name, value): ...@@ -6042,7 +6110,7 @@ def checkArgBool(name, value):
# Description: # Description:
# Configure the script via the info in a config file # Configure the script via the info in a config file
def configFromFile(file): def configFromFile(file):
Config = ConfigParser.ConfigParser() Config = configparser.ConfigParser()
Config.read(file) Config.read(file)
sections = Config.sections() sections = Config.sections()
...@@ -6270,7 +6338,7 @@ def printHelp(): ...@@ -6270,7 +6338,7 @@ def printHelp():
' default: suspend-{date}-{time}\n'\ ' default: suspend-{date}-{time}\n'\
' -rtcwake t Wakeup t seconds after suspend, set t to "off" to disable (default: 15)\n'\ ' -rtcwake t Wakeup t seconds after suspend, set t to "off" to disable (default: 15)\n'\
' -addlogs Add the dmesg and ftrace logs to the html output\n'\ ' -addlogs Add the dmesg and ftrace logs to the html output\n'\
' -turbostat Use turbostat to execute the command in freeze mode (default: disabled)\n'\ ' -noturbostat Dont use turbostat in freeze mode (default: disabled)\n'\
' -srgap Add a visible gap in the timeline between sus/res (default: disabled)\n'\ ' -srgap Add a visible gap in the timeline between sus/res (default: disabled)\n'\
' -skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\ ' -skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\
' -result fn Export a results table to a text file for parsing.\n'\ ' -result fn Export a results table to a text file for parsing.\n'\
...@@ -6340,7 +6408,7 @@ if __name__ == '__main__': ...@@ -6340,7 +6408,7 @@ if __name__ == '__main__':
for arg in args: for arg in args:
if(arg == '-m'): if(arg == '-m'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No mode supplied', True) doError('No mode supplied', True)
if val == 'command' and not sysvals.testcommand: if val == 'command' and not sysvals.testcommand:
...@@ -6384,10 +6452,8 @@ if __name__ == '__main__': ...@@ -6384,10 +6452,8 @@ if __name__ == '__main__':
sysvals.dmesglog = True sysvals.dmesglog = True
elif(arg == '-addlogftrace'): elif(arg == '-addlogftrace'):
sysvals.ftracelog = True sysvals.ftracelog = True
elif(arg == '-turbostat'): elif(arg == '-noturbostat'):
sysvals.tstat = True sysvals.tstat = False
if not sysvals.haveTurbostat():
doError('Turbostat command not found')
elif(arg == '-verbose'): elif(arg == '-verbose'):
sysvals.verbose = True sysvals.verbose = True
elif(arg == '-proc'): elif(arg == '-proc'):
...@@ -6400,7 +6466,7 @@ if __name__ == '__main__': ...@@ -6400,7 +6466,7 @@ if __name__ == '__main__':
sysvals.gzip = True sysvals.gzip = True
elif(arg == '-rs'): elif(arg == '-rs'):
try: try:
val = args.next() val = next(args)
except: except:
doError('-rs requires "enable" or "disable"', True) doError('-rs requires "enable" or "disable"', True)
if val.lower() in switchvalues: if val.lower() in switchvalues:
...@@ -6412,7 +6478,7 @@ if __name__ == '__main__': ...@@ -6412,7 +6478,7 @@ if __name__ == '__main__':
doError('invalid option: %s, use "enable/disable" or "on/off"' % val, True) doError('invalid option: %s, use "enable/disable" or "on/off"' % val, True)
elif(arg == '-display'): elif(arg == '-display'):
try: try:
val = args.next() val = next(args)
except: except:
doError('-display requires an mode value', True) doError('-display requires an mode value', True)
disopt = ['on', 'off', 'standby', 'suspend'] disopt = ['on', 'off', 'standby', 'suspend']
...@@ -6423,7 +6489,7 @@ if __name__ == '__main__': ...@@ -6423,7 +6489,7 @@ if __name__ == '__main__':
sysvals.max_graph_depth = getArgInt('-maxdepth', args, 0, 1000) sysvals.max_graph_depth = getArgInt('-maxdepth', args, 0, 1000)
elif(arg == '-rtcwake'): elif(arg == '-rtcwake'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No rtcwake time supplied', True) doError('No rtcwake time supplied', True)
if val.lower() in switchoff: if val.lower() in switchoff:
...@@ -6443,7 +6509,7 @@ if __name__ == '__main__': ...@@ -6443,7 +6509,7 @@ if __name__ == '__main__':
sysvals.cgtest = getArgInt('-cgtest', args, 0, 1) sysvals.cgtest = getArgInt('-cgtest', args, 0, 1)
elif(arg == '-cgphase'): elif(arg == '-cgphase'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No phase name supplied', True) doError('No phase name supplied', True)
d = Data(0) d = Data(0)
...@@ -6453,19 +6519,19 @@ if __name__ == '__main__': ...@@ -6453,19 +6519,19 @@ if __name__ == '__main__':
sysvals.cgphase = val sysvals.cgphase = val
elif(arg == '-cgfilter'): elif(arg == '-cgfilter'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No callgraph functions supplied', True) doError('No callgraph functions supplied', True)
sysvals.setCallgraphFilter(val) sysvals.setCallgraphFilter(val)
elif(arg == '-skipkprobe'): elif(arg == '-skipkprobe'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No kprobe functions supplied', True) doError('No kprobe functions supplied', True)
sysvals.skipKprobes(val) sysvals.skipKprobes(val)
elif(arg == '-cgskip'): elif(arg == '-cgskip'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No file supplied', True) doError('No file supplied', True)
if val.lower() in switchoff: if val.lower() in switchoff:
...@@ -6480,7 +6546,7 @@ if __name__ == '__main__': ...@@ -6480,7 +6546,7 @@ if __name__ == '__main__':
sysvals.callloopmaxlen = getArgFloat('-callloop-maxlen', args, 0.0, 1.0) sysvals.callloopmaxlen = getArgFloat('-callloop-maxlen', args, 0.0, 1.0)
elif(arg == '-cmd'): elif(arg == '-cmd'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No command string supplied', True) doError('No command string supplied', True)
sysvals.testcommand = val sysvals.testcommand = val
...@@ -6495,13 +6561,13 @@ if __name__ == '__main__': ...@@ -6495,13 +6561,13 @@ if __name__ == '__main__':
sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600) sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600)
elif(arg == '-o'): elif(arg == '-o'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No subdirectory name supplied', True) doError('No subdirectory name supplied', True)
sysvals.outdir = sysvals.setOutputFolder(val) sysvals.outdir = sysvals.setOutputFolder(val)
elif(arg == '-config'): elif(arg == '-config'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No text file supplied', True) doError('No text file supplied', True)
file = sysvals.configFile(val) file = sysvals.configFile(val)
...@@ -6510,7 +6576,7 @@ if __name__ == '__main__': ...@@ -6510,7 +6576,7 @@ if __name__ == '__main__':
configFromFile(file) configFromFile(file)
elif(arg == '-fadd'): elif(arg == '-fadd'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No text file supplied', True) doError('No text file supplied', True)
file = sysvals.configFile(val) file = sysvals.configFile(val)
...@@ -6519,7 +6585,7 @@ if __name__ == '__main__': ...@@ -6519,7 +6585,7 @@ if __name__ == '__main__':
sysvals.addFtraceFilterFunctions(file) sysvals.addFtraceFilterFunctions(file)
elif(arg == '-dmesg'): elif(arg == '-dmesg'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No dmesg file supplied', True) doError('No dmesg file supplied', True)
sysvals.notestrun = True sysvals.notestrun = True
...@@ -6528,7 +6594,7 @@ if __name__ == '__main__': ...@@ -6528,7 +6594,7 @@ if __name__ == '__main__':
doError('%s does not exist' % sysvals.dmesgfile) doError('%s does not exist' % sysvals.dmesgfile)
elif(arg == '-ftrace'): elif(arg == '-ftrace'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No ftrace file supplied', True) doError('No ftrace file supplied', True)
sysvals.notestrun = True sysvals.notestrun = True
...@@ -6537,7 +6603,7 @@ if __name__ == '__main__': ...@@ -6537,7 +6603,7 @@ if __name__ == '__main__':
doError('%s does not exist' % sysvals.ftracefile) doError('%s does not exist' % sysvals.ftracefile)
elif(arg == '-summary'): elif(arg == '-summary'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No directory supplied', True) doError('No directory supplied', True)
cmd = 'summary' cmd = 'summary'
...@@ -6547,13 +6613,13 @@ if __name__ == '__main__': ...@@ -6547,13 +6613,13 @@ if __name__ == '__main__':
doError('%s is not accesible' % val) doError('%s is not accesible' % val)
elif(arg == '-filter'): elif(arg == '-filter'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No devnames supplied', True) doError('No devnames supplied', True)
sysvals.setDeviceFilter(val) sysvals.setDeviceFilter(val)
elif(arg == '-result'): elif(arg == '-result'):
try: try:
val = args.next() val = next(args)
except: except:
doError('No result file supplied', True) doError('No result file supplied', True)
sysvals.result = val sysvals.result = val
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment