Skip to content

Commit 8c763ff

Browse files
tebrandtrafaeljw
authored andcommitted
pm-graph v5.13
- fix link to pm-graph homepage and in comments - add usleep_range() kprobe to -dev mode - add SIGUSR1 and SIGUSR2 to list of captured signals - kill -s USR1 causes sleepgraph to print out stack trace - kill -s USR2 prints stack trace and exits - stack trace is also printed to -result file - add legacy support for /sys/kernel/debug/tracing/ - allow multiple instances of trace funcs in the same phase - update javascript to draw device detail for multiple trace func instances - add -debugtiming option to print out timestamps on all outputs Signed-off-by: Todd Brandt <todd.e.brandt@intel.com> Link: https://patch.msgid.link/20240912055956.30108-1-todd.e.brandt@intel.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 8e929cb commit 8c763ff

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

tools/power/pm-graph/sleepgraph.8

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ as resume failures.
8181
.TP
8282
\fB-wifitrace\fR
8383
Trace through the wifi reconnect time and include it in the timeline.
84+
.TP
85+
\fB-debugtiming\fR
86+
Add timestamp to each printed output line, accurate to the millisecond.
8487

8588
.SS "advanced"
8689
.TP

tools/power/pm-graph/sleepgraph.py

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#
1919
# Links:
2020
# Home Page
21-
# https://01.org/pm-graph
21+
# https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/overview.html
2222
# Source repo
2323
# git@github.com:intel/pm-graph
2424
#
@@ -65,6 +65,7 @@
6565
from threading import Thread
6666
from subprocess import call, Popen, PIPE
6767
import base64
68+
import traceback
6869

6970
debugtiming = False
7071
mystarttime = time.time()
@@ -86,7 +87,7 @@ def ascii(text):
8687
# store system values and test parameters
8788
class SystemValues:
8889
title = 'SleepGraph'
89-
version = '5.12'
90+
version = '5.13'
9091
ansi = False
9192
rs = 0
9293
display = ''
@@ -236,7 +237,11 @@ class SystemValues:
236237
'msleep': { 'args_x86_64': {'time':'%di:s32'}, 'ub': 1 },
237238
'schedule_timeout': { 'args_x86_64': {'timeout':'%di:s32'}, 'ub': 1 },
238239
'udelay': { 'func':'__const_udelay', 'args_x86_64': {'loops':'%di:s32'}, 'ub': 1 },
239-
'usleep_range': { 'args_x86_64': {'min':'%di:s32', 'max':'%si:s32'}, 'ub': 1 },
240+
'usleep_range': {
241+
'func':'usleep_range_state',
242+
'args_x86_64': {'min':'%di:s32', 'max':'%si:s32'},
243+
'ub': 1
244+
},
240245
'mutex_lock_slowpath': { 'func':'__mutex_lock_slowpath', 'ub': 1 },
241246
'acpi_os_stall': {'ub': 1},
242247
'rt_mutex_slowlock': {'ub': 1},
@@ -342,15 +347,21 @@ def vprint(self, msg):
342347
if self.verbose or msg.startswith('WARNING:'):
343348
pprint(msg)
344349
def signalHandler(self, signum, frame):
345-
if not self.result:
346-
return
347350
signame = self.signames[signum] if signum in self.signames else 'UNKNOWN'
348-
msg = 'Signal %s caused a tool exit, line %d' % (signame, frame.f_lineno)
351+
if signame in ['SIGUSR1', 'SIGUSR2', 'SIGSEGV']:
352+
traceback.print_stack()
353+
stack = traceback.format_list(traceback.extract_stack())
354+
self.outputResult({'stack':stack})
355+
if signame == 'SIGUSR1':
356+
return
357+
msg = '%s caused a tool exit, line %d' % (signame, frame.f_lineno)
358+
pprint(msg)
349359
self.outputResult({'error':msg})
360+
os.kill(os.getpid(), signal.SIGKILL)
350361
sys.exit(3)
351362
def signalHandlerInit(self):
352363
capture = ['BUS', 'SYS', 'XCPU', 'XFSZ', 'PWR', 'HUP', 'INT', 'QUIT',
353-
'ILL', 'ABRT', 'FPE', 'SEGV', 'TERM']
364+
'ILL', 'ABRT', 'FPE', 'SEGV', 'TERM', 'USR1', 'USR2']
354365
self.signames = dict()
355366
for i in capture:
356367
s = 'SIG'+i
@@ -859,6 +870,11 @@ def verifyFtrace(self):
859870
# files needed for any trace data
860871
files = ['buffer_size_kb', 'current_tracer', 'trace', 'trace_clock',
861872
'trace_marker', 'trace_options', 'tracing_on']
873+
# legacy check for old systems
874+
if not os.path.exists(self.tpath+'trace'):
875+
self.tpath = '/sys/kernel/debug/tracing/'
876+
if not os.path.exists(self.epath):
877+
self.epath = '/sys/kernel/debug/tracing/events/power/'
862878
# files needed for callgraph trace data
863879
tp = self.tpath
864880
if(self.usecallgraph):
@@ -911,6 +927,13 @@ def outputResult(self, testdata, num=0):
911927
if num > 0:
912928
n = '%d' % num
913929
fp = open(self.result, 'a')
930+
if 'stack' in testdata:
931+
fp.write('Printing stack trace:\n')
932+
for line in testdata['stack']:
933+
fp.write(line)
934+
fp.close()
935+
self.sudoUserchown(self.result)
936+
return
914937
if 'error' in testdata:
915938
fp.write('result%s: fail\n' % n)
916939
fp.write('error%s: %s\n' % (n, testdata['error']))
@@ -1980,7 +2003,7 @@ def newAction(self, phase, name, pid, parent, start, end, drv, htmlclass='', col
19802003
length = -1.0
19812004
if(start >= 0 and end >= 0):
19822005
length = end - start
1983-
if pid == -2 or name not in sysvals.tracefuncs.keys():
2006+
if pid >= -2:
19842007
i = 2
19852008
origname = name
19862009
while(name in list):
@@ -2753,7 +2776,8 @@ def __init__(self, rowheight, scaleheight):
27532776
def createHeader(self, sv, stamp):
27542777
if(not stamp['time']):
27552778
return
2756-
self.html += '<div class="version"><a href="https://01.org/pm-graph">%s v%s</a></div>' \
2779+
self.html += '<div class="version"><a href="https://www.intel.com/content/www/'+\
2780+
'us/en/developer/topic-technology/open/pm-graph/overview.html">%s v%s</a></div>' \
27572781
% (sv.title, sv.version)
27582782
if sv.logmsg and sv.testlog:
27592783
self.html += '<button id="showtest" class="logbtn btnfmt">log</button>'
@@ -5238,12 +5262,16 @@ def addScriptCode(hf, testruns):
52385262
}
52395263
var info = dev[i].title.split(" ");
52405264
var pname = info[info.length-1];
5241-
pd[pname] = parseFloat(info[info.length-3].slice(1));
5242-
total[0] += pd[pname];
5265+
var length = parseFloat(info[info.length-3].slice(1));
5266+
if (pname in pd)
5267+
pd[pname] += length;
5268+
else
5269+
pd[pname] = length;
5270+
total[0] += length;
52435271
if(pname.indexOf("suspend") >= 0)
5244-
total[tidx] += pd[pname];
5272+
total[tidx] += length;
52455273
else
5246-
total[tidx+1] += pd[pname];
5274+
total[tidx+1] += length;
52475275
}
52485276
}
52495277
var devname = deviceTitle(this.title, total, cpu);
@@ -5262,7 +5290,7 @@ def addScriptCode(hf, testruns):
52625290
phases[i].style.left = left+"%";
52635291
phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms";
52645292
left += w;
5265-
var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id]+" ms<br></t4>";
5293+
var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id].toFixed(3)+" ms<br></t4>";
52665294
var pname = "<t3 style=\"font-size:"+fs2+"px\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>";
52675295
phases[i].innerHTML = time+pname;
52685296
} else {
@@ -6742,6 +6770,7 @@ def printHelp():
67426770
' -wifi If a wifi connection is available, check that it reconnects after resume.\n'\
67436771
' -wifitrace Trace kernel execution through wifi reconnect.\n'\
67446772
' -netfix Use netfix to reset the network in the event it fails to resume.\n'\
6773+
' -debugtiming Add timestamp to each printed line\n'\
67456774
' [testprep]\n'\
67466775
' -sync Sync the filesystems before starting the test\n'\
67476776
' -rs on/off Enable/disable runtime suspend for all devices, restore all after test\n'\
@@ -7047,7 +7076,6 @@ def printHelp():
70477076
except:
70487077
doError('No result file supplied', True)
70497078
sysvals.result = val
7050-
sysvals.signalHandlerInit()
70517079
else:
70527080
doError('Invalid argument: '+arg, True)
70537081

@@ -7057,6 +7085,7 @@ def printHelp():
70577085
if(sysvals.usecallgraph and sysvals.useprocmon):
70587086
doError('-proc is not compatible with -f')
70597087

7088+
sysvals.signalHandlerInit()
70607089
if sysvals.usecallgraph and sysvals.cgskip:
70617090
sysvals.vprint('Using cgskip file: %s' % sysvals.cgskip)
70627091
sysvals.setCallgraphBlacklist(sysvals.cgskip)

0 commit comments

Comments
 (0)