mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
pm-graph v5.8
- if wakeups occur in s2idle: "freeze time: N (-x ms waking y times) ms" - change FREEZELOOP and FREEZEWAKE to S2LOOP and S2WAKE for brevity - returns all sysfs vals to their initial state after testing - use the dmesg log for debugging until the test is completed, instrument the executeSuspend process to have a full trace, if test completes, formal dmesg log overwrites the debug log - fix CPU_ON and CPU_OFF devices in the timeline, should include [n] Signed-off-by: Todd Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
committed by
Rafael J. Wysocki
parent
418baf2c28
commit
d23e95c090
@@ -6,7 +6,7 @@
|
|||||||
|_| |___/ |_|
|
|_| |___/ |_|
|
||||||
|
|
||||||
pm-graph: suspend/resume/boot timing analysis tools
|
pm-graph: suspend/resume/boot timing analysis tools
|
||||||
Version: 5.7
|
Version: 5.8
|
||||||
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
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
- runs with python2 or python3, choice is made by /usr/bin/python link
|
- runs with python2 or python3, choice is made by /usr/bin/python link
|
||||||
- python
|
- python
|
||||||
- python-configparser (for python2 sleepgraph)
|
- python-configparser (for python2 sleepgraph)
|
||||||
- python-requests (for googlesheet.py)
|
- python-requests (for stresstester.py)
|
||||||
- linux-tools-common (for turbostat usage in sleepgraph)
|
- linux-tools-common (for turbostat usage in sleepgraph)
|
||||||
|
|
||||||
Ubuntu:
|
Ubuntu:
|
||||||
|
@@ -81,7 +81,7 @@ def ascii(text):
|
|||||||
# store system values and test parameters
|
# store system values and test parameters
|
||||||
class SystemValues:
|
class SystemValues:
|
||||||
title = 'SleepGraph'
|
title = 'SleepGraph'
|
||||||
version = '5.7'
|
version = '5.8'
|
||||||
ansi = False
|
ansi = False
|
||||||
rs = 0
|
rs = 0
|
||||||
display = ''
|
display = ''
|
||||||
@@ -92,8 +92,9 @@ class SystemValues:
|
|||||||
testlog = True
|
testlog = True
|
||||||
dmesglog = True
|
dmesglog = True
|
||||||
ftracelog = False
|
ftracelog = False
|
||||||
|
acpidebug = True
|
||||||
tstat = True
|
tstat = True
|
||||||
mindevlen = 0.0
|
mindevlen = 0.0001
|
||||||
mincglen = 0.0
|
mincglen = 0.0
|
||||||
cgphase = ''
|
cgphase = ''
|
||||||
cgtest = -1
|
cgtest = -1
|
||||||
@@ -115,6 +116,7 @@ class SystemValues:
|
|||||||
fpdtpath = '/sys/firmware/acpi/tables/FPDT'
|
fpdtpath = '/sys/firmware/acpi/tables/FPDT'
|
||||||
epath = '/sys/kernel/debug/tracing/events/power/'
|
epath = '/sys/kernel/debug/tracing/events/power/'
|
||||||
pmdpath = '/sys/power/pm_debug_messages'
|
pmdpath = '/sys/power/pm_debug_messages'
|
||||||
|
acpipath='/sys/module/acpi/parameters/debug_level'
|
||||||
traceevents = [
|
traceevents = [
|
||||||
'suspend_resume',
|
'suspend_resume',
|
||||||
'wakeup_source_activate',
|
'wakeup_source_activate',
|
||||||
@@ -162,16 +164,16 @@ class SystemValues:
|
|||||||
devdump = False
|
devdump = False
|
||||||
mixedphaseheight = True
|
mixedphaseheight = True
|
||||||
devprops = dict()
|
devprops = dict()
|
||||||
|
cfgdef = dict()
|
||||||
platinfo = []
|
platinfo = []
|
||||||
predelay = 0
|
predelay = 0
|
||||||
postdelay = 0
|
postdelay = 0
|
||||||
pmdebug = ''
|
|
||||||
tmstart = 'SUSPEND START %Y%m%d-%H:%M:%S.%f'
|
tmstart = 'SUSPEND START %Y%m%d-%H:%M:%S.%f'
|
||||||
tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:%S.%f'
|
tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:%S.%f'
|
||||||
tracefuncs = {
|
tracefuncs = {
|
||||||
'sys_sync': {},
|
'sys_sync': {},
|
||||||
'ksys_sync': {},
|
'ksys_sync': {},
|
||||||
'pm_notifier_call_chain_robust': {},
|
'__pm_notifier_call_chain': {},
|
||||||
'pm_prepare_console': {},
|
'pm_prepare_console': {},
|
||||||
'pm_notifier_call_chain': {},
|
'pm_notifier_call_chain': {},
|
||||||
'freeze_processes': {},
|
'freeze_processes': {},
|
||||||
@@ -490,9 +492,9 @@ class SystemValues:
|
|||||||
call('echo 0 > %s/wakealarm' % self.rtcpath, shell=True)
|
call('echo 0 > %s/wakealarm' % self.rtcpath, shell=True)
|
||||||
def initdmesg(self):
|
def initdmesg(self):
|
||||||
# get the latest time stamp from the dmesg log
|
# get the latest time stamp from the dmesg log
|
||||||
fp = Popen('dmesg', stdout=PIPE).stdout
|
lines = Popen('dmesg', stdout=PIPE).stdout.readlines()
|
||||||
ktime = '0'
|
ktime = '0'
|
||||||
for line in fp:
|
for line in reversed(lines):
|
||||||
line = ascii(line).replace('\r\n', '')
|
line = ascii(line).replace('\r\n', '')
|
||||||
idx = line.find('[')
|
idx = line.find('[')
|
||||||
if idx > 1:
|
if idx > 1:
|
||||||
@@ -500,7 +502,7 @@ class SystemValues:
|
|||||||
m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
|
m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
|
||||||
if(m):
|
if(m):
|
||||||
ktime = m.group('ktime')
|
ktime = m.group('ktime')
|
||||||
fp.close()
|
break
|
||||||
self.dmesgstart = float(ktime)
|
self.dmesgstart = float(ktime)
|
||||||
def getdmesg(self, testdata):
|
def getdmesg(self, testdata):
|
||||||
op = self.writeDatafileHeader(self.dmesgfile, testdata)
|
op = self.writeDatafileHeader(self.dmesgfile, testdata)
|
||||||
@@ -715,8 +717,6 @@ class SystemValues:
|
|||||||
self.fsetVal('0', 'events/kprobes/enable')
|
self.fsetVal('0', 'events/kprobes/enable')
|
||||||
self.fsetVal('', 'kprobe_events')
|
self.fsetVal('', 'kprobe_events')
|
||||||
self.fsetVal('1024', 'buffer_size_kb')
|
self.fsetVal('1024', 'buffer_size_kb')
|
||||||
if self.pmdebug:
|
|
||||||
self.setVal(self.pmdebug, self.pmdpath)
|
|
||||||
def setupAllKprobes(self):
|
def setupAllKprobes(self):
|
||||||
for name in self.tracefuncs:
|
for name in self.tracefuncs:
|
||||||
self.defaultKprobe(name, self.tracefuncs[name])
|
self.defaultKprobe(name, self.tracefuncs[name])
|
||||||
@@ -740,11 +740,7 @@ class SystemValues:
|
|||||||
# turn trace off
|
# turn trace off
|
||||||
self.fsetVal('0', 'tracing_on')
|
self.fsetVal('0', 'tracing_on')
|
||||||
self.cleanupFtrace()
|
self.cleanupFtrace()
|
||||||
# pm debug messages
|
self.testVal(self.pmdpath, 'basic', '1')
|
||||||
pv = self.getVal(self.pmdpath)
|
|
||||||
if pv != '1':
|
|
||||||
self.setVal('1', self.pmdpath)
|
|
||||||
self.pmdebug = pv
|
|
||||||
# set the trace clock to global
|
# set the trace clock to global
|
||||||
self.fsetVal('global', 'trace_clock')
|
self.fsetVal('global', 'trace_clock')
|
||||||
self.fsetVal('nop', 'current_tracer')
|
self.fsetVal('nop', 'current_tracer')
|
||||||
@@ -900,6 +896,14 @@ class SystemValues:
|
|||||||
if isgz:
|
if isgz:
|
||||||
return gzip.open(filename, mode+'t')
|
return gzip.open(filename, mode+'t')
|
||||||
return open(filename, mode)
|
return open(filename, mode)
|
||||||
|
def putlog(self, filename, text):
|
||||||
|
with self.openlog(filename, 'a') as fp:
|
||||||
|
fp.write(text)
|
||||||
|
fp.close()
|
||||||
|
def dlog(self, text):
|
||||||
|
self.putlog(self.dmesgfile, '# %s\n' % text)
|
||||||
|
def flog(self, text):
|
||||||
|
self.putlog(self.ftracefile, text)
|
||||||
def b64unzip(self, data):
|
def b64unzip(self, data):
|
||||||
try:
|
try:
|
||||||
out = codecs.decode(base64.b64decode(data), 'zlib').decode()
|
out = codecs.decode(base64.b64decode(data), 'zlib').decode()
|
||||||
@@ -992,9 +996,7 @@ class SystemValues:
|
|||||||
# add a line for each of these commands with their outputs
|
# add a line for each of these commands with their outputs
|
||||||
for name, cmdline, info in cmdafter:
|
for name, cmdline, info in cmdafter:
|
||||||
footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
|
footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
|
||||||
|
self.flog(footer)
|
||||||
with self.openlog(self.ftracefile, 'a') as fp:
|
|
||||||
fp.write(footer)
|
|
||||||
return True
|
return True
|
||||||
def commonPrefix(self, list):
|
def commonPrefix(self, list):
|
||||||
if len(list) < 2:
|
if len(list) < 2:
|
||||||
@@ -1034,6 +1036,7 @@ class SystemValues:
|
|||||||
cmdline, cmdpath = ' '.join(cargs[2:]), self.getExec(cargs[2])
|
cmdline, cmdpath = ' '.join(cargs[2:]), self.getExec(cargs[2])
|
||||||
if not cmdpath or (begin and not delta):
|
if not cmdpath or (begin and not delta):
|
||||||
continue
|
continue
|
||||||
|
self.dlog('[%s]' % cmdline)
|
||||||
try:
|
try:
|
||||||
fp = Popen([cmdpath]+cargs[3:], stdout=PIPE, stderr=PIPE).stdout
|
fp = Popen([cmdpath]+cargs[3:], stdout=PIPE, stderr=PIPE).stdout
|
||||||
info = ascii(fp.read()).strip()
|
info = ascii(fp.read()).strip()
|
||||||
@@ -1060,6 +1063,29 @@ class SystemValues:
|
|||||||
else:
|
else:
|
||||||
out.append((name, cmdline, '\tnothing' if not info else info))
|
out.append((name, cmdline, '\tnothing' if not info else info))
|
||||||
return out
|
return out
|
||||||
|
def testVal(self, file, fmt='basic', value=''):
|
||||||
|
if file == 'restoreall':
|
||||||
|
for f in self.cfgdef:
|
||||||
|
if os.path.exists(f):
|
||||||
|
fp = open(f, 'w')
|
||||||
|
fp.write(self.cfgdef[f])
|
||||||
|
fp.close()
|
||||||
|
self.cfgdef = dict()
|
||||||
|
elif value and os.path.exists(file):
|
||||||
|
fp = open(file, 'r+')
|
||||||
|
if fmt == 'radio':
|
||||||
|
m = re.match('.*\[(?P<v>.*)\].*', fp.read())
|
||||||
|
if m:
|
||||||
|
self.cfgdef[file] = m.group('v')
|
||||||
|
elif fmt == 'acpi':
|
||||||
|
line = fp.read().strip().split('\n')[-1]
|
||||||
|
m = re.match('.* (?P<v>[0-9A-Fx]*) .*', line)
|
||||||
|
if m:
|
||||||
|
self.cfgdef[file] = m.group('v')
|
||||||
|
else:
|
||||||
|
self.cfgdef[file] = fp.read().strip()
|
||||||
|
fp.write(value)
|
||||||
|
fp.close()
|
||||||
def haveTurbostat(self):
|
def haveTurbostat(self):
|
||||||
if not self.tstat:
|
if not self.tstat:
|
||||||
return False
|
return False
|
||||||
@@ -1201,6 +1227,57 @@ class SystemValues:
|
|||||||
self.multitest[sz] *= 1440
|
self.multitest[sz] *= 1440
|
||||||
elif unit == 'h':
|
elif unit == 'h':
|
||||||
self.multitest[sz] *= 60
|
self.multitest[sz] *= 60
|
||||||
|
def displayControl(self, cmd):
|
||||||
|
xset, ret = 'timeout 10 xset -d :0.0 {0}', 0
|
||||||
|
if self.sudouser:
|
||||||
|
xset = 'sudo -u %s %s' % (self.sudouser, xset)
|
||||||
|
if cmd == 'init':
|
||||||
|
ret = call(xset.format('dpms 0 0 0'), shell=True)
|
||||||
|
if not ret:
|
||||||
|
ret = call(xset.format('s off'), shell=True)
|
||||||
|
elif cmd == 'reset':
|
||||||
|
ret = call(xset.format('s reset'), shell=True)
|
||||||
|
elif cmd in ['on', 'off', 'standby', 'suspend']:
|
||||||
|
b4 = self.displayControl('stat')
|
||||||
|
ret = call(xset.format('dpms force %s' % cmd), shell=True)
|
||||||
|
if not ret:
|
||||||
|
curr = self.displayControl('stat')
|
||||||
|
self.vprint('Display Switched: %s -> %s' % (b4, curr))
|
||||||
|
if curr != cmd:
|
||||||
|
self.vprint('WARNING: Display failed to change to %s' % cmd)
|
||||||
|
if ret:
|
||||||
|
self.vprint('WARNING: Display failed to change to %s with xset' % cmd)
|
||||||
|
return ret
|
||||||
|
elif cmd == 'stat':
|
||||||
|
fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout
|
||||||
|
ret = 'unknown'
|
||||||
|
for line in fp:
|
||||||
|
m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line))
|
||||||
|
if(m and len(m.group('m')) >= 2):
|
||||||
|
out = m.group('m').lower()
|
||||||
|
ret = out[3:] if out[0:2] == 'in' else out
|
||||||
|
break
|
||||||
|
fp.close()
|
||||||
|
return ret
|
||||||
|
def setRuntimeSuspend(self, before=True):
|
||||||
|
if before:
|
||||||
|
# runtime suspend disable or enable
|
||||||
|
if self.rs > 0:
|
||||||
|
self.rstgt, self.rsval, self.rsdir = 'on', 'auto', 'enabled'
|
||||||
|
else:
|
||||||
|
self.rstgt, self.rsval, self.rsdir = 'auto', 'on', 'disabled'
|
||||||
|
pprint('CONFIGURING RUNTIME SUSPEND...')
|
||||||
|
self.rslist = deviceInfo(self.rstgt)
|
||||||
|
for i in self.rslist:
|
||||||
|
self.setVal(self.rsval, i)
|
||||||
|
pprint('runtime suspend %s on all devices (%d changed)' % (self.rsdir, len(self.rslist)))
|
||||||
|
pprint('waiting 5 seconds...')
|
||||||
|
time.sleep(5)
|
||||||
|
else:
|
||||||
|
# runtime suspend re-enable or re-disable
|
||||||
|
for i in self.rslist:
|
||||||
|
self.setVal(self.rstgt, i)
|
||||||
|
pprint('runtime suspend settings restored on %d devices' % len(self.rslist))
|
||||||
|
|
||||||
sysvals = SystemValues()
|
sysvals = SystemValues()
|
||||||
switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0']
|
switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0']
|
||||||
@@ -1640,15 +1717,20 @@ class Data:
|
|||||||
if 'resume_machine' in phase and 'suspend_machine' in lp:
|
if 'resume_machine' in phase and 'suspend_machine' in lp:
|
||||||
tS, tR = self.dmesg[lp]['end'], self.dmesg[phase]['start']
|
tS, tR = self.dmesg[lp]['end'], self.dmesg[phase]['start']
|
||||||
tL = tR - tS
|
tL = tR - tS
|
||||||
if tL > 0:
|
if tL <= 0:
|
||||||
left = True if tR > tZero else False
|
continue
|
||||||
self.trimTime(tS, tL, left)
|
left = True if tR > tZero else False
|
||||||
if 'trying' in self.dmesg[lp] and self.dmesg[lp]['trying'] >= 0.001:
|
self.trimTime(tS, tL, left)
|
||||||
tTry = round(self.dmesg[lp]['trying'] * 1000)
|
if 'waking' in self.dmesg[lp]:
|
||||||
text = '%.0f (-%.0f waking)' % (tL * 1000, tTry)
|
tCnt = self.dmesg[lp]['waking'][0]
|
||||||
|
if self.dmesg[lp]['waking'][1] >= 0.001:
|
||||||
|
tTry = '-%.0f' % (round(self.dmesg[lp]['waking'][1] * 1000))
|
||||||
else:
|
else:
|
||||||
text = '%.0f' % (tL * 1000)
|
tTry = '-%.3f' % (self.dmesg[lp]['waking'][1] * 1000)
|
||||||
self.tLow.append(text)
|
text = '%.0f (%s ms waking %d times)' % (tL * 1000, tTry, tCnt)
|
||||||
|
else:
|
||||||
|
text = '%.0f' % (tL * 1000)
|
||||||
|
self.tLow.append(text)
|
||||||
lp = phase
|
lp = phase
|
||||||
def getMemTime(self):
|
def getMemTime(self):
|
||||||
if not self.hwstart or not self.hwend:
|
if not self.hwstart or not self.hwend:
|
||||||
@@ -1921,7 +2003,7 @@ class Data:
|
|||||||
for dev in list:
|
for dev in list:
|
||||||
length = (list[dev]['end'] - list[dev]['start']) * 1000
|
length = (list[dev]['end'] - list[dev]['start']) * 1000
|
||||||
width = widfmt % (((list[dev]['end']-list[dev]['start'])*100)/tTotal)
|
width = widfmt % (((list[dev]['end']-list[dev]['start'])*100)/tTotal)
|
||||||
if width != '0.000000' and length >= mindevlen:
|
if length >= mindevlen:
|
||||||
devlist.append(dev)
|
devlist.append(dev)
|
||||||
self.tdevlist[phase] = devlist
|
self.tdevlist[phase] = devlist
|
||||||
def addHorizontalDivider(self, devname, devend):
|
def addHorizontalDivider(self, devname, devend):
|
||||||
@@ -3316,9 +3398,10 @@ def parseTraceLog(live=False):
|
|||||||
# trim out s2idle loops, track time trying to freeze
|
# trim out s2idle loops, track time trying to freeze
|
||||||
llp = data.lastPhase(2)
|
llp = data.lastPhase(2)
|
||||||
if llp.startswith('suspend_machine'):
|
if llp.startswith('suspend_machine'):
|
||||||
if 'trying' not in data.dmesg[llp]:
|
if 'waking' not in data.dmesg[llp]:
|
||||||
data.dmesg[llp]['trying'] = 0
|
data.dmesg[llp]['waking'] = [0, 0.0]
|
||||||
data.dmesg[llp]['trying'] += \
|
data.dmesg[llp]['waking'][0] += 1
|
||||||
|
data.dmesg[llp]['waking'][1] += \
|
||||||
t.time - data.dmesg[lp]['start']
|
t.time - data.dmesg[lp]['start']
|
||||||
data.currphase = ''
|
data.currphase = ''
|
||||||
del data.dmesg[lp]
|
del data.dmesg[lp]
|
||||||
@@ -4555,7 +4638,7 @@ def createHTML(testruns, testfail):
|
|||||||
# 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 sorted(data.tdevlist[b]):
|
for d in sorted(data.tdevlist[b]):
|
||||||
dname = d if '[' not in d else d.split('[')[0]
|
dname = d if ('[' not in d or 'CPU' in d) else d.split('[')[0]
|
||||||
name, dev = dname, phaselist[d]
|
name, dev = dname, phaselist[d]
|
||||||
drv = xtraclass = xtrainfo = xtrastyle = ''
|
drv = xtraclass = xtrainfo = xtrastyle = ''
|
||||||
if 'htmlclass' in dev:
|
if 'htmlclass' in dev:
|
||||||
@@ -5194,156 +5277,146 @@ def addScriptCode(hf, testruns):
|
|||||||
'</script>\n'
|
'</script>\n'
|
||||||
hf.write(script_code);
|
hf.write(script_code);
|
||||||
|
|
||||||
def setRuntimeSuspend(before=True):
|
|
||||||
global sysvals
|
|
||||||
sv = sysvals
|
|
||||||
if sv.rs == 0:
|
|
||||||
return
|
|
||||||
if before:
|
|
||||||
# runtime suspend disable or enable
|
|
||||||
if sv.rs > 0:
|
|
||||||
sv.rstgt, sv.rsval, sv.rsdir = 'on', 'auto', 'enabled'
|
|
||||||
else:
|
|
||||||
sv.rstgt, sv.rsval, sv.rsdir = 'auto', 'on', 'disabled'
|
|
||||||
pprint('CONFIGURING RUNTIME SUSPEND...')
|
|
||||||
sv.rslist = deviceInfo(sv.rstgt)
|
|
||||||
for i in sv.rslist:
|
|
||||||
sv.setVal(sv.rsval, i)
|
|
||||||
pprint('runtime suspend %s on all devices (%d changed)' % (sv.rsdir, len(sv.rslist)))
|
|
||||||
pprint('waiting 5 seconds...')
|
|
||||||
time.sleep(5)
|
|
||||||
else:
|
|
||||||
# runtime suspend re-enable or re-disable
|
|
||||||
for i in sv.rslist:
|
|
||||||
sv.setVal(sv.rstgt, i)
|
|
||||||
pprint('runtime suspend settings restored on %d devices' % len(sv.rslist))
|
|
||||||
|
|
||||||
# Function: executeSuspend
|
# Function: executeSuspend
|
||||||
# Description:
|
# Description:
|
||||||
# Execute system suspend through the sysfs interface, then copy the output
|
# Execute system suspend through the sysfs interface, then copy the output
|
||||||
# dmesg and ftrace files to the test output directory.
|
# dmesg and ftrace files to the test output directory.
|
||||||
def executeSuspend(quiet=False):
|
def executeSuspend(quiet=False):
|
||||||
pm = ProcessMonitor()
|
sv, tp, pm = sysvals, sysvals.tpath, ProcessMonitor()
|
||||||
tp = sysvals.tpath
|
if sv.wifi:
|
||||||
if sysvals.wifi:
|
wifi = sv.checkWifi()
|
||||||
wifi = sysvals.checkWifi()
|
sv.dlog('wifi check, connected device is "%s"' % wifi)
|
||||||
testdata = []
|
testdata = []
|
||||||
# run these commands to prepare the system for suspend
|
# run these commands to prepare the system for suspend
|
||||||
if sysvals.display:
|
if sv.display:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
pprint('SET DISPLAY TO %s' % sysvals.display.upper())
|
pprint('SET DISPLAY TO %s' % sv.display.upper())
|
||||||
displayControl(sysvals.display)
|
ret = sv.displayControl(sv.display)
|
||||||
|
sv.dlog('xset display %s, ret = %d' % (sv.display, ret))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if sysvals.sync:
|
if sv.sync:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
pprint('SYNCING FILESYSTEMS')
|
pprint('SYNCING FILESYSTEMS')
|
||||||
|
sv.dlog('syncing filesystems')
|
||||||
call('sync', shell=True)
|
call('sync', shell=True)
|
||||||
# mark the start point in the kernel ring buffer just as we start
|
sv.dlog('read dmesg')
|
||||||
sysvals.initdmesg()
|
sv.initdmesg()
|
||||||
# start ftrace
|
# start ftrace
|
||||||
if(sysvals.usecallgraph or sysvals.usetraceevents):
|
if(sv.usecallgraph or sv.usetraceevents):
|
||||||
if not quiet:
|
if not quiet:
|
||||||
pprint('START TRACING')
|
pprint('START TRACING')
|
||||||
sysvals.fsetVal('1', 'tracing_on')
|
sv.dlog('start ftrace tracing')
|
||||||
if sysvals.useprocmon:
|
sv.fsetVal('1', 'tracing_on')
|
||||||
|
if sv.useprocmon:
|
||||||
|
sv.dlog('start the process monitor')
|
||||||
pm.start()
|
pm.start()
|
||||||
sysvals.cmdinfo(True)
|
sv.dlog('run the cmdinfo list before')
|
||||||
|
sv.cmdinfo(True)
|
||||||
# execute however many s/r runs requested
|
# execute however many s/r runs requested
|
||||||
for count in range(1,sysvals.execcount+1):
|
for count in range(1,sv.execcount+1):
|
||||||
# x2delay in between test runs
|
# x2delay in between test runs
|
||||||
if(count > 1 and sysvals.x2delay > 0):
|
if(count > 1 and sv.x2delay > 0):
|
||||||
sysvals.fsetVal('WAIT %d' % sysvals.x2delay, 'trace_marker')
|
sv.fsetVal('WAIT %d' % sv.x2delay, 'trace_marker')
|
||||||
time.sleep(sysvals.x2delay/1000.0)
|
time.sleep(sv.x2delay/1000.0)
|
||||||
sysvals.fsetVal('WAIT END', 'trace_marker')
|
sv.fsetVal('WAIT END', 'trace_marker')
|
||||||
# start message
|
# start message
|
||||||
if sysvals.testcommand != '':
|
if sv.testcommand != '':
|
||||||
pprint('COMMAND START')
|
pprint('COMMAND START')
|
||||||
else:
|
else:
|
||||||
if(sysvals.rtcwake):
|
if(sv.rtcwake):
|
||||||
pprint('SUSPEND START')
|
pprint('SUSPEND START')
|
||||||
else:
|
else:
|
||||||
pprint('SUSPEND START (press a key to resume)')
|
pprint('SUSPEND START (press a key to resume)')
|
||||||
# set rtcwake
|
# set rtcwake
|
||||||
if(sysvals.rtcwake):
|
if(sv.rtcwake):
|
||||||
if not quiet:
|
if not quiet:
|
||||||
pprint('will issue an rtcwake in %d seconds' % sysvals.rtcwaketime)
|
pprint('will issue an rtcwake in %d seconds' % sv.rtcwaketime)
|
||||||
sysvals.rtcWakeAlarmOn()
|
sv.dlog('enable RTC wake alarm')
|
||||||
|
sv.rtcWakeAlarmOn()
|
||||||
# start of suspend trace marker
|
# start of suspend trace marker
|
||||||
if(sysvals.usecallgraph or sysvals.usetraceevents):
|
if(sv.usecallgraph or sv.usetraceevents):
|
||||||
sysvals.fsetVal(datetime.now().strftime(sysvals.tmstart), 'trace_marker')
|
sv.fsetVal(datetime.now().strftime(sv.tmstart), 'trace_marker')
|
||||||
# predelay delay
|
# predelay delay
|
||||||
if(count == 1 and sysvals.predelay > 0):
|
if(count == 1 and sv.predelay > 0):
|
||||||
sysvals.fsetVal('WAIT %d' % sysvals.predelay, 'trace_marker')
|
sv.fsetVal('WAIT %d' % sv.predelay, 'trace_marker')
|
||||||
time.sleep(sysvals.predelay/1000.0)
|
time.sleep(sv.predelay/1000.0)
|
||||||
sysvals.fsetVal('WAIT END', 'trace_marker')
|
sv.fsetVal('WAIT END', 'trace_marker')
|
||||||
# initiate suspend or command
|
# initiate suspend or command
|
||||||
|
sv.dlog('system executing a suspend')
|
||||||
tdata = {'error': ''}
|
tdata = {'error': ''}
|
||||||
if sysvals.testcommand != '':
|
if sv.testcommand != '':
|
||||||
res = call(sysvals.testcommand+' 2>&1', shell=True);
|
res = call(sv.testcommand+' 2>&1', shell=True);
|
||||||
if res != 0:
|
if res != 0:
|
||||||
tdata['error'] = 'cmd returned %d' % res
|
tdata['error'] = 'cmd returned %d' % res
|
||||||
else:
|
else:
|
||||||
mode = sysvals.suspendmode
|
mode = sv.suspendmode
|
||||||
if sysvals.memmode and os.path.exists(sysvals.mempowerfile):
|
if sv.memmode and os.path.exists(sv.mempowerfile):
|
||||||
mode = 'mem'
|
mode = 'mem'
|
||||||
pf = open(sysvals.mempowerfile, 'w')
|
sv.testVal(sv.mempowerfile, 'radio', sv.memmode)
|
||||||
pf.write(sysvals.memmode)
|
if sv.diskmode and os.path.exists(sv.diskpowerfile):
|
||||||
pf.close()
|
|
||||||
if sysvals.diskmode and os.path.exists(sysvals.diskpowerfile):
|
|
||||||
mode = 'disk'
|
mode = 'disk'
|
||||||
pf = open(sysvals.diskpowerfile, 'w')
|
sv.testVal(sv.diskpowerfile, 'radio', sv.diskmode)
|
||||||
pf.write(sysvals.diskmode)
|
if sv.acpidebug:
|
||||||
pf.close()
|
sv.testVal(sv.acpipath, 'acpi', '0xe')
|
||||||
if mode == 'freeze' and sysvals.haveTurbostat():
|
if mode == 'freeze' and sv.haveTurbostat():
|
||||||
# execution will pause here
|
# execution will pause here
|
||||||
turbo = sysvals.turbostat()
|
turbo = sv.turbostat()
|
||||||
if turbo:
|
if turbo:
|
||||||
tdata['turbo'] = turbo
|
tdata['turbo'] = turbo
|
||||||
else:
|
else:
|
||||||
pf = open(sysvals.powerfile, 'w')
|
pf = open(sv.powerfile, 'w')
|
||||||
pf.write(mode)
|
pf.write(mode)
|
||||||
# execution will pause here
|
# execution will pause here
|
||||||
try:
|
try:
|
||||||
pf.close()
|
pf.close()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
tdata['error'] = str(e)
|
tdata['error'] = str(e)
|
||||||
if(sysvals.rtcwake):
|
sv.dlog('system returned from resume')
|
||||||
sysvals.rtcWakeAlarmOff()
|
# reset everything
|
||||||
|
sv.testVal('restoreall')
|
||||||
|
if(sv.rtcwake):
|
||||||
|
sv.dlog('disable RTC wake alarm')
|
||||||
|
sv.rtcWakeAlarmOff()
|
||||||
# postdelay delay
|
# postdelay delay
|
||||||
if(count == sysvals.execcount and sysvals.postdelay > 0):
|
if(count == sv.execcount and sv.postdelay > 0):
|
||||||
sysvals.fsetVal('WAIT %d' % sysvals.postdelay, 'trace_marker')
|
sv.fsetVal('WAIT %d' % sv.postdelay, 'trace_marker')
|
||||||
time.sleep(sysvals.postdelay/1000.0)
|
time.sleep(sv.postdelay/1000.0)
|
||||||
sysvals.fsetVal('WAIT END', 'trace_marker')
|
sv.fsetVal('WAIT END', 'trace_marker')
|
||||||
# return from suspend
|
# return from suspend
|
||||||
pprint('RESUME COMPLETE')
|
pprint('RESUME COMPLETE')
|
||||||
if(sysvals.usecallgraph or sysvals.usetraceevents):
|
if(sv.usecallgraph or sv.usetraceevents):
|
||||||
sysvals.fsetVal(datetime.now().strftime(sysvals.tmend), 'trace_marker')
|
sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker')
|
||||||
if sysvals.wifi and wifi:
|
if sv.wifi and wifi:
|
||||||
tdata['wifi'] = sysvals.pollWifi(wifi)
|
tdata['wifi'] = sv.pollWifi(wifi)
|
||||||
if(sysvals.suspendmode == 'mem' or sysvals.suspendmode == 'command'):
|
sv.dlog('wifi check, %s' % tdata['wifi'])
|
||||||
|
if(sv.suspendmode == 'mem' or sv.suspendmode == 'command'):
|
||||||
|
sv.dlog('read the ACPI FPDT')
|
||||||
tdata['fw'] = getFPDT(False)
|
tdata['fw'] = getFPDT(False)
|
||||||
testdata.append(tdata)
|
testdata.append(tdata)
|
||||||
cmdafter = sysvals.cmdinfo(False)
|
sv.dlog('run the cmdinfo list after')
|
||||||
|
cmdafter = sv.cmdinfo(False)
|
||||||
# stop ftrace
|
# stop ftrace
|
||||||
if(sysvals.usecallgraph or sysvals.usetraceevents):
|
if(sv.usecallgraph or sv.usetraceevents):
|
||||||
if sysvals.useprocmon:
|
if sv.useprocmon:
|
||||||
|
sv.dlog('stop the process monitor')
|
||||||
pm.stop()
|
pm.stop()
|
||||||
sysvals.fsetVal('0', 'tracing_on')
|
sv.fsetVal('0', 'tracing_on')
|
||||||
# grab a copy of the dmesg output
|
# grab a copy of the dmesg output
|
||||||
if not quiet:
|
if not quiet:
|
||||||
pprint('CAPTURING DMESG')
|
pprint('CAPTURING DMESG')
|
||||||
sysvals.getdmesg(testdata)
|
sysvals.dlog('EXECUTION TRACE END')
|
||||||
|
sv.getdmesg(testdata)
|
||||||
# grab a copy of the ftrace output
|
# grab a copy of the ftrace output
|
||||||
if(sysvals.usecallgraph or sysvals.usetraceevents):
|
if(sv.usecallgraph or sv.usetraceevents):
|
||||||
if not quiet:
|
if not quiet:
|
||||||
pprint('CAPTURING TRACE')
|
pprint('CAPTURING TRACE')
|
||||||
op = sysvals.writeDatafileHeader(sysvals.ftracefile, testdata)
|
op = sv.writeDatafileHeader(sv.ftracefile, testdata)
|
||||||
fp = open(tp+'trace', 'r')
|
fp = open(tp+'trace', 'r')
|
||||||
for line in fp:
|
for line in fp:
|
||||||
op.write(line)
|
op.write(line)
|
||||||
op.close()
|
op.close()
|
||||||
sysvals.fsetVal('', 'trace')
|
sv.fsetVal('', 'trace')
|
||||||
sysvals.platforminfo(cmdafter)
|
sv.platforminfo(cmdafter)
|
||||||
|
|
||||||
def readFile(file):
|
def readFile(file):
|
||||||
if os.path.islink(file):
|
if os.path.islink(file):
|
||||||
@@ -5586,39 +5659,6 @@ def dmidecode(mempath, fatal=False):
|
|||||||
count += 1
|
count += 1
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def displayControl(cmd):
|
|
||||||
xset, ret = 'timeout 10 xset -d :0.0 {0}', 0
|
|
||||||
if sysvals.sudouser:
|
|
||||||
xset = 'sudo -u %s %s' % (sysvals.sudouser, xset)
|
|
||||||
if cmd == 'init':
|
|
||||||
ret = call(xset.format('dpms 0 0 0'), shell=True)
|
|
||||||
if not ret:
|
|
||||||
ret = call(xset.format('s off'), shell=True)
|
|
||||||
elif cmd == 'reset':
|
|
||||||
ret = call(xset.format('s reset'), shell=True)
|
|
||||||
elif cmd in ['on', 'off', 'standby', 'suspend']:
|
|
||||||
b4 = displayControl('stat')
|
|
||||||
ret = call(xset.format('dpms force %s' % cmd), shell=True)
|
|
||||||
if not ret:
|
|
||||||
curr = displayControl('stat')
|
|
||||||
sysvals.vprint('Display Switched: %s -> %s' % (b4, curr))
|
|
||||||
if curr != cmd:
|
|
||||||
sysvals.vprint('WARNING: Display failed to change to %s' % cmd)
|
|
||||||
if ret:
|
|
||||||
sysvals.vprint('WARNING: Display failed to change to %s with xset' % cmd)
|
|
||||||
return ret
|
|
||||||
elif cmd == 'stat':
|
|
||||||
fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout
|
|
||||||
ret = 'unknown'
|
|
||||||
for line in fp:
|
|
||||||
m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line))
|
|
||||||
if(m and len(m.group('m')) >= 2):
|
|
||||||
out = m.group('m').lower()
|
|
||||||
ret = out[3:] if out[0:2] == 'in' else out
|
|
||||||
break
|
|
||||||
fp.close()
|
|
||||||
return ret
|
|
||||||
|
|
||||||
# Function: getFPDT
|
# Function: getFPDT
|
||||||
# Description:
|
# Description:
|
||||||
# Read the acpi bios tables and pull out FPDT, the firmware data
|
# Read the acpi bios tables and pull out FPDT, the firmware data
|
||||||
@@ -6001,8 +6041,19 @@ def rerunTest(htmlfile=''):
|
|||||||
# execute a suspend/resume, gather the logs, and generate the output
|
# execute a suspend/resume, gather the logs, and generate the output
|
||||||
def runTest(n=0, quiet=False):
|
def runTest(n=0, quiet=False):
|
||||||
# prepare for the test
|
# prepare for the test
|
||||||
sysvals.initFtrace(quiet)
|
|
||||||
sysvals.initTestOutput('suspend')
|
sysvals.initTestOutput('suspend')
|
||||||
|
op = sysvals.writeDatafileHeader(sysvals.dmesgfile, [])
|
||||||
|
op.write('# EXECUTION TRACE START\n')
|
||||||
|
op.close()
|
||||||
|
if n <= 1:
|
||||||
|
if sysvals.rs != 0:
|
||||||
|
sysvals.dlog('%sabling runtime suspend' % ('en' if sysvals.rs > 0 else 'dis'))
|
||||||
|
sysvals.setRuntimeSuspend(True)
|
||||||
|
if sysvals.display:
|
||||||
|
ret = sysvals.displayControl('init')
|
||||||
|
sysvals.dlog('xset display init, ret = %d' % ret)
|
||||||
|
sysvals.dlog('initialize ftrace')
|
||||||
|
sysvals.initFtrace(quiet)
|
||||||
|
|
||||||
# execute the test
|
# execute the test
|
||||||
executeSuspend(quiet)
|
executeSuspend(quiet)
|
||||||
@@ -6098,8 +6149,16 @@ def data_from_html(file, outpath, issues, fulldetail=False):
|
|||||||
if wifi:
|
if wifi:
|
||||||
extra['wifi'] = wifi
|
extra['wifi'] = wifi
|
||||||
low = find_in_html(html, 'freeze time: <b>', ' ms</b>')
|
low = find_in_html(html, 'freeze time: <b>', ' ms</b>')
|
||||||
if low and 'waking' in low:
|
for lowstr in ['waking', '+']:
|
||||||
issue = 'FREEZEWAKE'
|
if not low:
|
||||||
|
break
|
||||||
|
if lowstr not in low:
|
||||||
|
continue
|
||||||
|
if lowstr == '+':
|
||||||
|
issue = 'S2LOOPx%d' % len(low.split('+'))
|
||||||
|
else:
|
||||||
|
m = re.match('.*waking *(?P<n>[0-9]*) *times.*', low)
|
||||||
|
issue = 'S2WAKEx%s' % m.group('n') if m else 'S2WAKExNaN'
|
||||||
match = [i for i in issues if i['match'] == issue]
|
match = [i for i in issues if i['match'] == issue]
|
||||||
if len(match) > 0:
|
if len(match) > 0:
|
||||||
match[0]['count'] += 1
|
match[0]['count'] += 1
|
||||||
@@ -6605,6 +6664,11 @@ if __name__ == '__main__':
|
|||||||
val = next(args)
|
val = next(args)
|
||||||
except:
|
except:
|
||||||
doError('-info requires one string argument', True)
|
doError('-info requires one string argument', True)
|
||||||
|
elif(arg == '-desc'):
|
||||||
|
try:
|
||||||
|
val = next(args)
|
||||||
|
except:
|
||||||
|
doError('-desc requires one string argument', True)
|
||||||
elif(arg == '-rs'):
|
elif(arg == '-rs'):
|
||||||
try:
|
try:
|
||||||
val = next(args)
|
val = next(args)
|
||||||
@@ -6814,9 +6878,9 @@ if __name__ == '__main__':
|
|||||||
runSummary(sysvals.outdir, True, genhtml)
|
runSummary(sysvals.outdir, True, genhtml)
|
||||||
elif(cmd in ['xon', 'xoff', 'xstandby', 'xsuspend', 'xinit', 'xreset']):
|
elif(cmd in ['xon', 'xoff', 'xstandby', 'xsuspend', 'xinit', 'xreset']):
|
||||||
sysvals.verbose = True
|
sysvals.verbose = True
|
||||||
ret = displayControl(cmd[1:])
|
ret = sysvals.displayControl(cmd[1:])
|
||||||
elif(cmd == 'xstat'):
|
elif(cmd == 'xstat'):
|
||||||
pprint('Display Status: %s' % displayControl('stat').upper())
|
pprint('Display Status: %s' % sysvals.displayControl('stat').upper())
|
||||||
elif(cmd == 'wificheck'):
|
elif(cmd == 'wificheck'):
|
||||||
dev = sysvals.checkWifi()
|
dev = sysvals.checkWifi()
|
||||||
if dev:
|
if dev:
|
||||||
@@ -6854,12 +6918,8 @@ if __name__ == '__main__':
|
|||||||
if mode.startswith('disk-'):
|
if mode.startswith('disk-'):
|
||||||
sysvals.diskmode = mode.split('-', 1)[-1]
|
sysvals.diskmode = mode.split('-', 1)[-1]
|
||||||
sysvals.suspendmode = 'disk'
|
sysvals.suspendmode = 'disk'
|
||||||
|
|
||||||
sysvals.systemInfo(dmidecode(sysvals.mempath))
|
sysvals.systemInfo(dmidecode(sysvals.mempath))
|
||||||
|
|
||||||
setRuntimeSuspend(True)
|
|
||||||
if sysvals.display:
|
|
||||||
displayControl('init')
|
|
||||||
failcnt, ret = 0, 0
|
failcnt, ret = 0, 0
|
||||||
if sysvals.multitest['run']:
|
if sysvals.multitest['run']:
|
||||||
# run multiple tests in a separate subdirectory
|
# run multiple tests in a separate subdirectory
|
||||||
@@ -6900,7 +6960,10 @@ if __name__ == '__main__':
|
|||||||
sysvals.testdir = sysvals.outdir
|
sysvals.testdir = sysvals.outdir
|
||||||
# run the test in the current directory
|
# run the test in the current directory
|
||||||
ret = runTest()
|
ret = runTest()
|
||||||
|
|
||||||
|
# reset to default values after testing
|
||||||
if sysvals.display:
|
if sysvals.display:
|
||||||
displayControl('reset')
|
sysvals.displayControl('reset')
|
||||||
setRuntimeSuspend(False)
|
if sysvals.rs != 0:
|
||||||
|
sysvals.setRuntimeSuspend(False)
|
||||||
sys.exit(ret)
|
sys.exit(ret)
|
||||||
|
Reference in New Issue
Block a user