Lines Matching refs:self
297 def __init__(self):
298 self.archargs = 'args_'+platform.machine()
299 self.hostname = platform.node()
300 if(self.hostname == ''):
301 self.hostname = 'localhost'
308 self.rtcpath = rtc
310 self.ansi = True
311 self.testdir = datetime.now().strftime('suspend-%y%m%d-%H%M%S')
314 self.sudouser = os.environ['SUDO_USER']
315 def resetlog(self):
316 self.logmsg = ''
317 self.platinfo = []
318 def vprint(self, msg):
319 self.logmsg += msg+'\n'
320 if self.verbose or msg.startswith('WARNING:'):
322 def signalHandler(self, signum, frame):
323 if not self.result:
325 signame = self.signames[signum] if signum in self.signames else 'UNKNOWN'
327 self.outputResult({'error':msg})
329 def signalHandlerInit(self):
332 self.signames = dict()
337 signal.signal(signum, self.signalHandler)
340 self.signames[signum] = s
341 def rootCheck(self, fatal=True):
342 if(os.access(self.powerfile, os.W_OK)):
347 self.outputResult({'error':msg})
350 def rootUser(self, fatal=False):
356 self.outputResult({'error':msg})
359 def usable(self, file):
361 def getExec(self, cmd):
376 def setPrecision(self, num):
379 self.timeformat = '%.{0}f'.format(num)
380 def setOutputFolder(self, value):
385 args['hostname'] = args['host'] = self.hostname
386 args['mode'] = self.suspendmode
388 def setOutputFile(self):
389 if self.dmesgfile != '':
390 m = re.match('(?P<name>.*)_dmesg\.txt.*', self.dmesgfile)
392 self.htmlfile = m.group('name')+'.html'
393 if self.ftracefile != '':
394 m = re.match('(?P<name>.*)_ftrace\.txt.*', self.ftracefile)
396 self.htmlfile = m.group('name')+'.html'
397 def systemInfo(self, info):
412 self.sysstamp = '# sysinfo | man:%s | plat:%s | cpu:%s | bios:%s | biosdate:%s | numcpu:%d | memsz:%d | memfr:%d' % \
413 (m, p, c, b, r, self.cpucount, self.memtotal, self.memfree)
414 def printSystemInfo(self, fatal=False):
415 self.rootCheck(True)
416 out = dmidecode(self.mempath, fatal)
422 print(fmt % ('cpucount', ('%d' % self.cpucount)))
423 print(fmt % ('memtotal', ('%d kB' % self.memtotal)))
424 print(fmt % ('memfree', ('%d kB' % self.memfree)))
425 def cpuInfo(self):
426 self.cpucount = 0
430 self.cpucount += 1
436 self.memtotal = int(m.group('sz'))
439 self.memfree = int(m.group('sz'))
441 def initTestOutput(self, name):
442 self.prefix = self.hostname
447 self.teststamp = \
448 '# '+testtime+' '+self.prefix+' '+self.suspendmode+' '+kver
450 if self.gzip:
452 self.dmesgfile = \
453 self.testdir+'/'+self.prefix+'_'+self.suspendmode+'_dmesg.txt'+ext
454 self.ftracefile = \
455 self.testdir+'/'+self.prefix+'_'+self.suspendmode+'_ftrace.txt'+ext
456 self.htmlfile = \
457 self.testdir+'/'+self.prefix+'_'+self.suspendmode+'.html'
458 if not os.path.isdir(self.testdir):
459 os.makedirs(self.testdir)
460 self.sudoUserchown(self.testdir)
461 def getValueList(self, value):
467 def setDeviceFilter(self, value):
468 self.devicefilter = self.getValueList(value)
469 def setCallgraphFilter(self, value):
470 self.cgfilter = self.getValueList(value)
471 def skipKprobes(self, value):
472 for k in self.getValueList(value):
473 if k in self.tracefuncs:
474 del self.tracefuncs[k]
475 if k in self.dev_tracefuncs:
476 del self.dev_tracefuncs[k]
477 def setCallgraphBlacklist(self, file):
478 self.cgblacklist = self.listFromFile(file)
479 def rtcWakeAlarmOn(self):
480 call('echo 0 > '+self.rtcpath+'/wakealarm', shell=True)
481 nowtime = open(self.rtcpath+'/since_epoch', 'r').read().strip()
487 alarm = nowtime + self.rtcwaketime
488 call('echo %d > %s/wakealarm' % (alarm, self.rtcpath), shell=True)
489 def rtcWakeAlarmOff(self):
490 call('echo 0 > %s/wakealarm' % self.rtcpath, shell=True)
491 def initdmesg(self):
504 self.dmesgstart = float(ktime)
505 def getdmesg(self, testdata):
506 op = self.writeDatafileHeader(self.dmesgfile, testdata)
518 if ktime > self.dmesgstart:
522 def listFromFile(self, file):
531 def addFtraceFilterFunctions(self, file):
532 for i in self.listFromFile(file):
535 self.tracefuncs[i] = dict()
536 def getFtraceFilterFunctions(self, current):
537 self.rootCheck(True)
539 call('cat '+self.tpath+'available_filter_functions', shell=True)
541 master = self.listFromFile(self.tpath+'available_filter_functions')
542 for i in sorted(self.tracefuncs):
543 if 'func' in self.tracefuncs[i]:
544 i = self.tracefuncs[i]['func']
548 print(self.colorText(i))
549 def setFtraceFilterFunctions(self, list):
550 master = self.listFromFile(self.tpath+'available_filter_functions')
559 fp = open(self.tpath+'set_graph_function', 'w')
562 def basicKprobe(self, name):
563 self.kprobes[name] = {'name': name,'func': name,'args': dict(),'format': name}
564 def defaultKprobe(self, name, kdata):
569 if self.archargs in k:
570 k['args'] = k[self.archargs]
574 self.kprobes[name] = k
575 def kprobeColor(self, name):
576 if name not in self.kprobes or 'color' not in self.kprobes[name]:
578 return self.kprobes[name]['color']
579 def kprobeDisplayName(self, name, dataraw):
580 if name not in self.kprobes:
581 self.basicKprobe(name)
592 fmt, args = self.kprobes[name]['format'], self.kprobes[name]['args']
607 def kprobeText(self, kname, kprobe):
616 if self.archargs in kprobe:
617 args = kprobe[self.archargs]
630 def addKprobes(self, output=False):
631 if len(self.kprobes) < 1:
639 linesout = len(self.kprobes)
640 for name in sorted(self.kprobes):
641 res = self.colorText('YES', 32)
642 if not self.testKprobe(name, self.kprobes[name]):
643 res = self.colorText('NO')
646 if name in self.tracefuncs:
648 elif name in self.dev_tracefuncs:
649 if 'ub' in self.dev_tracefuncs[name]:
660 self.kprobes.pop(name)
662 self.fsetVal('', 'kprobe_events')
665 kprobeevents += self.kprobeText(kp, self.kprobes[kp])
666 self.fsetVal(kprobeevents, 'kprobe_events')
668 check = self.fgetVal('kprobe_events')
671 self.fsetVal('1', 'events/kprobes/enable')
672 def testKprobe(self, kname, kprobe):
673 self.fsetVal('0', 'events/kprobes/enable')
674 kprobeevents = self.kprobeText(kname, kprobe)
678 self.fsetVal(kprobeevents, 'kprobe_events')
679 check = self.fgetVal('kprobe_events')
687 def setVal(self, val, file):
698 def fsetVal(self, val, path):
699 return self.setVal(val, self.tpath+path)
700 def getVal(self, file):
711 def fgetVal(self, path):
712 return self.getVal(self.tpath+path)
713 def cleanupFtrace(self):
714 if(self.usecallgraph or self.usetraceevents or self.usedevsrc):
715 self.fsetVal('0', 'events/kprobes/enable')
716 self.fsetVal('', 'kprobe_events')
717 self.fsetVal('1024', 'buffer_size_kb')
718 if self.pmdebug:
719 self.setVal(self.pmdebug, self.pmdpath)
720 def setupAllKprobes(self):
721 for name in self.tracefuncs:
722 self.defaultKprobe(name, self.tracefuncs[name])
723 for name in self.dev_tracefuncs:
724 self.defaultKprobe(name, self.dev_tracefuncs[name])
725 def isCallgraphFunc(self, name):
726 if len(self.tracefuncs) < 1 and self.suspendmode == 'command':
728 for i in self.tracefuncs:
729 if 'func' in self.tracefuncs[i]:
730 f = self.tracefuncs[i]['func']
736 def initFtrace(self, quiet=False):
741 self.fsetVal('0', 'tracing_on')
742 self.cleanupFtrace()
744 pv = self.getVal(self.pmdpath)
746 self.setVal('1', self.pmdpath)
747 self.pmdebug = pv
749 self.fsetVal('global', 'trace_clock')
750 self.fsetVal('nop', 'current_tracer')
752 cpus = max(1, self.cpucount)
753 if self.bufsize > 0:
754 tgtsize = self.bufsize
755 elif self.usecallgraph or self.usedevsrc:
756 bmax = (1*1024*1024) if self.suspendmode in ['disk', 'command'] \
758 tgtsize = min(self.memfree, bmax)
761 while not self.fsetVal('%d' % (tgtsize // cpus), 'buffer_size_kb'):
765 tgtsize = int(self.fgetVal('buffer_size_kb')) * cpus
767 self.vprint('Setting trace buffers to %d kB (%d kB per cpu)' % (tgtsize, tgtsize/cpus))
769 if(self.usecallgraph):
771 self.fsetVal('function_graph', 'current_tracer')
772 self.fsetVal('', 'set_ftrace_filter')
774 self.fsetVal('print-parent', 'trace_options')
775 self.fsetVal('funcgraph-abstime', 'trace_options')
776 self.fsetVal('funcgraph-cpu', 'trace_options')
777 self.fsetVal('funcgraph-duration', 'trace_options')
778 self.fsetVal('funcgraph-proc', 'trace_options')
779 self.fsetVal('funcgraph-tail', 'trace_options')
780 self.fsetVal('nofuncgraph-overhead', 'trace_options')
781 self.fsetVal('context-info', 'trace_options')
782 self.fsetVal('graph-time', 'trace_options')
783 self.fsetVal('%d' % self.max_graph_depth, 'max_graph_depth')
785 if(self.usetraceevents):
787 for fn in self.tracefuncs:
788 if 'func' in self.tracefuncs[fn]:
789 cf.append(self.tracefuncs[fn]['func'])
792 if self.ftop:
793 self.setFtraceFilterFunctions([self.ftopfunc])
795 self.setFtraceFilterFunctions(cf)
797 elif self.usekprobes:
798 for name in self.tracefuncs:
799 self.defaultKprobe(name, self.tracefuncs[name])
800 if self.usedevsrc:
801 for name in self.dev_tracefuncs:
802 self.defaultKprobe(name, self.dev_tracefuncs[name])
805 self.addKprobes(self.verbose)
806 if(self.usetraceevents):
808 events = iter(self.traceevents)
810 self.fsetVal('1', 'events/power/'+e+'/enable')
812 self.fsetVal('', 'trace')
813 def verifyFtrace(self):
818 tp = self.tpath
819 if(self.usecallgraph):
829 def verifyKprobes(self):
832 tp = self.tpath
837 def colorText(self, str, color=31):
838 if not self.ansi:
841 def writeDatafileHeader(self, filename, testdata):
842 fp = self.openlog(filename, 'w')
843 fp.write('%s\n%s\n# command | %s\n' % (self.teststamp, self.sysstamp, self.cmdline))
856 def sudoUserchown(self, dir):
857 if os.path.exists(dir) and self.sudouser:
859 call(cmd.format(self.sudouser, dir), shell=True)
860 def outputResult(self, testdata, num=0):
861 if not self.result:
866 fp = open(self.result, 'a')
881 self.sudoUserchown(self.result)
882 def configFile(self, file):
891 def openlog(self, filename, mode):
892 isgz = self.gzip
903 def b64unzip(self, data):
909 def b64zip(self, data):
912 def platforminfo(self, cmdafter):
914 if not os.path.exists(self.ftracefile):
919 if self.suspendmode == 'command' and self.testcommand:
920 footer += '# platform-testcmd: %s\n' % (self.testcommand)
925 tf = self.openlog(self.ftracefile, 'r')
927 if tp.stampInfo(line, self):
990 footer += '# platform-devinfo: %s\n' % self.b64zip(out)
994 footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
996 with self.openlog(self.ftracefile, 'a') as fp:
999 def commonPrefix(self, list):
1011 def dictify(self, text, format):
1028 def cmdinfo(self, begin, debug=False):
1031 self.cmd1 = dict()
1032 for cargs in self.infocmds:
1034 cmdline, cmdpath = ' '.join(cargs[2:]), self.getExec(cargs[2])
1044 self.cmd1[name] = self.dictify(info, delta)
1045 elif not debug and delta and name in self.cmd1:
1046 before, after = self.cmd1[name], self.dictify(info, delta)
1048 prefix = self.commonPrefix(list(before.keys()))
1063 def haveTurbostat(self):
1064 if not self.tstat:
1066 cmd = self.getExec('turbostat')
1073 self.vprint(out)
1076 def turbostat(self):
1077 cmd = self.getExec('turbostat')
1079 fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile)
1093 self.vprint(errmsg)
1094 if not self.verbose:
1097 if self.verbose:
1105 def wifiDetails(self, dev):
1115 def checkWifi(self, dev=''):
1126 def pollWifi(self, dev, timeout=60):
1129 w = self.checkWifi(dev)
1132 (self.wifiDetails(dev), max(0, time.time() - start))
1134 return '%s timeout %d' % (self.wifiDetails(dev), timeout)
1135 def errorSummary(self, errinfo, msg):
1140 if self.hostname not in entry['urls']:
1141 entry['urls'][self.hostname] = [self.htmlfile]
1142 elif self.htmlfile not in entry['urls'][self.hostname]:
1143 entry['urls'][self.hostname].append(self.htmlfile)
1163 'urls': {self.hostname: [self.htmlfile]}
1166 def multistat(self, start, idx, finish):
1167 if 'time' in self.multitest:
1168 id = '%d Duration=%dmin' % (idx+1, self.multitest['time'])
1170 id = '%d/%d' % (idx+1, self.multitest['count'])
1172 if 'start' not in self.multitest:
1173 self.multitest['start'] = self.multitest['last'] = t
1174 self.multitest['total'] = 0.0
1177 dt = t - self.multitest['last']
1179 if idx == 0 and self.multitest['delay'] > 0:
1180 self.multitest['total'] += self.multitest['delay']
1183 self.multitest['total'] += dt
1184 self.multitest['last'] = t
1185 avg = self.multitest['total'] / idx
1186 if 'time' in self.multitest:
1190 left = timedelta(seconds=((self.multitest['count'] - idx) * int(avg)))
1193 def multiinit(self, c, d):
1197 self.multitest['run'] = True
1198 self.multitest[sz] = getArgInt('multi: n d (exec count)', c, 1, 1000000, False)
1199 self.multitest['delay'] = getArgInt('multi: n d (delay between tests)', d, 0, 3600, False)
1201 self.multitest[sz] *= 1440
1203 self.multitest[sz] *= 60
1220 def __init__(self):
1221 self.syspath = ''
1222 self.altname = ''
1223 self.isasync = True
1224 self.xtraclass = ''
1225 self.xtrainfo = ''
1226 def out(self, dev):
1227 return '%s,%s,%d;' % (dev, self.altname, self.isasync)
1228 def debug(self, dev):
1229 pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.isasync))
1230 def altName(self, dev):
1231 if not self.altname or self.altname == dev:
1233 return '%s [%s]' % (self.altname, dev)
1234 def xtraClass(self):
1235 if self.xtraclass:
1236 return ' '+self.xtraclass
1237 if not self.isasync:
1240 def xtraInfo(self):
1241 if self.xtraclass:
1242 return ' '+self.xtraclass
1243 if self.isasync:
1252 def __init__(self, nodename, nodedepth):
1253 self.name = nodename
1254 self.children = []
1255 self.depth = nodedepth
1311 def __init__(self, num):
1313 self.start = 0.0 # test start
1314 self.end = 0.0 # test end
1315 self.hwstart = 0 # rtc test start
1316 self.hwend = 0 # rtc test end
1317 self.tSuspended = 0.0 # low-level suspend start
1318 self.tResumed = 0.0 # low-level resume start
1319 self.tKernSus = 0.0 # kernel level suspend start
1320 self.tKernRes = 0.0 # kernel level resume end
1321 self.fwValid = False # is firmware data available
1322 self.fwSuspend = 0 # time spent in firmware suspend
1323 self.fwResume = 0 # time spent in firmware resume
1324 self.html_device_id = 0
1325 self.stamp = 0
1326 self.outfile = ''
1327 self.kerror = False
1328 self.wifi = dict()
1329 self.turbostat = 0
1330 self.enterfail = ''
1331 self.currphase = ''
1332 self.pstl = dict() # process timeline
1333 self.testnumber = num
1334 self.idstr = idchar[num]
1335 self.dmesgtext = [] # dmesg text file in memory
1336 self.dmesg = dict() # root data structure
1337 self.errorinfo = {'suspend':[],'resume':[]}
1338 self.tLow = [] # time spent in low-level suspends (standby/freeze)
1339 self.devpids = []
1340 self.devicegroups = 0
1341 def sortedPhases(self):
1342 return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order'])
1343 def initDevicegroups(self):
1345 for phase in sorted(self.dmesg.keys()):
1349 self.dmesg[pnew] = self.dmesg.pop(phase)
1350 self.devicegroups = []
1351 for phase in self.sortedPhases():
1352 self.devicegroups.append([phase])
1353 def nextPhase(self, phase, offset):
1354 order = self.dmesg[phase]['order'] + offset
1355 for p in self.dmesg:
1356 if self.dmesg[p]['order'] == order:
1359 def lastPhase(self, depth=1):
1360 plist = self.sortedPhases()
1364 def turbostatInfo(self):
1367 for line in self.dmesgtext:
1378 def extractErrorInfo(self):
1379 lf = self.dmesgtext
1380 if len(self.dmesgtext) < 1 and sysvals.dmesgfile:
1393 if t < self.start or t > self.end:
1395 dir = 'suspend' if t < self.tSuspended else 'resume'
1399 for err in self.errlist:
1400 if re.match(self.errlist[err], msg):
1402 self.kerror = True
1407 self.errorinfo[dir].append((type, t, idx1, idx2))
1408 if self.kerror:
1410 if len(self.dmesgtext) < 1 and sysvals.dmesgfile:
1413 def setStart(self, time, msg=''):
1414 self.start = time
1417 self.hwstart = datetime.strptime(msg, sysvals.tmstart)
1419 self.hwstart = 0
1420 def setEnd(self, time, msg=''):
1421 self.end = time
1424 self.hwend = datetime.strptime(msg, sysvals.tmend)
1426 self.hwend = 0
1427 def isTraceEventOutsideDeviceCalls(self, pid, time):
1428 for phase in self.sortedPhases():
1429 list = self.dmesg[phase]['list']
1436 def sourcePhase(self, start):
1437 for phase in self.sortedPhases():
1440 pend = self.dmesg[phase]['end']
1444 def sourceDevice(self, phaselist, start, end, pid, type):
1447 list = self.dmesg[phase]['list']
1468 def addDeviceFunctionCall(self, displayname, kprobename, proc, pid, start, end, cdata, rdata):
1470 phases = self.sortedPhases()
1471 tgtdev = self.sourceDevice(phases, start, end, pid, 'device')
1474 if not tgtdev and pid in self.devpids:
1478 tgtdev = self.sourceDevice(phases, start, end, pid, 'thread')
1485 tgtphase = self.sourcePhase(start)
1486 self.newAction(tgtphase, threadname, pid, '', start, end, '', ' kth', '')
1487 return self.addDeviceFunctionCall(displayname, kprobename, proc, pid, start, end, cdata, rdata)
1517 def overflowDevices(self):
1520 for phase in self.sortedPhases():
1521 list = self.dmesg[phase]['list']
1524 if dev['end'] > self.end:
1527 def mergeOverlapDevices(self, devlist):
1531 for phase in self.sortedPhases():
1532 list = self.dmesg[phase]['list']
1544 def usurpTouchingThread(self, name, dev):
1546 for phase in self.sortedPhases():
1547 list = self.dmesg[phase]['list']
1558 def stitchTouchingThreads(self, testlist):
1560 for phase in self.sortedPhases():
1561 list = self.dmesg[phase]['list']
1568 def optimizeDevSrc(self):
1570 for phase in self.sortedPhases():
1571 list = self.dmesg[phase]['list']
1586 def trimTimeVal(self, t, t0, dT, left):
1601 def trimTime(self, t0, dT, left):
1602 self.tSuspended = self.trimTimeVal(self.tSuspended, t0, dT, left)
1603 self.tResumed = self.trimTimeVal(self.tResumed, t0, dT, left)
1604 self.start = self.trimTimeVal(self.start, t0, dT, left)
1605 self.tKernSus = self.trimTimeVal(self.tKernSus, t0, dT, left)
1606 self.tKernRes = self.trimTimeVal(self.tKernRes, t0, dT, left)
1607 self.end = self.trimTimeVal(self.end, t0, dT, left)
1608 for phase in self.sortedPhases():
1609 p = self.dmesg[phase]
1610 p['start'] = self.trimTimeVal(p['start'], t0, dT, left)
1611 p['end'] = self.trimTimeVal(p['end'], t0, dT, left)
1615 d['start'] = self.trimTimeVal(d['start'], t0, dT, left)
1616 d['end'] = self.trimTimeVal(d['end'], t0, dT, left)
1620 cg.start = self.trimTimeVal(cg.start, t0, dT, left)
1621 cg.end = self.trimTimeVal(cg.end, t0, dT, left)
1623 line.time = self.trimTimeVal(line.time, t0, dT, left)
1626 e.time = self.trimTimeVal(e.time, t0, dT, left)
1627 e.end = self.trimTimeVal(e.end, t0, dT, left)
1631 for e in self.errorinfo[dir]:
1633 tm = self.trimTimeVal(tm, t0, dT, left)
1635 self.errorinfo[dir] = list
1636 def trimFreezeTime(self, tZero):
1639 for phase in self.sortedPhases():
1641 tS, tR = self.dmesg[lp]['end'], self.dmesg[phase]['start']
1645 self.trimTime(tS, tL, left)
1646 if 'trying' in self.dmesg[lp] and self.dmesg[lp]['trying'] >= 0.001:
1647 tTry = round(self.dmesg[lp]['trying'] * 1000)
1651 self.tLow.append(text)
1653 def getMemTime(self):
1654 if not self.hwstart or not self.hwend:
1656 stime = (self.tSuspended - self.start) * 1000000
1657 rtime = (self.end - self.tResumed) * 1000000
1658 hws = self.hwstart + timedelta(microseconds=stime)
1659 hwr = self.hwend - timedelta(microseconds=rtime)
1660 self.tLow.append('%.0f'%((hwr - hws).total_seconds() * 1000))
1661 def getTimeValues(self):
1662 sktime = (self.tSuspended - self.tKernSus) * 1000
1663 rktime = (self.tKernRes - self.tResumed) * 1000
1665 def setPhase(self, phase, ktime, isbegin, order=-1):
1668 if self.currphase:
1669 if 'resume_machine' not in self.currphase:
1670 sysvals.vprint('WARNING: phase %s failed to end' % self.currphase)
1671 self.dmesg[self.currphase]['end'] = ktime
1672 phases = self.dmesg.keys()
1673 color = self.phasedef[phase]['color']
1678 self.dmesg[phase] = {'list': dict(), 'start': -1.0, 'end': -1.0,
1680 self.dmesg[phase]['start'] = ktime
1681 self.currphase = phase
1684 if phase not in self.currphase:
1685 if self.currphase:
1686 sysvals.vprint('WARNING: %s ended instead of %s, ftrace corruption?' % (phase, self.currphase))
1690 phase = self.currphase
1691 self.dmesg[phase]['end'] = ktime
1692 self.currphase = ''
1694 def sortedDevices(self, phase):
1695 list = self.dmesg[phase]['list']
1697 def fixupInitcalls(self, phase):
1699 phaselist = self.dmesg[phase]['list']
1703 for p in self.sortedPhases():
1704 if self.dmesg[p]['end'] > dev['start']:
1705 dev['end'] = self.dmesg[p]['end']
1708 def deviceFilter(self, devicefilter):
1709 for phase in self.sortedPhases():
1710 list = self.dmesg[phase]['list']
1722 def fixupInitcallsThatDidntReturn(self):
1724 for phase in self.sortedPhases():
1725 self.fixupInitcalls(phase)
1726 def phaseOverlap(self, phases):
1729 for group in self.devicegroups:
1739 self.devicegroups.remove(group)
1740 self.devicegroups.append(newgroup)
1741 def newActionGlobal(self, name, start, end, pid=-1, color=''):
1743 phases = self.sortedPhases()
1749 pstart = self.dmesg[phase]['start']
1750 pend = self.dmesg[phase]['end']
1763 p0start = self.dmesg[phases[0]]['start']
1774 self.phaseOverlap(myphases)
1776 newname = self.newAction(targetphase, name, pid, '', start, end, '', htmlclass, color)
1779 def newAction(self, phase, name, pid, parent, start, end, drv, htmlclass='', color=''):
1781 self.html_device_id += 1
1782 devid = '%s%d' % (self.idstr, self.html_device_id)
1783 list = self.dmesg[phase]['list']
1800 def findDevice(self, phase, name):
1801 list = self.dmesg[phase]['list']
1809 def deviceChildren(self, devname, phase):
1811 list = self.dmesg[phase]['list']
1816 def maxDeviceNameSize(self, phase):
1818 for name in self.dmesg[phase]['list']:
1822 def printDetails(self):
1824 sysvals.vprint(' test start: %f' % self.start)
1825 sysvals.vprint('kernel suspend start: %f' % self.tKernSus)
1827 for phase in self.sortedPhases():
1828 devlist = self.dmesg[phase]['list']
1829 dc, ps, pe = len(devlist), self.dmesg[phase]['start'], self.dmesg[phase]['end']
1830 if not tS and ps >= self.tSuspended:
1831 sysvals.vprint(' machine suspended: %f' % self.tSuspended)
1833 if not tR and ps >= self.tResumed:
1834 sysvals.vprint(' machine resumed: %f' % self.tResumed)
1839 maxname = '%d' % self.maxDeviceNameSize(phase)
1848 sysvals.vprint(' kernel resume end: %f' % self.tKernRes)
1849 sysvals.vprint(' test end: %f' % self.end)
1850 def deviceChildrenAllPhases(self, devname):
1852 for phase in self.sortedPhases():
1853 list = self.deviceChildren(devname, phase)
1858 def masterTopology(self, name, list, depth):
1864 clist = self.deviceChildrenAllPhases(cname)
1865 cnode = self.masterTopology(cname, clist, depth+1)
1868 def printTopology(self, node):
1873 for phase in self.sortedPhases():
1874 list = self.dmesg[phase]['list']
1888 html += self.printTopology(cnode)
1891 def rootDeviceList(self):
1894 for phase in self.sortedPhases():
1895 list = self.dmesg[phase]['list']
1901 for phase in self.sortedPhases():
1902 list = self.dmesg[phase]['list']
1911 def deviceTopology(self):
1912 rootlist = self.rootDeviceList()
1913 master = self.masterTopology('', rootlist, 0)
1914 return self.printTopology(master)
1915 def selectTimelineDevices(self, widfmt, tTotal, mindevlen):
1917 self.tdevlist = dict()
1918 for phase in self.dmesg:
1920 list = self.dmesg[phase]['list']
1926 self.tdevlist[phase] = devlist
1927 def addHorizontalDivider(self, devname, devend):
1929 self.newAction(phase, devname, -2, '', \
1930 self.start, devend, '', ' sec', '')
1931 if phase not in self.tdevlist:
1932 self.tdevlist[phase] = []
1933 self.tdevlist[phase].append(devname)
1934 d = DevItem(0, phase, self.dmesg[phase]['list'][devname])
1936 def addProcessUsageEvent(self, name, times):
1946 if name in self.pstl[t]:
1955 out = self.newActionGlobal(name, start, end, -3)
1959 dev = self.dmesg[phase]['list'][devname]
1968 list = self.pstl[t]
1981 def createProcessUsageEvents(self):
1984 for t in sorted(self.pstl):
1985 pslist = self.pstl[t]
1992 for t in sorted(self.pstl):
1993 if t < self.tSuspended:
2001 c = self.addProcessUsageEvent(ps, tsus)
2004 c = self.addProcessUsageEvent(ps, tres)
2007 def handleEndMarker(self, time, msg=''):
2008 dm = self.dmesg
2009 self.setEnd(time, msg)
2010 self.initDevicegroups()
2016 np = self.nextPhase('resume_machine', 1)
2020 if self.tKernRes == 0.0:
2021 self.tKernRes = time
2023 if self.tKernSus == 0.0:
2024 self.tKernSus = time
2028 def debugPrint(self):
2029 for p in self.sortedPhases():
2030 list = self.dmesg[p]['list']
2040 def __init__(self, name, args, caller, ret, start, end, u, proc, pid, color):
2041 self.row = 0
2042 self.count = 1
2043 self.name = name
2044 self.args = args
2045 self.caller = caller
2046 self.ret = ret
2047 self.time = start
2048 self.length = end - start
2049 self.end = end
2050 self.ubiquitous = u
2051 self.proc = proc
2052 self.pid = pid
2053 self.color = color
2054 def title(self):
2056 if self.count > 1:
2057 cnt = '(x%d)' % self.count
2058 l = '%0.3fms' % (self.length * 1000)
2059 if self.ubiquitous:
2061 (self.name, self.args, cnt, self.caller, self.ret, l)
2063 title = '%s(%s) %s%s(%s)' % (self.name, self.args, self.ret, cnt, l)
2065 def text(self):
2066 if self.count > 1:
2067 text = '%s(x%d)' % (self.name, self.count)
2069 text = self.name
2071 def repeat(self, tgt):
2073 dt = self.time - tgt.end
2075 if tgt.caller == self.caller and \
2076 tgt.name == self.name and tgt.args == self.args and \
2077 tgt.proc == self.proc and tgt.pid == self.pid and \
2078 tgt.ret == self.ret and dt >= 0 and \
2080 self.length < sysvals.callloopmaxlen:
2096 def __init__(self, t, m='', d=''):
2097 self.length = 0.0
2098 self.fcall = False
2099 self.freturn = False
2100 self.fevent = False
2101 self.fkprobe = False
2102 self.depth = 0
2103 self.name = ''
2104 self.type = ''
2105 self.time = float(t)
2120 self.name = emm.group('msg')
2121 self.type = emm.group('call')
2123 self.name = msg
2124 km = re.match('^(?P<n>.*)_cal$', self.type)
2126 self.fcall = True
2127 self.fkprobe = True
2128 self.type = km.group('n')
2130 km = re.match('^(?P<n>.*)_ret$', self.type)
2132 self.freturn = True
2133 self.fkprobe = True
2134 self.type = km.group('n')
2136 self.fevent = True
2140 self.length = float(d)/1000000
2145 self.depth = self.getDepth(match.group('d'))
2149 self.freturn = True
2154 self.name = match.group('n').strip()
2157 self.fcall = True
2162 self.name = match.group('n').strip()
2165 self.freturn = True
2168 self.name = match.group('n').strip()
2171 self.name = m
2172 def isCall(self):
2173 return self.fcall and not self.freturn
2174 def isReturn(self):
2175 return self.freturn and not self.fcall
2176 def isLeaf(self):
2177 return self.fcall and self.freturn
2178 def getDepth(self, str):
2180 def debugPrint(self, info=''):
2181 if self.isLeaf():
2182 pprint(' -- %12.6f (depth=%02d): %s(); (%.3f us) %s' % (self.time, \
2183 self.depth, self.name, self.length*1000000, info))
2184 elif self.freturn:
2185 pprint(' -- %12.6f (depth=%02d): %s} (%.3f us) %s' % (self.time, \
2186 self.depth, self.name, self.length*1000000, info))
2188 pprint(' -- %12.6f (depth=%02d): %s() { (%.3f us) %s' % (self.time, \
2189 self.depth, self.name, self.length*1000000, info))
2190 def startMarker(self):
2192 if not self.fevent:
2195 if(self.name.startswith('SUSPEND START')):
2199 if(self.type == 'suspend_resume' and
2200 re.match('suspend_enter\[.*\] begin', self.name)):
2203 def endMarker(self):
2205 if not self.fevent:
2208 if(self.name.startswith('RESUME COMPLETE')):
2212 if(self.type == 'suspend_resume' and
2213 re.match('thaw_processes\[.*\] end', self.name)):
2225 def __init__(self, pid, sv):
2226 self.id = ''
2227 self.invalid = False
2228 self.name = ''
2229 self.partial = False
2230 self.ignore = False
2231 self.start = -1.0
2232 self.end = -1.0
2233 self.list = []
2234 self.depth = 0
2235 self.pid = pid
2236 self.sv = sv
2237 def addLine(self, line):
2239 if(self.invalid):
2244 if(self.depth < 0):
2245 self.invalidate(line)
2248 if self.ignore:
2249 if line.depth > self.depth:
2252 self.list[-1].freturn = True
2253 self.list[-1].length = line.time - self.list[-1].time
2254 self.ignore = False
2255 # if this is a return at self.depth, no more work is needed
2256 if line.depth == self.depth and line.isReturn():
2258 self.end = line.time
2267 if len(self.list) > 0:
2268 last = self.list[-1]
2273 mismatch = prelinedep - self.depth
2274 warning = self.sv.verbose and abs(mismatch) > 1
2279 while prelinedep < self.depth:
2280 self.depth -= 1
2283 last.depth = self.depth
2290 vline.depth = self.depth
2291 vline.name = self.vfname
2293 self.list.append(vline)
2307 while prelinedep > self.depth:
2316 vline.depth = self.depth
2317 vline.name = self.vfname
2319 self.list.append(vline)
2320 self.depth += 1
2322 self.start = vline.time
2336 md = self.sv.max_graph_depth
2339 if (md and self.depth >= md - 1) or (line.name in self.sv.cgblacklist):
2340 self.ignore = True
2342 self.depth += 1
2344 self.depth -= 1
2348 (line.name in self.sv.cgblacklist):
2349 while len(self.list) > 0 and self.list[-1].depth > line.depth:
2350 self.list.pop(-1)
2351 if len(self.list) == 0:
2352 self.invalid = True
2354 self.list[-1].freturn = True
2355 self.list[-1].length = line.time - self.list[-1].time
2356 self.list[-1].name = line.name
2358 if len(self.list) < 1:
2359 self.start = line.time
2362 if mismatch < 0 and self.list[-1].depth == 0 and self.list[-1].freturn:
2363 line = self.list[-1]
2367 self.list.append(line)
2369 if(self.start < 0):
2370 self.start = line.time
2371 self.end = line.time
2373 self.end += line.length
2374 if self.list[0].name == self.vfname:
2375 self.invalid = True
2377 self.partial = True
2380 def invalidate(self, line):
2381 if(len(self.list) > 0):
2382 first = self.list[0]
2383 self.list = []
2384 self.list.append(first)
2385 self.invalid = True
2386 id = 'task %s' % (self.pid)
2387 window = '(%f - %f)' % (self.start, line.time)
2388 if(self.depth < 0):
2394 def slice(self, dev):
2395 minicg = FTraceCallGraph(dev['pid'], self.sv)
2396 minicg.name = self.name
2399 for l in self.list:
2414 def repair(self, enddepth):
2417 last = self.list[-1]
2422 fixed = self.addLine(t)
2424 self.end = last.time
2427 def postProcess(self):
2428 if len(self.list) > 0:
2429 self.name = self.list[0].name
2433 for l in self.list:
2444 if self.sv.verbose:
2451 if cl.name == self.vfname:
2461 if self.sv.verbose:
2465 return self.repair(cnt)
2466 def deviceMatch(self, pid, data):
2473 if(self.name in borderphase):
2474 p = borderphase[self.name]
2479 self.start <= dev['start'] and
2480 self.end >= dev['end']):
2481 cg = self.slice(dev)
2487 if(data.dmesg[p]['start'] <= self.start and
2488 self.start <= data.dmesg[p]['end']):
2493 self.start <= dev['start'] and
2494 self.end >= dev['end']):
2495 dev['ftrace'] = self
2500 def newActionFromFunction(self, data):
2501 name = self.name
2504 fs = self.start
2505 fe = self.end
2510 if(data.dmesg[p]['start'] <= self.start and
2511 self.start < data.dmesg[p]['end']):
2519 data.dmesg[phase]['list'][myname]['ftrace'] = self
2520 def debugPrint(self, info=''):
2522 (self.name, self.pid, self.start, self.end,
2523 (self.end - self.start)*1000000))
2524 for l in self.list:
2537 def __init__(self, test, phase, dev):
2538 self.test = test
2539 self.phase = phase
2540 self.dev = dev
2541 def isa(self, cls):
2542 if 'htmlclass' in self.dev and cls in self.dev['htmlclass']:
2556 def __init__(self, rowheight, scaleheight):
2557 self.html = ''
2558 self.height = 0 # total timeline height
2559 self.scaleH = scaleheight # timescale (top) row height
2560 self.rowH = rowheight # device row height
2561 self.bodyH = 0 # body height
2562 self.rows = 0 # total timeline rows
2563 self.rowlines = dict()
2564 self.rowheight = dict()
2565 def createHeader(self, sv, stamp):
2568 self.html += '<div class="version"><a href="https://01.org/pm-graph">%s v%s</a></div>' \
2571 self.html += '<button id="showtest" class="logbtn btnfmt">log</button>'
2573 self.html += '<button id="showdmesg" class="logbtn btnfmt">dmesg</button>'
2575 self.html += '<button id="showftrace" class="logbtn btnfmt">ftrace</button>'
2577 self.html += headline_stamp.format(stamp['host'], stamp['kernel'],
2582 self.html += headline_sysinfo.format(stamp['man'], stamp['plat'], stamp['cpu'])
2591 def getDeviceRows(self, rawlist):
2632 def getPhaseRows(self, devlist, row=0, sortby='length'):
2652 dev['devrows'] = self.getDeviceRows(dev['src'])
2687 if t not in self.rowlines or t not in self.rowheight:
2688 self.rowlines[t] = dict()
2689 self.rowheight[t] = dict()
2690 if p not in self.rowlines[t] or p not in self.rowheight[t]:
2691 self.rowlines[t][p] = dict()
2692 self.rowheight[t][p] = dict()
2693 rh = self.rowH
2699 self.rowlines[t][p][row] = rowheight
2700 self.rowheight[t][p][row] = rowheight * rh
2702 if(row > self.rows):
2703 self.rows = int(row)
2705 def phaseRowHeight(self, test, phase, row):
2706 return self.rowheight[test][phase][row]
2707 def phaseRowTop(self, test, phase, row):
2709 for i in sorted(self.rowheight[test][phase]):
2712 top += self.rowheight[test][phase][i]
2714 def calcTotalRows(self):
2718 for t in self.rowlines:
2719 for p in self.rowlines[t]:
2721 for i in sorted(self.rowlines[t][p]):
2722 total += self.rowlines[t][p][i]
2725 if total == len(self.rowlines[t][p]):
2727 self.height = self.scaleH + (maxrows*self.rowH)
2728 self.bodyH = self.height - self.scaleH
2731 for i in sorted(self.rowheight[t][p]):
2732 self.rowheight[t][p][i] = float(self.bodyH)/len(self.rowlines[t][p])
2733 def createZoomBox(self, mode='command', testcount=1):
2741 self.html += html_devlist2
2742 self.html += html_devlist1.format('1')
2744 self.html += html_devlist1.format('')
2745 self.html += html_zoombox
2746 self.html += html_timeline.format('dmesg', self.height)
2757 def createTimeScale(self, m0, mMax, tTotal, mode):
2785 self.html += output+'</div>\n'
2814 def __init__(self):
2815 self.stamp = ''
2816 self.sysinfo = ''
2817 self.cmdline = ''
2818 self.testerror = []
2819 self.turbostat = []
2820 self.wifi = []
2821 self.fwdata = []
2822 self.ftrace_line_fmt = self.ftrace_line_fmt_nop
2823 self.cgformat = False
2824 self.data = 0
2825 self.ktemp = dict()
2826 def setTracerType(self, tracer):
2828 self.cgformat = True
2829 self.ftrace_line_fmt = self.ftrace_line_fmt_fg
2831 self.ftrace_line_fmt = self.ftrace_line_fmt_nop
2834 def stampInfo(self, line, sv):
2835 if re.match(self.stampfmt, line):
2836 self.stamp = line
2838 elif re.match(self.sysinfofmt, line):
2839 self.sysinfo = line
2841 elif re.match(self.tstatfmt, line):
2842 self.turbostat.append(line)
2844 elif re.match(self.wififmt, line):
2845 self.wifi.append(line)
2847 elif re.match(self.testerrfmt, line):
2848 self.testerror.append(line)
2850 elif re.match(self.firmwarefmt, line):
2851 self.fwdata.append(line)
2853 elif(re.match(self.devpropfmt, line)):
2854 self.parseDevprops(line, sv)
2856 elif(re.match(self.pinfofmt, line)):
2857 self.parsePlatformInfo(line, sv)
2859 m = re.match(self.cmdlinefmt, line)
2861 self.cmdline = m.group('cmd')
2863 m = re.match(self.tracertypefmt, line)
2865 self.setTracerType(m.group('t'))
2868 def parseStamp(self, data, sv):
2870 m = re.match(self.stampfmt, self.stamp)
2871 if not self.stamp or not m:
2881 if re.match(self.sysinfofmt, self.sysinfo):
2882 for f in self.sysinfo.split('|'):
2892 self.machinesuspend = 'timekeeping_freeze\[.*'
2894 self.machinesuspend = 'machine_suspend\[.*'
2905 sv.cmdline = self.cmdline
2909 if sv.suspendmode == 'mem' and len(self.fwdata) > data.testnumber:
2910 m = re.match(self.firmwarefmt, self.fwdata[data.testnumber])
2916 if len(self.turbostat) > data.testnumber:
2917 m = re.match(self.tstatfmt, self.turbostat[data.testnumber])
2921 if len(self.wifi) > data.testnumber:
2922 m = re.match(self.wififmt, self.wifi[data.testnumber])
2928 if len(self.testerror) > data.testnumber:
2929 m = re.match(self.testerrfmt, self.testerror[data.testnumber])
2932 def devprops(self, data):
2947 def parseDevprops(self, line, sv):
2951 props = self.devprops(line[idx:])
2955 def parsePlatformInfo(self, line, sv):
2956 m = re.match(self.pinfofmt, line)
2961 sv.devprops = self.devprops(sv.b64unzip(info))
2978 def __init__(self, dataobj):
2979 self.data = dataobj
2980 self.ftemp = dict()
2981 self.ttemp = dict()
2984 def __init__(self):
2985 self.proclist = dict()
2986 self.running = False
2987 def procstat(self):
2998 if pid not in self.proclist:
2999 self.proclist[pid] = {'name' : name, 'user' : user, 'kern' : kern}
3001 val = self.proclist[pid]
3012 val = self.proclist[pid]
3017 def processMonitor(self, tid):
3018 while self.running:
3019 out = self.procstat()
3022 def start(self):
3023 self.thread = Thread(target=self.processMonitor, args=(0,))
3024 self.running = True
3025 self.thread.start()
3026 def stop(self):
3027 self.running = False