~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/power/pm-graph/sleepgraph.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/power/pm-graph/sleepgraph.py (Version linux-6.12-rc7) and /tools/power/pm-graph/sleepgraph.py (Version linux-2.6.32.71)


  1 #!/usr/bin/env python3                            
  2 # SPDX-License-Identifier: GPL-2.0-only           
  3 #                                                 
  4 # Tool for analyzing suspend/resume timing        
  5 # Copyright (c) 2013, Intel Corporation.          
  6 #                                                 
  7 # This program is free software; you can redis    
  8 # under the terms and conditions of the GNU Ge    
  9 # version 2, as published by the Free Software    
 10 #                                                 
 11 # This program is distributed in the hope it w    
 12 # ANY WARRANTY; without even the implied warra    
 13 # FITNESS FOR A PARTICULAR PURPOSE.  See the G    
 14 # more details.                                   
 15 #                                                 
 16 # Authors:                                        
 17 #        Todd Brandt <todd.e.brandt@linux.intel    
 18 #                                                 
 19 # Links:                                          
 20 #        Home Page                                
 21 #          https://01.org/pm-graph                
 22 #        Source repo                              
 23 #          git@github.com:intel/pm-graph          
 24 #                                                 
 25 # Description:                                    
 26 #        This tool is designed to assist kerne    
 27 #        their linux stack's suspend/resume ti    
 28 #        with a few extra options enabled, the    
 29 #        will capture dmesg and ftrace data un    
 30 #        is transformed into a device timeline    
 31 #        and detailed view of which devices an    
 32 #        time in suspend/resume. The output is    
 33 #        viewed in firefox or chrome.             
 34 #                                                 
 35 #        The following kernel build options ar    
 36 #                CONFIG_DEVMEM=y                  
 37 #                CONFIG_PM_DEBUG=y                
 38 #                CONFIG_PM_SLEEP_DEBUG=y          
 39 #                CONFIG_FTRACE=y                  
 40 #                CONFIG_FUNCTION_TRACER=y         
 41 #                CONFIG_FUNCTION_GRAPH_TRACER=    
 42 #                CONFIG_KPROBES=y                 
 43 #                CONFIG_KPROBES_ON_FTRACE=y       
 44 #                                                 
 45 #        For kernel versions older than 3.15:     
 46 #        The following additional kernel param    
 47 #                (e.g. in file /etc/default/gr    
 48 #                GRUB_CMDLINE_LINUX_DEFAULT=".    
 49 #                                                 
 50                                                   
 51 # ----------------- LIBRARIES ----------------    
 52                                                   
 53 import sys                                        
 54 import time                                       
 55 import os                                         
 56 import string                                     
 57 import re                                         
 58 import platform                                   
 59 import signal                                     
 60 import codecs                                     
 61 from datetime import datetime, timedelta          
 62 import struct                                     
 63 import configparser                               
 64 import gzip                                       
 65 from threading import Thread                      
 66 from subprocess import call, Popen, PIPE          
 67 import base64                                     
 68                                                   
 69 debugtiming = False                               
 70 mystarttime = time.time()                         
 71 def pprint(msg):                                  
 72         if debugtiming:                           
 73                 print('[%09.3f] %s' % (time.ti    
 74         else:                                     
 75                 print(msg)                        
 76         sys.stdout.flush()                        
 77                                                   
 78 def ascii(text):                                  
 79         return text.decode('ascii', 'ignore')     
 80                                                   
 81 # ----------------- CLASSES ------------------    
 82                                                   
 83 # Class: SystemValues                             
 84 # Description:                                    
 85 #        A global, single-instance container u    
 86 #        store system values and test paramete    
 87 class SystemValues:                               
 88         title = 'SleepGraph'                      
 89         version = '5.12'                          
 90         ansi = False                              
 91         rs = 0                                    
 92         display = ''                              
 93         gzip = False                              
 94         sync = False                              
 95         wifi = False                              
 96         netfix = False                            
 97         verbose = False                           
 98         testlog = True                            
 99         dmesglog = True                           
100         ftracelog = False                         
101         acpidebug = True                          
102         tstat = True                              
103         wifitrace = False                         
104         mindevlen = 0.0001                        
105         mincglen = 0.0                            
106         cgphase = ''                              
107         cgtest = -1                               
108         cgskip = ''                               
109         maxfail = 0                               
110         multitest = {'run': False, 'count': 10    
111         max_graph_depth = 0                       
112         callloopmaxgap = 0.0001                   
113         callloopmaxlen = 0.005                    
114         bufsize = 0                               
115         cpucount = 0                              
116         memtotal = 204800                         
117         memfree = 204800                          
118         osversion = ''                            
119         srgap = 0                                 
120         cgexp = False                             
121         testdir = ''                              
122         outdir = ''                               
123         tpath = '/sys/kernel/tracing/'            
124         fpdtpath = '/sys/firmware/acpi/tables/    
125         epath = '/sys/kernel/tracing/events/po    
126         pmdpath = '/sys/power/pm_debug_message    
127         s0ixpath = '/sys/module/intel_pmc_core    
128         s0ixres = '/sys/devices/system/cpu/cpu    
129         acpipath='/sys/module/acpi/parameters/    
130         traceevents = [                           
131                 'suspend_resume',                 
132                 'wakeup_source_activate',         
133                 'wakeup_source_deactivate',       
134                 'device_pm_callback_end',         
135                 'device_pm_callback_start'        
136         ]                                         
137         logmsg = ''                               
138         testcommand = ''                          
139         mempath = '/dev/mem'                      
140         powerfile = '/sys/power/state'            
141         mempowerfile = '/sys/power/mem_sleep'     
142         diskpowerfile = '/sys/power/disk'         
143         suspendmode = 'mem'                       
144         memmode = ''                              
145         diskmode = ''                             
146         hostname = 'localhost'                    
147         prefix = 'test'                           
148         teststamp = ''                            
149         sysstamp = ''                             
150         dmesgstart = 0.0                          
151         dmesgfile = ''                            
152         ftracefile = ''                           
153         htmlfile = 'output.html'                  
154         result = ''                               
155         rtcwake = True                            
156         rtcwaketime = 15                          
157         rtcpath = ''                              
158         devicefilter = []                         
159         cgfilter = []                             
160         stamp = 0                                 
161         execcount = 1                             
162         x2delay = 0                               
163         skiphtml = False                          
164         usecallgraph = False                      
165         ftopfunc = 'pm_suspend'                   
166         ftop = False                              
167         usetraceevents = False                    
168         usetracemarkers = True                    
169         useftrace = True                          
170         usekprobes = True                         
171         usedevsrc = False                         
172         useprocmon = False                        
173         notestrun = False                         
174         cgdump = False                            
175         devdump = False                           
176         mixedphaseheight = True                   
177         devprops = dict()                         
178         cfgdef = dict()                           
179         platinfo = []                             
180         predelay = 0                              
181         postdelay = 0                             
182         tmstart = 'SUSPEND START %Y%m%d-%H:%M:    
183         tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:    
184         tracefuncs = {                            
185                 'async_synchronize_full': {},     
186                 'sys_sync': {},                   
187                 'ksys_sync': {},                  
188                 '__pm_notifier_call_chain': {}    
189                 'pm_prepare_console': {},         
190                 'pm_notifier_call_chain': {},     
191                 'freeze_processes': {},           
192                 'freeze_kernel_threads': {},      
193                 'pm_restrict_gfp_mask': {},       
194                 'acpi_suspend_begin': {},         
195                 'acpi_hibernation_begin': {},     
196                 'acpi_hibernation_enter': {},     
197                 'acpi_hibernation_leave': {},     
198                 'acpi_pm_freeze': {},             
199                 'acpi_pm_thaw': {},               
200                 'acpi_s2idle_end': {},            
201                 'acpi_s2idle_sync': {},           
202                 'acpi_s2idle_begin': {},          
203                 'acpi_s2idle_prepare': {},        
204                 'acpi_s2idle_prepare_late': {}    
205                 'acpi_s2idle_wake': {},           
206                 'acpi_s2idle_wakeup': {},         
207                 'acpi_s2idle_restore': {},        
208                 'acpi_s2idle_restore_early': {    
209                 'hibernate_preallocate_memory'    
210                 'create_basic_memory_bitmaps':    
211                 'swsusp_write': {},               
212                 'suspend_console': {},            
213                 'acpi_pm_prepare': {},            
214                 'syscore_suspend': {},            
215                 'arch_enable_nonboot_cpus_end'    
216                 'syscore_resume': {},             
217                 'acpi_pm_finish': {},             
218                 'resume_console': {},             
219                 'acpi_pm_end': {},                
220                 'pm_restore_gfp_mask': {},        
221                 'thaw_processes': {},             
222                 'pm_restore_console': {},         
223                 'CPU_OFF': {                      
224                         'func':'_cpu_down',       
225                         'args_x86_64': {'cpu':    
226                         'format': 'CPU_OFF[{cp    
227                 },                                
228                 'CPU_ON': {                       
229                         'func':'_cpu_up',         
230                         'args_x86_64': {'cpu':    
231                         'format': 'CPU_ON[{cpu    
232                 },                                
233         }                                         
234         dev_tracefuncs = {                        
235                 # general wait/delay/sleep        
236                 'msleep': { 'args_x86_64': {'t    
237                 'schedule_timeout': { 'args_x8    
238                 'udelay': { 'func':'__const_ud    
239                 'usleep_range': { 'args_x86_64    
240                 'mutex_lock_slowpath': { 'func    
241                 'acpi_os_stall': {'ub': 1},       
242                 'rt_mutex_slowlock': {'ub': 1}    
243                 # ACPI                            
244                 'acpi_resume_power_resources':    
245                 'acpi_ps_execute_method': { 'a    
246                         'fullpath':'+0(+40(%di    
247                 }},                               
248                 # mei_me                          
249                 'mei_reset': {},                  
250                 # filesystem                      
251                 'ext4_sync_fs': {},               
252                 # 80211                           
253                 'ath10k_bmi_read_memory': { 'a    
254                 'ath10k_bmi_write_memory': { '    
255                 'ath10k_bmi_fast_download': {     
256                 'iwlagn_mac_start': {},           
257                 'iwlagn_alloc_bcast_station':     
258                 'iwl_trans_pcie_start_hw': {},    
259                 'iwl_trans_pcie_start_fw': {},    
260                 'iwl_run_init_ucode': {},         
261                 'iwl_load_ucode_wait_alive': {    
262                 'iwl_alive_start': {},            
263                 'iwlagn_mac_stop': {},            
264                 'iwlagn_mac_suspend': {},         
265                 'iwlagn_mac_resume': {},          
266                 'iwlagn_mac_add_interface': {}    
267                 'iwlagn_mac_remove_interface':    
268                 'iwlagn_mac_change_interface':    
269                 'iwlagn_mac_config': {},          
270                 'iwlagn_configure_filter': {},    
271                 'iwlagn_mac_hw_scan': {},         
272                 'iwlagn_bss_info_changed': {},    
273                 'iwlagn_mac_channel_switch': {    
274                 'iwlagn_mac_flush': {},           
275                 # ATA                             
276                 'ata_eh_recover': { 'args_x86_    
277                 # i915                            
278                 'i915_gem_resume': {},            
279                 'i915_restore_state': {},         
280                 'intel_opregion_setup': {},       
281                 'g4x_pre_enable_dp': {},          
282                 'vlv_pre_enable_dp': {},          
283                 'chv_pre_enable_dp': {},          
284                 'g4x_enable_dp': {},              
285                 'vlv_enable_dp': {},              
286                 'intel_hpd_init': {},             
287                 'intel_opregion_register': {},    
288                 'intel_dp_detect': {},            
289                 'intel_hdmi_detect': {},          
290                 'intel_opregion_init': {},        
291                 'intel_fbdev_set_suspend': {},    
292         }                                         
293         infocmds = [                              
294                 [0, 'sysinfo', 'uname', '-a'],    
295                 [0, 'cpuinfo', 'head', '-7', '    
296                 [0, 'kparams', 'cat', '/proc/c    
297                 [0, 'mcelog', 'mcelog'],          
298                 [0, 'pcidevices', 'lspci', '-t    
299                 [0, 'usbdevices', 'lsusb', '-t    
300                 [0, 'acpidevices', 'sh', '-c',    
301                 [0, 's0ix_require', 'cat', '/s    
302                 [0, 's0ix_debug', 'cat', '/sys    
303                 [0, 'ethtool', 'ethtool', '{et    
304                 [1, 's0ix_residency', 'cat', '    
305                 [1, 'interrupts', 'cat', '/pro    
306                 [1, 'wakeups', 'cat', '/sys/ke    
307                 [2, 'gpecounts', 'sh', '-c', '    
308                 [2, 'suspendstats', 'sh', '-c'    
309                 [2, 'cpuidle', 'sh', '-c', 'gr    
310                 [2, 'battery', 'sh', '-c', 'gr    
311                 [2, 'thermal', 'sh', '-c', 'gr    
312         ]                                         
313         cgblacklist = []                          
314         kprobes = dict()                          
315         timeformat = '%.3f'                       
316         cmdline = '%s %s' % \                     
317                         (os.path.basename(sys.    
318         sudouser = ''                             
319         def __init__(self):                       
320                 self.archargs = 'args_'+platfo    
321                 self.hostname = platform.node(    
322                 if(self.hostname == ''):          
323                         self.hostname = 'local    
324                 rtc = "rtc0"                      
325                 if os.path.exists('/dev/rtc'):    
326                         rtc = os.readlink('/de    
327                 rtc = '/sys/class/rtc/'+rtc       
328                 if os.path.exists(rtc) and os.    
329                         os.path.exists(rtc+'/t    
330                         self.rtcpath = rtc        
331                 if (hasattr(sys.stdout, 'isatt    
332                         self.ansi = True          
333                 self.testdir = datetime.now().    
334                 if os.getuid() == 0 and 'SUDO_    
335                         os.environ['SUDO_USER'    
336                         self.sudouser = os.env    
337         def resetlog(self):                       
338                 self.logmsg = ''                  
339                 self.platinfo = []                
340         def vprint(self, msg):                    
341                 self.logmsg += msg+'\n'           
342                 if self.verbose or msg.startsw    
343                         pprint(msg)               
344         def signalHandler(self, signum, frame)    
345                 if not self.result:               
346                         return                    
347                 signame = self.signames[signum    
348                 msg = 'Signal %s caused a tool    
349                 self.outputResult({'error':msg    
350                 sys.exit(3)                       
351         def signalHandlerInit(self):              
352                 capture = ['BUS', 'SYS', 'XCPU    
353                         'ILL', 'ABRT', 'FPE',     
354                 self.signames = dict()            
355                 for i in capture:                 
356                         s = 'SIG'+i               
357                         try:                      
358                                 signum = getat    
359                                 signal.signal(    
360                         except:                   
361                                 continue          
362                         self.signames[signum]     
363         def rootCheck(self, fatal=True):          
364                 if(os.access(self.powerfile, o    
365                         return True               
366                 if fatal:                         
367                         msg = 'This command re    
368                         pprint('ERROR: %s\n' %    
369                         self.outputResult({'er    
370                         sys.exit(1)               
371                 return False                      
372         def rootUser(self, fatal=False):          
373                 if 'USER' in os.environ and os    
374                         return True               
375                 if fatal:                         
376                         msg = 'This command mu    
377                         pprint('ERROR: %s\n' %    
378                         self.outputResult({'er    
379                         sys.exit(1)               
380                 return False                      
381         def usable(self, file, ishtml=False):     
382                 if not os.path.exists(file) or    
383                         return False              
384                 if ishtml:                        
385                         try:                      
386                                 fp = open(file    
387                                 res = fp.read(    
388                                 fp.close()        
389                         except:                   
390                                 return False      
391                         if '<html>' not in res    
392                                 return False      
393                 return True                       
394         def getExec(self, cmd):                   
395                 try:                              
396                         fp = Popen(['which', c    
397                         out = ascii(fp.read())    
398                         fp.close()                
399                 except:                           
400                         out = ''                  
401                 if out:                           
402                         return out                
403                 for path in ['/sbin', '/bin',     
404                         '/usr/local/sbin', '/u    
405                         cmdfull = os.path.join    
406                         if os.path.exists(cmdf    
407                                 return cmdfull    
408                 return out                        
409         def setPrecision(self, num):              
410                 if num < 0 or num > 6:            
411                         return                    
412                 self.timeformat = '%.{0}f'.for    
413         def setOutputFolder(self, value):         
414                 args = dict()                     
415                 n = datetime.now()                
416                 args['date'] = n.strftime('%y%    
417                 args['time'] = n.strftime('%H%    
418                 args['hostname'] = args['host'    
419                 args['mode'] = self.suspendmod    
420                 return value.format(**args)       
421         def setOutputFile(self):                  
422                 if self.dmesgfile != '':          
423                         m = re.match(r'(?P<nam    
424                         if(m):                    
425                                 self.htmlfile     
426                 if self.ftracefile != '':         
427                         m = re.match(r'(?P<nam    
428                         if(m):                    
429                                 self.htmlfile     
430         def systemInfo(self, info):               
431                 p = m = ''                        
432                 if 'baseboard-manufacturer' in    
433                         m = info['baseboard-ma    
434                 elif 'system-manufacturer' in     
435                         m = info['system-manuf    
436                 if 'system-product-name' in in    
437                         p = info['system-produ    
438                 elif 'baseboard-product-name'     
439                         p = info['baseboard-pr    
440                 if m[:5].lower() == 'intel' an    
441                         p = info['baseboard-pr    
442                 c = info['processor-version']     
443                 b = info['bios-version'] if 'b    
444                 r = info['bios-release-date']     
445                 self.sysstamp = '# sysinfo | m    
446                         (m, p, c, b, r, self.c    
447                 if self.osversion:                
448                         self.sysstamp += ' | o    
449         def printSystemInfo(self, fatal=False)    
450                 self.rootCheck(True)              
451                 out = dmidecode(self.mempath,     
452                 if len(out) < 1:                  
453                         return                    
454                 fmt = '%-24s: %s'                 
455                 if self.osversion:                
456                         print(fmt % ('os-versi    
457                 for name in sorted(out):          
458                         print(fmt % (name, out    
459                 print(fmt % ('cpucount', ('%d'    
460                 print(fmt % ('memtotal', ('%d     
461                 print(fmt % ('memfree', ('%d k    
462         def cpuInfo(self):                        
463                 self.cpucount = 0                 
464                 if os.path.exists('/proc/cpuin    
465                         with open('/proc/cpuin    
466                                 for line in fp    
467                                         if re.    
468                                                   
469                 if os.path.exists('/proc/memin    
470                         with open('/proc/memin    
471                                 for line in fp    
472                                         m = re    
473                                         if m:     
474                                                   
475                                         m = re    
476                                         if m:     
477                                                   
478                 if os.path.exists('/etc/os-rel    
479                         with open('/etc/os-rel    
480                                 for line in fp    
481                                         if lin    
482                                                   
483         def initTestOutput(self, name):           
484                 self.prefix = self.hostname       
485                 v = open('/proc/version', 'r')    
486                 kver = v.split()[2]               
487                 fmt = name+'-%m%d%y-%H%M%S'       
488                 testtime = datetime.now().strf    
489                 self.teststamp = \                
490                         '# '+testtime+' '+self    
491                 ext = ''                          
492                 if self.gzip:                     
493                         ext = '.gz'               
494                 self.dmesgfile = \                
495                         self.testdir+'/'+self.    
496                 self.ftracefile = \               
497                         self.testdir+'/'+self.    
498                 self.htmlfile = \                 
499                         self.testdir+'/'+self.    
500                 if not os.path.isdir(self.test    
501                         os.makedirs(self.testd    
502                 self.sudoUserchown(self.testdi    
503         def getValueList(self, value):            
504                 out = []                          
505                 for i in value.split(','):        
506                         if i.strip():             
507                                 out.append(i.s    
508                 return out                        
509         def setDeviceFilter(self, value):         
510                 self.devicefilter = self.getVa    
511         def setCallgraphFilter(self, value):      
512                 self.cgfilter = self.getValueL    
513         def skipKprobes(self, value):             
514                 for k in self.getValueList(val    
515                         if k in self.tracefunc    
516                                 del self.trace    
517                         if k in self.dev_trace    
518                                 del self.dev_t    
519         def setCallgraphBlacklist(self, file):    
520                 self.cgblacklist = self.listFr    
521         def rtcWakeAlarmOn(self):                 
522                 call('echo 0 > '+self.rtcpath+    
523                 nowtime = open(self.rtcpath+'/    
524                 if nowtime:                       
525                         nowtime = int(nowtime)    
526                 else:                             
527                         # if hardware time fai    
528                         nowtime = int(datetime    
529                 alarm = nowtime + self.rtcwake    
530                 call('echo %d > %s/wakealarm'     
531         def rtcWakeAlarmOff(self):                
532                 call('echo 0 > %s/wakealarm' %    
533         def initdmesg(self):                      
534                 # get the latest time stamp fr    
535                 lines = Popen('dmesg', stdout=    
536                 ktime = '0'                       
537                 for line in reversed(lines):      
538                         line = ascii(line).rep    
539                         idx = line.find('[')      
540                         if idx > 1:               
541                                 line = line[id    
542                         m = re.match(r'[ \t]*(    
543                         if(m):                    
544                                 ktime = m.grou    
545                                 break             
546                 self.dmesgstart = float(ktime)    
547         def getdmesg(self, testdata):             
548                 op = self.writeDatafileHeader(    
549                 # store all new dmesg lines si    
550                 fp = Popen('dmesg', stdout=PIP    
551                 for line in fp:                   
552                         line = ascii(line).rep    
553                         idx = line.find('[')      
554                         if idx > 1:               
555                                 line = line[id    
556                         m = re.match(r'[ \t]*(    
557                         if(not m):                
558                                 continue          
559                         ktime = float(m.group(    
560                         if ktime > self.dmesgs    
561                                 op.write(line)    
562                 fp.close()                        
563                 op.close()                        
564         def listFromFile(self, file):             
565                 list = []                         
566                 fp = open(file)                   
567                 for i in fp.read().split('\n')    
568                         i = i.strip()             
569                         if i and i[0] != '#':     
570                                 list.append(i)    
571                 fp.close()                        
572                 return list                       
573         def addFtraceFilterFunctions(self, fil    
574                 for i in self.listFromFile(fil    
575                         if len(i) < 2:            
576                                 continue          
577                         self.tracefuncs[i] = d    
578         def getFtraceFilterFunctions(self, cur    
579                 self.rootCheck(True)              
580                 if not current:                   
581                         call('cat '+self.tpath    
582                         return                    
583                 master = self.listFromFile(sel    
584                 for i in sorted(self.tracefunc    
585                         if 'func' in self.trac    
586                                 i = self.trace    
587                         if i in master:           
588                                 print(i)          
589                         else:                     
590                                 print(self.col    
591         def setFtraceFilterFunctions(self, lis    
592                 master = self.listFromFile(sel    
593                 flist = ''                        
594                 for i in list:                    
595                         if i not in master:       
596                                 continue          
597                         if ' [' in i:             
598                                 flist += i.spl    
599                         else:                     
600                                 flist += i+'\n    
601                 fp = open(self.tpath+'set_grap    
602                 fp.write(flist)                   
603                 fp.close()                        
604         def basicKprobe(self, name):              
605                 self.kprobes[name] = {'name':     
606         def defaultKprobe(self, name, kdata):     
607                 k = kdata                         
608                 for field in ['name', 'format'    
609                         if field not in k:        
610                                 k[field] = nam    
611                 if self.archargs in k:            
612                         k['args'] = k[self.arc    
613                 else:                             
614                         k['args'] = dict()        
615                         k['format'] = name        
616                 self.kprobes[name] = k            
617         def kprobeColor(self, name):              
618                 if name not in self.kprobes or    
619                         return ''                 
620                 return self.kprobes[name]['col    
621         def kprobeDisplayName(self, name, data    
622                 if name not in self.kprobes:      
623                         self.basicKprobe(name)    
624                 data = ''                         
625                 quote=0                           
626                 # first remvoe any spaces insi    
627                 for c in dataraw:                 
628                         if c == '"':              
629                                 quote = (quote    
630                         if quote and c == ' ':    
631                                 data += '_'       
632                         elif c != '"':            
633                                 data += c         
634                 fmt, args = self.kprobes[name]    
635                 arglist = dict()                  
636                 # now process the args            
637                 for arg in sorted(args):          
638                         arglist[arg] = ''         
639                         m = re.match(r'.* '+ar    
640                         if m:                     
641                                 arglist[arg] =    
642                         else:                     
643                                 m = re.match(r    
644                                 if m:             
645                                         arglis    
646                 out = fmt.format(**arglist)       
647                 out = out.replace(' ', '_').re    
648                 return out                        
649         def kprobeText(self, kname, kprobe):      
650                 name = fmt = func = kname         
651                 args = dict()                     
652                 if 'name' in kprobe:              
653                         name = kprobe['name']     
654                 if 'format' in kprobe:            
655                         fmt = kprobe['format']    
656                 if 'func' in kprobe:              
657                         func = kprobe['func']     
658                 if self.archargs in kprobe:       
659                         args = kprobe[self.arc    
660                 if 'args' in kprobe:              
661                         args = kprobe['args']     
662                 if re.findall('{(?P<n>[a-z,A-Z    
663                         doError('Kprobe "%s" h    
664                 for arg in re.findall('{(?P<n>    
665                         if arg not in args:       
666                                 doError('Kprob    
667                 val = 'p:%s_cal %s' % (name, f    
668                 for i in sorted(args):            
669                         val += ' %s=%s' % (i,     
670                 val += '\nr:%s_ret %s $retval\    
671                 return val                        
672         def addKprobes(self, output=False):       
673                 if len(self.kprobes) < 1:         
674                         return                    
675                 if output:                        
676                         pprint('    kprobe fun    
677                 # first test each kprobe          
678                 rejects = []                      
679                 # sort kprobes: trace, ub-dev,    
680                 kpl = [[], [], [], []]            
681                 linesout = len(self.kprobes)      
682                 for name in sorted(self.kprobe    
683                         res = self.colorText('    
684                         if not self.testKprobe    
685                                 res = self.col    
686                                 rejects.append    
687                         else:                     
688                                 if name in sel    
689                                         kpl[0]    
690                                 elif name in s    
691                                         if 'ub    
692                                                   
693                                         else:     
694                                                   
695                                 else:             
696                                         kpl[2]    
697                         if output:                
698                                 pprint('          
699                 kplist = kpl[0] + kpl[1] + kpl    
700                 # remove all failed ones from     
701                 for name in rejects:              
702                         self.kprobes.pop(name)    
703                 # set the kprobes all at once     
704                 self.fsetVal('', 'kprobe_event    
705                 kprobeevents = ''                 
706                 for kp in kplist:                 
707                         kprobeevents += self.k    
708                 self.fsetVal(kprobeevents, 'kp    
709                 if output:                        
710                         check = self.fgetVal('    
711                         linesack = (len(check.    
712                         pprint('    kprobe fun    
713                 self.fsetVal('1', 'events/kpro    
714         def testKprobe(self, kname, kprobe):      
715                 self.fsetVal('0', 'events/kpro    
716                 kprobeevents = self.kprobeText    
717                 if not kprobeevents:              
718                         return False              
719                 try:                              
720                         self.fsetVal(kprobeeve    
721                         check = self.fgetVal('    
722                 except:                           
723                         return False              
724                 linesout = len(kprobeevents.sp    
725                 linesack = len(check.split('\n    
726                 if linesack < linesout:           
727                         return False              
728                 return True                       
729         def setVal(self, val, file):              
730                 if not os.path.exists(file):      
731                         return False              
732                 try:                              
733                         fp = open(file, 'wb',     
734                         fp.write(val.encode())    
735                         fp.flush()                
736                         fp.close()                
737                 except:                           
738                         return False              
739                 return True                       
740         def fsetVal(self, val, path):             
741                 if not self.useftrace:            
742                         return False              
743                 return self.setVal(val, self.t    
744         def getVal(self, file):                   
745                 res = ''                          
746                 if not os.path.exists(file):      
747                         return res                
748                 try:                              
749                         fp = open(file, 'r')      
750                         res = fp.read()           
751                         fp.close()                
752                 except:                           
753                         pass                      
754                 return res                        
755         def fgetVal(self, path):                  
756                 if not self.useftrace:            
757                         return ''                 
758                 return self.getVal(self.tpath+    
759         def cleanupFtrace(self):                  
760                 if self.useftrace:                
761                         self.fsetVal('0', 'eve    
762                         self.fsetVal('', 'kpro    
763                         self.fsetVal('1024', '    
764         def setupAllKprobes(self):                
765                 for name in self.tracefuncs:      
766                         self.defaultKprobe(nam    
767                 for name in self.dev_tracefunc    
768                         self.defaultKprobe(nam    
769         def isCallgraphFunc(self, name):          
770                 if len(self.tracefuncs) < 1 an    
771                         return True               
772                 for i in self.tracefuncs:         
773                         if 'func' in self.trac    
774                                 f = self.trace    
775                         else:                     
776                                 f = i             
777                         if name == f:             
778                                 return True       
779                 return False                      
780         def initFtrace(self, quiet=False):        
781                 if not self.useftrace:            
782                         return                    
783                 if not quiet:                     
784                         sysvals.printSystemInf    
785                         pprint('INITIALIZING F    
786                 # turn trace off                  
787                 self.fsetVal('0', 'tracing_on'    
788                 self.cleanupFtrace()              
789                 # set the trace clock to globa    
790                 self.fsetVal('global', 'trace_    
791                 self.fsetVal('nop', 'current_t    
792                 # set trace buffer to an appro    
793                 cpus = max(1, self.cpucount)      
794                 if self.bufsize > 0:              
795                         tgtsize = self.bufsize    
796                 elif self.usecallgraph or self    
797                         bmax = (1*1024*1024) i    
798                                 else (3*1024*1    
799                         tgtsize = min(self.mem    
800                 else:                             
801                         tgtsize = 65536           
802                 while not self.fsetVal('%d' %     
803                         # if the size failed t    
804                         tgtsize -= 65536          
805                         if tgtsize < 65536:       
806                                 tgtsize = int(    
807                                 break             
808                 self.vprint('Setting trace buf    
809                 # initialize the callgraph tra    
810                 if(self.usecallgraph):            
811                         # set trace type          
812                         self.fsetVal('function    
813                         self.fsetVal('', 'set_    
814                         # temporary hack to fi    
815                         fp = open(self.tpath+'    
816                         fp.write('native_queue    
817                         fp.close()                
818                         # set trace format opt    
819                         self.fsetVal('print-pa    
820                         self.fsetVal('funcgrap    
821                         self.fsetVal('funcgrap    
822                         self.fsetVal('funcgrap    
823                         self.fsetVal('funcgrap    
824                         self.fsetVal('funcgrap    
825                         self.fsetVal('nofuncgr    
826                         self.fsetVal('context-    
827                         self.fsetVal('graph-ti    
828                         self.fsetVal('%d' % se    
829                         cf = ['dpm_run_callbac    
830                         if(self.usetraceevents    
831                                 cf += ['dpm_pr    
832                         for fn in self.tracefu    
833                                 if 'func' in s    
834                                         cf.app    
835                                 else:             
836                                         cf.app    
837                         if self.ftop:             
838                                 self.setFtrace    
839                         else:                     
840                                 self.setFtrace    
841                 # initialize the kprobe trace     
842                 elif self.usekprobes:             
843                         for name in self.trace    
844                                 self.defaultKp    
845                         if self.usedevsrc:        
846                                 for name in se    
847                                         self.d    
848                         if not quiet:             
849                                 pprint('INITIA    
850                         self.addKprobes(self.v    
851                 if(self.usetraceevents):          
852                         # turn trace events on    
853                         events = iter(self.tra    
854                         for e in events:          
855                                 self.fsetVal('    
856                 # clear the trace buffer          
857                 self.fsetVal('', 'trace')         
858         def verifyFtrace(self):                   
859                 # files needed for any trace d    
860                 files = ['buffer_size_kb', 'cu    
861                                  'trace_marker    
862                 # files needed for callgraph t    
863                 tp = self.tpath                   
864                 if(self.usecallgraph):            
865                         files += [                
866                                 'available_fil    
867                                 'set_ftrace_fi    
868                                 'set_graph_fun    
869                         ]                         
870                 for f in files:                   
871                         if(os.path.exists(tp+f    
872                                 return False      
873                 return True                       
874         def verifyKprobes(self):                  
875                 # files needed for kprobes to     
876                 files = ['kprobe_events', 'eve    
877                 tp = self.tpath                   
878                 for f in files:                   
879                         if(os.path.exists(tp+f    
880                                 return False      
881                 return True                       
882         def colorText(self, str, color=31):       
883                 if not self.ansi:                 
884                         return str                
885                 return '\x1B[%d;40m%s\x1B[m' %    
886         def writeDatafileHeader(self, filename    
887                 fp = self.openlog(filename, 'w    
888                 fp.write('%s\n%s\n# command |     
889                 for test in testdata:             
890                         if 'fw' in test:          
891                                 fw = test['fw'    
892                                 if(fw):           
893                                         fp.wri    
894                         if 'turbo' in test:       
895                                 fp.write('# tu    
896                         if 'wifi' in test:        
897                                 fp.write('# wi    
898                         if 'netfix' in test:      
899                                 fp.write('# ne    
900                         if test['error'] or le    
901                                 fp.write('# en    
902                 return fp                         
903         def sudoUserchown(self, dir):             
904                 if os.path.exists(dir) and sel    
905                         cmd = 'chown -R {0}:{0    
906                         call(cmd.format(self.s    
907         def outputResult(self, testdata, num=0    
908                 if not self.result:               
909                         return                    
910                 n = ''                            
911                 if num > 0:                       
912                         n = '%d' % num            
913                 fp = open(self.result, 'a')       
914                 if 'error' in testdata:           
915                         fp.write('result%s: fa    
916                         fp.write('error%s: %s\    
917                 else:                             
918                         fp.write('result%s: pa    
919                 if 'mode' in testdata:            
920                         fp.write('mode%s: %s\n    
921                 for v in ['suspend', 'resume',    
922                         if v in testdata:         
923                                 fp.write('%s%s    
924                 for v in ['fwsuspend', 'fwresu    
925                         if v in testdata:         
926                                 fp.write('%s%s    
927                 if 'bugurl' in testdata:          
928                         fp.write('url%s: %s\n'    
929                 fp.close()                        
930                 self.sudoUserchown(self.result    
931         def configFile(self, file):               
932                 dir = os.path.dirname(os.path.    
933                 if os.path.exists(file):          
934                         return file               
935                 elif os.path.exists(dir+'/'+fi    
936                         return dir+'/'+file       
937                 elif os.path.exists(dir+'/conf    
938                         return dir+'/config/'+    
939                 return ''                         
940         def openlog(self, filename, mode):        
941                 isgz = self.gzip                  
942                 if mode == 'r':                   
943                         try:                      
944                                 with gzip.open    
945                                         test =    
946                                 isgz = True       
947                         except:                   
948                                 isgz = False      
949                 if isgz:                          
950                         return gzip.open(filen    
951                 return open(filename, mode)       
952         def putlog(self, filename, text):         
953                 with self.openlog(filename, 'a    
954                         fp.write(text)            
955                         fp.close()                
956         def dlog(self, text):                     
957                 if not self.dmesgfile:            
958                         return                    
959                 self.putlog(self.dmesgfile, '#    
960         def flog(self, text):                     
961                 self.putlog(self.ftracefile, t    
962         def b64unzip(self, data):                 
963                 try:                              
964                         out = codecs.decode(ba    
965                 except:                           
966                         out = data                
967                 return out                        
968         def b64zip(self, data):                   
969                 out = base64.b64encode(codecs.    
970                 return out                        
971         def platforminfo(self, cmdafter):         
972                 # add platform info on to a co    
973                 if not os.path.exists(self.ftr    
974                         return False              
975                 footer = '#\n'                    
976                                                   
977                 # add test command string line    
978                 if self.suspendmode == 'comman    
979                         footer += '# platform-    
980                                                   
981                 # get a list of target devices    
982                 props = dict()                    
983                 tp = TestProps()                  
984                 tf = self.openlog(self.ftracef    
985                 for line in tf:                   
986                         if tp.stampInfo(line,     
987                                 continue          
988                         # parse only valid lin    
989                         m = re.match(tp.ftrace    
990                         if(not m or 'device_pm    
991                                 continue          
992                         m = re.match(r'.*: (?P    
993                         if(not m):                
994                                 continue          
995                         dev = m.group('d')        
996                         if dev not in props:      
997                                 props[dev] = D    
998                 tf.close()                        
999                                                   
1000                 # now get the syspath for eac    
1001                 for dirname, dirnames, filena    
1002                         if(re.match(r'.*/powe    
1003                                 dev = dirname    
1004                                 if dev in pro    
1005                                         props    
1006                                                  
1007                 # now fill in the properties     
1008                 for dev in sorted(props):        
1009                         dirname = props[dev].    
1010                         if not dirname or not    
1011                                 continue         
1012                         props[dev].isasync =     
1013                         if os.path.exists(dir    
1014                                 fp = open(dir    
1015                                 if 'enabled'     
1016                                         props    
1017                                 fp.close()       
1018                         fields = os.listdir(d    
1019                         for file in ['product    
1020                                 if file not i    
1021                                         conti    
1022                                 try:             
1023                                         with     
1024                                                  
1025                                 except:          
1026                                         conti    
1027                                 if file == 'i    
1028                                         idv,     
1029                                         try:     
1030                                                  
1031                                                  
1032                                         excep    
1033                                                  
1034                                                  
1035                                         props    
1036                                 break            
1037                         if props[dev].altname    
1038                                 out = props[d    
1039                                         .repl    
1040                                 props[dev].al    
1041                                                  
1042                 # add a devinfo line to the b    
1043                 out = ''                         
1044                 for dev in sorted(props):        
1045                         out += props[dev].out    
1046                 footer += '# platform-devinfo    
1047                                                  
1048                 # add a line for each of thes    
1049                 for name, cmdline, info in cm    
1050                         footer += '# platform    
1051                 self.flog(footer)                
1052                 return True                      
1053         def commonPrefix(self, list):            
1054                 if len(list) < 2:                
1055                         return ''                
1056                 prefix = list[0]                 
1057                 for s in list[1:]:               
1058                         while s[:len(prefix)]    
1059                                 prefix = pref    
1060                         if not prefix:           
1061                                 break            
1062                 if '/' in prefix and prefix[-    
1063                         prefix = prefix[0:pre    
1064                 return prefix                    
1065         def dictify(self, text, format):         
1066                 out = dict()                     
1067                 header = True if format == 1     
1068                 delim = ' ' if format == 1 el    
1069                 for line in text.split('\n'):    
1070                         if header:               
1071                                 header, out['    
1072                                 continue         
1073                         line = line.strip()      
1074                         if delim in line:        
1075                                 data = line.s    
1076                                 num = re.sear    
1077                                 if format ==     
1078                                         out[d    
1079                                 else:            
1080                                         out[d    
1081                 return out                       
1082         def cmdinfovar(self, arg):               
1083                 if arg == 'ethdev':              
1084                         try:                     
1085                                 cmd = [self.g    
1086                                 fp = Popen(cm    
1087                                 info = ascii(    
1088                                 fp.close()       
1089                         except:                  
1090                                 return 'iptoo    
1091                         for line in info.spli    
1092                                 if line[0] ==    
1093                                         retur    
1094                         return 'nodevicefound    
1095                 return 'unknown'                 
1096         def cmdinfo(self, begin, debug=False)    
1097                 out = []                         
1098                 if begin:                        
1099                         self.cmd1 = dict()       
1100                 for cargs in self.infocmds:      
1101                         delta, name, args = c    
1102                         for i in range(len(ar    
1103                                 if args[i][0]    
1104                                         args[    
1105                         cmdline, cmdpath = '     
1106                         if not cmdpath or (be    
1107                                 continue         
1108                         self.dlog('[%s]' % cm    
1109                         try:                     
1110                                 fp = Popen([c    
1111                                 info = ascii(    
1112                                 fp.close()       
1113                         except:                  
1114                                 continue         
1115                         if not debug and begi    
1116                                 self.cmd1[nam    
1117                         elif not debug and de    
1118                                 before, after    
1119                                 dinfo = ('\t%    
1120                                 prefix = self    
1121                                 for key in so    
1122                                         if ke    
1123                                                  
1124                                                  
1125                                                  
1126                                                  
1127                                                  
1128                                                  
1129                                                  
1130                                 dinfo = '\tno    
1131                                 out.append((n    
1132                         else:                    
1133                                 out.append((n    
1134                 return out                       
1135         def testVal(self, file, fmt='basic',     
1136                 if file == 'restoreall':         
1137                         for f in self.cfgdef:    
1138                                 if os.path.ex    
1139                                         fp =     
1140                                         fp.wr    
1141                                         fp.cl    
1142                         self.cfgdef = dict()     
1143                 elif value and os.path.exists    
1144                         fp = open(file, 'r+')    
1145                         if fmt == 'radio':       
1146                                 m = re.match(    
1147                                 if m:            
1148                                         self.    
1149                         elif fmt == 'acpi':      
1150                                 line = fp.rea    
1151                                 m = re.match(    
1152                                 if m:            
1153                                         self.    
1154                         else:                    
1155                                 self.cfgdef[f    
1156                         fp.write(value)          
1157                         fp.close()               
1158         def s0ixSupport(self):                   
1159                 if not os.path.exists(self.s0    
1160                         return False             
1161                 fp = open(sysvals.mempowerfil    
1162                 data = fp.read().strip()         
1163                 fp.close()                       
1164                 if '[s2idle]' in data:           
1165                         return True              
1166                 return False                     
1167         def haveTurbostat(self):                 
1168                 if not self.tstat:               
1169                         return False             
1170                 cmd = self.getExec('turbostat    
1171                 if not cmd:                      
1172                         return False             
1173                 fp = Popen([cmd, '-v'], stdou    
1174                 out = ascii(fp.read()).strip(    
1175                 fp.close()                       
1176                 if re.match(r'turbostat versi    
1177                         self.vprint(out)         
1178                         return True              
1179                 return False                     
1180         def turbostat(self, s0ixready):          
1181                 cmd = self.getExec('turbostat    
1182                 rawout = keyline = valline =     
1183                 fullcmd = '%s -q -S echo free    
1184                 fp = Popen(['sh', '-c', fullc    
1185                 for line in fp.stderr:           
1186                         line = ascii(line)       
1187                         rawout += line           
1188                         if keyline and vallin    
1189                                 continue         
1190                         if re.match(r'(?i)Avg    
1191                                 keyline = lin    
1192                         elif keyline:            
1193                                 valline = lin    
1194                 fp.wait()                        
1195                 if not keyline or not valline    
1196                         errmsg = 'unrecognize    
1197                         self.vprint(errmsg)      
1198                         if not self.verbose:     
1199                                 pprint(errmsg    
1200                         return (fp.returncode    
1201                 if self.verbose:                 
1202                         pprint(rawout.strip()    
1203                 out = []                         
1204                 for key in keyline:              
1205                         idx = keyline.index(k    
1206                         val = valline[idx]       
1207                         if key == 'SYS%LPI' a    
1208                                 continue         
1209                         out.append('%s=%s' %     
1210                 return (fp.returncode, '|'.jo    
1211         def netfixon(self, net='both'):          
1212                 cmd = self.getExec('netfix')     
1213                 if not cmd:                      
1214                         return ''                
1215                 fp = Popen([cmd, '-s', net, '    
1216                 out = ascii(fp.read()).strip(    
1217                 fp.close()                       
1218                 return out                       
1219         def wifiDetails(self, dev):              
1220                 try:                             
1221                         info = open('/sys/cla    
1222                 except:                          
1223                         return dev               
1224                 vals = [dev]                     
1225                 for prop in info.split('\n'):    
1226                         if prop.startswith('D    
1227                                 vals.append(p    
1228                 return ':'.join(vals)            
1229         def checkWifi(self, dev=''):             
1230                 try:                             
1231                         w = open('/proc/net/w    
1232                 except:                          
1233                         return ''                
1234                 for line in reversed(w.split(    
1235                         m = re.match(r' *(?P<    
1236                         if not m or (dev and     
1237                                 continue         
1238                         return m.group('dev')    
1239                 return ''                        
1240         def pollWifi(self, dev, timeout=10):     
1241                 start = time.time()              
1242                 while (time.time() - start) <    
1243                         w = self.checkWifi(de    
1244                         if w:                    
1245                                 return '%s re    
1246                                         (self    
1247                         time.sleep(0.01)         
1248                 return '%s timeout %d' % (sel    
1249         def errorSummary(self, errinfo, msg):    
1250                 found = False                    
1251                 for entry in errinfo:            
1252                         if re.match(entry['ma    
1253                                 entry['count'    
1254                                 if self.hostn    
1255                                         entry    
1256                                 elif self.htm    
1257                                         entry    
1258                                 found = True     
1259                                 break            
1260                 if found:                        
1261                         return                   
1262                 arr = msg.split()                
1263                 for j in range(len(arr)):        
1264                         if re.match(r'^[0-9,\    
1265                                 arr[j] = r'[0    
1266                         else:                    
1267                                 arr[j] = arr[    
1268                                         .repl    
1269                                         .repl    
1270                                         .repl    
1271                                         .repl    
1272                 mstr = ' *'.join(arr)            
1273                 entry = {                        
1274                         'line': msg,             
1275                         'match': mstr,           
1276                         'count': 1,              
1277                         'urls': {self.hostnam    
1278                 }                                
1279                 errinfo.append(entry)            
1280         def multistat(self, start, idx, finis    
1281                 if 'time' in self.multitest:     
1282                         id = '%d Duration=%dm    
1283                 else:                            
1284                         id = '%d/%d' % (idx+1    
1285                 t = time.time()                  
1286                 if 'start' not in self.multit    
1287                         self.multitest['start    
1288                         self.multitest['total    
1289                         pprint('TEST (%s) STA    
1290                         return                   
1291                 dt = t - self.multitest['last    
1292                 if not start:                    
1293                         if idx == 0 and self.    
1294                                 self.multites    
1295                         pprint('TEST (%s) COM    
1296                         return                   
1297                 self.multitest['total'] += dt    
1298                 self.multitest['last'] = t       
1299                 avg = self.multitest['total']    
1300                 if 'time' in self.multitest:     
1301                         left = finish - datet    
1302                         left -= timedelta(mic    
1303                 else:                            
1304                         left = timedelta(seco    
1305                 pprint('TEST (%s) START - Avg    
1306                         (id, avg, str(left)))    
1307         def multiinit(self, c, d):               
1308                 sz, unit = 'count', 'm'          
1309                 if c.endswith('d') or c.endsw    
1310                         sz, unit, c = 'time',    
1311                 self.multitest['run'] = True     
1312                 self.multitest[sz] = getArgIn    
1313                 self.multitest['delay'] = get    
1314                 if unit == 'd':                  
1315                         self.multitest[sz] *=    
1316                 elif unit == 'h':                
1317                         self.multitest[sz] *=    
1318         def displayControl(self, cmd):           
1319                 xset, ret = 'timeout 10 xset     
1320                 if self.sudouser:                
1321                         xset = 'sudo -u %s %s    
1322                 if cmd == 'init':                
1323                         ret = call(xset.forma    
1324                         if not ret:              
1325                                 ret = call(xs    
1326                 elif cmd == 'reset':             
1327                         ret = call(xset.forma    
1328                 elif cmd in ['on', 'off', 'st    
1329                         b4 = self.displayCont    
1330                         ret = call(xset.forma    
1331                         if not ret:              
1332                                 curr = self.d    
1333                                 self.vprint('    
1334                                 if curr != cm    
1335                                         self.    
1336                         if ret:                  
1337                                 self.vprint('    
1338                                 return ret       
1339                 elif cmd == 'stat':              
1340                         fp = Popen(xset.forma    
1341                         ret = 'unknown'          
1342                         for line in fp:          
1343                                 m = re.match(    
1344                                 if(m and len(    
1345                                         out =    
1346                                         ret =    
1347                                         break    
1348                         fp.close()               
1349                 return ret                       
1350         def setRuntimeSuspend(self, before=Tr    
1351                 if before:                       
1352                         # runtime suspend dis    
1353                         if self.rs > 0:          
1354                                 self.rstgt, s    
1355                         else:                    
1356                                 self.rstgt, s    
1357                         pprint('CONFIGURING R    
1358                         self.rslist = deviceI    
1359                         for i in self.rslist:    
1360                                 self.setVal(s    
1361                         pprint('runtime suspe    
1362                         pprint('waiting 5 sec    
1363                         time.sleep(5)            
1364                 else:                            
1365                         # runtime suspend re-    
1366                         for i in self.rslist:    
1367                                 self.setVal(s    
1368                         pprint('runtime suspe    
1369         def start(self, pm):                     
1370                 if self.useftrace:               
1371                         self.dlog('start ftra    
1372                         self.fsetVal('1', 'tr    
1373                         if self.useprocmon:      
1374                                 self.dlog('st    
1375                                 pm.start()       
1376         def stop(self, pm):                      
1377                 if self.useftrace:               
1378                         if self.useprocmon:      
1379                                 self.dlog('st    
1380                                 pm.stop()        
1381                         self.dlog('stop ftrac    
1382                         self.fsetVal('0', 'tr    
1383                                                  
1384 sysvals = SystemValues()                         
1385 switchvalues = ['enable', 'disable', 'on', 'o    
1386 switchoff = ['disable', 'off', 'false', '0']     
1387 suspendmodename = {                              
1388         'standby': 'standby (S1)',               
1389         'freeze': 'freeze (S2idle)',             
1390         'mem': 'suspend (S3)',                   
1391         'disk': 'hibernate (S4)'                 
1392 }                                                
1393                                                  
1394 # Class: DevProps                                
1395 # Description:                                   
1396 #        Simple class which holds property va    
1397 #        for all the devices used in the time    
1398 class DevProps:                                  
1399         def __init__(self):                      
1400                 self.syspath = ''                
1401                 self.altname = ''                
1402                 self.isasync = True              
1403                 self.xtraclass = ''              
1404                 self.xtrainfo = ''               
1405         def out(self, dev):                      
1406                 return '%s,%s,%d;' % (dev, se    
1407         def debug(self, dev):                    
1408                 pprint('%s:\n\taltname = %s\n    
1409         def altName(self, dev):                  
1410                 if not self.altname or self.a    
1411                         return dev               
1412                 return '%s [%s]' % (self.altn    
1413         def xtraClass(self):                     
1414                 if self.xtraclass:               
1415                         return ' '+self.xtrac    
1416                 if not self.isasync:             
1417                         return ' sync'           
1418                 return ''                        
1419         def xtraInfo(self):                      
1420                 if self.xtraclass:               
1421                         return ' '+self.xtrac    
1422                 if self.isasync:                 
1423                         return ' (async)'        
1424                 return ' (sync)'                 
1425                                                  
1426 # Class: DeviceNode                              
1427 # Description:                                   
1428 #        A container used to create a device     
1429 #        and a tree of child nodes. Used by D    
1430 class DeviceNode:                                
1431         def __init__(self, nodename, nodedept    
1432                 self.name = nodename             
1433                 self.children = []               
1434                 self.depth = nodedepth           
1435                                                  
1436 # Class: Data                                    
1437 # Description:                                   
1438 #        The primary container for suspend/re    
1439 #        each test run. The data is organized    
1440 #        Data.dmesg {                            
1441 #               phases {                         
1442 #                       10 sequential, non-ov    
1443 #                       contents: times for p    
1444 #                       devlist {                
1445 #                               device callba    
1446 #                               device {         
1447 #                                       a sin    
1448 #                                       conte    
1449 #                                                
1450 #                                                
1451 #                                                
1452 #                               }                
1453 #                       }                        
1454 #               }                                
1455 #       }                                        
1456 #                                                
1457 class Data:                                      
1458         phasedef = {                             
1459                 'suspend_prepare': {'order':     
1460                         'suspend': {'order':     
1461                    'suspend_late': {'order':     
1462                   'suspend_noirq': {'order':     
1463                 'suspend_machine': {'order':     
1464                  'resume_machine': {'order':     
1465                    'resume_noirq': {'order':     
1466                    'resume_early': {'order':     
1467                          'resume': {'order':     
1468                 'resume_complete': {'order':     
1469         }                                        
1470         errlist = {                              
1471                 'HWERROR' : r'.*\[ *Hardware     
1472                 'FWBUG'   : r'.*\[ *Firmware     
1473                 'TASKFAIL': r'.*Freezing .*af    
1474                 'BUG'     : r'(?i).*\bBUG\b.*    
1475                 'ERROR'   : r'(?i).*\bERROR\b    
1476                 'WARNING' : r'(?i).*\bWARNING    
1477                 'FAULT'   : r'(?i).*\bFAULT\b    
1478                 'FAIL'    : r'(?i).*\bFAILED\    
1479                 'INVALID' : r'(?i).*\bINVALID    
1480                 'CRASH'   : r'(?i).*\bCRASHED    
1481                 'TIMEOUT' : r'(?i).*\bTIMEOUT    
1482                 'ABORT'   : r'(?i).*\bABORT\b    
1483                 'IRQ'     : r'.*\bgenirq: .*'    
1484                 'ACPI'    : r'.*\bACPI *(?P<b    
1485                 'DISKFULL': r'.*\bNo space le    
1486                 'USBERR'  : r'.*usb .*device     
1487                 'ATAERR'  : r' *ata[0-9\.]*:     
1488                 'MEIERR'  : r' *mei.*: .*fail    
1489                 'TPMERR'  : r'(?i) *tpm *tpm[    
1490         }                                        
1491         def __init__(self, num):                 
1492                 idchar = 'abcdefghij'            
1493                 self.start = 0.0 # test start    
1494                 self.end = 0.0   # test end      
1495                 self.hwstart = 0 # rtc test s    
1496                 self.hwend = 0   # rtc test e    
1497                 self.tSuspended = 0.0 # low-l    
1498                 self.tResumed = 0.0   # low-l    
1499                 self.tKernSus = 0.0   # kerne    
1500                 self.tKernRes = 0.0   # kerne    
1501                 self.fwValid = False  # is fi    
1502                 self.fwSuspend = 0    # time     
1503                 self.fwResume = 0     # time     
1504                 self.html_device_id = 0          
1505                 self.stamp = 0                   
1506                 self.outfile = ''                
1507                 self.kerror = False              
1508                 self.wifi = dict()               
1509                 self.turbostat = 0               
1510                 self.enterfail = ''              
1511                 self.currphase = ''              
1512                 self.pstl = dict()    # proce    
1513                 self.testnumber = num            
1514                 self.idstr = idchar[num]         
1515                 self.dmesgtext = []   # dmesg    
1516                 self.dmesg = dict()   # root     
1517                 self.errorinfo = {'suspend':[    
1518                 self.tLow = []        # time     
1519                 self.devpids = []                
1520                 self.devicegroups = 0            
1521         def sortedPhases(self):                  
1522                 return sorted(self.dmesg, key    
1523         def initDevicegroups(self):              
1524                 # called when phases are all     
1525                 for phase in sorted(self.dmes    
1526                         if '*' in phase:         
1527                                 p = phase.spl    
1528                                 pnew = '%s%d'    
1529                                 self.dmesg[pn    
1530                 self.devicegroups = []           
1531                 for phase in self.sortedPhase    
1532                         self.devicegroups.app    
1533         def nextPhase(self, phase, offset):      
1534                 order = self.dmesg[phase]['or    
1535                 for p in self.dmesg:             
1536                         if self.dmesg[p]['ord    
1537                                 return p         
1538                 return ''                        
1539         def lastPhase(self, depth=1):            
1540                 plist = self.sortedPhases()      
1541                 if len(plist) < depth:           
1542                         return ''                
1543                 return plist[-1*depth]           
1544         def turbostatInfo(self):                 
1545                 tp = TestProps()                 
1546                 out = {'syslpi':'N/A','pkgpc1    
1547                 for line in self.dmesgtext:      
1548                         m = re.match(tp.tstat    
1549                         if not m:                
1550                                 continue         
1551                         for i in m.group('t')    
1552                                 if 'SYS%LPI'     
1553                                         out['    
1554                                 elif 'pc10' i    
1555                                         out['    
1556                         break                    
1557                 return out                       
1558         def extractErrorInfo(self):              
1559                 lf = self.dmesgtext              
1560                 if len(self.dmesgtext) < 1 an    
1561                         lf = sysvals.openlog(    
1562                 i = 0                            
1563                 tp = TestProps()                 
1564                 list = []                        
1565                 for line in lf:                  
1566                         i += 1                   
1567                         if tp.stampInfo(line,    
1568                                 continue         
1569                         m = re.match(r'[ \t]*    
1570                         if not m:                
1571                                 continue         
1572                         t = float(m.group('kt    
1573                         if t < self.start or     
1574                                 continue         
1575                         dir = 'suspend' if t     
1576                         msg = m.group('msg')     
1577                         if re.match(r'capabil    
1578                                 continue         
1579                         for err in self.errli    
1580                                 if re.match(s    
1581                                         list.    
1582                                         self.    
1583                                         break    
1584                 tp.msglist = []                  
1585                 for msg, type, dir, t, idx1,     
1586                         tp.msglist.append(msg    
1587                         self.errorinfo[dir].a    
1588                 if self.kerror:                  
1589                         sysvals.dmesglog = Tr    
1590                 if len(self.dmesgtext) < 1 an    
1591                         lf.close()               
1592                 return tp                        
1593         def setStart(self, time, msg=''):        
1594                 self.start = time                
1595                 if msg:                          
1596                         try:                     
1597                                 self.hwstart     
1598                         except:                  
1599                                 self.hwstart     
1600         def setEnd(self, time, msg=''):          
1601                 self.end = time                  
1602                 if msg:                          
1603                         try:                     
1604                                 self.hwend =     
1605                         except:                  
1606                                 self.hwend =     
1607         def isTraceEventOutsideDeviceCalls(se    
1608                 for phase in self.sortedPhase    
1609                         list = self.dmesg[pha    
1610                         for dev in list:         
1611                                 d = list[dev]    
1612                                 if(d['pid'] =    
1613                                         time     
1614                                         retur    
1615                 return True                      
1616         def sourcePhase(self, start):            
1617                 for phase in self.sortedPhase    
1618                         if 'machine' in phase    
1619                                 continue         
1620                         pend = self.dmesg[pha    
1621                         if start <= pend:        
1622                                 return phase     
1623                 return 'resume_complete' if '    
1624         def sourceDevice(self, phaselist, sta    
1625                 tgtdev = ''                      
1626                 for phase in phaselist:          
1627                         list = self.dmesg[pha    
1628                         for devname in list:     
1629                                 dev = list[de    
1630                                 # pid must ma    
1631                                 if dev['pid']    
1632                                         conti    
1633                                 devS = dev['s    
1634                                 devE = dev['e    
1635                                 if type == 'd    
1636                                         # dev    
1637                                         if(st    
1638                                                  
1639                                 elif type ==     
1640                                         # thr    
1641                                         if st    
1642                                                  
1643                                         if en    
1644                                                  
1645                                 tgtdev = dev     
1646                                 break            
1647                 return tgtdev                    
1648         def addDeviceFunctionCall(self, displ    
1649                 # try to place the call in a     
1650                 phases = self.sortedPhases()     
1651                 tgtdev = self.sourceDevice(ph    
1652                 # calls with device pids that    
1653                 # TODO: include these somehow    
1654                 if not tgtdev and pid in self    
1655                         return False             
1656                 # try to place the call in a     
1657                 if not tgtdev:                   
1658                         tgtdev = self.sourceD    
1659                 # create new thread blocks, e    
1660                 if not tgtdev:                   
1661                         if proc == '<...>':      
1662                                 threadname =     
1663                         else:                    
1664                                 threadname =     
1665                         tgtphase = self.sourc    
1666                         if not tgtphase:         
1667                                 return False     
1668                         self.newAction(tgtpha    
1669                         return self.addDevice    
1670                 # this should not happen         
1671                 if not tgtdev:                   
1672                         sysvals.vprint('[%f -    
1673                                 (start, end,     
1674                         return False             
1675                 # place the call data inside     
1676                 if('src' not in tgtdev):         
1677                         tgtdev['src'] = []       
1678                 dtf = sysvals.dev_tracefuncs     
1679                 ubiquitous = False               
1680                 if kprobename in dtf and 'ub'    
1681                         ubiquitous = True        
1682                 mc = re.match(r'\(.*\) *(?P<a    
1683                 mr = re.match(r'\((?P<caller>    
1684                 if mc and mr:                    
1685                         c = mr.group('caller'    
1686                         a = mc.group('args').    
1687                         r = mr.group('ret')      
1688                         if len(r) > 6:           
1689                                 r = ''           
1690                         else:                    
1691                                 r = 'ret=%s '    
1692                         if ubiquitous and c i    
1693                                 return False     
1694                 else:                            
1695                         return False             
1696                 color = sysvals.kprobeColor(k    
1697                 e = DevFunction(displayname,     
1698                 tgtdev['src'].append(e)          
1699                 return True                      
1700         def overflowDevices(self):               
1701                 # get a list of devices that     
1702                 devlist = []                     
1703                 for phase in self.sortedPhase    
1704                         list = self.dmesg[pha    
1705                         for devname in list:     
1706                                 dev = list[de    
1707                                 if dev['end']    
1708                                         devli    
1709                 return devlist                   
1710         def mergeOverlapDevices(self, devlist    
1711                 # merge any devices that over    
1712                 for dev in devlist:              
1713                         devname = dev['name']    
1714                         for phase in self.sor    
1715                                 list = self.d    
1716                                 if devname no    
1717                                         conti    
1718                                 tdev = list[d    
1719                                 o = min(dev['    
1720                                 if o <= 0:       
1721                                         conti    
1722                                 dev['end'] =     
1723                                 if 'src' not     
1724                                         conti    
1725                                 dev['src'] +=    
1726                                 del list[devn    
1727         def usurpTouchingThread(self, name, d    
1728                 # the caller test has priorit    
1729                 for phase in self.sortedPhase    
1730                         list = self.dmesg[pha    
1731                         if name in list:         
1732                                 tdev = list[n    
1733                                 if tdev['star    
1734                                         dev['    
1735                                         if 's    
1736                                                  
1737                                         if 's    
1738                                                  
1739                                         del l    
1740                                 break            
1741         def stitchTouchingThreads(self, testl    
1742                 # merge any threads between t    
1743                 for phase in self.sortedPhase    
1744                         list = self.dmesg[pha    
1745                         for devname in list:     
1746                                 dev = list[de    
1747                                 if 'htmlclass    
1748                                         conti    
1749                                 for data in t    
1750                                         data.    
1751         def optimizeDevSrc(self):                
1752                 # merge any src call loops to    
1753                 for phase in self.sortedPhase    
1754                         list = self.dmesg[pha    
1755                         for dev in list:         
1756                                 if 'src' not     
1757                                         conti    
1758                                 src = list[de    
1759                                 p = 0            
1760                                 for e in sort    
1761                                         if no    
1762                                                  
1763                                                  
1764                                         # e i    
1765                                         p.end    
1766                                         p.len    
1767                                         p.cou    
1768                                         src.r    
1769         def trimTimeVal(self, t, t0, dT, left    
1770                 if left:                         
1771                         if(t > t0):              
1772                                 if(t - dT < t    
1773                                         retur    
1774                                 return t - dT    
1775                         else:                    
1776                                 return t         
1777                 else:                            
1778                         if(t < t0 + dT):         
1779                                 if(t > t0):      
1780                                         retur    
1781                                 return t + dT    
1782                         else:                    
1783                                 return t         
1784         def trimTime(self, t0, dT, left):        
1785                 self.tSuspended = self.trimTi    
1786                 self.tResumed = self.trimTime    
1787                 self.start = self.trimTimeVal    
1788                 self.tKernSus = self.trimTime    
1789                 self.tKernRes = self.trimTime    
1790                 self.end = self.trimTimeVal(s    
1791                 for phase in self.sortedPhase    
1792                         p = self.dmesg[phase]    
1793                         p['start'] = self.tri    
1794                         p['end'] = self.trimT    
1795                         list = p['list']         
1796                         for name in list:        
1797                                 d = list[name    
1798                                 d['start'] =     
1799                                 d['end'] = se    
1800                                 d['length'] =    
1801                                 if('ftrace' i    
1802                                         cg =     
1803                                         cg.st    
1804                                         cg.en    
1805                                         for l    
1806                                                  
1807                                 if('src' in d    
1808                                         for e    
1809                                                  
1810                                                  
1811                                                  
1812                                 if('cpuexec'     
1813                                         cpuex    
1814                                         for e    
1815                                                  
1816                                                  
1817                                                  
1818                                                  
1819                                         d['cp    
1820                 for dir in ['suspend', 'resum    
1821                         list = []                
1822                         for e in self.errorin    
1823                                 type, tm, idx    
1824                                 tm = self.tri    
1825                                 list.append((    
1826                         self.errorinfo[dir] =    
1827         def trimFreezeTime(self, tZero):         
1828                 # trim out any standby or fre    
1829                 lp = ''                          
1830                 for phase in self.sortedPhase    
1831                         if 'resume_machine' i    
1832                                 tS, tR = self    
1833                                 tL = tR - tS     
1834                                 if tL <= 0:      
1835                                         conti    
1836                                 left = True i    
1837                                 self.trimTime    
1838                                 if 'waking' i    
1839                                         tCnt     
1840                                         if se    
1841                                                  
1842                                         else:    
1843                                                  
1844                                         text     
1845                                 else:            
1846                                         text     
1847                                 self.tLow.app    
1848                         lp = phase               
1849         def getMemTime(self):                    
1850                 if not self.hwstart or not se    
1851                         return                   
1852                 stime = (self.tSuspended - se    
1853                 rtime = (self.end - self.tRes    
1854                 hws = self.hwstart + timedelt    
1855                 hwr = self.hwend - timedelta(    
1856                 self.tLow.append('%.0f'%((hwr    
1857         def getTimeValues(self):                 
1858                 s = (self.tSuspended - self.t    
1859                 r = (self.tKernRes - self.tRe    
1860                 return (max(s, 0), max(r, 0))    
1861         def setPhase(self, phase, ktime, isbe    
1862                 if(isbegin):                     
1863                         # phase start over cu    
1864                         if self.currphase:       
1865                                 if 'resume_ma    
1866                                         sysva    
1867                                 self.dmesg[se    
1868                         phases = self.dmesg.k    
1869                         color = self.phasedef    
1870                         count = len(phases) i    
1871                         # create unique name     
1872                         while phase in phases    
1873                                 phase += '*'     
1874                         self.dmesg[phase] = {    
1875                                 'row': 0, 'co    
1876                         self.dmesg[phase]['st    
1877                         self.currphase = phas    
1878                 else:                            
1879                         # phase end without a    
1880                         if phase not in self.    
1881                                 if self.currp    
1882                                         sysva    
1883                                 else:            
1884                                         sysva    
1885                                         retur    
1886                         phase = self.currphas    
1887                         self.dmesg[phase]['en    
1888                         self.currphase = ''      
1889                 return phase                     
1890         def sortedDevices(self, phase):          
1891                 list = self.dmesg[phase]['lis    
1892                 return sorted(list, key=lambd    
1893         def fixupInitcalls(self, phase):         
1894                 # if any calls never returned    
1895                 phaselist = self.dmesg[phase]    
1896                 for devname in phaselist:        
1897                         dev = phaselist[devna    
1898                         if(dev['end'] < 0):      
1899                                 for p in self    
1900                                         if se    
1901                                                  
1902                                                  
1903                                 sysvals.vprin    
1904         def deviceFilter(self, devicefilter):    
1905                 for phase in self.sortedPhase    
1906                         list = self.dmesg[pha    
1907                         rmlist = []              
1908                         for name in list:        
1909                                 keep = False     
1910                                 for filter in    
1911                                         if fi    
1912                                                  
1913                                                  
1914                                 if not keep:     
1915                                         rmlis    
1916                         for name in rmlist:      
1917                                 del list[name    
1918         def fixupInitcallsThatDidntReturn(sel    
1919                 # if any calls never returned    
1920                 for phase in self.sortedPhase    
1921                         self.fixupInitcalls(p    
1922         def phaseOverlap(self, phases):          
1923                 rmgroups = []                    
1924                 newgroup = []                    
1925                 for group in self.devicegroup    
1926                         for phase in phases:     
1927                                 if phase not     
1928                                         conti    
1929                                 for p in grou    
1930                                         if p     
1931                                                  
1932                                 if group not     
1933                                         rmgro    
1934                 for group in rmgroups:           
1935                         self.devicegroups.rem    
1936                 self.devicegroups.append(newg    
1937         def newActionGlobal(self, name, start    
1938                 # which phase is this device     
1939                 phases = self.sortedPhases()     
1940                 targetphase = 'none'             
1941                 htmlclass = ''                   
1942                 overlap = 0.0                    
1943                 myphases = []                    
1944                 for phase in phases:             
1945                         pstart = self.dmesg[p    
1946                         pend = self.dmesg[pha    
1947                         # see if the action o    
1948                         o = max(0, min(end, p    
1949                         if o > 0:                
1950                                 myphases.appe    
1951                         # set the target phas    
1952                         if o > overlap:          
1953                                 if overlap >     
1954                                         conti    
1955                                 targetphase =    
1956                                 overlap = o      
1957                 # if no target phase was foun    
1958                 if targetphase == 'none':        
1959                         p0start = self.dmesg[    
1960                         if start <= p0start:     
1961                                 targetphase =    
1962                         else:                    
1963                                 targetphase =    
1964                 if pid == -2:                    
1965                         htmlclass = ' bg'        
1966                 elif pid == -3:                  
1967                         htmlclass = ' ps'        
1968                 if len(myphases) > 1:            
1969                         htmlclass = ' bg'        
1970                         self.phaseOverlap(myp    
1971                 if targetphase in phases:        
1972                         newname = self.newAct    
1973                         return (targetphase,     
1974                 return False                     
1975         def newAction(self, phase, name, pid,    
1976                 # new device callback for a s    
1977                 self.html_device_id += 1         
1978                 devid = '%s%d' % (self.idstr,    
1979                 list = self.dmesg[phase]['lis    
1980                 length = -1.0                    
1981                 if(start >= 0 and end >= 0):     
1982                         length = end - start     
1983                 if pid == -2 or name not in s    
1984                         i = 2                    
1985                         origname = name          
1986                         while(name in list):     
1987                                 name = '%s[%d    
1988                                 i += 1           
1989                 list[name] = {'name': name, '    
1990                         'par': parent, 'lengt    
1991                 if htmlclass:                    
1992                         list[name]['htmlclass    
1993                 if color:                        
1994                         list[name]['color'] =    
1995                 return name                      
1996         def findDevice(self, phase, name):       
1997                 list = self.dmesg[phase]['lis    
1998                 mydev = ''                       
1999                 for devname in sorted(list):     
2000                         if name == devname or    
2001                                 mydev = devna    
2002                 if mydev:                        
2003                         return list[mydev]       
2004                 return False                     
2005         def deviceChildren(self, devname, pha    
2006                 devlist = []                     
2007                 list = self.dmesg[phase]['lis    
2008                 for child in list:               
2009                         if(list[child]['par']    
2010                                 devlist.appen    
2011                 return devlist                   
2012         def maxDeviceNameSize(self, phase):      
2013                 size = 0                         
2014                 for name in self.dmesg[phase]    
2015                         if len(name) > size:     
2016                                 size = len(na    
2017                 return size                      
2018         def printDetails(self):                  
2019                 sysvals.vprint('Timeline Deta    
2020                 sysvals.vprint('          tes    
2021                 sysvals.vprint('kernel suspen    
2022                 tS = tR = False                  
2023                 for phase in self.sortedPhase    
2024                         devlist = self.dmesg[    
2025                         dc, ps, pe = len(devl    
2026                         if not tS and ps >= s    
2027                                 sysvals.vprin    
2028                                 tS = True        
2029                         if not tR and ps >= s    
2030                                 sysvals.vprin    
2031                                 tR = True        
2032                         sysvals.vprint('%20s:    
2033                         if sysvals.devdump:      
2034                                 sysvals.vprin    
2035                                 maxname = '%d    
2036                                 fmt = '%3d) %    
2037                                 c = 1            
2038                                 for name in s    
2039                                         s = d    
2040                                         e = d    
2041                                         sysva    
2042                                         c +=     
2043                                 sysvals.vprin    
2044                 sysvals.vprint('   kernel res    
2045                 sysvals.vprint('            t    
2046         def deviceChildrenAllPhases(self, dev    
2047                 devlist = []                     
2048                 for phase in self.sortedPhase    
2049                         list = self.deviceChi    
2050                         for dev in sorted(lis    
2051                                 if dev not in    
2052                                         devli    
2053                 return devlist                   
2054         def masterTopology(self, name, list,     
2055                 node = DeviceNode(name, depth    
2056                 for cname in list:               
2057                         # avoid recursions       
2058                         if name == cname:        
2059                                 continue         
2060                         clist = self.deviceCh    
2061                         cnode = self.masterTo    
2062                         node.children.append(    
2063                 return node                      
2064         def printTopology(self, node):           
2065                 html = ''                        
2066                 if node.name:                    
2067                         info = ''                
2068                         drv = ''                 
2069                         for phase in self.sor    
2070                                 list = self.d    
2071                                 if node.name     
2072                                         s = l    
2073                                         e = l    
2074                                         if li    
2075                                                  
2076                                         info     
2077                         html += '<li><b>'+nod    
2078                         if info:                 
2079                                 html += '<ul>    
2080                         html += '</li>'          
2081                 if len(node.children) > 0:       
2082                         html += '<ul>'           
2083                         for cnode in node.chi    
2084                                 html += self.    
2085                         html += '</ul>'          
2086                 return html                      
2087         def rootDeviceList(self):                
2088                 # list of devices graphed        
2089                 real = []                        
2090                 for phase in self.sortedPhase    
2091                         list = self.dmesg[pha    
2092                         for dev in sorted(lis    
2093                                 if list[dev][    
2094                                         real.    
2095                 # list of top-most root devic    
2096                 rootlist = []                    
2097                 for phase in self.sortedPhase    
2098                         list = self.dmesg[pha    
2099                         for dev in sorted(lis    
2100                                 pdev = list[d    
2101                                 pid = list[de    
2102                                 if(pid < 0 or    
2103                                         conti    
2104                                 if pdev and p    
2105                                         rootl    
2106                 return rootlist                  
2107         def deviceTopology(self):                
2108                 rootlist = self.rootDeviceLis    
2109                 master = self.masterTopology(    
2110                 return self.printTopology(mas    
2111         def selectTimelineDevices(self, widfm    
2112                 # only select devices that wi    
2113                 self.tdevlist = dict()           
2114                 for phase in self.dmesg:         
2115                         devlist = []             
2116                         list = self.dmesg[pha    
2117                         for dev in list:         
2118                                 length = (lis    
2119                                 width = widfm    
2120                                 if length >=     
2121                                         devli    
2122                         self.tdevlist[phase]     
2123         def addHorizontalDivider(self, devnam    
2124                 phase = 'suspend_prepare'        
2125                 self.newAction(phase, devname    
2126                         self.start, devend, '    
2127                 if phase not in self.tdevlist    
2128                         self.tdevlist[phase]     
2129                 self.tdevlist[phase].append(d    
2130                 d = DevItem(0, phase, self.dm    
2131                 return d                         
2132         def addProcessUsageEvent(self, name,     
2133                 # get the start and end times    
2134                 cpuexec = dict()                 
2135                 tlast = start = end = -1         
2136                 for t in sorted(times):          
2137                         if tlast < 0:            
2138                                 tlast = t        
2139                                 continue         
2140                         if name in self.pstl[    
2141                                 if start < 0:    
2142                                         start    
2143                                 end, key = t,    
2144                                 maxj = (t - t    
2145                                 cpuexec[key]     
2146                         tlast = t                
2147                 if start < 0 or end < 0:         
2148                         return                   
2149                 # add a new action for this p    
2150                 out = self.newActionGlobal(na    
2151                 if out:                          
2152                         phase, devname = out     
2153                         dev = self.dmesg[phas    
2154                         dev['cpuexec'] = cpue    
2155         def createProcessUsageEvents(self):      
2156                 # get an array of process nam    
2157                 proclist = {'sus': dict(), 'r    
2158                 tdata = {'sus': [], 'res': []    
2159                 for t in sorted(self.pstl):      
2160                         dir = 'sus' if t < se    
2161                         for ps in sorted(self    
2162                                 if ps not in     
2163                                         procl    
2164                         tdata[dir].append(t)     
2165                 # process the events for susp    
2166                 if len(proclist['sus']) > 0 o    
2167                         sysvals.vprint('Proce    
2168                 for dir in ['sus', 'res']:       
2169                         for ps in sorted(proc    
2170                                 self.addProce    
2171         def handleEndMarker(self, time, msg='    
2172                 dm = self.dmesg                  
2173                 self.setEnd(time, msg)           
2174                 self.initDevicegroups()          
2175                 # give suspend_prepare an end    
2176                 if 'suspend_prepare' in dm an    
2177                         dm['suspend_prepare']    
2178                 # assume resume machine ends     
2179                 if 'resume_machine' in dm and    
2180                         np = self.nextPhase('    
2181                         if np:                   
2182                                 dm['resume_ma    
2183                 # if kernel resume end not fo    
2184                 if self.tKernRes == 0.0:         
2185                         self.tKernRes = time     
2186                 # if kernel suspend start not    
2187                 if self.tKernSus == 0.0:         
2188                         self.tKernSus = time     
2189                 # set resume complete to end     
2190                 if 'resume_complete' in dm:      
2191                         dm['resume_complete']    
2192         def initcall_debug_call(self, line, q    
2193                 m = re.match(r'.*(\[ *)(?P<t>    
2194                         r'PM: *calling .* @ (    
2195                 if not m:                        
2196                         m = re.match(r'.*(\[     
2197                                 r'calling .*     
2198                 if not m:                        
2199                         m = re.match(r'.*(\[     
2200                                 r'(?P<f>.*)\+     
2201                 if m:                            
2202                         return True if quick     
2203                 return False if quick else ('    
2204         def initcall_debug_return(self, line,    
2205                 m = re.match(r'.*(\[ *)(?P<t>    
2206                         r'.* returned (?P<r>[    
2207                 if not m:                        
2208                         m = re.match(r'.*(\[     
2209                                 r'.* returned    
2210                 if not m:                        
2211                         m = re.match(r'.*(\[     
2212                                 r'(?P<f>.*)\+    
2213                 if m:                            
2214                         return True if quick     
2215                 return False if quick else ('    
2216         def debugPrint(self):                    
2217                 for p in self.sortedPhases():    
2218                         list = self.dmesg[p][    
2219                         for devname in sorted    
2220                                 dev = list[de    
2221                                 if 'ftrace' i    
2222                                         dev['    
2223                                                  
2224 # Class: DevFunction                             
2225 # Description:                                   
2226 #        A container for kprobe function data    
2227 class DevFunction:                               
2228         def __init__(self, name, args, caller    
2229                 self.row = 0                     
2230                 self.count = 1                   
2231                 self.name = name                 
2232                 self.args = args                 
2233                 self.caller = caller             
2234                 self.ret = ret                   
2235                 self.time = start                
2236                 self.length = end - start        
2237                 self.end = end                   
2238                 self.ubiquitous = u              
2239                 self.proc = proc                 
2240                 self.pid = pid                   
2241                 self.color = color               
2242         def title(self):                         
2243                 cnt = ''                         
2244                 if self.count > 1:               
2245                         cnt = '(x%d)' % self.    
2246                 l = '%0.3fms' % (self.length     
2247                 if self.ubiquitous:              
2248                         title = '%s(%s)%s <-     
2249                                 (self.name, s    
2250                 else:                            
2251                         title = '%s(%s) %s%s(    
2252                 return title.replace('"', '')    
2253         def text(self):                          
2254                 if self.count > 1:               
2255                         text = '%s(x%d)' % (s    
2256                 else:                            
2257                         text = self.name         
2258                 return text                      
2259         def repeat(self, tgt):                   
2260                 # is the tgt call just a repe    
2261                 dt = self.time - tgt.end         
2262                 # only combine calls if -all-    
2263                 if tgt.caller == self.caller     
2264                         tgt.name == self.name    
2265                         tgt.proc == self.proc    
2266                         tgt.ret == self.ret a    
2267                         dt <= sysvals.callloo    
2268                         self.length < sysvals    
2269                         return True              
2270                 return False                     
2271                                                  
2272 # Class: FTraceLine                              
2273 # Description:                                   
2274 #        A container for a single line of ftr    
2275 #                callgraph line:                 
2276 #                         call: "  dpm_run_ca    
2277 #                       return: "  }"            
2278 #                         leaf: " dpm_run_cal    
2279 #                trace event:                    
2280 #                        tracing_mark_write:     
2281 #                        suspend_resume: phas    
2282 #                        device_pm_callback:     
2283 class FTraceLine:                                
2284         def __init__(self, t, m='', d=''):       
2285                 self.length = 0.0                
2286                 self.fcall = False               
2287                 self.freturn = False             
2288                 self.fevent = False              
2289                 self.fkprobe = False             
2290                 self.depth = 0                   
2291                 self.name = ''                   
2292                 self.type = ''                   
2293                 self.time = float(t)             
2294                 if not m and not d:              
2295                         return                   
2296                 # is this a trace event          
2297                 if(d == 'traceevent' or re.ma    
2298                         if(d == 'traceevent')    
2299                                 # nop format     
2300                                 msg = m          
2301                         else:                    
2302                                 # function_gr    
2303                                 em = re.match    
2304                                 msg = em.grou    
2305                                                  
2306                         emm = re.match(r'^(?P    
2307                         if(emm):                 
2308                                 self.name = e    
2309                                 self.type = e    
2310                         else:                    
2311                                 self.name = m    
2312                         km = re.match(r'^(?P<    
2313                         if km:                   
2314                                 self.fcall =     
2315                                 self.fkprobe     
2316                                 self.type = k    
2317                                 return           
2318                         km = re.match(r'^(?P<    
2319                         if km:                   
2320                                 self.freturn     
2321                                 self.fkprobe     
2322                                 self.type = k    
2323                                 return           
2324                         self.fevent = True       
2325                         return                   
2326                 # convert the duration to sec    
2327                 if(d):                           
2328                         self.length = float(d    
2329                 # the indentation determines     
2330                 match = re.match(r'^(?P<d> *)    
2331                 if(not match):                   
2332                         return                   
2333                 self.depth = self.getDepth(ma    
2334                 m = match.group('o')             
2335                 # function return                
2336                 if(m[0] == '}'):                 
2337                         self.freturn = True      
2338                         if(len(m) > 1):          
2339                                 # includes co    
2340                                 match = re.ma    
2341                                 if(match):       
2342                                         self.    
2343                 # function call                  
2344                 else:                            
2345                         self.fcall = True        
2346                         # function call with     
2347                         if(m[-1] == '{'):        
2348                                 match = re.ma    
2349                                 if(match):       
2350                                         self.    
2351                         # function call with     
2352                         elif(m[-1] == ';'):      
2353                                 self.freturn     
2354                                 match = re.ma    
2355                                 if(match):       
2356                                         self.    
2357                         # something else (pos    
2358                         else:                    
2359                                 self.name = m    
2360         def isCall(self):                        
2361                 return self.fcall and not sel    
2362         def isReturn(self):                      
2363                 return self.freturn and not s    
2364         def isLeaf(self):                        
2365                 return self.fcall and self.fr    
2366         def getDepth(self, str):                 
2367                 return len(str)/2                
2368         def debugPrint(self, info=''):           
2369                 if self.isLeaf():                
2370                         pprint(' -- %12.6f (d    
2371                                 self.depth, s    
2372                 elif self.freturn:               
2373                         pprint(' -- %12.6f (d    
2374                                 self.depth, s    
2375                 else:                            
2376                         pprint(' -- %12.6f (d    
2377                                 self.depth, s    
2378         def startMarker(self):                   
2379                 # Is this the starting line o    
2380                 if not self.fevent:              
2381                         return False             
2382                 if sysvals.usetracemarkers:      
2383                         if(self.name.startswi    
2384                                 return True      
2385                         return False             
2386                 else:                            
2387                         if(self.type == 'susp    
2388                                 re.match(r'su    
2389                                 return True      
2390                         return False             
2391         def endMarker(self):                     
2392                 # Is this the ending line of     
2393                 if not self.fevent:              
2394                         return False             
2395                 if sysvals.usetracemarkers:      
2396                         if(self.name.startswi    
2397                                 return True      
2398                         return False             
2399                 else:                            
2400                         if(self.type == 'susp    
2401                                 re.match(r'th    
2402                                 return True      
2403                         return False             
2404                                                  
2405 # Class: FTraceCallGraph                         
2406 # Description:                                   
2407 #        A container for the ftrace callgraph    
2408 #        This can be a dpm_run_callback, dpm_    
2409 #        Each instance is tied to a single de    
2410 #        comprised of an ordered list of FTra    
2411 class FTraceCallGraph:                           
2412         vfname = 'missing_function_name'         
2413         def __init__(self, pid, sv):             
2414                 self.id = ''                     
2415                 self.invalid = False             
2416                 self.name = ''                   
2417                 self.partial = False             
2418                 self.ignore = False              
2419                 self.start = -1.0                
2420                 self.end = -1.0                  
2421                 self.list = []                   
2422                 self.depth = 0                   
2423                 self.pid = pid                   
2424                 self.sv = sv                     
2425         def addLine(self, line):                 
2426                 # if this is already invalid,    
2427                 if(self.invalid):                
2428                         if(line.depth == 0 an    
2429                                 return 1         
2430                         return 0                 
2431                 # invalidate on bad depth        
2432                 if(self.depth < 0):              
2433                         self.invalidate(line)    
2434                         return 0                 
2435                 # ignore data til we return t    
2436                 if self.ignore:                  
2437                         if line.depth > self.    
2438                                 return 0         
2439                         else:                    
2440                                 self.list[-1]    
2441                                 self.list[-1]    
2442                                 self.ignore =    
2443                                 # if this is     
2444                                 if line.depth    
2445                                         if li    
2446                                                  
2447                                                  
2448                                         retur    
2449                 # compare current depth with     
2450                 prelinedep = line.depth          
2451                 if line.isReturn():              
2452                         prelinedep += 1          
2453                 last = 0                         
2454                 lasttime = line.time             
2455                 if len(self.list) > 0:           
2456                         last = self.list[-1]     
2457                         lasttime = last.time     
2458                         if last.isLeaf():        
2459                                 lasttime += l    
2460                 # handle low misalignments by    
2461                 mismatch = prelinedep - self.    
2462                 warning = self.sv.verbose and    
2463                 info = []                        
2464                 if mismatch < 0:                 
2465                         idx = 0                  
2466                         # add return calls to    
2467                         while prelinedep < se    
2468                                 self.depth -=    
2469                                 if idx == 0 a    
2470                                         # spe    
2471                                         last.    
2472                                         last.    
2473                                         last.    
2474                                         if wa    
2475                                                  
2476                                 else:            
2477                                         vline    
2478                                         vline    
2479                                         vline    
2480                                         vline    
2481                                         self.    
2482                                         if wa    
2483                                                  
2484                                                  
2485                                                  
2486                                 idx += 1         
2487                         if warning:              
2488                                 info.append((    
2489                 # handle high misalignments b    
2490                 elif mismatch > 0:               
2491                         idx = 0                  
2492                         if warning:              
2493                                 info.append((    
2494                         # add calls to get th    
2495                         while prelinedep > se    
2496                                 if idx == 0 a    
2497                                         # spe    
2498                                         line.    
2499                                         preli    
2500                                         if wa    
2501                                                  
2502                                 else:            
2503                                         vline    
2504                                         vline    
2505                                         vline    
2506                                         vline    
2507                                         self.    
2508                                         self.    
2509                                         if no    
2510                                                  
2511                                         if wa    
2512                                                  
2513                                 idx += 1         
2514                         if warning and ('[mak    
2515                                 info.append((    
2516                 if warning:                      
2517                         pprint('WARNING: ftra    
2518                         for i in info:           
2519                                 t, obj = i       
2520                                 if obj:          
2521                                         obj.d    
2522                 # process the call and set th    
2523                 skipadd = False                  
2524                 md = self.sv.max_graph_depth     
2525                 if line.isCall():                
2526                         # ignore blacklisted/    
2527                         if (md and self.depth    
2528                                 self.ignore =    
2529                         else:                    
2530                                 self.depth +=    
2531                 elif line.isReturn():            
2532                         self.depth -= 1          
2533                         # remove blacklisted/    
2534                         if (last and last.isC    
2535                                 (md and last     
2536                                 (line.name in    
2537                                 while len(sel    
2538                                         self.    
2539                                 if len(self.l    
2540                                         self.    
2541                                         retur    
2542                                 self.list[-1]    
2543                                 self.list[-1]    
2544                                 self.list[-1]    
2545                                 skipadd = Tru    
2546                 if len(self.list) < 1:           
2547                         self.start = line.tim    
2548                 # check for a mismatch that r    
2549                 res = 1                          
2550                 if mismatch < 0 and self.list    
2551                         line = self.list[-1]     
2552                         skipadd = True           
2553                         res = -1                 
2554                 if not skipadd:                  
2555                         self.list.append(line    
2556                 if(line.depth == 0 and line.f    
2557                         if(self.start < 0):      
2558                                 self.start =     
2559                         self.end = line.time     
2560                         if line.fcall:           
2561                                 self.end += l    
2562                         if self.list[0].name     
2563                                 self.invalid     
2564                         if res == -1:            
2565                                 self.partial     
2566                         return res               
2567                 return 0                         
2568         def invalidate(self, line):              
2569                 if(len(self.list) > 0):          
2570                         first = self.list[0]     
2571                         self.list = []           
2572                         self.list.append(firs    
2573                 self.invalid = True              
2574                 id = 'task %s' % (self.pid)      
2575                 window = '(%f - %f)' % (self.    
2576                 if(self.depth < 0):              
2577                         pprint('Data misalign    
2578                                 ' (buffer ove    
2579                 else:                            
2580                         pprint('Too much data    
2581                                 ' '+window+',    
2582         def slice(self, dev):                    
2583                 minicg = FTraceCallGraph(dev[    
2584                 minicg.name = self.name          
2585                 mydepth = -1                     
2586                 good = False                     
2587                 for l in self.list:              
2588                         if(l.time < dev['star    
2589                                 continue         
2590                         if mydepth < 0:          
2591                                 if l.name ==     
2592                                         mydep    
2593                                 continue         
2594                         elif l.depth == mydep    
2595                                 good = True      
2596                                 break            
2597                         l.depth -= mydepth       
2598                         minicg.addLine(l)        
2599                 if not good or len(minicg.lis    
2600                         return 0                 
2601                 return minicg                    
2602         def repair(self, enddepth):              
2603                 # bring the depth back to 0 w    
2604                 fixed = False                    
2605                 last = self.list[-1]             
2606                 for i in reversed(range(endde    
2607                         t = FTraceLine(last.t    
2608                         t.depth = i              
2609                         t.freturn = True         
2610                         fixed = self.addLine(    
2611                         if fixed != 0:           
2612                                 self.end = la    
2613                                 return True      
2614                 return False                     
2615         def postProcess(self):                   
2616                 if len(self.list) > 0:           
2617                         self.name = self.list    
2618                 stack = dict()                   
2619                 cnt = 0                          
2620                 last = 0                         
2621                 for l in self.list:              
2622                         # ftrace bug: reporte    
2623                         # check each leaf and    
2624                         if last and last.isLe    
2625                                 if last.lengt    
2626                                         last.    
2627                         if l.isCall():           
2628                                 stack[l.depth    
2629                                 cnt += 1         
2630                         elif l.isReturn():       
2631                                 if(l.depth no    
2632                                         if se    
2633                                                  
2634                                                  
2635                                         retur    
2636                                 # calculate c    
2637                                 cl = stack[l.    
2638                                 cl.length = l    
2639                                 if cl.name ==    
2640                                         cl.na    
2641                                 stack.pop(l.d    
2642                                 l.length = 0     
2643                                 cnt -= 1         
2644                         last = l                 
2645                 if(cnt == 0):                    
2646                         # trace caught the wh    
2647                         return True              
2648                 elif(cnt < 0):                   
2649                         if self.sv.verbose:      
2650                                 pprint('Post     
2651                         return False             
2652                 # trace ended before call tre    
2653                 return self.repair(cnt)          
2654         def deviceMatch(self, pid, data):        
2655                 found = ''                       
2656                 # add the callgraph data to t    
2657                 borderphase = {                  
2658                         'dpm_prepare': 'suspe    
2659                         'dpm_complete': 'resu    
2660                 }                                
2661                 if(self.name in borderphase):    
2662                         p = borderphase[self.    
2663                         list = data.dmesg[p][    
2664                         for devname in list:     
2665                                 dev = list[de    
2666                                 if(pid == dev    
2667                                         self.    
2668                                         self.    
2669                                         cg =     
2670                                         if cg    
2671                                                  
2672                                         found    
2673                         return found             
2674                 for p in data.sortedPhases():    
2675                         if(data.dmesg[p]['sta    
2676                                 self.start <=    
2677                                 list = data.d    
2678                                 for devname i    
2679                                         dev =    
2680                                         if(pi    
2681                                                  
2682                                                  
2683                                                  
2684                                                  
2685                                                  
2686                                 break            
2687                 return found                     
2688         def newActionFromFunction(self, data)    
2689                 name = self.name                 
2690                 if name in ['dpm_run_callback    
2691                         return                   
2692                 fs = self.start                  
2693                 fe = self.end                    
2694                 if fs < data.start or fe > da    
2695                         return                   
2696                 phase = ''                       
2697                 for p in data.sortedPhases():    
2698                         if(data.dmesg[p]['sta    
2699                                 self.start <     
2700                                 phase = p        
2701                                 break            
2702                 if not phase:                    
2703                         return                   
2704                 out = data.newActionGlobal(na    
2705                 if out:                          
2706                         phase, myname = out      
2707                         data.dmesg[phase]['li    
2708         def debugPrint(self, info=''):           
2709                 pprint('%s pid=%d [%f - %f] %    
2710                         (self.name, self.pid,    
2711                         (self.end - self.star    
2712                 for l in self.list:              
2713                         if l.isLeaf():           
2714                                 pprint('%f (%    
2715                                         l.dep    
2716                         elif l.freturn:          
2717                                 pprint('%f (%    
2718                                         l.dep    
2719                         else:                    
2720                                 pprint('%f (%    
2721                                         l.dep    
2722                 pprint(' ')                      
2723                                                  
2724 class DevItem:                                   
2725         def __init__(self, test, phase, dev):    
2726                 self.test = test                 
2727                 self.phase = phase               
2728                 self.dev = dev                   
2729         def isa(self, cls):                      
2730                 if 'htmlclass' in self.dev an    
2731                         return True              
2732                 return False                     
2733                                                  
2734 # Class: Timeline                                
2735 # Description:                                   
2736 #        A container for a device timeline wh    
2737 #        all the html properties to display i    
2738 class Timeline:                                  
2739         html_tblock = '<div id="block{0}" cla    
2740         html_device = '<div id="{0}" title="{    
2741         html_phase = '<div class="phase" styl    
2742         html_phaselet = '<div id="{0}" class=    
2743         html_legend = '<div id="p{3}" class="    
2744         def __init__(self, rowheight, scalehe    
2745                 self.html = ''                   
2746                 self.height = 0  # total time    
2747                 self.scaleH = scaleheight # t    
2748                 self.rowH = rowheight     # d    
2749                 self.bodyH = 0   # body heigh    
2750                 self.rows = 0    # total time    
2751                 self.rowlines = dict()           
2752                 self.rowheight = dict()          
2753         def createHeader(self, sv, stamp):       
2754                 if(not stamp['time']):           
2755                         return                   
2756                 self.html += '<div class="ver    
2757                         % (sv.title, sv.versi    
2758                 if sv.logmsg and sv.testlog:     
2759                         self.html += '<button    
2760                 if sv.dmesglog:                  
2761                         self.html += '<button    
2762                 if sv.ftracelog:                 
2763                         self.html += '<button    
2764                 headline_stamp = '<div class=    
2765                 self.html += headline_stamp.f    
2766                         stamp['mode'], stamp[    
2767                 if 'man' in stamp and 'plat'     
2768                         stamp['man'] and stam    
2769                         headline_sysinfo = '<    
2770                         self.html += headline    
2771                                                  
2772         # Function: getDeviceRows                
2773         # Description:                           
2774         #    determine how may rows the devic    
2775         # Arguments:                             
2776         #        rawlist: the list of devices    
2777         # Output:                                
2778         #        The total number of rows nee    
2779         def getDeviceRows(self, rawlist):        
2780                 # clear all rows and set them    
2781                 sortdict = dict()                
2782                 for item in rawlist:             
2783                         item.row = -1            
2784                         sortdict[item] = item    
2785                 sortlist = sorted(sortdict, k    
2786                 remaining = len(sortlist)        
2787                 rowdata = dict()                 
2788                 row = 1                          
2789                 # try to pack each row with a    
2790                 while(remaining > 0):            
2791                         if(row not in rowdata    
2792                                 rowdata[row]     
2793                         for i in sortlist:       
2794                                 if(i.row >= 0    
2795                                         conti    
2796                                 s = i.time       
2797                                 e = i.time +     
2798                                 valid = True     
2799                                 for ritem in     
2800                                         rs =     
2801                                         re =     
2802                                         if(no    
2803                                                  
2804                                                  
2805                                                  
2806                                 if(valid):       
2807                                         rowda    
2808                                         i.row    
2809                                         remai    
2810                         row += 1                 
2811                 return row                       
2812         # Function: getPhaseRows                 
2813         # Description:                           
2814         #        Organize the timeline entrie    
2815         #        number of rows possible, wit    
2816         # Arguments:                             
2817         #        devlist: the list of devices    
2818         # Output:                                
2819         #        The total number of rows nee    
2820         def getPhaseRows(self, devlist, row=0    
2821                 # clear all rows and set them    
2822                 remaining = len(devlist)         
2823                 rowdata = dict()                 
2824                 sortdict = dict()                
2825                 myphases = []                    
2826                 # initialize all device rows     
2827                 for item in devlist:             
2828                         dev = item.dev           
2829                         tp = (item.test, item    
2830                         if tp not in myphases    
2831                                 myphases.appe    
2832                         dev['row'] = -1          
2833                         if sortby == 'start':    
2834                                 # sort by sta    
2835                                 sortdict[item    
2836                         else:                    
2837                                 # sort by len    
2838                                 sortdict[item    
2839                         if 'src' in dev:         
2840                                 dev['devrows'    
2841                 # sort the devlist by length     
2842                 sortlist = sorted(sortdict, k    
2843                 orderedlist = []                 
2844                 for item in sortlist:            
2845                         if item.dev['pid'] ==    
2846                                 orderedlist.a    
2847                 for item in sortlist:            
2848                         if item not in ordere    
2849                                 orderedlist.a    
2850                 # try to pack each row with a    
2851                 while(remaining > 0):            
2852                         rowheight = 1            
2853                         if(row not in rowdata    
2854                                 rowdata[row]     
2855                         for item in orderedli    
2856                                 dev = item.de    
2857                                 if(dev['row']    
2858                                         s = d    
2859                                         e = d    
2860                                         valid    
2861                                         for r    
2862                                                  
2863                                                  
2864                                                  
2865                                                  
2866                                                  
2867                                                  
2868                                         if(va    
2869                                                  
2870                                                  
2871                                                  
2872                                                  
2873                                                  
2874                         for t, p in myphases:    
2875                                 if t not in s    
2876                                         self.    
2877                                         self.    
2878                                 if p not in s    
2879                                         self.    
2880                                         self.    
2881                                 rh = self.row    
2882                                 # section hea    
2883                                 if len(rowdat    
2884                                         'html    
2885                                         'sec'    
2886                                         rh =     
2887                                 self.rowlines    
2888                                 self.rowheigh    
2889                         row += 1                 
2890                 if(row > self.rows):             
2891                         self.rows = int(row)     
2892                 return row                       
2893         def phaseRowHeight(self, test, phase,    
2894                 return self.rowheight[test][p    
2895         def phaseRowTop(self, test, phase, ro    
2896                 top = 0                          
2897                 for i in sorted(self.rowheigh    
2898                         if i >= row:             
2899                                 break            
2900                         top += self.rowheight    
2901                 return top                       
2902         def calcTotalRows(self):                 
2903                 # Calculate the heights and o    
2904                 maxrows = 0                      
2905                 standardphases = []              
2906                 for t in self.rowlines:          
2907                         for p in self.rowline    
2908                                 total = 0        
2909                                 for i in sort    
2910                                         total    
2911                                 if total > ma    
2912                                         maxro    
2913                                 if total == l    
2914                                         stand    
2915                 self.height = self.scaleH + (    
2916                 self.bodyH = self.height - se    
2917                 # if there is 1 line per row,    
2918                 for t, p in standardphases:      
2919                         for i in sorted(self.    
2920                                 self.rowheigh    
2921         def createZoomBox(self, mode='command    
2922                 # Create bounding box, add bu    
2923                 html_zoombox = '<center><butt    
2924                 html_timeline = '<div id="dme    
2925                 html_devlist1 = '<button id="    
2926                 html_devlist2 = '<button id="    
2927                 if mode != 'command':            
2928                         if testcount > 1:        
2929                                 self.html +=     
2930                                 self.html +=     
2931                         else:                    
2932                                 self.html +=     
2933                 self.html += html_zoombox        
2934                 self.html += html_timeline.fo    
2935         # Function: createTimeScale              
2936         # Description:                           
2937         #        Create the timescale for a t    
2938         # Arguments:                             
2939         #        m0: start time (mode begin)     
2940         #        mMax: end time (mode end)       
2941         #        tTotal: total timeline time     
2942         #        mode: suspend or resume         
2943         # Output:                                
2944         #        The html code needed to disp    
2945         def createTimeScale(self, m0, mMax, t    
2946                 timescale = '<div class="t" s    
2947                 rline = '<div class="t" style    
2948                 output = '<div class="timesca    
2949                 # set scale for timeline         
2950                 mTotal = mMax - m0               
2951                 tS = 0.1                         
2952                 if(tTotal <= 0):                 
2953                         return output+'</div>    
2954                 if(tTotal > 4):                  
2955                         tS = 1                   
2956                 divTotal = int(mTotal/tS) + 1    
2957                 divEdge = (mTotal - tS*(divTo    
2958                 for i in range(divTotal):        
2959                         htmlline = ''            
2960                         if(mode == 'suspend')    
2961                                 pos = '%0.3f'    
2962                                 val = '%0.fms    
2963                                 if(i == divTo    
2964                                         val =    
2965                                 htmlline = ti    
2966                         else:                    
2967                                 pos = '%0.3f'    
2968                                 val = '%0.fms    
2969                                 htmlline = ti    
2970                                 if(i == 0):      
2971                                         htmll    
2972                         output += htmlline       
2973                 self.html += output+'</div>\n    
2974                                                  
2975 # Class: TestProps                               
2976 # Description:                                   
2977 #        A list of values describing the prop    
2978 class TestProps:                                 
2979         stampfmt = r'# [a-z]*-(?P<m>[0-9]{2})    
2980                                 r'(?P<H>[0-9]    
2981                                 r' (?P<host>.    
2982         wififmt    = r'^# wifi *(?P<d>\S*) *(    
2983         tstatfmt   = r'^# turbostat (?P<t>\S*    
2984         testerrfmt = r'^# enter_sleep_error (    
2985         sysinfofmt = r'^# sysinfo .*'            
2986         cmdlinefmt = r'^# command \| (?P<cmd>    
2987         kparamsfmt = r'^# kparams \| (?P<kp>.    
2988         devpropfmt = r'# Device Properties: .    
2989         pinfofmt   = r'# platform-(?P<val>[a-    
2990         tracertypefmt = r'# tracer: (?P<t>.*)    
2991         firmwarefmt = r'# fwsuspend (?P<s>[0-    
2992         procexecfmt = r'ps - (?P<ps>.*)$'        
2993         procmultifmt = r'@(?P<n>[0-9]*)\|(?P<    
2994         ftrace_line_fmt_fg = \                   
2995                 r'^ *(?P<time>[0-9\.]*) *\| *    
2996                 r' *(?P<proc>.*)-(?P<pid>[0-9    
2997                 r'[ +!#\*@$]*(?P<dur>[0-9\.]*    
2998         ftrace_line_fmt_nop = \                  
2999                 r' *(?P<proc>.*)-(?P<pid>[0-9    
3000                 r'(?P<flags>\S*) *(?P<time>[0    
3001                 r'(?P<msg>.*)'                   
3002         machinesuspend = r'machine_suspend\[.    
3003         multiproclist = dict()                   
3004         multiproctime = 0.0                      
3005         multiproccnt = 0                         
3006         def __init__(self):                      
3007                 self.stamp = ''                  
3008                 self.sysinfo = ''                
3009                 self.cmdline = ''                
3010                 self.testerror = []              
3011                 self.turbostat = []              
3012                 self.wifi = []                   
3013                 self.fwdata = []                 
3014                 self.ftrace_line_fmt = self.f    
3015                 self.cgformat = False            
3016                 self.data = 0                    
3017                 self.ktemp = dict()              
3018         def setTracerType(self, tracer):         
3019                 if(tracer == 'function_graph'    
3020                         self.cgformat = True     
3021                         self.ftrace_line_fmt     
3022                 elif(tracer == 'nop'):           
3023                         self.ftrace_line_fmt     
3024                 else:                            
3025                         doError('Invalid trac    
3026         def stampInfo(self, line, sv):           
3027                 if re.match(self.stampfmt, li    
3028                         self.stamp = line        
3029                         return True              
3030                 elif re.match(self.sysinfofmt    
3031                         self.sysinfo = line      
3032                         return True              
3033                 elif re.match(self.tstatfmt,     
3034                         self.turbostat.append    
3035                         return True              
3036                 elif re.match(self.wififmt, l    
3037                         self.wifi.append(line    
3038                         return True              
3039                 elif re.match(self.testerrfmt    
3040                         self.testerror.append    
3041                         return True              
3042                 elif re.match(self.firmwarefm    
3043                         self.fwdata.append(li    
3044                         return True              
3045                 elif(re.match(self.devpropfmt    
3046                         self.parseDevprops(li    
3047                         return True              
3048                 elif(re.match(self.pinfofmt,     
3049                         self.parsePlatformInf    
3050                         return True              
3051                 m = re.match(self.cmdlinefmt,    
3052                 if m:                            
3053                         self.cmdline = m.grou    
3054                         return True              
3055                 m = re.match(self.tracertypef    
3056                 if(m):                           
3057                         self.setTracerType(m.    
3058                         return True              
3059                 return False                     
3060         def parseStamp(self, data, sv):          
3061                 # global test data               
3062                 m = re.match(self.stampfmt, s    
3063                 if not self.stamp or not m:      
3064                         doError('data does no    
3065                 data.stamp = {'time': '', 'ho    
3066                 dt = datetime(int(m.group('y'    
3067                         int(m.group('d')), in    
3068                         int(m.group('S')))       
3069                 data.stamp['time'] = dt.strft    
3070                 data.stamp['host'] = m.group(    
3071                 data.stamp['mode'] = m.group(    
3072                 data.stamp['kernel'] = m.grou    
3073                 if re.match(self.sysinfofmt,     
3074                         for f in self.sysinfo    
3075                                 if '#' in f:     
3076                                         conti    
3077                                 tmp = f.strip    
3078                                 key = tmp[0]     
3079                                 val = tmp[1]     
3080                                 data.stamp[ke    
3081                 sv.hostname = data.stamp['hos    
3082                 sv.suspendmode = data.stamp['    
3083                 if sv.suspendmode == 'freeze'    
3084                         self.machinesuspend =    
3085                 else:                            
3086                         self.machinesuspend =    
3087                 if sv.suspendmode == 'command    
3088                         modes = ['on', 'freez    
3089                         fp = sv.openlog(sv.ft    
3090                         for line in fp:          
3091                                 m = re.match(    
3092                                 if m and m.gr    
3093                                         sv.su    
3094                                         data.    
3095                                         break    
3096                         fp.close()               
3097                 sv.cmdline = self.cmdline        
3098                 if not sv.stamp:                 
3099                         sv.stamp = data.stamp    
3100                 # firmware data                  
3101                 if sv.suspendmode == 'mem' an    
3102                         m = re.match(self.fir    
3103                         if m:                    
3104                                 data.fwSuspen    
3105                                 if(data.fwSus    
3106                                         data.    
3107                 # turbostat data                 
3108                 if len(self.turbostat) > data    
3109                         m = re.match(self.tst    
3110                         if m:                    
3111                                 data.turbosta    
3112                 # wifi data                      
3113                 if len(self.wifi) > data.test    
3114                         m = re.match(self.wif    
3115                         if m:                    
3116                                 data.wifi = {    
3117                                         'time    
3118                                 data.stamp['w    
3119                 # sleep mode enter errors        
3120                 if len(self.testerror) > data    
3121                         m = re.match(self.tes    
3122                         if m:                    
3123                                 data.enterfai    
3124         def devprops(self, data):                
3125                 props = dict()                   
3126                 devlist = data.split(';')        
3127                 for dev in devlist:              
3128                         f = dev.split(',')       
3129                         if len(f) < 3:           
3130                                 continue         
3131                         dev = f[0]               
3132                         props[dev] = DevProps    
3133                         props[dev].altname =     
3134                         if int(f[2]):            
3135                                 props[dev].is    
3136                         else:                    
3137                                 props[dev].is    
3138                 return props                     
3139         def parseDevprops(self, line, sv):       
3140                 idx = line.index(': ') + 2       
3141                 if idx >= len(line):             
3142                         return                   
3143                 props = self.devprops(line[id    
3144                 if sv.suspendmode == 'command    
3145                         sv.testcommand = prop    
3146                 sv.devprops = props              
3147         def parsePlatformInfo(self, line, sv)    
3148                 m = re.match(self.pinfofmt, l    
3149                 if not m:                        
3150                         return                   
3151                 name, info = m.group('val'),     
3152                 if name == 'devinfo':            
3153                         sv.devprops = self.de    
3154                         return                   
3155                 elif name == 'testcmd':          
3156                         sv.testcommand = info    
3157                         return                   
3158                 field = info.split('|')          
3159                 if len(field) < 2:               
3160                         return                   
3161                 cmdline = field[0].strip()       
3162                 output = sv.b64unzip(field[1]    
3163                 sv.platinfo.append([name, cmd    
3164                                                  
3165 # Class: TestRun                                 
3166 # Description:                                   
3167 #        A container for a suspend/resume tes    
3168 #        there could be more than one, and th    
3169 class TestRun:                                   
3170         def __init__(self, dataobj):             
3171                 self.data = dataobj              
3172                 self.ftemp = dict()              
3173                 self.ttemp = dict()              
3174                                                  
3175 class ProcessMonitor:                            
3176         maxchars = 512                           
3177         def __init__(self):                      
3178                 self.proclist = dict()           
3179                 self.running = False             
3180         def procstat(self):                      
3181                 c = ['cat /proc/[1-9]*/stat 2    
3182                 process = Popen(c, shell=True    
3183                 running = dict()                 
3184                 for line in process.stdout:      
3185                         data = ascii(line).sp    
3186                         pid = data[0]            
3187                         name = re.sub('[()]',    
3188                         user = int(data[13])     
3189                         kern = int(data[14])     
3190                         kjiff = ujiff = 0        
3191                         if pid not in self.pr    
3192                                 self.proclist    
3193                         else:                    
3194                                 val = self.pr    
3195                                 ujiff = user     
3196                                 kjiff = kern     
3197                                 val['user'] =    
3198                                 val['kern'] =    
3199                         if ujiff > 0 or kjiff    
3200                                 running[pid]     
3201                 process.wait()                   
3202                 out = ['']                       
3203                 for pid in running:              
3204                         jiffies = running[pid    
3205                         val = self.proclist[p    
3206                         if len(out[-1]) > sel    
3207                                 out.append(''    
3208                         elif len(out[-1]) > 0    
3209                                 out[-1] += ',    
3210                         out[-1] += '%s-%s %d'    
3211                 if len(out) > 1:                 
3212                         for line in out:         
3213                                 sysvals.fsetV    
3214                 else:                            
3215                         sysvals.fsetVal('ps -    
3216         def processMonitor(self, tid):           
3217                 while self.running:              
3218                         self.procstat()          
3219         def start(self):                         
3220                 self.thread = Thread(target=s    
3221                 self.running = True              
3222                 self.thread.start()              
3223         def stop(self):                          
3224                 self.running = False             
3225                                                  
3226 # ----------------- FUNCTIONS ---------------    
3227                                                  
3228 # Function: doesTraceLogHaveTraceEvents          
3229 # Description:                                   
3230 #        Quickly determine if the ftrace log     
3231 #        markers, and/or kprobes required for    
3232 def doesTraceLogHaveTraceEvents():               
3233         kpcheck = ['_cal: (', '_ret: (']         
3234         techeck = ['suspend_resume', 'device_    
3235         tmcheck = ['SUSPEND START', 'RESUME C    
3236         sysvals.usekprobes = False               
3237         fp = sysvals.openlog(sysvals.ftracefi    
3238         for line in fp:                          
3239                 # check for kprobes              
3240                 if not sysvals.usekprobes:       
3241                         for i in kpcheck:        
3242                                 if i in line:    
3243                                         sysva    
3244                 # check for all necessary tra    
3245                 check = techeck[:]               
3246                 for i in techeck:                
3247                         if i in line:            
3248                                 check.remove(    
3249                 techeck = check                  
3250                 # check for all necessary tra    
3251                 check = tmcheck[:]               
3252                 for i in tmcheck:                
3253                         if i in line:            
3254                                 check.remove(    
3255                 tmcheck = check                  
3256         fp.close()                               
3257         sysvals.usetraceevents = True if len(    
3258         sysvals.usetracemarkers = True if len    
3259                                                  
3260 # Function: appendIncompleteTraceLog             
3261 # Description:                                   
3262 #        Adds callgraph data which lacks trac    
3263 #        for timelines generated from 3.15 or    
3264 # Arguments:                                     
3265 #        testruns: the array of Data objects     
3266 def appendIncompleteTraceLog(testruns):          
3267         # create TestRun vessels for ftrace p    
3268         testcnt = len(testruns)                  
3269         testidx = 0                              
3270         testrun = []                             
3271         for data in testruns:                    
3272                 testrun.append(TestRun(data))    
3273                                                  
3274         # extract the callgraph and traceeven    
3275         sysvals.vprint('Analyzing the ftrace     
3276                 os.path.basename(sysvals.ftra    
3277         tp = TestProps()                         
3278         tf = sysvals.openlog(sysvals.ftracefi    
3279         data = 0                                 
3280         for line in tf:                          
3281                 # remove any latent carriage     
3282                 line = line.replace('\r\n', '    
3283                 if tp.stampInfo(line, sysvals    
3284                         continue                 
3285                 # parse only valid lines, if     
3286                 m = re.match(tp.ftrace_line_f    
3287                 if(not m):                       
3288                         continue                 
3289                 # gather the basic message da    
3290                 m_time = m.group('time')         
3291                 m_pid = m.group('pid')           
3292                 m_msg = m.group('msg')           
3293                 if(tp.cgformat):                 
3294                         m_param3 = m.group('d    
3295                 else:                            
3296                         m_param3 = 'traceeven    
3297                 if(m_time and m_pid and m_msg    
3298                         t = FTraceLine(m_time    
3299                         pid = int(m_pid)         
3300                 else:                            
3301                         continue                 
3302                 # the line should be a call,     
3303                 if(not t.fcall and not t.fret    
3304                         continue                 
3305                 # look for the suspend start     
3306                 if(t.startMarker()):             
3307                         data = testrun[testid    
3308                         tp.parseStamp(data, s    
3309                         data.setStart(t.time,    
3310                         continue                 
3311                 if(not data):                    
3312                         continue                 
3313                 # find the end of resume         
3314                 if(t.endMarker()):               
3315                         data.setEnd(t.time, t    
3316                         testidx += 1             
3317                         if(testidx >= testcnt    
3318                                 break            
3319                         continue                 
3320                 # trace event processing         
3321                 if(t.fevent):                    
3322                         continue                 
3323                 # call/return processing         
3324                 elif sysvals.usecallgraph:       
3325                         # create a callgraph     
3326                         if(pid not in testrun    
3327                                 testrun[testi    
3328                                 testrun[testi    
3329                         # when the call is fi    
3330                         cg = testrun[testidx]    
3331                         res = cg.addLine(t)      
3332                         if(res != 0):            
3333                                 testrun[testi    
3334                         if(res == -1):           
3335                                 testrun[testi    
3336         tf.close()                               
3337                                                  
3338         for test in testrun:                     
3339                 # add the callgraph data to t    
3340                 for pid in test.ftemp:           
3341                         for cg in test.ftemp[    
3342                                 if len(cg.lis    
3343                                         conti    
3344                                 if(not cg.pos    
3345                                         id =     
3346                                         sysva    
3347                                                  
3348                                         conti    
3349                                 callstart = c    
3350                                 callend = cg.    
3351                                 for p in test    
3352                                         if(te    
3353                                                  
3354                                                  
3355                                                  
3356                                                  
3357                                                  
3358                                                  
3359                                                  
3360                                                  
3361                                                  
3362                                                  
3363 # Function: loadTraceLog                         
3364 # Description:                                   
3365 #        load the ftrace file into memory and    
3366 # Output:                                        
3367 #        TestProps instance and an array of l    
3368 def loadTraceLog():                              
3369         tp, data, lines, trace = TestProps(),    
3370         tf = sysvals.openlog(sysvals.ftracefi    
3371         for line in tf:                          
3372                 # remove any latent carriage     
3373                 line = line.replace('\r\n', '    
3374                 if tp.stampInfo(line, sysvals    
3375                         continue                 
3376                 # ignore all other commented     
3377                 if line[0] == '#':               
3378                         continue                 
3379                 # ftrace line: parse only val    
3380                 m = re.match(tp.ftrace_line_f    
3381                 if(not m):                       
3382                         continue                 
3383                 dur = m.group('dur') if tp.cg    
3384                 info = (m.group('time'), m.gr    
3385                         m.group('msg'), dur)     
3386                 # group the data by timestamp    
3387                 t = float(info[0])               
3388                 if t in data:                    
3389                         data[t].append(info)     
3390                 else:                            
3391                         data[t] = [info]         
3392                 # we only care about trace ev    
3393                 if (info[3].startswith('suspe    
3394                         info[3].startswith('t    
3395                                 trace.append(    
3396         tf.close()                               
3397         for t in sorted(data):                   
3398                 first, last, blk = [], [], da    
3399                 if len(blk) > 1 and t in trac    
3400                         # move certain lines     
3401                         for i in range(len(bl    
3402                                 if 'SUSPEND S    
3403                                         first    
3404                                 elif re.match    
3405                                         last.    
3406                                 elif re.match    
3407                                         first    
3408                                 elif 'RESUME     
3409                                         last.    
3410                         if len(first) == 1 an    
3411                                 blk.insert(0,    
3412                         elif len(last) == 1 a    
3413                                 blk.append(bl    
3414                 for info in blk:                 
3415                         lines.append(info)       
3416         return (tp, lines)                       
3417                                                  
3418 # Function: parseTraceLog                        
3419 # Description:                                   
3420 #        Analyze an ftrace log output file ge    
3421 #        the execution phase. Used when the f    
3422 #        and includes the suspend_resume and     
3423 #        The ftrace filename is taken from sy    
3424 # Output:                                        
3425 #        An array of Data objects                
3426 def parseTraceLog(live=False):                   
3427         sysvals.vprint('Analyzing the ftrace     
3428                 os.path.basename(sysvals.ftra    
3429         if(os.path.exists(sysvals.ftracefile)    
3430                 doError('%s does not exist' %    
3431         if not live:                             
3432                 sysvals.setupAllKprobes()        
3433         ksuscalls = ['ksys_sync', 'pm_prepare    
3434         krescalls = ['pm_restore_console']       
3435         tracewatch = ['irq_wakeup']              
3436         if sysvals.usekprobes:                   
3437                 tracewatch += ['sync_filesyst    
3438                         'syscore_resume', 're    
3439                         'CPU_OFF', 'acpi_susp    
3440                                                  
3441         # extract the callgraph and traceeven    
3442         s2idle_enter = hwsus = False             
3443         testruns, testdata = [], []              
3444         testrun, data, limbo = 0, 0, True        
3445         phase = 'suspend_prepare'                
3446         tp, tf = loadTraceLog()                  
3447         for m_time, m_proc, m_pid, m_msg, m_p    
3448                 # gather the basic message da    
3449                 if(m_time and m_pid and m_msg    
3450                         t = FTraceLine(m_time    
3451                         pid = int(m_pid)         
3452                 else:                            
3453                         continue                 
3454                 # the line should be a call,     
3455                 if(not t.fcall and not t.fret    
3456                         continue                 
3457                 # find the start of suspend      
3458                 if(t.startMarker()):             
3459                         data, limbo = Data(le    
3460                         testdata.append(data)    
3461                         testrun = TestRun(dat    
3462                         testruns.append(testr    
3463                         tp.parseStamp(data, s    
3464                         data.setStart(t.time,    
3465                         data.first_suspend_pr    
3466                         phase = data.setPhase    
3467                         continue                 
3468                 if(not data or limbo):           
3469                         continue                 
3470                 # process cpu exec line          
3471                 if t.type == 'tracing_mark_wr    
3472                         if t.name == 'CMD COM    
3473                                 data.tKernRes    
3474                         m = re.match(tp.proce    
3475                         if(m):                   
3476                                 parts, msg =     
3477                                 m = re.match(    
3478                                 if(m):           
3479                                         parts    
3480                                         if tp    
3481                                                  
3482                                                  
3483                                         procl    
3484                                         tp.mu    
3485                                 else:            
3486                                         procl    
3487                                         tp.mu    
3488                                 for ps in msg    
3489                                         val =    
3490                                         if no    
3491                                                  
3492                                         name     
3493                                         procl    
3494                                 if parts == 1    
3495                                         data.    
3496                                 elif parts ==    
3497                                         data.    
3498                                         tp.mu    
3499                                 continue         
3500                 # find the end of resume         
3501                 if(t.endMarker()):               
3502                         if data.tKernRes == 0    
3503                                 data.tKernRes    
3504                         data.handleEndMarker(    
3505                         if(not sysvals.usetra    
3506                                 # no trace ma    
3507                                 # the event w    
3508                                 if('thaw_proc    
3509                                         # if     
3510                                         testr    
3511                         limbo = True             
3512                         continue                 
3513                 # trace event processing         
3514                 if(t.fevent):                    
3515                         if(t.type == 'suspend    
3516                                 # suspend_res    
3517                                 if(re.match(r    
3518                                         isbeg    
3519                                 elif(re.match    
3520                                         isbeg    
3521                                 else:            
3522                                         conti    
3523                                 if '[' in t.n    
3524                                         m = r    
3525                                 else:            
3526                                         m = r    
3527                                 name = m.grou    
3528                                 # ignore thes    
3529                                 if(name.split    
3530                                         conti    
3531                                 # -- phase ch    
3532                                 # start of ke    
3533                                 if(re.match(r    
3534                                         if(is    
3535                                                  
3536                                         conti    
3537                                 # suspend_pre    
3538                                 elif(re.match    
3539                                         if is    
3540                                                  
3541                                                  
3542                                                  
3543                                                  
3544                                         phase    
3545                                         conti    
3546                                 # suspend sta    
3547                                 elif(re.match    
3548                                         phase    
3549                                         conti    
3550                                 # suspend_lat    
3551                                 elif(re.match    
3552                                         phase    
3553                                         conti    
3554                                 # suspend_noi    
3555                                 elif(re.match    
3556                                         phase    
3557                                         conti    
3558                                 # suspend_mac    
3559                                 elif(re.match    
3560                                         lp =     
3561                                         if(is    
3562                                                  
3563                                                  
3564                                                  
3565                                                  
3566                                                  
3567                                                  
3568                                                  
3569                                                  
3570                                                  
3571                                                  
3572                                                  
3573                                                  
3574                                                  
3575                                                  
3576                                                  
3577                                                  
3578                                                  
3579                                         else:    
3580                                                  
3581                                                  
3582                                                  
3583                                                  
3584                                                  
3585                                                  
3586                                                  
3587                                                  
3588                                                  
3589                                                  
3590                                         conti    
3591                                 # resume_noir    
3592                                 elif(re.match    
3593                                         phase    
3594                                         conti    
3595                                 # resume_earl    
3596                                 elif(re.match    
3597                                         phase    
3598                                         conti    
3599                                 # resume star    
3600                                 elif(re.match    
3601                                         phase    
3602                                         conti    
3603                                 # resume comp    
3604                                 elif(re.match    
3605                                         phase    
3606                                         conti    
3607                                 # skip trace     
3608                                 if(not data.i    
3609                                         conti    
3610                                 # global even    
3611                                 if(name not i    
3612                                         testr    
3613                                 # special han    
3614                                 if name == 'm    
3615                                         if hw    
3616                                                  
3617                                         elif     
3618                                                  
3619                                                  
3620                                                  
3621                                         elif     
3622                                                  
3623                                                  
3624                                                  
3625                                         conti    
3626                                 if(isbegin):     
3627                                         # cre    
3628                                         testr    
3629                                                  
3630                                 else:            
3631                                         if(le    
3632                                                  
3633                                                  
3634                         # device callback sta    
3635                         elif(t.type == 'devic    
3636                                 if phase not     
3637                                         conti    
3638                                 m = re.match(    
3639                                         t.nam    
3640                                 if(not m):       
3641                                         conti    
3642                                 drv = m.group    
3643                                 n = m.group('    
3644                                 p = m.group('    
3645                                 if(n and p):     
3646                                         data.    
3647                                         if pi    
3648                                                  
3649                         # device callback fin    
3650                         elif(t.type == 'devic    
3651                                 if phase not     
3652                                         conti    
3653                                 m = re.match(    
3654                                 if(not m):       
3655                                         conti    
3656                                 n = m.group('    
3657                                 dev = data.fi    
3658                                 if dev:          
3659                                         dev['    
3660                                         dev['    
3661                 # kprobe event processing        
3662                 elif(t.fkprobe):                 
3663                         kprobename = t.type      
3664                         kprobedata = t.name      
3665                         key = (kprobename, pi    
3666                         # displayname is gene    
3667                         displayname = ''         
3668                         if(t.fcall):             
3669                                 displayname =    
3670                                 if not displa    
3671                                         conti    
3672                                 if(key not in    
3673                                         tp.kt    
3674                                 tp.ktemp[key]    
3675                                         'pid'    
3676                                         'begi    
3677                                         'end'    
3678                                         'name    
3679                                         'cdat    
3680                                         'proc    
3681                                 })               
3682                                 # start of ke    
3683                                 if(data.tKern    
3684                                         and k    
3685                                         data.    
3686                         elif(t.freturn):         
3687                                 if(key not in    
3688                                         conti    
3689                                 e = next((x f    
3690                                 if not e:        
3691                                         conti    
3692                                 if (t.time -     
3693                                         tp.kt    
3694                                         conti    
3695                                 e['end'] = t.    
3696                                 e['rdata'] =     
3697                                 # end of kern    
3698                                 if(phase != '    
3699                                         if ph    
3700                                                  
3701                                         data.    
3702                                                  
3703                 # callgraph processing           
3704                 elif sysvals.usecallgraph:       
3705                         # create a callgraph     
3706                         key = (m_proc, pid)      
3707                         if(key not in testrun    
3708                                 testrun.ftemp    
3709                                 testrun.ftemp    
3710                         # when the call is fi    
3711                         cg = testrun.ftemp[ke    
3712                         res = cg.addLine(t)      
3713                         if(res != 0):            
3714                                 testrun.ftemp    
3715                         if(res == -1):           
3716                                 testrun.ftemp    
3717         if len(testdata) < 1:                    
3718                 sysvals.vprint('WARNING: ftra    
3719         if data and not data.devicegroups:       
3720                 sysvals.vprint('WARNING: ftra    
3721                 data.handleEndMarker(t.time,     
3722                                                  
3723         if sysvals.suspendmode == 'command':     
3724                 for test in testruns:            
3725                         for p in test.data.so    
3726                                 if p == 'susp    
3727                                         test.    
3728                                         test.    
3729                                 else:            
3730                                         test.    
3731                                         test.    
3732                         test.data.tSuspended     
3733                         test.data.tResumed =     
3734                         test.data.fwValid = F    
3735                                                  
3736         # dev source and procmon events can b    
3737         if sysvals.usedevsrc or sysvals.usepr    
3738                 sysvals.mixedphaseheight = Fa    
3739                                                  
3740         # expand phase boundaries so there ar    
3741         for data in testdata:                    
3742                 lp = data.sortedPhases()[0]      
3743                 for p in data.sortedPhases():    
3744                         if(p != lp and not ('    
3745                                 data.dmesg[lp    
3746                         lp = p                   
3747                                                  
3748         for i in range(len(testruns)):           
3749                 test = testruns[i]               
3750                 data = test.data                 
3751                 # find the total time range f    
3752                 tlb, tle = data.start, data.e    
3753                 if i < len(testruns) - 1:        
3754                         tle = testruns[i+1].d    
3755                 # add the process usage data     
3756                 if sysvals.useprocmon:           
3757                         data.createProcessUsa    
3758                 # add the traceevent data to     
3759                 if(sysvals.usetraceevents):      
3760                         # add actual trace fu    
3761                         for name in sorted(te    
3762                                 for event in     
3763                                         if ev    
3764                                                  
3765                                         title    
3766                                         if na    
3767                                                  
3768                                         data.    
3769                         # add the kprobe base    
3770                         for key in sorted(tp.    
3771                                 name, pid = k    
3772                                 if name not i    
3773                                         conti    
3774                                 if pid not in    
3775                                         data.    
3776                                 for e in tp.k    
3777                                         kb, k    
3778                                         if ke    
3779                                                  
3780                                         color    
3781                                         data.    
3782                         # add config base kpr    
3783                         if sysvals.usedevsrc:    
3784                                 for key in so    
3785                                         name,    
3786                                         if na    
3787                                                  
3788                                         for e    
3789                                                  
3790                                                  
3791                                                  
3792                                                  
3793                                                  
3794                 if sysvals.usecallgraph:         
3795                         # add the callgraph d    
3796                         sortlist = dict()        
3797                         for key in sorted(tes    
3798                                 proc, pid = k    
3799                                 for cg in tes    
3800                                         if le    
3801                                                  
3802                                         if(no    
3803                                                  
3804                                                  
3805                                                  
3806                                                  
3807                                         # mat    
3808                                         devna    
3809                                         if sy    
3810                                                  
3811                                         if no    
3812                                                  
3813                                                  
3814                                         elif     
3815                                                  
3816                                                  
3817                         # create blocks for o    
3818                         for sortkey in sorted    
3819                                 cg = sortlist    
3820                                 name = cg.nam    
3821                                 if sysvals.is    
3822                                         sysva    
3823                                         cg.ne    
3824         if sysvals.suspendmode == 'command':     
3825                 return (testdata, '')            
3826                                                  
3827         # fill in any missing phases             
3828         error = []                               
3829         for data in testdata:                    
3830                 tn = '' if len(testdata) == 1    
3831                 terr = ''                        
3832                 phasedef = data.phasedef         
3833                 lp = 'suspend_prepare'           
3834                 for p in sorted(phasedef, key    
3835                         if p not in data.dmes    
3836                                 if not terr:     
3837                                         ph =     
3838                                         if p     
3839                                                  
3840                                                  
3841                                                  
3842                                                  
3843                                         else:    
3844                                                  
3845                                         pprin    
3846                                         error    
3847                                         if da    
3848                                                  
3849                                         if da    
3850                                                  
3851                                         data.    
3852                                 sysvals.vprin    
3853                         lp = p                   
3854                 if not terr and 'dev' in data    
3855                         terr = '%s%s failed i    
3856                                 (sysvals.susp    
3857                         error.append(terr)       
3858                 if not terr and data.enterfai    
3859                         pprint('test%s FAILED    
3860                         terr = 'test%s failed    
3861                         error.append(terr)       
3862                 if data.tSuspended == 0:         
3863                         data.tSuspended = dat    
3864                 if data.tResumed == 0:           
3865                         data.tResumed = data.    
3866                                                  
3867                 if(len(sysvals.devicefilter)     
3868                         data.deviceFilter(sys    
3869                 data.fixupInitcallsThatDidntR    
3870                 if sysvals.usedevsrc:            
3871                         data.optimizeDevSrc()    
3872                                                  
3873         # x2: merge any overlapping devices b    
3874         if sysvals.usedevsrc and len(testdata    
3875                 tc = len(testdata)               
3876                 for i in range(tc - 1):          
3877                         devlist = testdata[i]    
3878                         for j in range(i + 1,    
3879                                 testdata[j].m    
3880                 testdata[0].stitchTouchingThr    
3881         return (testdata, ', '.join(error))      
3882                                                  
3883 # Function: loadKernelLog                        
3884 # Description:                                   
3885 #        load the dmesg file into memory and     
3886 # Output:                                        
3887 #        An array of empty Data objects with     
3888 def loadKernelLog():                             
3889         sysvals.vprint('Analyzing the dmesg d    
3890                 os.path.basename(sysvals.dmes    
3891         if(os.path.exists(sysvals.dmesgfile)     
3892                 doError('%s does not exist' %    
3893                                                  
3894         # there can be multiple test runs in     
3895         tp = TestProps()                         
3896         tp.stamp = datetime.now().strftime('#    
3897         testruns = []                            
3898         data = 0                                 
3899         lf = sysvals.openlog(sysvals.dmesgfil    
3900         for line in lf:                          
3901                 line = line.replace('\r\n', '    
3902                 idx = line.find('[')             
3903                 if idx > 1:                      
3904                         line = line[idx:]        
3905                 if tp.stampInfo(line, sysvals    
3906                         continue                 
3907                 m = re.match(r'[ \t]*(\[ *)(?    
3908                 if(not m):                       
3909                         continue                 
3910                 msg = m.group("msg")             
3911                 if re.match(r'PM: Syncing fil    
3912                         re.match(r'PM: suspen    
3913                         if(data):                
3914                                 testruns.appe    
3915                         data = Data(len(testr    
3916                         tp.parseStamp(data, s    
3917                 if(not data):                    
3918                         continue                 
3919                 m = re.match(r'.* *(?P<k>[0-9    
3920                 if(m):                           
3921                         sysvals.stamp['kernel    
3922                 m = re.match(r'PM: Preparing     
3923                 if not m:                        
3924                         m = re.match(r'PM: Pr    
3925                 if m:                            
3926                         sysvals.stamp['mode']    
3927                 data.dmesgtext.append(line)      
3928         lf.close()                               
3929                                                  
3930         if sysvals.suspendmode == 's2idle':      
3931                 sysvals.suspendmode = 'freeze    
3932         elif sysvals.suspendmode == 'deep':      
3933                 sysvals.suspendmode = 'mem'      
3934         if data:                                 
3935                 testruns.append(data)            
3936         if len(testruns) < 1:                    
3937                 doError('dmesg log has no sus    
3938                         % sysvals.dmesgfile)     
3939                                                  
3940         # fix lines with same timestamp/funct    
3941         for data in testruns:                    
3942                 last = ''                        
3943                 for line in data.dmesgtext:      
3944                         ct, cf, n, p = data.i    
3945                         rt, rf, l = data.init    
3946                         if ct and rt and ct =    
3947                                 i = data.dmes    
3948                                 j = data.dmes    
3949                                 data.dmesgtex    
3950                                 data.dmesgtex    
3951                         last = line              
3952         return testruns                          
3953                                                  
3954 # Function: parseKernelLog                       
3955 # Description:                                   
3956 #        Analyse a dmesg log output file gene    
3957 #        the execution phase. Create a set of    
3958 #        for subsequent formatting in the htm    
3959 #        This call is only for legacy support    
3960 #        data lacks the suspend_resume or dev    
3961 # Arguments:                                     
3962 #        data: an empty Data object (with dme    
3963 # Output:                                        
3964 #        The filled Data object                  
3965 def parseKernelLog(data):                        
3966         phase = 'suspend_runtime'                
3967                                                  
3968         if(data.fwValid):                        
3969                 sysvals.vprint('Firmware Susp    
3970                         (data.fwSuspend, data    
3971                                                  
3972         # dmesg phase match table                
3973         dm = {                                   
3974                 'suspend_prepare': ['PM: Sync    
3975                         'suspend': ['PM: Ente    
3976                                     'PM: Susp    
3977                    'suspend_late': ['PM: susp    
3978                                                  
3979                   'suspend_noirq': ['PM: late    
3980                                                  
3981                 'suspend_machine': ['PM: susp    
3982                                                  
3983                                                  
3984                  'resume_machine': ['[PM: ]*T    
3985                                                  
3986                                                  
3987                                                  
3988                    'resume_noirq': ['PM: resu    
3989                                                  
3990                    'resume_early': ['PM: noir    
3991                                                  
3992                          'resume': ['PM: earl    
3993                                                  
3994                 'resume_complete': ['PM: resu    
3995                                                  
3996                     'post_resume': [r'.*Resta    
3997         }                                        
3998                                                  
3999         # action table (expected events that     
4000         at = {                                   
4001                 'sync_filesystems': {            
4002                         'smsg': '.*[Ff]+ilesy    
4003                         'emsg': 'PM: Preparin    
4004                 'freeze_user_processes': {       
4005                         'smsg': 'Freezing use    
4006                         'emsg': 'Freezing rem    
4007                 'freeze_tasks': {                
4008                         'smsg': 'Freezing rem    
4009                         'emsg': 'PM: Suspendi    
4010                 'ACPI prepare': {                
4011                         'smsg': 'ACPI: Prepar    
4012                         'emsg': 'PM: Saving p    
4013                 'PM vns': {                      
4014                         'smsg': 'PM: Saving p    
4015                         'emsg': 'Disabling no    
4016         }                                        
4017                                                  
4018         t0 = -1.0                                
4019         cpu_start = -1.0                         
4020         prevktime = -1.0                         
4021         actions = dict()                         
4022         for line in data.dmesgtext:              
4023                 # parse each dmesg line into     
4024                 m = re.match(r'[ \t]*(\[ *)(?    
4025                 if(m):                           
4026                         val = m.group('ktime'    
4027                         try:                     
4028                                 ktime = float    
4029                         except:                  
4030                                 continue         
4031                         msg = m.group('msg')     
4032                         # initialize data sta    
4033                         if t0 < 0:               
4034                                 data.setStart    
4035                                 t0 = ktime       
4036                 else:                            
4037                         continue                 
4038                                                  
4039                 # check for a phase change li    
4040                 phasechange = False              
4041                 for p in dm:                     
4042                         for s in dm[p]:          
4043                                 if(re.match(s    
4044                                         phase    
4045                                         dm[p]    
4046                                         break    
4047                                                  
4048                 # hack for determining resume    
4049                 if(not sysvals.usetraceevents    
4050                         and phase == 'resume_    
4051                         data.initcall_debug_c    
4052                         data.setPhase(phase,     
4053                         phase = 'resume_noirq    
4054                         data.setPhase(phase,     
4055                                                  
4056                 if phasechange:                  
4057                         if phase == 'suspend_    
4058                                 data.setPhase    
4059                                 data.setStart    
4060                                 data.tKernSus    
4061                         elif phase == 'suspen    
4062                                 lp = data.las    
4063                                 if lp:           
4064                                         data.    
4065                                 data.setPhase    
4066                         elif phase == 'suspen    
4067                                 lp = data.las    
4068                                 if lp:           
4069                                         data.    
4070                                 data.setPhase    
4071                         elif phase == 'suspen    
4072                                 lp = data.las    
4073                                 if lp:           
4074                                         data.    
4075                                 data.setPhase    
4076                         elif phase == 'suspen    
4077                                 lp = data.las    
4078                                 if lp:           
4079                                         data.    
4080                                 data.setPhase    
4081                         elif phase == 'resume    
4082                                 lp = data.las    
4083                                 if(sysvals.su    
4084                                         data.    
4085                                         if lp    
4086                                                  
4087                                 else:            
4088                                         data.    
4089                                         if lp    
4090                                                  
4091                                 data.tResumed    
4092                                 data.setPhase    
4093                         elif phase == 'resume    
4094                                 lp = data.las    
4095                                 if lp:           
4096                                         data.    
4097                                 data.setPhase    
4098                         elif phase == 'resume    
4099                                 lp = data.las    
4100                                 if lp:           
4101                                         data.    
4102                                 data.setPhase    
4103                         elif phase == 'resume    
4104                                 lp = data.las    
4105                                 if lp:           
4106                                         data.    
4107                                 data.setPhase    
4108                         elif phase == 'resume    
4109                                 lp = data.las    
4110                                 if lp:           
4111                                         data.    
4112                                 data.setPhase    
4113                         elif phase == 'post_r    
4114                                 lp = data.las    
4115                                 if lp:           
4116                                         data.    
4117                                 data.setEnd(k    
4118                                 data.tKernRes    
4119                                 break            
4120                                                  
4121                 # -- device callbacks --         
4122                 if(phase in data.sortedPhases    
4123                         # device init call       
4124                         t, f, n, p = data.ini    
4125                         if t and f and n and     
4126                                 data.newActio    
4127                         else:                    
4128                                 # device init    
4129                                 t, f, l = dat    
4130                                 if t and f an    
4131                                         list     
4132                                         if(f     
4133                                                  
4134                                                  
4135                                                  
4136                                                  
4137                 # if trace events are not ava    
4138                 if(not sysvals.usetraceevents    
4139                         # look for known acti    
4140                         for a in sorted(at):     
4141                                 if(re.match(a    
4142                                         if(a     
4143                                                  
4144                                 if(re.match(a    
4145                                         if(a     
4146                                                  
4147                         # now look for CPU on    
4148                         if(re.match(r'Disabli    
4149                                 # start of fi    
4150                                 cpu_start = k    
4151                         elif(re.match(r'Enabl    
4152                                 # start of fi    
4153                                 cpu_start = k    
4154                         elif(re.match(r'smpbo    
4155                                 or re.match(r    
4156                                 # end of a cp    
4157                                 m = re.match(    
4158                                 if(not m):       
4159                                         m = r    
4160                                 cpu = 'CPU'+m    
4161                                 if(cpu not in    
4162                                         actio    
4163                                 actions[cpu].    
4164                                 cpu_start = k    
4165                         elif(re.match(r'CPU(?    
4166                                 # end of a cp    
4167                                 m = re.match(    
4168                                 cpu = 'CPU'+m    
4169                                 if(cpu not in    
4170                                         actio    
4171                                 actions[cpu].    
4172                                 cpu_start = k    
4173                 prevktime = ktime                
4174         data.initDevicegroups()                  
4175                                                  
4176         # fill in any missing phases             
4177         phasedef = data.phasedef                 
4178         terr, lp = '', 'suspend_prepare'         
4179         if lp not in data.dmesg:                 
4180                 doError('dmesg log format has    
4181         for p in sorted(phasedef, key=lambda     
4182                 if p not in data.dmesg:          
4183                         if not terr:             
4184                                 pprint('TEST     
4185                                 terr = '%s fa    
4186                                 if data.tSusp    
4187                                         data.    
4188                                 if data.tResu    
4189                                         data.    
4190                         sysvals.vprint('WARNI    
4191                 lp = p                           
4192         lp = data.sortedPhases()[0]              
4193         for p in data.sortedPhases():            
4194                 if(p != lp and not ('machine'    
4195                         data.dmesg[lp]['end']    
4196                 lp = p                           
4197         if data.tSuspended == 0:                 
4198                 data.tSuspended = data.tKernR    
4199         if data.tResumed == 0:                   
4200                 data.tResumed = data.tSuspend    
4201                                                  
4202         # fill in any actions we've found        
4203         for name in sorted(actions):             
4204                 for event in actions[name]:      
4205                         data.newActionGlobal(    
4206                                                  
4207         if(len(sysvals.devicefilter) > 0):       
4208                 data.deviceFilter(sysvals.dev    
4209         data.fixupInitcallsThatDidntReturn()     
4210         return True                              
4211                                                  
4212 def callgraphHTML(sv, hf, num, cg, title, col    
4213         html_func_top = '<article id="{0}" cl    
4214         html_func_start = '<article>\n<input     
4215         html_func_end = '</article>\n'           
4216         html_func_leaf = '<article>{0} {1}</a    
4217                                                  
4218         cgid = devid                             
4219         if cg.id:                                
4220                 cgid += cg.id                    
4221         cglen = (cg.end - cg.start) * 1000       
4222         if cglen < sv.mincglen:                  
4223                 return num                       
4224                                                  
4225         fmt = '<r>(%.3f ms @ '+sv.timeformat+'    
4226         flen = fmt % (cglen, cg.start, cg.end    
4227         hf.write(html_func_top.format(cgid, c    
4228         num += 1                                 
4229         for line in cg.list:                     
4230                 if(line.length < 0.000000001)    
4231                         flen = ''                
4232                 else:                            
4233                         fmt = '<n>(%.3f ms @ '    
4234                         flen = fmt % (line.le    
4235                 if line.isLeaf():                
4236                         if line.length * 1000    
4237                                 continue         
4238                         hf.write(html_func_le    
4239                 elif line.freturn:               
4240                         hf.write(html_func_en    
4241                 else:                            
4242                         hf.write(html_func_st    
4243                         num += 1                 
4244         hf.write(html_func_end)                  
4245         return num                               
4246                                                  
4247 def addCallgraphs(sv, hf, data):                 
4248         hf.write('<section id="callgraphs" cl    
4249         # write out the ftrace data converted    
4250         num = 0                                  
4251         for p in data.sortedPhases():            
4252                 if sv.cgphase and p != sv.cgp    
4253                         continue                 
4254                 list = data.dmesg[p]['list']     
4255                 for d in data.sortedDevices(p    
4256                         if len(sv.cgfilter) >    
4257                                 continue         
4258                         dev = list[d]            
4259                         color = 'white'          
4260                         if 'color' in data.dm    
4261                                 color = data.    
4262                         if 'color' in dev:       
4263                                 color = dev['    
4264                         name = d if '[' not i    
4265                         if(d in sv.devprops):    
4266                                 name = sv.dev    
4267                         if 'drv' in dev and d    
4268                                 name += ' {%s    
4269                         if sv.suspendmode in     
4270                                 name += ' '+p    
4271                         if('ftrace' in dev):     
4272                                 cg = dev['ftr    
4273                                 if cg.name ==    
4274                                         name     
4275                                 num = callgra    
4276                                         name,    
4277                         if('ftraces' in dev):    
4278                                 for cg in dev    
4279                                         num =    
4280                                                  
4281         hf.write('\n\n    </section>\n')         
4282                                                  
4283 def summaryCSS(title, center=True):              
4284         tdcenter = 'text-align:center;' if ce    
4285         out = '<!DOCTYPE html>\n<html>\n<head    
4286         <meta http-equiv="content-type" conte    
4287         <title>'+title+'</title>\n\              
4288         <style type=\'text/css\'>\n\             
4289                 .stamp {width: 100%;text-alig    
4290                 table {width:100%;border-coll    
4291                 th {border: 1px solid black;b    
4292                 td {font: 14px "Times New Rom    
4293                 tr.head td {border: 1px solid    
4294                 tr.alt {background-color:#ddd    
4295                 tr.notice {color:red;}\n\        
4296                 .minval {background-color:#BB    
4297                 .medval {background-color:#BB    
4298                 .maxval {background-color:#FF    
4299                 .head a {color:#000;text-deco    
4300         </style>\n</head>\n<body>\n'             
4301         return out                               
4302                                                  
4303 # Function: createHTMLSummarySimple              
4304 # Description:                                   
4305 #        Create summary html file for a serie    
4306 # Arguments:                                     
4307 #        testruns: array of Data objects from    
4308 def createHTMLSummarySimple(testruns, htmlfil    
4309         # write the html header first (html h    
4310         html = summaryCSS('Summary - SleepGra    
4311                                                  
4312         # extract the test data into list        
4313         list = dict()                            
4314         tAvg, tMin, tMax, tMed = [0.0, 0.0],     
4315         iMin, iMed, iMax = [0, 0], [0, 0], [0    
4316         num = 0                                  
4317         useturbo = usewifi = False               
4318         lastmode = ''                            
4319         cnt = dict()                             
4320         for data in sorted(testruns, key=lamb    
4321                 mode = data['mode']              
4322                 if mode not in list:             
4323                         list[mode] = {'data':    
4324                 if lastmode and lastmode != m    
4325                         for i in range(2):       
4326                                 s = sorted(tM    
4327                                 list[lastmode    
4328                                 iMed[i] = tMe    
4329                         list[lastmode]['avg']    
4330                         list[lastmode]['min']    
4331                         list[lastmode]['max']    
4332                         list[lastmode]['idx']    
4333                         tAvg, tMin, tMax, tMe    
4334                         iMin, iMed, iMax = [0    
4335                         num = 0                  
4336                 pkgpc10 = syslpi = wifi = ''     
4337                 if 'pkgpc10' in data and 'sys    
4338                         pkgpc10, syslpi, uset    
4339                 if 'wifi' in data:               
4340                         wifi, usewifi = data[    
4341                 res = data['result']             
4342                 tVal = [float(data['suspend']    
4343                 list[mode]['data'].append([da    
4344                         data['time'], tVal[0]    
4345                         data['issues'], data[    
4346                         data['res_worst'], da    
4347                         (data['fullmode'] if     
4348                 idx = len(list[mode]['data'])    
4349                 if res.startswith('fail in'):    
4350                         res = 'fail'             
4351                 if res not in cnt:               
4352                         cnt[res] = 1             
4353                 else:                            
4354                         cnt[res] += 1            
4355                 if res == 'pass':                
4356                         for i in range(2):       
4357                                 tMed[i][tVal[    
4358                                 tAvg[i] += tV    
4359                                 if tMin[i] ==    
4360                                         iMin[    
4361                                         tMin[    
4362                                 if tMax[i] ==    
4363                                         iMax[    
4364                                         tMax[    
4365                         num += 1                 
4366                 lastmode = mode                  
4367         if lastmode and num > 0:                 
4368                 for i in range(2):               
4369                         s = sorted(tMed[i])      
4370                         list[lastmode]['med']    
4371                         iMed[i] = tMed[i][lis    
4372                 list[lastmode]['avg'] = [tAvg    
4373                 list[lastmode]['min'] = tMin     
4374                 list[lastmode]['max'] = tMax     
4375                 list[lastmode]['idx'] = (iMin    
4376                                                  
4377         # group test header                      
4378         desc = []                                
4379         for ilk in sorted(cnt, reverse=True):    
4380                 if cnt[ilk] > 0:                 
4381                         desc.append('%d %s' %    
4382         html += '<div class="stamp">%s (%d te    
4383         th = '\t<th>{0}</th>\n'                  
4384         td = '\t<td>{0}</td>\n'                  
4385         tdh = '\t<td{1}>{0}</td>\n'              
4386         tdlink = '\t<td><a href="{0}">html</a    
4387         cols = 12                                
4388         if useturbo:                             
4389                 cols += 2                        
4390         if usewifi:                              
4391                 cols += 1                        
4392         colspan = '%d' % cols                    
4393                                                  
4394         # table header                           
4395         html += '<table>\n<tr>\n' + th.format    
4396                 th.format('Mode') + th.format    
4397                 th.format('Test Time') + th.f    
4398                 th.format('Suspend') + th.for    
4399                 th.format('Worst Suspend Devi    
4400                 th.format('Worst Resume Devic    
4401         if useturbo:                             
4402                 html += th.format('PkgPC10')     
4403         if usewifi:                              
4404                 html += th.format('Wifi')        
4405         html += th.format('Detail')+'</tr>\n'    
4406         # export list into html                  
4407         head = '<tr class="head"><td>{0}</td>    
4408                 '<td colspan='+colspan+' clas    
4409                 '<span class=minval><a href="    
4410                 '<span class=medval><a href="    
4411                 '<span class=maxval><a href="    
4412                 'Resume Avg={6} '+\              
4413                 '<span class=minval><a href="    
4414                 '<span class=medval><a href="    
4415                 '<span class=maxval><a href="    
4416                 '</tr>\n'                        
4417         headnone = '<tr class="head"><td>{0}<    
4418                 colspan+'></td></tr>\n'          
4419         for mode in sorted(list):                
4420                 # header line for each suspen    
4421                 num = 0                          
4422                 tAvg, tMin, tMax, tMed = list    
4423                         list[mode]['max'], li    
4424                 count = len(list[mode]['data'    
4425                 if 'idx' in list[mode]:          
4426                         iMin, iMed, iMax = li    
4427                         html += head.format('    
4428                                 '%.3f' % tAvg    
4429                                 '%.3f' % tAvg    
4430                                 mode.lower()     
4431                         )                        
4432                 else:                            
4433                         iMin = iMed = iMax =     
4434                         html += headnone.form    
4435                 for d in list[mode]['data']:     
4436                         # row classes - alter    
4437                         rcls = ['alt'] if num    
4438                         if d[6] != 'pass':       
4439                                 rcls.append('    
4440                         html += '<tr class="'    
4441                         # figure out if the l    
4442                         idx = list[mode]['dat    
4443                         tHigh = ['', '']         
4444                         for i in range(2):       
4445                                 tag = 's%s' %    
4446                                 if idx == iMi    
4447                                         tHigh    
4448                                 elif idx == i    
4449                                         tHigh    
4450                                 elif idx == i    
4451                                         tHigh    
4452                         html += td.format("%d    
4453                         html += td.format(d[1    
4454                         html += td.format(d[0    
4455                         html += td.format(d[1    
4456                         html += td.format(d[2    
4457                         html += td.format(d[6    
4458                         html += td.format(d[7    
4459                         html += tdh.format('%    
4460                         html += tdh.format('%    
4461                         html += td.format(d[8    
4462                         html += td.format('%.    
4463                         html += td.format(d[1    
4464                         html += td.format('%.    
4465                         if useturbo:             
4466                                 html += td.fo    
4467                                 html += td.fo    
4468                         if usewifi:              
4469                                 html += td.fo    
4470                         html += tdlink.format    
4471                         html += '</tr>\n'        
4472                         num += 1                 
4473                                                  
4474         # flush the data to file                 
4475         hf = open(htmlfile, 'w')                 
4476         hf.write(html+'</table>\n</body>\n</h    
4477         hf.close()                               
4478                                                  
4479 def createHTMLDeviceSummary(testruns, htmlfil    
4480         html = summaryCSS('Device Summary - S    
4481                                                  
4482         # create global device list from all     
4483         devall = dict()                          
4484         for data in testruns:                    
4485                 host, url, devlist = data['ho    
4486                 for type in devlist:             
4487                         if type not in devall    
4488                                 devall[type]     
4489                         mdevlist, devlist = d    
4490                         for name in devlist:     
4491                                 length = devl    
4492                                 if name not i    
4493                                         mdevl    
4494                                                  
4495                                                  
4496                                 else:            
4497                                         if le    
4498                                                  
4499                                                  
4500                                                  
4501                                         mdevl    
4502                                         mdevl    
4503                                                  
4504         # generate the html                      
4505         th = '\t<th>{0}</th>\n'                  
4506         td = '\t<td align=center>{0}</td>\n'     
4507         tdr = '\t<td align=right>{0}</td>\n'     
4508         tdlink = '\t<td align=center><a href=    
4509         limit = 1                                
4510         for type in sorted(devall, reverse=Tr    
4511                 num = 0                          
4512                 devlist = devall[type]           
4513                 # table header                   
4514                 html += '<div class="stamp">%    
4515                         (title, type.upper(),    
4516                 html += '<tr>\n' + '<th align    
4517                         th.format('Average Ti    
4518                         th.format('Worst Time    
4519                         th.format('Link (wors    
4520                 for name in sorted(devlist, k    
4521                         devlist[k]['total'],     
4522                         data = devall[type][n    
4523                         data['average'] = dat    
4524                         if data['average'] <     
4525                                 continue         
4526                         # row classes - alter    
4527                         rcls = ['alt'] if num    
4528                         html += '<tr class="'    
4529                         html += tdr.format(da    
4530                         html += td.format('%.    
4531                         html += td.format(dat    
4532                         html += td.format('%.    
4533                         html += td.format(dat    
4534                         html += tdlink.format    
4535                         html += '</tr>\n'        
4536                         num += 1                 
4537                 html += '</table>\n'             
4538                                                  
4539         # flush the data to file                 
4540         hf = open(htmlfile, 'w')                 
4541         hf.write(html+'</body>\n</html>\n')      
4542         hf.close()                               
4543         return devall                            
4544                                                  
4545 def createHTMLIssuesSummary(testruns, issues,    
4546         multihost = len([e for e in issues if    
4547         html = summaryCSS('Issues Summary - S    
4548         total = len(testruns)                    
4549                                                  
4550         # generate the html                      
4551         th = '\t<th>{0}</th>\n'                  
4552         td = '\t<td align={0}>{1}</td>\n'        
4553         tdlink = '<a href="{1}">{0}</a>'         
4554         subtitle = '%d issues' % len(issues)     
4555         html += '<div class="stamp">%s (%s)</    
4556         html += '<tr>\n' + th.format('Issue')    
4557         if multihost:                            
4558                 html += th.format('Hosts')       
4559         html += th.format('Tests') + th.forma    
4560                 th.format('First Instance') +    
4561                                                  
4562         num = 0                                  
4563         for e in sorted(issues, key=lambda v:    
4564                 testtotal = 0                    
4565                 links = []                       
4566                 for host in sorted(e['urls'])    
4567                         links.append(tdlink.f    
4568                         testtotal += len(e['u    
4569                 rate = '%d/%d (%.2f%%)' % (te    
4570                 # row classes - alternate row    
4571                 rcls = ['alt'] if num % 2 ==     
4572                 html += '<tr class="'+(' '.jo    
4573                 html += td.format('left', e['    
4574                 html += td.format('center', e    
4575                 if multihost:                    
4576                         html += td.format('ce    
4577                 html += td.format('center', t    
4578                 html += td.format('center', r    
4579                 html += td.format('center now    
4580                 html += '</tr>\n'                
4581                 num += 1                         
4582                                                  
4583         # flush the data to file                 
4584         hf = open(htmlfile, 'w')                 
4585         hf.write(html+'</table>\n'+extra+'</b    
4586         hf.close()                               
4587         return issues                            
4588                                                  
4589 def ordinal(value):                              
4590         suffix = 'th'                            
4591         if value < 10 or value > 19:             
4592                 if value % 10 == 1:              
4593                         suffix = 'st'            
4594                 elif value % 10 == 2:            
4595                         suffix = 'nd'            
4596                 elif value % 10 == 3:            
4597                         suffix = 'rd'            
4598         return '%d%s' % (value, suffix)          
4599                                                  
4600 # Function: createHTML                           
4601 # Description:                                   
4602 #        Create the output html file from the    
4603 # Arguments:                                     
4604 #        testruns: array of Data objects from    
4605 # Output:                                        
4606 #        True if the html file was created, f    
4607 def createHTML(testruns, testfail):              
4608         if len(testruns) < 1:                    
4609                 pprint('ERROR: Not enough tes    
4610                 return                           
4611                                                  
4612         kerror = False                           
4613         for data in testruns:                    
4614                 if data.kerror:                  
4615                         kerror = True            
4616                 if(sysvals.suspendmode in ['f    
4617                         data.trimFreezeTime(t    
4618                 else:                            
4619                         data.getMemTime()        
4620                                                  
4621         # html function templates                
4622         html_error = '<div id="{1}" title="ke    
4623         html_traceevent = '<div title="{0}" c    
4624         html_cpuexec = '<div class="jiffie" s    
4625         html_timetotal = '<table class="time1    
4626                 '<td class="green" title="{3}    
4627                 '<td class="yellow" title="{4    
4628                 '</tr>\n</table>\n'              
4629         html_timetotal2 = '<table class="time    
4630                 '<td class="green" title="{4}    
4631                 '<td class="gray" title="time    
4632                 '<td class="yellow" title="{5    
4633                 '</tr>\n</table>\n'              
4634         html_timetotal3 = '<table class="time    
4635                 '<td class="green">Execution     
4636                 '<td class="yellow">Command:     
4637                 '</tr>\n</table>\n'              
4638         html_fail = '<table class="testfail">    
4639         html_kdesc = '<td class="{3}" title="    
4640         html_fwdesc = '<td class="{3}" title=    
4641         html_wifdesc = '<td class="yellow" ti    
4642                                                  
4643         # html format variables                  
4644         scaleH = 20                              
4645         if kerror:                               
4646                 scaleH = 40                      
4647                                                  
4648         # device timeline                        
4649         devtl = Timeline(30, scaleH)             
4650                                                  
4651         # write the test title and general in    
4652         devtl.createHeader(sysvals, testruns[    
4653                                                  
4654         # Generate the header for this timeli    
4655         for data in testruns:                    
4656                 tTotal = data.end - data.star    
4657                 if(tTotal == 0):                 
4658                         doError('No timeline     
4659                 if sysvals.suspendmode == 'co    
4660                         run_time = '%.0f' % (    
4661                         if sysvals.testcomman    
4662                                 testdesc = sy    
4663                         else:                    
4664                                 testdesc = 'u    
4665                         if(len(testruns) > 1)    
4666                                 testdesc = or    
4667                         thtml = html_timetota    
4668                         devtl.html += thtml      
4669                         continue                 
4670                 # typical full suspend/resume    
4671                 stot, rtot = sktime, rktime =    
4672                 ssrc, rsrc, testdesc, testdes    
4673                 if data.fwValid:                 
4674                         stot += (data.fwSuspe    
4675                         rtot += (data.fwResum    
4676                         ssrc.append('firmware    
4677                         rsrc.append('firmware    
4678                         testdesc = 'Total'       
4679                 if 'time' in data.wifi and da    
4680                         rtot += data.end - da    
4681                         rsrc.append('wifi')      
4682                         testdesc = 'Total'       
4683                 suspend_time, resume_time = '    
4684                 stitle = 'time from kernel su    
4685                         (sysvals.suspendmode,    
4686                 rtitle = 'time from %s mode t    
4687                         (sysvals.suspendmode,    
4688                 if(len(testruns) > 1):           
4689                         testdesc = testdesc2     
4690                         testdesc2 += ' '         
4691                 if(len(data.tLow) == 0):         
4692                         thtml = html_timetota    
4693                                 resume_time,     
4694                 else:                            
4695                         low_time = '+'.join(d    
4696                         thtml = html_timetota    
4697                                 resume_time,     
4698                 devtl.html += thtml              
4699                 if not data.fwValid and 'dev'    
4700                         continue                 
4701                 # extra detail when the times    
4702                 thtml = '<table class="time2"    
4703                 thtml += html_kdesc.format(te    
4704                 if data.fwValid:                 
4705                         sftime = '%.3f'%(data    
4706                         rftime = '%.3f'%(data    
4707                         thtml += html_fwdesc.    
4708                         thtml += html_fwdesc.    
4709                 thtml += html_kdesc.format(te    
4710                 if 'time' in data.wifi:          
4711                         if data.wifi['stat']     
4712                                 wtime = '%.0f    
4713                         else:                    
4714                                 wtime = 'TIME    
4715                         thtml += html_wifdesc    
4716                 thtml += '</tr>\n</table>\n'     
4717                 devtl.html += thtml              
4718         if testfail:                             
4719                 devtl.html += html_fail.forma    
4720                                                  
4721         # time scale for potentially multiple    
4722         t0 = testruns[0].start                   
4723         tMax = testruns[-1].end                  
4724         tTotal = tMax - t0                       
4725                                                  
4726         # determine the maximum number of row    
4727         fulllist = []                            
4728         threadlist = []                          
4729         pscnt = 0                                
4730         devcnt = 0                               
4731         for data in testruns:                    
4732                 data.selectTimelineDevices('%    
4733                 for group in data.devicegroup    
4734                         devlist = []             
4735                         for phase in group:      
4736                                 for devname i    
4737                                         d = D    
4738                                         devli    
4739                                         if d.    
4740                                                  
4741                                         else:    
4742                                                  
4743                                                  
4744                                                  
4745                                                  
4746                                                  
4747                         if sysvals.mixedphase    
4748                                 devtl.getPhas    
4749         if not sysvals.mixedphaseheight:         
4750                 if len(threadlist) > 0 and le    
4751                         if pscnt > 0 and devc    
4752                                 msg = 'user p    
4753                         elif pscnt > 0:          
4754                                 msg = 'user p    
4755                         else:                    
4756                                 msg = 'device    
4757                         d = testruns[0].addHo    
4758                         fulllist.insert(0, d)    
4759                 devtl.getPhaseRows(fulllist)     
4760                 if len(threadlist) > 0:          
4761                         d = testruns[0].addHo    
4762                         threadlist.insert(0,     
4763                         devtl.getPhaseRows(th    
4764         devtl.calcTotalRows()                    
4765                                                  
4766         # draw the full timeline                 
4767         devtl.createZoomBox(sysvals.suspendmo    
4768         for data in testruns:                    
4769                 # draw each test run and bloc    
4770                 phases = {'suspend':[],'resum    
4771                 for phase in data.sortedPhase    
4772                         if data.dmesg[phase][    
4773                                 phases['resum    
4774                         else:                    
4775                                 phases['suspe    
4776                 # now draw the actual timelin    
4777                 for dir in phases:               
4778                         # draw suspend and re    
4779                         bname = '%s%d' % (dir    
4780                         if dir == 'suspend':     
4781                                 m0 = data.sta    
4782                                 mMax = data.t    
4783                                 left = '%f' %    
4784                         else:                    
4785                                 m0 = data.tSu    
4786                                 mMax = data.e    
4787                                 # in an x2 ru    
4788                                 if len(testru    
4789                                         mMax     
4790                                 left = '%f' %    
4791                         mTotal = mMax - m0       
4792                         # if a timeline block    
4793                         if mTotal == 0:          
4794                                 continue         
4795                         width = '%f' % (((mTo    
4796                         devtl.html += devtl.h    
4797                         for b in phases[dir]:    
4798                                 # draw the ph    
4799                                 phase = data.    
4800                                 length = phas    
4801                                 left = '%f' %    
4802                                 width = '%f'     
4803                                 devtl.html +=    
4804                                         '%.3f    
4805                                         data.    
4806                         for e in data.errorin    
4807                                 # draw red li    
4808                                 type, t, idx1    
4809                                 id = '%d_%d'     
4810                                 right = '%f'     
4811                                 devtl.html +=    
4812                         for b in phases[dir]:    
4813                                 # draw the de    
4814                                 phaselist = d    
4815                                 for d in sort    
4816                                         dname    
4817                                         name,    
4818                                         drv =    
4819                                         if 'h    
4820                                                  
4821                                         if 'c    
4822                                                  
4823                                         if(d     
4824                                                  
4825                                                  
4826                                                  
4827                                         elif     
4828                                                  
4829                                         if('d    
4830                                                  
4831                                         rowhe    
4832                                         rowto    
4833                                         top =    
4834                                         left     
4835                                         width    
4836                                         lengt    
4837                                         title    
4838                                         if sy    
4839                                                  
4840                                         elif     
4841                                                  
4842                                                  
4843                                                  
4844                                                  
4845                                         else:    
4846                                                  
4847                                         devtl    
4848                                                  
4849                                                  
4850                                         if('c    
4851                                                  
4852                                                  
4853                                                  
4854                                                  
4855                                                  
4856                                                  
4857                                                  
4858                                                  
4859                                                  
4860                                         if('s    
4861                                                  
4862                                         # dra    
4863                                         for e    
4864                                                  
4865                                                  
4866                                                  
4867                                                  
4868                                                  
4869                                                  
4870                                                  
4871                                                  
4872                                                  
4873                                                  
4874                                                  
4875                                                  
4876                         # draw the time scale    
4877                         devtl.createTimeScale    
4878                         devtl.html += '</div>    
4879                                                  
4880         # timeline is finished                   
4881         devtl.html += '</div>\n</div>\n'         
4882                                                  
4883         # draw a legend which describes the p    
4884         if sysvals.suspendmode != 'command':     
4885                 phasedef = testruns[-1].phase    
4886                 devtl.html += '<div class="le    
4887                 pdelta = 100.0/len(phasedef.k    
4888                 pmargin = pdelta / 4.0           
4889                 for phase in sorted(phasedef,    
4890                         id, p = '', phasedef[    
4891                         for word in phase.spl    
4892                                 id += word[0]    
4893                         order = '%.2f' % ((p[    
4894                         name = phase.replace(    
4895                         devtl.html += devtl.h    
4896                 devtl.html += '</div>\n'         
4897                                                  
4898         hf = open(sysvals.htmlfile, 'w')         
4899         addCSS(hf, sysvals, len(testruns), ke    
4900                                                  
4901         # write the device timeline              
4902         hf.write(devtl.html)                     
4903         hf.write('<div id="devicedetailtitle"    
4904         hf.write('<div id="devicedetail" styl    
4905         # draw the colored boxes for the devi    
4906         for data in testruns:                    
4907                 hf.write('<div id="devicedeta    
4908                 pscolor = 'linear-gradient(to    
4909                 hf.write(devtl.html_phaselet.    
4910                         '0', '0', pscolor))      
4911                 for b in data.sortedPhases():    
4912                         phase = data.dmesg[b]    
4913                         length = phase['end']    
4914                         left = '%.3f' % (((ph    
4915                         width = '%.3f' % ((le    
4916                         hf.write(devtl.html_p    
4917                                 data.dmesg[b]    
4918                 hf.write(devtl.html_phaselet.    
4919                         '0', '0', pscolor))      
4920                 if sysvals.suspendmode == 'co    
4921                         hf.write(devtl.html_p    
4922                 hf.write('</div>\n')             
4923         hf.write('</div>\n')                     
4924                                                  
4925         # write the ftrace data (callgraph)      
4926         if sysvals.cgtest >= 0 and len(testru    
4927                 data = testruns[sysvals.cgtes    
4928         else:                                    
4929                 data = testruns[-1]              
4930         if sysvals.usecallgraph:                 
4931                 addCallgraphs(sysvals, hf, da    
4932                                                  
4933         # add the test log as a hidden div       
4934         if sysvals.testlog and sysvals.logmsg    
4935                 hf.write('<div id="testlog" s    
4936         # add the dmesg log as a hidden div      
4937         if sysvals.dmesglog and sysvals.dmesg    
4938                 hf.write('<div id="dmesglog"     
4939                 lf = sysvals.openlog(sysvals.    
4940                 for line in lf:                  
4941                         line = line.replace('    
4942                         hf.write(line)           
4943                 lf.close()                       
4944                 hf.write('</div>\n')             
4945         # add the ftrace log as a hidden div     
4946         if sysvals.ftracelog and sysvals.ftra    
4947                 hf.write('<div id="ftracelog"    
4948                 lf = sysvals.openlog(sysvals.    
4949                 for line in lf:                  
4950                         hf.write(line)           
4951                 lf.close()                       
4952                 hf.write('</div>\n')             
4953                                                  
4954         # write the footer and close             
4955         addScriptCode(hf, testruns)              
4956         hf.write('</body>\n</html>\n')           
4957         hf.close()                               
4958         return True                              
4959                                                  
4960 def addCSS(hf, sv, testcount=1, kerror=False,    
4961         kernel = sv.stamp['kernel']              
4962         host = sv.hostname[0].upper()+sv.host    
4963         mode = sv.suspendmode                    
4964         if sv.suspendmode in suspendmodename:    
4965                 mode = suspendmodename[sv.sus    
4966         title = host+' '+mode+' '+kernel         
4967                                                  
4968         # various format changes by flags        
4969         cgchk = 'checked'                        
4970         cgnchk = 'not(:checked)'                 
4971         if sv.cgexp:                             
4972                 cgchk = 'not(:checked)'          
4973                 cgnchk = 'checked'               
4974                                                  
4975         hoverZ = 'z-index:8;'                    
4976         if sv.usedevsrc:                         
4977                 hoverZ = ''                      
4978                                                  
4979         devlistpos = 'absolute'                  
4980         if testcount > 1:                        
4981                 devlistpos = 'relative'          
4982                                                  
4983         scaleTH = 20                             
4984         if kerror:                               
4985                 scaleTH = 60                     
4986                                                  
4987         # write the html header first (html h    
4988         html_header = '<!DOCTYPE html>\n<html    
4989         <meta http-equiv="content-type" conte    
4990         <title>'+title+'</title>\n\              
4991         <style type=\'text/css\'>\n\             
4992                 body {overflow-y:scroll;}\n\     
4993                 .stamp {width:100%;text-align    
4994                 .stamp.sysinfo {font:10px Ari    
4995                 .callgraph {margin-top:30px;b    
4996                 .callgraph article * {padding    
4997                 h1 {color:black;font:bold 30p    
4998                 t0 {color:black;font:bold 30p    
4999                 t1 {color:black;font:30px Tim    
5000                 t2 {color:black;font:25px Tim    
5001                 t3 {color:black;font:20px Tim    
5002                 t4 {color:black;font:bold 30p    
5003                 cS {font:bold 13px Times;}\n\    
5004                 table {width:100%;}\n\           
5005                 .gray {background:rgba(80,80,    
5006                 .green {background:rgba(204,2    
5007                 .purple {background:rgba(128,    
5008                 .yellow {background:rgba(255,    
5009                 .blue {background:rgba(169,20    
5010                 .time1 {font:22px Arial;borde    
5011                 .time2 {font:15px Arial;borde    
5012                 .testfail {font:bold 22px Ari    
5013                 td {text-align:center;}\n\       
5014                 r {color:#500000;font:15px Ta    
5015                 n {color:#505050;font:15px Ta    
5016                 .tdhl {color:red;}\n\            
5017                 .hide {display:none;}\n\         
5018                 .pf {display:none;}\n\           
5019                 .pf:'+cgchk+' + label {backgr    
5020                 .pf:'+cgnchk+' ~ label {backg    
5021                 .pf:'+cgchk+' ~ *:not(:nth-ch    
5022                 .zoombox {position:relative;w    
5023                 .timeline {position:relative;    
5024                 .thread {position:absolute;he    
5025                 .thread.ps {border-radius:3px    
5026                 .thread:hover {background:whi    
5027                 .thread.sec,.thread.sec:hover    
5028                 .hover {background:white;bord    
5029                 .hover.sync {background:white    
5030                 .hover.bg,.hover.kth,.hover.s    
5031                 .jiffie {position:absolute;po    
5032                 .traceevent {position:absolut    
5033                 .traceevent:hover {color:whit    
5034                 .phase {position:absolute;ove    
5035                 .phaselet {float:left;overflo    
5036                 .t {position:absolute;line-he    
5037                 .err {position:absolute;top:0    
5038                 .legend {position:relative; w    
5039                 .legend .square {position:abs    
5040                 button {height:40px;width:200    
5041                 .btnfmt {position:relative;fl    
5042                 .devlist {position:'+devlistp    
5043                 a:link {color:white;text-deco    
5044                 a:visited {color:white;}\n\      
5045                 a:hover {color:white;}\n\        
5046                 a:active {color:white;}\n\       
5047                 .version {position:relative;f    
5048                 #devicedetail {min-height:100    
5049                 .tblock {position:absolute;he    
5050                 .tback {position:absolute;wid    
5051                 .bg {z-index:1;}\n\              
5052 '+extra+'\                                       
5053         </style>\n</head>\n<body>\n'             
5054         hf.write(html_header)                    
5055                                                  
5056 # Function: addScriptCode                        
5057 # Description:                                   
5058 #        Adds the javascript code to the outp    
5059 # Arguments:                                     
5060 #        hf: the open html file pointer          
5061 #        testruns: array of Data objects from    
5062 def addScriptCode(hf, testruns):                 
5063         t0 = testruns[0].start * 1000            
5064         tMax = testruns[-1].end * 1000           
5065         hf.write('<script type="text/javascri    
5066         # create an array in javascript memor    
5067         detail = '      var devtable = [];\n'    
5068         for data in testruns:                    
5069                 topo = data.deviceTopology()     
5070                 detail += '     devtable[%d]     
5071         detail += '     var bounds = [%f,%f];    
5072         # add the code which will manipulate     
5073         hf.write(detail);                        
5074         script_code = r"""      var resolutio    
5075         var dragval = [0, 0];                    
5076         function redrawTimescale(t0, tMax, tS    
5077                 var rline = '<div class="t" s    
5078                 var tTotal = tMax - t0;          
5079                 var list = document.getElemen    
5080                 for (var i = 0; i < list.leng    
5081                         var timescale = list[    
5082                         var m0 = t0 + (tTotal    
5083                         var mTotal = tTotal*p    
5084                         var mMax = m0 + mTota    
5085                         var html = "";           
5086                         var divTotal = Math.f    
5087                         if(divTotal > 1000) c    
5088                         var divEdge = (mTotal    
5089                         var pos = 0.0, val =     
5090                         for (var j = 0; j < d    
5091                                 var htmlline     
5092                                 var mode = li    
5093                                 if(mode == "s    
5094                                         pos =    
5095                                         val =    
5096                                         if(j     
5097                                                  
5098                                         else     
5099                                                  
5100                                 } else {         
5101                                         pos =    
5102                                         val =    
5103                                         htmll    
5104                                         if(j     
5105                                                  
5106                                                  
5107                                                  
5108                                                  
5109                                 }                
5110                                 html += htmll    
5111                         }                        
5112                         timescale.innerHTML =    
5113                 }                                
5114         }                                        
5115         function zoomTimeline() {                
5116                 var dmesg = document.getEleme    
5117                 var zoombox = document.getEle    
5118                 var left = zoombox.scrollLeft    
5119                 var val = parseFloat(dmesg.st    
5120                 var newval = 100;                
5121                 var sh = window.outerWidth /     
5122                 if(this.id == "zoomin") {        
5123                         newval = val * 1.2;      
5124                         if(newval > 910034) n    
5125                         dmesg.style.width = n    
5126                         zoombox.scrollLeft =     
5127                 } else if (this.id == "zoomou    
5128                         newval = val / 1.2;      
5129                         if(newval < 100) newv    
5130                         dmesg.style.width = n    
5131                         zoombox.scrollLeft =     
5132                 } else {                         
5133                         zoombox.scrollLeft =     
5134                         dmesg.style.width = "    
5135                 }                                
5136                 var tS = [10000, 5000, 2000,     
5137                 var t0 = bounds[0];              
5138                 var tMax = bounds[1];            
5139                 var tTotal = tMax - t0;          
5140                 var wTotal = tTotal * 100.0 /    
5141                 var idx = 7*window.innerWidth    
5142                 for(var i = 0; (i < tS.length    
5143                 if(i >= tS.length) i = tS.len    
5144                 if(tS[i] == resolution) retur    
5145                 resolution = tS[i];              
5146                 redrawTimescale(t0, tMax, tS[    
5147         }                                        
5148         function deviceName(title) {             
5149                 var name = title.slice(0, tit    
5150                 return name;                     
5151         }                                        
5152         function deviceHover() {                 
5153                 var name = deviceName(this.ti    
5154                 var dmesg = document.getEleme    
5155                 var dev = dmesg.getElementsBy    
5156                 var cpu = -1;                    
5157                 if(name.match("CPU_ON\[[0-9]*    
5158                         cpu = parseInt(name.s    
5159                 else if(name.match("CPU_OFF\[    
5160                         cpu = parseInt(name.s    
5161                 for (var i = 0; i < dev.lengt    
5162                         dname = deviceName(de    
5163                         var cname = dev[i].cl    
5164                         if((cpu >= 0 && dname    
5165                                 (name == dnam    
5166                         {                        
5167                                 dev[i].classN    
5168                         } else {                 
5169                                 dev[i].classN    
5170                         }                        
5171                 }                                
5172         }                                        
5173         function deviceUnhover() {               
5174                 var dmesg = document.getEleme    
5175                 var dev = dmesg.getElementsBy    
5176                 for (var i = 0; i < dev.lengt    
5177                         dev[i].className = de    
5178                 }                                
5179         }                                        
5180         function deviceTitle(title, total, cp    
5181                 var prefix = "Total";            
5182                 if(total.length > 3) {           
5183                         prefix = "Average";      
5184                         total[1] = (total[1]+    
5185                         total[2] = (total[2]+    
5186                 }                                
5187                 var devtitle = document.getEl    
5188                 var name = deviceName(title);    
5189                 if(cpu >= 0) name = "CPU"+cpu    
5190                 var driver = "";                 
5191                 var tS = "<t2>(</t2>";           
5192                 var tR = "<t2>)</t2>";           
5193                 if(total[1] > 0)                 
5194                         tS = "<t2>("+prefix+"    
5195                 if(total[2] > 0)                 
5196                         tR = " <t2>"+prefix+"    
5197                 var s = title.indexOf("{");      
5198                 var e = title.indexOf("}");      
5199                 if((s >= 0) && (e >= 0))         
5200                         driver = title.slice(<    
5201                 if(total[1] > 0 && total[2] >    
5202                         devtitle.innerHTML =     
5203                 else                             
5204                         devtitle.innerHTML =     
5205                 return name;                     
5206         }                                        
5207         function deviceDetail() {                
5208                 var devinfo = document.getEle    
5209                 devinfo.style.display = "bloc    
5210                 var name = deviceName(this.ti    
5211                 var cpu = -1;                    
5212                 if(name.match("CPU_ON\[[0-9]*    
5213                         cpu = parseInt(name.s    
5214                 else if(name.match("CPU_OFF\[    
5215                         cpu = parseInt(name.s    
5216                 var dmesg = document.getEleme    
5217                 var dev = dmesg.getElementsBy    
5218                 var idlist = [];                 
5219                 var pdata = [[]];                
5220                 if(document.getElementById("d    
5221                         pdata = [[], []];        
5222                 var pd = pdata[0];               
5223                 var total = [0.0, 0.0, 0.0];     
5224                 for (var i = 0; i < dev.lengt    
5225                         dname = deviceName(de    
5226                         if((cpu >= 0 && dname    
5227                                 (name == dnam    
5228                         {                        
5229                                 idlist[idlist    
5230                                 var tidx = 1;    
5231                                 if(dev[i].id[    
5232                                         pd =     
5233                                 } else {         
5234                                         if(pd    
5235                                         if(to    
5236                                         pd =     
5237                                         tidx     
5238                                 }                
5239                                 var info = de    
5240                                 var pname = i    
5241                                 pd[pname] = p    
5242                                 total[0] += p    
5243                                 if(pname.inde    
5244                                         total    
5245                                 else             
5246                                         total    
5247                         }                        
5248                 }                                
5249                 var devname = deviceTitle(thi    
5250                 var left = 0.0;                  
5251                 for (var t = 0; t < pdata.len    
5252                         pd = pdata[t];           
5253                         devinfo = document.ge    
5254                         var phases = devinfo.    
5255                         for (var i = 0; i < p    
5256                                 if(phases[i].    
5257                                         var w    
5258                                         var f    
5259                                         if(w     
5260                                         var f    
5261                                         phase    
5262                                         phase    
5263                                         phase    
5264                                         left     
5265                                         var t    
5266                                         var p    
5267                                         phase    
5268                                 } else {         
5269                                         phase    
5270                                         phase    
5271                                 }                
5272                         }                        
5273                 }                                
5274                 if(typeof devstats !== 'undef    
5275                         callDetail(this.id, t    
5276                 var cglist = document.getElem    
5277                 if(!cglist) return;              
5278                 var cg = cglist.getElementsBy    
5279                 if(cg.length < 10) return;       
5280                 for (var i = 0; i < cg.length    
5281                         cgid = cg[i].id.split    
5282                         if(idlist.indexOf(cgi    
5283                                 cg[i].style.d    
5284                         } else {                 
5285                                 cg[i].style.d    
5286                         }                        
5287                 }                                
5288         }                                        
5289         function callDetail(devid, devtitle)     
5290                 if(!(devid in devstats) || de    
5291                         return;                  
5292                 var list = devstats[devid];      
5293                 var tmp = devtitle.split(" ")    
5294                 var name = tmp[0], phase = tm    
5295                 var dd = document.getElementB    
5296                 var total = parseFloat(tmp[1]    
5297                 var mlist = [];                  
5298                 var maxlen = 0;                  
5299                 var info = []                    
5300                 for(var i in list) {             
5301                         if(list[i][0] == "@")    
5302                                 info = list[i    
5303                                 continue;        
5304                         }                        
5305                         var tmp = list[i].spl    
5306                         var t = parseFloat(tm    
5307                         var p = (t*100.0/tota    
5308                         mlist[mlist.length] =    
5309                         if(f.length > maxlen)    
5310                                 maxlen = f.le    
5311                 }                                
5312                 var pad = 5;                     
5313                 if(mlist.length == 0) pad = 3    
5314                 var html = '<div style="paddi    
5315                 if(info.length > 2)              
5316                         html += " start=<b>"+    
5317                 if(info.length > 3)              
5318                         html += ", length<i>(    
5319                 if(info.length > 4)              
5320                         html += ", return=<b>    
5321                 html += "</t3></div>";           
5322                 if(mlist.length > 0) {           
5323                         html += '<table class    
5324                         for(var i in mlist)      
5325                                 html += "<td     
5326                         html += "</tr><tr><th    
5327                         for(var i in mlist)      
5328                                 html += "<td>    
5329                         html += "</tr><tr><th    
5330                         for(var i in mlist)      
5331                                 html += "<td>    
5332                         html += "</tr><tr><th    
5333                         for(var i in mlist)      
5334                                 html += "<td>    
5335                         html += "</tr></table    
5336                 }                                
5337                 dd.innerHTML = html;             
5338                 var height = (maxlen*5)+100;     
5339                 dd.style.height = height+"px"    
5340                 document.getElementById("devi    
5341         }                                        
5342         function callSelect() {                  
5343                 var cglist = document.getElem    
5344                 if(!cglist) return;              
5345                 var cg = cglist.getElementsBy    
5346                 for (var i = 0; i < cg.length    
5347                         if(this.id == cg[i].i    
5348                                 cg[i].style.d    
5349                         } else {                 
5350                                 cg[i].style.d    
5351                         }                        
5352                 }                                
5353         }                                        
5354         function devListWindow(e) {              
5355                 var win = window.open();         
5356                 var html = "<title>"+e.target    
5357                         "<style type=\"text/c    
5358                         "   ul {list-style-ty    
5359                         "</style>"               
5360                 var dt = devtable[0];            
5361                 if(e.target.id != "devlist1")    
5362                         dt = devtable[1];        
5363                 win.document.write(html+dt);     
5364         }                                        
5365         function errWindow() {                   
5366                 var range = this.id.split("_"    
5367                 var idx1 = parseInt(range[0])    
5368                 var idx2 = parseInt(range[1])    
5369                 var win = window.open();         
5370                 var log = document.getElement    
5371                 var title = "<title>dmesg log    
5372                 var text = log.innerHTML.spli    
5373                 var html = "";                   
5374                 for(var i = 0; i < text.lengt    
5375                         if(i == idx1) {          
5376                                 html += "<e i    
5377                         } else if(i > idx1 &&    
5378                                 html += "<e>"    
5379                         } else {                 
5380                                 html += text[    
5381                         }                        
5382                 }                                
5383                 win.document.write("<style>e{    
5384                 win.location.hash = "#target"    
5385                 win.document.close();            
5386         }                                        
5387         function logWindow(e) {                  
5388                 var name = e.target.id.slice(    
5389                 var win = window.open();         
5390                 var log = document.getElement    
5391                 var title = "<title>"+documen    
5392                 win.document.write(title+"<pr    
5393                 win.document.close();            
5394         }                                        
5395         function onMouseDown(e) {                
5396                 dragval[0] = e.clientX;          
5397                 dragval[1] = document.getElem    
5398                 document.onmousemove = onMous    
5399         }                                        
5400         function onMouseMove(e) {                
5401                 var zoombox = document.getEle    
5402                 zoombox.scrollLeft = dragval[    
5403         }                                        
5404         function onMouseUp(e) {                  
5405                 document.onmousemove = null;     
5406         }                                        
5407         function onKeyPress(e) {                 
5408                 var c = e.charCode;              
5409                 if(c != 42 && c != 43 && c !=    
5410                 var click = document.createEv    
5411                 click.initEvent("click", true    
5412                 if(c == 43)                      
5413                         document.getElementBy    
5414                 else if(c == 45)                 
5415                         document.getElementBy    
5416                 else if(c == 42)                 
5417                         document.getElementBy    
5418         }                                        
5419         window.addEventListener("resize", fun    
5420         window.addEventListener("load", funct    
5421                 var dmesg = document.getEleme    
5422                 dmesg.style.width = "100%"       
5423                 dmesg.onmousedown = onMouseDo    
5424                 document.onmouseup = onMouseU    
5425                 document.onkeypress = onKeyPr    
5426                 document.getElementById("zoom    
5427                 document.getElementById("zoom    
5428                 document.getElementById("zoom    
5429                 var list = document.getElemen    
5430                 for (var i = 0; i < list.leng    
5431                         list[i].onclick = err    
5432                 var list = document.getElemen    
5433                 for (var i = 0; i < list.leng    
5434                         list[i].onclick = log    
5435                 list = document.getElementsBy    
5436                 for (var i = 0; i < list.leng    
5437                         list[i].onclick = dev    
5438                 var dev = dmesg.getElementsBy    
5439                 for (var i = 0; i < dev.lengt    
5440                         dev[i].onclick = devi    
5441                         dev[i].onmouseover =     
5442                         dev[i].onmouseout = d    
5443                 }                                
5444                 var dev = dmesg.getElementsBy    
5445                 for (var i = 0; i < dev.lengt    
5446                         dev[i].onclick = call    
5447                 zoomTimeline();                  
5448         });                                      
5449 </script> """                                    
5450         hf.write(script_code);                   
5451                                                  
5452 # Function: executeSuspend                       
5453 # Description:                                   
5454 #        Execute system suspend through the s    
5455 #        dmesg and ftrace files to the test o    
5456 def executeSuspend(quiet=False):                 
5457         sv, tp, pm = sysvals, sysvals.tpath,     
5458         if sv.wifi:                              
5459                 wifi = sv.checkWifi()            
5460                 sv.dlog('wifi check, connecte    
5461         testdata = []                            
5462         # run these commands to prepare the s    
5463         if sv.display:                           
5464                 if not quiet:                    
5465                         pprint('SET DISPLAY T    
5466                 ret = sv.displayControl(sv.di    
5467                 sv.dlog('xset display %s, ret    
5468                 time.sleep(1)                    
5469         if sv.sync:                              
5470                 if not quiet:                    
5471                         pprint('SYNCING FILES    
5472                 sv.dlog('syncing filesystems'    
5473                 call('sync', shell=True)         
5474         sv.dlog('read dmesg')                    
5475         sv.initdmesg()                           
5476         sv.dlog('cmdinfo before')                
5477         sv.cmdinfo(True)                         
5478         sv.start(pm)                             
5479         # execute however many s/r runs reque    
5480         for count in range(1,sv.execcount+1):    
5481                 # x2delay in between test run    
5482                 if(count > 1 and sv.x2delay >    
5483                         sv.fsetVal('WAIT %d'     
5484                         time.sleep(sv.x2delay    
5485                         sv.fsetVal('WAIT END'    
5486                 # start message                  
5487                 if sv.testcommand != '':         
5488                         pprint('COMMAND START    
5489                 else:                            
5490                         if(sv.rtcwake):          
5491                                 pprint('SUSPE    
5492                         else:                    
5493                                 pprint('SUSPE    
5494                 # set rtcwake                    
5495                 if(sv.rtcwake):                  
5496                         if not quiet:            
5497                                 pprint('will     
5498                         sv.dlog('enable RTC w    
5499                         sv.rtcWakeAlarmOn()      
5500                 # start of suspend trace mark    
5501                 sv.fsetVal(datetime.now().str    
5502                 # predelay delay                 
5503                 if(count == 1 and sv.predelay    
5504                         sv.fsetVal('WAIT %d'     
5505                         time.sleep(sv.predela    
5506                         sv.fsetVal('WAIT END'    
5507                 # initiate suspend or command    
5508                 sv.dlog('system executing a s    
5509                 tdata = {'error': ''}            
5510                 if sv.testcommand != '':         
5511                         res = call(sv.testcom    
5512                         if res != 0:             
5513                                 tdata['error'    
5514                 else:                            
5515                         s0ixready = sv.s0ixSu    
5516                         mode = sv.suspendmode    
5517                         if sv.memmode and os.    
5518                                 mode = 'mem'     
5519                                 sv.testVal(sv    
5520                         if sv.diskmode and os    
5521                                 mode = 'disk'    
5522                                 sv.testVal(sv    
5523                         if sv.acpidebug:         
5524                                 sv.testVal(sv    
5525                         if ((mode == 'freeze'    
5526                                 and sv.haveTu    
5527                                 # execution w    
5528                                 retval, turbo    
5529                                 if retval !=     
5530                                         tdata    
5531                                 if turbo:        
5532                                         tdata    
5533                         else:                    
5534                                 pf = open(sv.    
5535                                 pf.write(mode    
5536                                 # execution w    
5537                                 try:             
5538                                         pf.fl    
5539                                         pf.cl    
5540                                 except Except    
5541                                         tdata    
5542                 sv.fsetVal('CMD COMPLETE', 't    
5543                 sv.dlog('system returned')       
5544                 # reset everything               
5545                 sv.testVal('restoreall')         
5546                 if(sv.rtcwake):                  
5547                         sv.dlog('disable RTC     
5548                         sv.rtcWakeAlarmOff()     
5549                 # postdelay delay                
5550                 if(count == sv.execcount and     
5551                         sv.fsetVal('WAIT %d'     
5552                         time.sleep(sv.postdel    
5553                         sv.fsetVal('WAIT END'    
5554                 # return from suspend            
5555                 pprint('RESUME COMPLETE')        
5556                 if(count < sv.execcount):        
5557                         sv.fsetVal(datetime.n    
5558                 elif(not sv.wifitrace):          
5559                         sv.fsetVal(datetime.n    
5560                         sv.stop(pm)              
5561                 if sv.wifi and wifi:             
5562                         tdata['wifi'] = sv.po    
5563                         sv.dlog('wifi check,     
5564                 if(count == sv.execcount and     
5565                         sv.fsetVal(datetime.n    
5566                         sv.stop(pm)              
5567                 if sv.netfix:                    
5568                         tdata['netfix'] = sv.    
5569                         sv.dlog('netfix, %s'     
5570                 if(sv.suspendmode == 'mem' or    
5571                         sv.dlog('read the ACP    
5572                         tdata['fw'] = getFPDT    
5573                 testdata.append(tdata)           
5574         sv.dlog('cmdinfo after')                 
5575         cmdafter = sv.cmdinfo(False)             
5576         # grab a copy of the dmesg output        
5577         if not quiet:                            
5578                 pprint('CAPTURING DMESG')        
5579         sv.getdmesg(testdata)                    
5580         # grab a copy of the ftrace output       
5581         if sv.useftrace:                         
5582                 if not quiet:                    
5583                         pprint('CAPTURING TRA    
5584                 op = sv.writeDatafileHeader(s    
5585                 fp = open(tp+'trace', 'rb')      
5586                 op.write(ascii(fp.read()))       
5587                 op.close()                       
5588                 sv.fsetVal('', 'trace')          
5589                 sv.platforminfo(cmdafter)        
5590                                                  
5591 def readFile(file):                              
5592         if os.path.islink(file):                 
5593                 return os.readlink(file).spli    
5594         else:                                    
5595                 return sysvals.getVal(file).s    
5596                                                  
5597 # Function: ms2nice                              
5598 # Description:                                   
5599 #        Print out a very concise time string    
5600 # Output:                                        
5601 #        The time string, e.g. "1901m16s"        
5602 def ms2nice(val):                                
5603         val = int(val)                           
5604         h = val // 3600000                       
5605         m = (val // 60000) % 60                  
5606         s = (val // 1000) % 60                   
5607         if h > 0:                                
5608                 return '%d:%02d:%02d' % (h, m    
5609         if m > 0:                                
5610                 return '%02d:%02d' % (m, s)      
5611         return '%ds' % s                         
5612                                                  
5613 def yesno(val):                                  
5614         list = {'enabled':'A', 'disabled':'S'    
5615                 'active':'A', 'suspended':'S'    
5616         if val not in list:                      
5617                 return ' '                       
5618         return list[val]                         
5619                                                  
5620 # Function: deviceInfo                           
5621 # Description:                                   
5622 #        Detect all the USB hosts and devices    
5623 #        a list of USB device names to sysval    
5624 def deviceInfo(output=''):                       
5625         if not output:                           
5626                 pprint('LEGEND\n'\               
5627                 '----------------------------    
5628                 '  A = async/sync PM queue (A    
5629                 '  R = runtime suspend enable    
5630                 '  S = runtime status active/    
5631                 '  U = runtime usage count\n'    
5632                 '----------------------------    
5633                 'DEVICE                     N    
5634                 '----------------------------    
5635                                                  
5636         res = []                                 
5637         tgtval = 'runtime_status'                
5638         lines = dict()                           
5639         for dirname, dirnames, filenames in o    
5640                 if(not re.match(r'.*/power',     
5641                         'control' not in file    
5642                         tgtval not in filenam    
5643                         continue                 
5644                 name = ''                        
5645                 dirname = dirname[:-6]           
5646                 device = dirname.split('/')[-    
5647                 power = dict()                   
5648                 power[tgtval] = readFile('%s/    
5649                 # only list devices which sup    
5650                 if power[tgtval] not in ['act    
5651                         continue                 
5652                 for i in ['product', 'driver'    
5653                         file = '%s/%s' % (dir    
5654                         if os.path.exists(fil    
5655                                 name = readFi    
5656                                 break            
5657                 for i in ['async', 'control',    
5658                         'runtime_active_kids'    
5659                         'runtime_suspended_ti    
5660                         if i in filenames:       
5661                                 power[i] = re    
5662                 if output:                       
5663                         if power['control'] =    
5664                                 res.append('%    
5665                         continue                 
5666                 lines[dirname] = '%-26s %-26s    
5667                         (device[:26], name[:2    
5668                         yesno(power['async'])    
5669                         yesno(power['control'    
5670                         yesno(power['runtime_    
5671                         power['runtime_usage'    
5672                         power['runtime_active    
5673                         ms2nice(power['runtim    
5674                         ms2nice(power['runtim    
5675         for i in sorted(lines):                  
5676                 print(lines[i])                  
5677         return res                               
5678                                                  
5679 # Function: getModes                             
5680 # Description:                                   
5681 #        Determine the supported power modes     
5682 # Output:                                        
5683 #        A string list of the available modes    
5684 def getModes():                                  
5685         modes = []                               
5686         if(os.path.exists(sysvals.powerfile))    
5687                 fp = open(sysvals.powerfile,     
5688                 modes = fp.read().split()        
5689                 fp.close()                       
5690         if(os.path.exists(sysvals.mempowerfil    
5691                 deep = False                     
5692                 fp = open(sysvals.mempowerfil    
5693                 for m in fp.read().split():      
5694                         memmode = m.strip('[]    
5695                         if memmode == 'deep':    
5696                                 deep = True      
5697                         else:                    
5698                                 modes.append(    
5699                 fp.close()                       
5700                 if 'mem' in modes and not dee    
5701                         modes.remove('mem')      
5702         if('disk' in modes and os.path.exists    
5703                 fp = open(sysvals.diskpowerfi    
5704                 for m in fp.read().split():      
5705                         modes.append('disk-%s    
5706                 fp.close()                       
5707         return modes                             
5708                                                  
5709 def dmidecode_backup(out, fatal=False):          
5710         cpath, spath, info = '/proc/cpuinfo',    
5711                 'bios-vendor': 'bios_vendor',    
5712                 'bios-version': 'bios_version    
5713                 'bios-release-date': 'bios_da    
5714                 'system-manufacturer': 'sys_v    
5715                 'system-product-name': 'produ    
5716                 'system-version': 'product_ve    
5717                 'system-serial-number': 'prod    
5718                 'baseboard-manufacturer': 'bo    
5719                 'baseboard-product-name': 'bo    
5720                 'baseboard-version': 'board_v    
5721                 'baseboard-serial-number': 'b    
5722                 'chassis-manufacturer': 'chas    
5723                 'chassis-version': 'chassis_v    
5724                 'chassis-serial-number': 'cha    
5725         }                                        
5726         for key in info:                         
5727                 if key not in out:               
5728                         val = sysvals.getVal(    
5729                         if val and val.lower(    
5730                                 out[key] = va    
5731         if 'processor-version' not in out and    
5732                 with open(cpath, 'r') as fp:     
5733                         for line in fp:          
5734                                 m = re.match(    
5735                                 if m:            
5736                                         out['    
5737                                         break    
5738         if fatal and len(out) < 1:               
5739                 doError('dmidecode failed to     
5740                         (sysvals.mempath, spa    
5741         return out                               
5742                                                  
5743 # Function: dmidecode                            
5744 # Description:                                   
5745 #        Read the bios tables and pull out sy    
5746 # Arguments:                                     
5747 #        mempath: /dev/mem or custom mem path    
5748 #        fatal: True to exit on error, False     
5749 # Output:                                        
5750 #        A dict object with all available key    
5751 def dmidecode(mempath, fatal=False):             
5752         out = dict()                             
5753         if(not (os.path.exists(mempath) and o    
5754                 return dmidecode_backup(out,     
5755                                                  
5756         # the list of values to retrieve, wit    
5757         info = {                                 
5758                 'bios-vendor': (0, 4),           
5759                 'bios-version': (0, 5),          
5760                 'bios-release-date': (0, 8),     
5761                 'system-manufacturer': (1, 4)    
5762                 'system-product-name': (1, 5)    
5763                 'system-version': (1, 6),        
5764                 'system-serial-number': (1, 7    
5765                 'baseboard-manufacturer': (2,    
5766                 'baseboard-product-name': (2,    
5767                 'baseboard-version': (2, 6),     
5768                 'baseboard-serial-number': (2    
5769                 'chassis-manufacturer': (3, 4    
5770                 'chassis-version': (3, 6),       
5771                 'chassis-serial-number': (3,     
5772                 'processor-manufacturer': (4,    
5773                 'processor-version': (4, 16),    
5774         }                                        
5775                                                  
5776         # by default use legacy scan, but try    
5777         memaddr, memsize = 0xf0000, 0x10000      
5778         for ep in ['/sys/firmware/efi/systab'    
5779                 if not os.path.exists(ep) or     
5780                         continue                 
5781                 fp = open(ep, 'r')               
5782                 buf = fp.read()                  
5783                 fp.close()                       
5784                 i = buf.find('SMBIOS=')          
5785                 if i >= 0:                       
5786                         try:                     
5787                                 memaddr = int    
5788                                 memsize = 0x2    
5789                         except:                  
5790                                 continue         
5791                                                  
5792         # read in the memory for scanning        
5793         try:                                     
5794                 fp = open(mempath, 'rb')         
5795                 fp.seek(memaddr)                 
5796                 buf = fp.read(memsize)           
5797         except:                                  
5798                 return dmidecode_backup(out,     
5799         fp.close()                               
5800                                                  
5801         # search for either an SM table or DM    
5802         i = base = length = num = 0              
5803         while(i < memsize):                      
5804                 if buf[i:i+4] == b'_SM_' and     
5805                         length = struct.unpac    
5806                         base, num = struct.un    
5807                         break                    
5808                 elif buf[i:i+5] == b'_DMI_':     
5809                         length = struct.unpac    
5810                         base, num = struct.un    
5811                         break                    
5812                 i += 16                          
5813         if base == 0 and length == 0 and num     
5814                 return dmidecode_backup(out,     
5815                                                  
5816         # read in the SM or DMI table            
5817         try:                                     
5818                 fp = open(mempath, 'rb')         
5819                 fp.seek(base)                    
5820                 buf = fp.read(length)            
5821         except:                                  
5822                 return dmidecode_backup(out,     
5823         fp.close()                               
5824                                                  
5825         # scan the table for the values we wa    
5826         count = i = 0                            
5827         while(count < num and i <= len(buf) -    
5828                 type, size, handle = struct.u    
5829                 n = i + size                     
5830                 while n < len(buf) - 1:          
5831                         if 0 == struct.unpack    
5832                                 break            
5833                         n += 1                   
5834                 data = buf[i+size:n+2].split(    
5835                 for name in info:                
5836                         itype, idxadr = info[    
5837                         if itype == type:        
5838                                 idx = struct.    
5839                                 if idx > 0 an    
5840                                         s = d    
5841                                         if s.    
5842                                                  
5843                 i = n + 2                        
5844                 count += 1                       
5845         return out                               
5846                                                  
5847 # Function: getFPDT                              
5848 # Description:                                   
5849 #        Read the acpi bios tables and pull o    
5850 # Arguments:                                     
5851 #        output: True to output the info to s    
5852 def getFPDT(output):                             
5853         rectype = {}                             
5854         rectype[0] = 'Firmware Basic Boot Per    
5855         rectype[1] = 'S3 Performance Table Re    
5856         prectype = {}                            
5857         prectype[0] = 'Basic S3 Resume Perfor    
5858         prectype[1] = 'Basic S3 Suspend Perfo    
5859                                                  
5860         sysvals.rootCheck(True)                  
5861         if(not os.path.exists(sysvals.fpdtpat    
5862                 if(output):                      
5863                         doError('file does no    
5864                 return False                     
5865         if(not os.access(sysvals.fpdtpath, os    
5866                 if(output):                      
5867                         doError('file is not     
5868                 return False                     
5869         if(not os.path.exists(sysvals.mempath    
5870                 if(output):                      
5871                         doError('file does no    
5872                 return False                     
5873         if(not os.access(sysvals.mempath, os.    
5874                 if(output):                      
5875                         doError('file is not     
5876                 return False                     
5877                                                  
5878         fp = open(sysvals.fpdtpath, 'rb')        
5879         buf = fp.read()                          
5880         fp.close()                               
5881                                                  
5882         if(len(buf) < 36):                       
5883                 if(output):                      
5884                         doError('Invalid FPDT    
5885                                 'be at least     
5886                 return False                     
5887                                                  
5888         table = struct.unpack('4sIBB6s8sI4sI'    
5889         if(output):                              
5890                 pprint('\n'\                     
5891                 'Firmware Performance Data Ta    
5892                 '                  Signature     
5893                 '               Table Length     
5894                 '                   Revision     
5895                 '                   Checksum     
5896                 '                     OEM ID     
5897                 '               OEM Table ID     
5898                 '               OEM Revision     
5899                 '                 Creator ID     
5900                 '           Creator Revision     
5901                 '' % (ascii(table[0]), ascii(    
5902                         table[3], ascii(table    
5903                         ascii(table[7]), tabl    
5904                                                  
5905         if(table[0] != b'FPDT'):                 
5906                 if(output):                      
5907                         doError('Invalid FPDT    
5908                 return False                     
5909         if(len(buf) <= 36):                      
5910                 return False                     
5911         i = 0                                    
5912         fwData = [0, 0]                          
5913         records = buf[36:]                       
5914         try:                                     
5915                 fp = open(sysvals.mempath, 'r    
5916         except:                                  
5917                 pprint('WARNING: /dev/mem is     
5918                 return False                     
5919         while(i < len(records)):                 
5920                 header = struct.unpack('HBB',    
5921                 if(header[0] not in rectype):    
5922                         i += header[1]           
5923                         continue                 
5924                 if(header[1] != 16):             
5925                         i += header[1]           
5926                         continue                 
5927                 addr = struct.unpack('Q', rec    
5928                 try:                             
5929                         fp.seek(addr)            
5930                         first = fp.read(8)       
5931                 except:                          
5932                         if(output):              
5933                                 pprint('Bad a    
5934                         return [0, 0]            
5935                 rechead = struct.unpack('4sI'    
5936                 recdata = fp.read(rechead[1]-    
5937                 if(rechead[0] == b'FBPT'):       
5938                         record = struct.unpac    
5939                         if(output):              
5940                                 pprint('%s (%    
5941                                 '                
5942                                 '  OS Loader     
5943                                 ' OS Loader S    
5944                                 '     ExitBoo    
5945                                 '      ExitBo    
5946                                 '' % (rectype    
5947                                         recor    
5948                 elif(rechead[0] == b'S3PT'):     
5949                         if(output):              
5950                                 pprint('%s (%    
5951                         j = 0                    
5952                         while(j < len(recdata    
5953                                 prechead = st    
5954                                 if(prechead[0    
5955                                         conti    
5956                                 if(prechead[0    
5957                                         recor    
5958                                         fwDat    
5959                                         if(ou    
5960                                                  
5961                                                  
5962                                                  
5963                                                  
5964                                                  
5965                                                  
5966                                 elif(prechead    
5967                                         recor    
5968                                         fwDat    
5969                                         if(ou    
5970                                                  
5971                                                  
5972                                                  
5973                                                  
5974                                                  
5975                                                  
5976                                                  
5977                                 j += prechead    
5978                 if(output):                      
5979                         pprint('')               
5980                 i += header[1]                   
5981         fp.close()                               
5982         return fwData                            
5983                                                  
5984 # Function: statusCheck                          
5985 # Description:                                   
5986 #        Verify that the requested command an    
5987 #        print the results to the terminal       
5988 # Output:                                        
5989 #        True if the test will work, False if    
5990 def statusCheck(probecheck=False):               
5991         status = ''                              
5992                                                  
5993         pprint('Checking this system (%s)...'    
5994                                                  
5995         # check we have root access              
5996         res = sysvals.colorText('NO (No featu    
5997         if(sysvals.rootCheck(False)):            
5998                 res = 'YES'                      
5999         pprint('    have root access: %s' % r    
6000         if(res != 'YES'):                        
6001                 pprint('    Try running this     
6002                 return 'missing root access'     
6003                                                  
6004         # check sysfs is mounted                 
6005         res = sysvals.colorText('NO (No featu    
6006         if(os.path.exists(sysvals.powerfile))    
6007                 res = 'YES'                      
6008         pprint('    is sysfs mounted: %s' % r    
6009         if(res != 'YES'):                        
6010                 return 'sysfs is missing'        
6011                                                  
6012         # check target mode is a valid mode      
6013         if sysvals.suspendmode != 'command':     
6014                 res = sysvals.colorText('NO')    
6015                 modes = getModes()               
6016                 if(sysvals.suspendmode in mod    
6017                         res = 'YES'              
6018                 else:                            
6019                         status = '%s mode is     
6020                 pprint('    is "%s" a valid p    
6021                 if(res == 'NO'):                 
6022                         pprint('      valid p    
6023                         pprint('      please     
6024                                                  
6025         # check if ftrace is available           
6026         if sysvals.useftrace:                    
6027                 res = sysvals.colorText('NO')    
6028                 sysvals.useftrace = sysvals.v    
6029                 efmt = '"{0}" uses ftrace, an    
6030                 if sysvals.useftrace:            
6031                         res = 'YES'              
6032                 elif sysvals.usecallgraph:       
6033                         status = efmt.format(    
6034                 elif sysvals.usedevsrc:          
6035                         status = efmt.format(    
6036                 elif sysvals.useprocmon:         
6037                         status = efmt.format(    
6038                 pprint('    is ftrace support    
6039                                                  
6040         # check if kprobes are available         
6041         if sysvals.usekprobes:                   
6042                 res = sysvals.colorText('NO')    
6043                 sysvals.usekprobes = sysvals.    
6044                 if(sysvals.usekprobes):          
6045                         res = 'YES'              
6046                 else:                            
6047                         sysvals.usedevsrc = F    
6048                 pprint('    are kprobes suppo    
6049                                                  
6050         # what data source are we using          
6051         res = 'DMESG (very limited, ftrace is    
6052         if sysvals.useftrace:                    
6053                 sysvals.usetraceevents = True    
6054                 for e in sysvals.traceevents:    
6055                         if not os.path.exists    
6056                                 sysvals.usetr    
6057                 if(sysvals.usetraceevents):      
6058                         res = 'FTRACE (all tr    
6059         pprint('    timeline data source: %s'    
6060                                                  
6061         # check if rtcwake                       
6062         res = sysvals.colorText('NO')            
6063         if(sysvals.rtcpath != ''):               
6064                 res = 'YES'                      
6065         elif(sysvals.rtcwake):                   
6066                 status = 'rtcwake is not prop    
6067         pprint('    is rtcwake supported: %s'    
6068                                                  
6069         # check info commands                    
6070         pprint('    optional commands this to    
6071         no = sysvals.colorText('MISSING')        
6072         yes = sysvals.colorText('FOUND', 32)     
6073         for c in ['turbostat', 'mcelog', 'lsp    
6074                 if c == 'turbostat':             
6075                         res = yes if sysvals.    
6076                 else:                            
6077                         res = yes if sysvals.    
6078                 pprint('        %s: %s' % (c,    
6079                                                  
6080         if not probecheck:                       
6081                 return status                    
6082                                                  
6083         # verify kprobes                         
6084         if sysvals.usekprobes:                   
6085                 for name in sysvals.tracefunc    
6086                         sysvals.defaultKprobe    
6087                 if sysvals.usedevsrc:            
6088                         for name in sysvals.d    
6089                                 sysvals.defau    
6090                 sysvals.addKprobes(True)         
6091                                                  
6092         return status                            
6093                                                  
6094 # Function: doError                              
6095 # Description:                                   
6096 #        generic error function for catastrph    
6097 # Arguments:                                     
6098 #        msg: the error message to print         
6099 #        help: True if printHelp should be ca    
6100 def doError(msg, help=False):                    
6101         if(help == True):                        
6102                 printHelp()                      
6103         pprint('ERROR: %s\n' % msg)              
6104         sysvals.outputResult({'error':msg})      
6105         sys.exit(1)                              
6106                                                  
6107 # Function: getArgInt                            
6108 # Description:                                   
6109 #        pull out an integer argument from th    
6110 def getArgInt(name, args, min, max, main=True    
6111         if main:                                 
6112                 try:                             
6113                         arg = next(args)         
6114                 except:                          
6115                         doError(name+': no ar    
6116         else:                                    
6117                 arg = args                       
6118         try:                                     
6119                 val = int(arg)                   
6120         except:                                  
6121                 doError(name+': non-integer v    
6122         if(val < min or val > max):              
6123                 doError(name+': value should     
6124         return val                               
6125                                                  
6126 # Function: getArgFloat                          
6127 # Description:                                   
6128 #        pull out a float argument from the c    
6129 def getArgFloat(name, args, min, max, main=Tr    
6130         if main:                                 
6131                 try:                             
6132                         arg = next(args)         
6133                 except:                          
6134                         doError(name+': no ar    
6135         else:                                    
6136                 arg = args                       
6137         try:                                     
6138                 val = float(arg)                 
6139         except:                                  
6140                 doError(name+': non-numerical    
6141         if(val < min or val > max):              
6142                 doError(name+': value should     
6143         return val                               
6144                                                  
6145 def processData(live=False, quiet=False):        
6146         if not quiet:                            
6147                 pprint('PROCESSING: %s' % sys    
6148         sysvals.vprint('usetraceevents=%s, us    
6149                 (sysvals.usetraceevents, sysv    
6150         error = ''                               
6151         if(sysvals.usetraceevents):              
6152                 testruns, error = parseTraceL    
6153                 if sysvals.dmesgfile:            
6154                         for data in testruns:    
6155                                 data.extractE    
6156         else:                                    
6157                 testruns = loadKernelLog()       
6158                 for data in testruns:            
6159                         parseKernelLog(data)     
6160                 if(sysvals.ftracefile and (sy    
6161                         appendIncompleteTrace    
6162         if not sysvals.stamp:                    
6163                 pprint('ERROR: data does not     
6164                 return (testruns, {'error': '    
6165         shown = ['os', 'bios', 'biosdate', 'c    
6166                         'memsz', 'mode', 'num    
6167         sysvals.vprint('System Info:')           
6168         for key in sorted(sysvals.stamp):        
6169                 if key in shown:                 
6170                         sysvals.vprint('    %    
6171         sysvals.vprint('Command:\n    %s' % s    
6172         for data in testruns:                    
6173                 if data.turbostat:               
6174                         idx, s = 0, 'Turbosta    
6175                         for val in data.turbo    
6176                                 idx += len(va    
6177                                 if idx >= 80:    
6178                                         idx =    
6179                                         s +=     
6180                                 s += val + '     
6181                         sysvals.vprint(s)        
6182                 data.printDetails()              
6183         if len(sysvals.platinfo) > 0:            
6184                 sysvals.vprint('\nPlatform In    
6185                 for info in sysvals.platinfo:    
6186                         sysvals.vprint('[%s -    
6187                         sysvals.vprint(info[2    
6188                 sysvals.vprint('')               
6189         if sysvals.cgdump:                       
6190                 for data in testruns:            
6191                         data.debugPrint()        
6192                 sys.exit(0)                      
6193         if len(testruns) < 1:                    
6194                 pprint('ERROR: Not enough tes    
6195                 return (testruns, {'error': '    
6196         sysvals.vprint('Creating the html tim    
6197         createHTML(testruns, error)              
6198         if not quiet:                            
6199                 pprint('DONE:       %s' % sys    
6200         data = testruns[0]                       
6201         stamp = data.stamp                       
6202         stamp['suspend'], stamp['resume'] = d    
6203         if data.fwValid:                         
6204                 stamp['fwsuspend'], stamp['fw    
6205         if error:                                
6206                 stamp['error'] = error           
6207         return (testruns, stamp)                 
6208                                                  
6209 # Function: rerunTest                            
6210 # Description:                                   
6211 #        generate an output from an existing     
6212 def rerunTest(htmlfile=''):                      
6213         if sysvals.ftracefile:                   
6214                 doesTraceLogHaveTraceEvents()    
6215         if not sysvals.dmesgfile and not sysv    
6216                 doError('recreating this html    
6217         if htmlfile:                             
6218                 sysvals.htmlfile = htmlfile      
6219         else:                                    
6220                 sysvals.setOutputFile()          
6221         if os.path.exists(sysvals.htmlfile):     
6222                 if not os.path.isfile(sysvals    
6223                         doError('a directory     
6224                 elif not os.access(sysvals.ht    
6225                         doError('missing perm    
6226         testruns, stamp = processData()          
6227         sysvals.resetlog()                       
6228         return stamp                             
6229                                                  
6230 # Function: runTest                              
6231 # Description:                                   
6232 #        execute a suspend/resume, gather the    
6233 def runTest(n=0, quiet=False):                   
6234         # prepare for the test                   
6235         sysvals.initTestOutput('suspend')        
6236         op = sysvals.writeDatafileHeader(sysv    
6237         op.write('# EXECUTION TRACE START\n')    
6238         op.close()                               
6239         if n <= 1:                               
6240                 if sysvals.rs != 0:              
6241                         sysvals.dlog('%sablin    
6242                         sysvals.setRuntimeSus    
6243                 if sysvals.display:              
6244                         ret = sysvals.display    
6245                         sysvals.dlog('xset di    
6246         sysvals.testVal(sysvals.pmdpath, 'bas    
6247         sysvals.testVal(sysvals.s0ixpath, 'ba    
6248         sysvals.dlog('initialize ftrace')        
6249         sysvals.initFtrace(quiet)                
6250                                                  
6251         # execute the test                       
6252         executeSuspend(quiet)                    
6253         sysvals.cleanupFtrace()                  
6254         if sysvals.skiphtml:                     
6255                 sysvals.outputResult({}, n)      
6256                 sysvals.sudoUserchown(sysvals    
6257                 return                           
6258         testruns, stamp = processData(True, q    
6259         for data in testruns:                    
6260                 del data                         
6261         sysvals.sudoUserchown(sysvals.testdir    
6262         sysvals.outputResult(stamp, n)           
6263         if 'error' in stamp:                     
6264                 return 2                         
6265         return 0                                 
6266                                                  
6267 def find_in_html(html, start, end, firstonly=    
6268         cnt, out, list = len(html), [], []       
6269         if firstonly:                            
6270                 m = re.search(start, html)       
6271                 if m:                            
6272                         list.append(m)           
6273         else:                                    
6274                 list = re.finditer(start, htm    
6275         for match in list:                       
6276                 s = match.end()                  
6277                 e = cnt if (len(out) < 1 or s    
6278                 m = re.search(end, html[s:e])    
6279                 if not m:                        
6280                         break                    
6281                 e = s + m.start()                
6282                 str = html[s:e]                  
6283                 if end == 'ms':                  
6284                         num = re.search(r'[-+    
6285                         str = num.group() if     
6286                 if firstonly:                    
6287                         return str               
6288                 out.append(str)                  
6289         if firstonly:                            
6290                 return ''                        
6291         return out                               
6292                                                  
6293 def data_from_html(file, outpath, issues, ful    
6294         try:                                     
6295                 html = open(file, 'r').read()    
6296         except:                                  
6297                 html = ascii(open(file, 'rb')    
6298         sysvals.htmlfile = os.path.relpath(fi    
6299         # extract general info                   
6300         suspend = find_in_html(html, 'Kernel     
6301         resume = find_in_html(html, 'Kernel R    
6302         sysinfo = find_in_html(html, '<div cl    
6303         line = find_in_html(html, '<div class    
6304         stmp = line.split()                      
6305         if not suspend or not resume or len(s    
6306                 return False                     
6307         try:                                     
6308                 dt = datetime.strptime(' '.jo    
6309         except:                                  
6310                 return False                     
6311         sysvals.hostname = stmp[0]               
6312         tstr = dt.strftime('%Y/%m/%d %H:%M:%S    
6313         error = find_in_html(html, '<table cl    
6314         if error:                                
6315                 m = re.match(r'[a-z0-9]* fail    
6316                 if m:                            
6317                         result = 'fail in %s'    
6318                 else:                            
6319                         result = 'fail'          
6320         else:                                    
6321                 result = 'pass'                  
6322         # extract error info                     
6323         tp, ilist = False, []                    
6324         extra = dict()                           
6325         log = find_in_html(html, '<div id="dm    
6326                 '</div>').strip()                
6327         if log:                                  
6328                 d = Data(0)                      
6329                 d.end = 999999999                
6330                 d.dmesgtext = log.split('\n')    
6331                 tp = d.extractErrorInfo()        
6332                 if len(issues) < 100:            
6333                         for msg in tp.msglist    
6334                                 sysvals.error    
6335                 if stmp[2] == 'freeze':          
6336                         extra = d.turbostatIn    
6337                 elist = dict()                   
6338                 for dir in d.errorinfo:          
6339                         for err in d.errorinf    
6340                                 if err[0] not    
6341                                         elist    
6342                                 elist[err[0]]    
6343                 for i in elist:                  
6344                         ilist.append('%sx%d'     
6345                 line = find_in_html(log, '# w    
6346                 if line:                         
6347                         extra['wifi'] = line     
6348                 line = find_in_html(log, '# n    
6349                 if line:                         
6350                         extra['netfix'] = lin    
6351                 line = find_in_html(log, '# c    
6352                 if line:                         
6353                         m = re.match(r'.* -m     
6354                         if m:                    
6355                                 extra['fullmo    
6356         low = find_in_html(html, 'freeze time    
6357         for lowstr in ['waking', '+']:           
6358                 if not low:                      
6359                         break                    
6360                 if lowstr not in low:            
6361                         continue                 
6362                 if lowstr == '+':                
6363                         issue = 'S2LOOPx%d' %    
6364                 else:                            
6365                         m = re.match(r'.*waki    
6366                         issue = 'S2WAKEx%s' %    
6367                 match = [i for i in issues if    
6368                 if len(match) > 0:               
6369                         match[0]['count'] +=     
6370                         if sysvals.hostname n    
6371                                 match[0]['url    
6372                         elif sysvals.htmlfile    
6373                                 match[0]['url    
6374                 else:                            
6375                         issues.append({          
6376                                 'match': issu    
6377                                 'urls': {sysv    
6378                         })                       
6379                 ilist.append(issue)              
6380         # extract device info                    
6381         devices = dict()                         
6382         for line in html.split('\n'):            
6383                 m = re.match(r' *<div id=\"[a    
6384                 if not m or 'thread kth' in l    
6385                         continue                 
6386                 m = re.match(r'(?P<n>.*) \((?    
6387                 if not m:                        
6388                         continue                 
6389                 name, time, phase = m.group('    
6390                 if name == 'async_synchronize    
6391                         continue                 
6392                 if ' async' in name or ' sync    
6393                         name = ' '.join(name.    
6394                 if phase.startswith('suspend'    
6395                         d = 'suspend'            
6396                 elif phase.startswith('resume    
6397                         d = 'resume'             
6398                 else:                            
6399                         continue                 
6400                 if d not in devices:             
6401                         devices[d] = dict()      
6402                 if name not in devices[d]:       
6403                         devices[d][name] = 0.    
6404                 devices[d][name] += float(tim    
6405         # create worst device info               
6406         worst = dict()                           
6407         for d in ['suspend', 'resume']:          
6408                 worst[d] = {'name':'', 'time'    
6409                 dev = devices[d] if d in devi    
6410                 if dev and len(dev.keys()) >     
6411                         n = sorted(dev, key=l    
6412                         worst[d]['name'], wor    
6413         data = {                                 
6414                 'mode': stmp[2],                 
6415                 'host': stmp[0],                 
6416                 'kernel': stmp[1],               
6417                 'sysinfo': sysinfo,              
6418                 'time': tstr,                    
6419                 'result': result,                
6420                 'issues': ' '.join(ilist),       
6421                 'suspend': suspend,              
6422                 'resume': resume,                
6423                 'devlist': devices,              
6424                 'sus_worst': worst['suspend']    
6425                 'sus_worsttime': worst['suspe    
6426                 'res_worst': worst['resume'][    
6427                 'res_worsttime': worst['resum    
6428                 'url': sysvals.htmlfile,         
6429         }                                        
6430         for key in extra:                        
6431                 data[key] = extra[key]           
6432         if fulldetail:                           
6433                 data['funclist'] = find_in_ht    
6434         if tp:                                   
6435                 for arg in ['-multi ', '-info    
6436                         if arg in tp.cmdline:    
6437                                 data['target'    
6438                                 break            
6439         return data                              
6440                                                  
6441 def genHtml(subdir, force=False):                
6442         for dirname, dirnames, filenames in o    
6443                 sysvals.dmesgfile = sysvals.f    
6444                 for filename in filenames:       
6445                         file = os.path.join(d    
6446                         if sysvals.usable(fil    
6447                                 if(re.match(r    
6448                                         sysva    
6449                                 elif(re.match    
6450                                         sysva    
6451                 sysvals.setOutputFile()          
6452                 if (sysvals.dmesgfile or sysv    
6453                         (force or not sysvals    
6454                         pprint('FTRACE: %s' %    
6455                         if sysvals.dmesgfile:    
6456                                 pprint('DMESG    
6457                         rerunTest()              
6458                                                  
6459 # Function: runSummary                           
6460 # Description:                                   
6461 #        create a summary of tests in a sub-d    
6462 def runSummary(subdir, local=True, genhtml=Fa    
6463         inpath = os.path.abspath(subdir)         
6464         outpath = os.path.abspath('.') if loc    
6465         pprint('Generating a summary of folde    
6466         if genhtml:                              
6467                 genHtml(subdir)                  
6468         target, issues, testruns = '', [], []    
6469         desc = {'host':[],'mode':[],'kernel':    
6470         for dirname, dirnames, filenames in o    
6471                 for filename in filenames:       
6472                         if(not re.match(r'.*.    
6473                                 continue         
6474                         data = data_from_html    
6475                         if(not data):            
6476                                 continue         
6477                         if 'target' in data:     
6478                                 target = data    
6479                         testruns.append(data)    
6480                         for key in desc:         
6481                                 if data[key]     
6482                                         desc[    
6483         pprint('Summary files:')                 
6484         if len(desc['host']) == len(desc['mod    
6485                 title = '%s %s %s' % (desc['h    
6486                 if target:                       
6487                         title += ' %s' % targ    
6488         else:                                    
6489                 title = inpath                   
6490         createHTMLSummarySimple(testruns, os.    
6491         pprint('   summary.html         - tab    
6492         createHTMLDeviceSummary(testruns, os.    
6493         pprint('   summary-devices.html - ker    
6494         createHTMLIssuesSummary(testruns, iss    
6495         pprint('   summary-issues.html  - ker    
6496                                                  
6497 # Function: checkArgBool                         
6498 # Description:                                   
6499 #        check if a boolean string value is t    
6500 def checkArgBool(name, value):                   
6501         if value in switchvalues:                
6502                 if value in switchoff:           
6503                         return False             
6504                 return True                      
6505         doError('invalid boolean --> (%s: %s)    
6506         return False                             
6507                                                  
6508 # Function: configFromFile                       
6509 # Description:                                   
6510 #        Configure the script via the info in    
6511 def configFromFile(file):                        
6512         Config = configparser.ConfigParser()     
6513                                                  
6514         Config.read(file)                        
6515         sections = Config.sections()             
6516         overridekprobes = False                  
6517         overridedevkprobes = False               
6518         if 'Settings' in sections:               
6519                 for opt in Config.options('Se    
6520                         value = Config.get('S    
6521                         option = opt.lower()     
6522                         if(option == 'verbose    
6523                                 sysvals.verbo    
6524                         elif(option == 'addlo    
6525                                 sysvals.dmesg    
6526                         elif(option == 'dev')    
6527                                 sysvals.usede    
6528                         elif(option == 'proc'    
6529                                 sysvals.usepr    
6530                         elif(option == 'x2'):    
6531                                 if checkArgBo    
6532                                         sysva    
6533                         elif(option == 'callg    
6534                                 sysvals.useca    
6535                         elif(option == 'overr    
6536                                 overridekprob    
6537                         elif(option == 'overr    
6538                                 overridedevkp    
6539                         elif(option == 'skiph    
6540                                 sysvals.skiph    
6541                         elif(option == 'sync'    
6542                                 sysvals.sync     
6543                         elif(option == 'rs' o    
6544                                 if value in s    
6545                                         if va    
6546                                                  
6547                                         else:    
6548                                                  
6549                                 else:            
6550                                         doErr    
6551                         elif(option == 'displ    
6552                                 disopt = ['on    
6553                                 if value not     
6554                                         doErr    
6555                                 sysvals.displ    
6556                         elif(option == 'gzip'    
6557                                 sysvals.gzip     
6558                         elif(option == 'cgfil    
6559                                 sysvals.setCa    
6560                         elif(option == 'cgski    
6561                                 if value in s    
6562                                         sysva    
6563                                 else:            
6564                                         sysva    
6565                                         if(no    
6566                                                  
6567                         elif(option == 'cgtes    
6568                                 sysvals.cgtes    
6569                         elif(option == 'cgpha    
6570                                 d = Data(0)      
6571                                 if value not     
6572                                         doErr    
6573                                                  
6574                                 sysvals.cgpha    
6575                         elif(option == 'fadd'    
6576                                 file = sysval    
6577                                 if(not file):    
6578                                         doErr    
6579                                 sysvals.addFt    
6580                         elif(option == 'resul    
6581                                 sysvals.resul    
6582                         elif(option == 'multi    
6583                                 nums = value.    
6584                                 if len(nums)     
6585                                         doErr    
6586                                 sysvals.multi    
6587                         elif(option == 'devic    
6588                                 sysvals.setDe    
6589                         elif(option == 'expan    
6590                                 sysvals.cgexp    
6591                         elif(option == 'srgap    
6592                                 if checkArgBo    
6593                                         sysva    
6594                         elif(option == 'mode'    
6595                                 sysvals.suspe    
6596                         elif(option == 'comma    
6597                                 sysvals.testc    
6598                         elif(option == 'x2del    
6599                                 sysvals.x2del    
6600                         elif(option == 'prede    
6601                                 sysvals.prede    
6602                         elif(option == 'postd    
6603                                 sysvals.postd    
6604                         elif(option == 'maxde    
6605                                 sysvals.max_g    
6606                         elif(option == 'rtcwa    
6607                                 if value in s    
6608                                         sysva    
6609                                 else:            
6610                                         sysva    
6611                                         sysva    
6612                         elif(option == 'timep    
6613                                 sysvals.setPr    
6614                         elif(option == 'minde    
6615                                 sysvals.minde    
6616                         elif(option == 'calll    
6617                                 sysvals.calll    
6618                         elif(option == 'calll    
6619                                 sysvals.calll    
6620                         elif(option == 'mincg    
6621                                 sysvals.mincg    
6622                         elif(option == 'bufsi    
6623                                 sysvals.bufsi    
6624                         elif(option == 'outpu    
6625                                 sysvals.outdi    
6626                                                  
6627         if sysvals.suspendmode == 'command' a    
6628                 doError('No command supplied     
6629                                                  
6630         # compatibility errors                   
6631         if sysvals.usedevsrc and sysvals.usec    
6632                 doError('-dev is not compatib    
6633         if sysvals.usecallgraph and sysvals.u    
6634                 doError('-proc is not compati    
6635                                                  
6636         if overridekprobes:                      
6637                 sysvals.tracefuncs = dict()      
6638         if overridedevkprobes:                   
6639                 sysvals.dev_tracefuncs = dict    
6640                                                  
6641         kprobes = dict()                         
6642         kprobesec = 'dev_timeline_functions_'    
6643         if kprobesec in sections:                
6644                 for name in Config.options(kp    
6645                         text = Config.get(kpr    
6646                         kprobes[name] = (text    
6647         kprobesec = 'timeline_functions_'+pla    
6648         if kprobesec in sections:                
6649                 for name in Config.options(kp    
6650                         if name in kprobes:      
6651                                 doError('Dupl    
6652                         text = Config.get(kpr    
6653                         kprobes[name] = (text    
6654                                                  
6655         for name in kprobes:                     
6656                 function = name                  
6657                 format = name                    
6658                 color = ''                       
6659                 args = dict()                    
6660                 text, dev = kprobes[name]        
6661                 data = text.split()              
6662                 i = 0                            
6663                 for val in data:                 
6664                         # bracketted strings     
6665                         if val[0] == '[' and     
6666                                 for prop in v    
6667                                         p = p    
6668                                         if p[    
6669                                                  
6670                                                  
6671                                                  
6672                                                  
6673                                                  
6674                                 continue         
6675                         # first real arg shou    
6676                         if i == 0:               
6677                                 format = val     
6678                         # all other args are     
6679                         else:                    
6680                                 d = val.split    
6681                                 args[d[0]] =     
6682                         i += 1                   
6683                 if not function or not format    
6684                         doError('Invalid kpro    
6685                 for arg in re.findall('{(?P<n    
6686                         if arg not in args:      
6687                                 doError('Kpro    
6688                 if (dev and name in sysvals.d    
6689                         doError('Duplicate ti    
6690                                                  
6691                 kp = {                           
6692                         'name': name,            
6693                         'func': function,        
6694                         'format': format,        
6695                         sysvals.archargs: arg    
6696                 }                                
6697                 if color:                        
6698                         kp['color'] = color      
6699                 if dev:                          
6700                         sysvals.dev_tracefunc    
6701                 else:                            
6702                         sysvals.tracefuncs[na    
6703                                                  
6704 # Function: printHelp                            
6705 # Description:                                   
6706 #        print out the help text                 
6707 def printHelp():                                 
6708         pprint('\n%s v%s\n'\                     
6709         'Usage: sudo sleepgraph <options> <co    
6710         '\n'\                                    
6711         'Description:\n'\                        
6712         '  This tool is designed to assist ke    
6713         '  their linux stack\'s suspend/resum    
6714         '  with a few extra options enabled,     
6715         '  capture dmesg and ftrace data unti    
6716         '  transformed into a device timeline    
6717         '  a detailed view of which devices/s    
6718         '  time in suspend/resume.\n'\           
6719         '\n'\                                    
6720         '  If no specific command is given, t    
6721         '  a suspend/resume and capture the d    
6722         '\n'\                                    
6723         '  Generates output files in subdirec    
6724         '   HTML output:                    <    
6725         '   raw dmesg output:               <    
6726         '   raw ftrace output:              <    
6727         '\n'\                                    
6728         'Options:\n'\                            
6729         '   -h           Print this help text    
6730         '   -v           Print the current to    
6731         '   -config fn   Pull arguments and c    
6732         '   -verbose     Print extra informat    
6733         '   -m mode      Mode to initiate for    
6734         '   -o name      Overrides the output    
6735         '                default: suspend-{da    
6736         '   -rtcwake t   Wakeup t seconds aft    
6737         '   -addlogs     Add the dmesg and ft    
6738         '   -noturbostat Dont use turbostat i    
6739         '   -srgap       Add a visible gap in    
6740         '   -skiphtml    Run the test and cap    
6741         '   -result fn   Export a results tab    
6742         '   -wifi        If a wifi connection    
6743         '   -wifitrace   Trace kernel executi    
6744         '   -netfix      Use netfix to reset     
6745         '  [testprep]\n'\                        
6746         '   -sync        Sync the filesystems    
6747         '   -rs on/off   Enable/disable runti    
6748         '   -display m   Change the display m    
6749         '  [advanced]\n'\                        
6750         '   -gzip        Gzip the trace and d    
6751         '   -cmd {s}     Run the timeline ove    
6752         '   -proc        Add usermode process    
6753         '   -dev         Add kernel function     
6754         '   -x2          Run two suspend/resu    
6755         '   -x2delay t   Include t ms delay b    
6756         '   -predelay t  Include t ms delay b    
6757         '   -postdelay t Include t ms delay a    
6758         '   -mindev ms   Discard all device b    
6759         '   -multi n d   Execute <n> consecut    
6760         '                by a "d", "h", or "m    
6761         '                The outputs will be     
6762         '   -maxfail n   Abort a -multi run a    
6763         '  [debug]\n'\                           
6764         '   -f           Use ftrace to create    
6765         '   -ftop        Use ftrace on the to    
6766         '   -maxdepth N  limit the callgraph     
6767         '   -expandcg    pre-expand the callg    
6768         '   -fadd file   Add functions to be     
6769         '   -filter "d1,d2,..." Filter out al    
6770         '   -mincg  ms   Discard all callgrap    
6771         '   -cgphase P   Only show callgraph     
6772         '   -cgtest N    Only show callgraph     
6773         '   -timeprec N  Number of significan    
6774         '   -cgfilter S  Filter the callgraph    
6775         '   -cgskip file Callgraph functions     
6776         '   -bufsize N   Set trace buffer siz    
6777         '   -devdump     Print out all the ra    
6778         '   -cgdump      Print out all the ra    
6779         '\n'\                                    
6780         'Other commands:\n'\                     
6781         '   -modes       List available suspe    
6782         '   -status      Test to see if the s    
6783         '   -fpdt        Print out the conten    
6784         '   -wificheck   Print out wifi conne    
6785         '   -x<mode>     Test xset by togglin    
6786         '   -sysinfo     Print out system inf    
6787         '   -devinfo     Print out the pm set    
6788         '   -cmdinfo     Print out all the pl    
6789         '   -flist       Print the list of fu    
6790         '   -flistall    Print all functions     
6791         '   -summary dir Create a summary of     
6792         '  [redo]\n'\                            
6793         '   -ftrace ftracefile  Create HTML o    
6794         '   -dmesg dmesgfile    Create HTML o    
6795         '' % (sysvals.title, sysvals.version,    
6796         return True                              
6797                                                  
6798 # ----------------- MAIN --------------------    
6799 # exec start (skipped if script is loaded as     
6800 if __name__ == '__main__':                       
6801         genhtml = False                          
6802         cmd = ''                                 
6803         simplecmds = ['-sysinfo', '-modes', '    
6804                 '-devinfo', '-status', '-xon'    
6805                 '-xinit', '-xreset', '-xstat'    
6806         if '-f' in sys.argv:                     
6807                 sysvals.cgskip = sysvals.conf    
6808         # loop through the command line argum    
6809         args = iter(sys.argv[1:])                
6810         for arg in args:                         
6811                 if(arg == '-m'):                 
6812                         try:                     
6813                                 val = next(ar    
6814                         except:                  
6815                                 doError('No m    
6816                         if val == 'command' a    
6817                                 doError('No c    
6818                         sysvals.suspendmode =    
6819                 elif(arg in simplecmds):         
6820                         cmd = arg[1:]            
6821                 elif(arg == '-h'):               
6822                         printHelp()              
6823                         sys.exit(0)              
6824                 elif(arg == '-v'):               
6825                         pprint("Version %s" %    
6826                         sys.exit(0)              
6827                 elif(arg == '-debugtiming'):     
6828                         debugtiming = True       
6829                 elif(arg == '-x2'):              
6830                         sysvals.execcount = 2    
6831                 elif(arg == '-x2delay'):         
6832                         sysvals.x2delay = get    
6833                 elif(arg == '-predelay'):        
6834                         sysvals.predelay = ge    
6835                 elif(arg == '-postdelay'):       
6836                         sysvals.postdelay = g    
6837                 elif(arg == '-f'):               
6838                         sysvals.usecallgraph     
6839                 elif(arg == '-ftop'):            
6840                         sysvals.usecallgraph     
6841                         sysvals.ftop = True      
6842                         sysvals.usekprobes =     
6843                 elif(arg == '-skiphtml'):        
6844                         sysvals.skiphtml = Tr    
6845                 elif(arg == '-cgdump'):          
6846                         sysvals.cgdump = True    
6847                 elif(arg == '-devdump'):         
6848                         sysvals.devdump = Tru    
6849                 elif(arg == '-genhtml'):         
6850                         genhtml = True           
6851                 elif(arg == '-addlogs'):         
6852                         sysvals.dmesglog = sy    
6853                 elif(arg == '-nologs'):          
6854                         sysvals.dmesglog = sy    
6855                 elif(arg == '-addlogdmesg'):     
6856                         sysvals.dmesglog = Tr    
6857                 elif(arg == '-addlogftrace'):    
6858                         sysvals.ftracelog = T    
6859                 elif(arg == '-noturbostat'):     
6860                         sysvals.tstat = False    
6861                 elif(arg == '-verbose'):         
6862                         sysvals.verbose = Tru    
6863                 elif(arg == '-proc'):            
6864                         sysvals.useprocmon =     
6865                 elif(arg == '-dev'):             
6866                         sysvals.usedevsrc = T    
6867                 elif(arg == '-sync'):            
6868                         sysvals.sync = True      
6869                 elif(arg == '-wifi'):            
6870                         sysvals.wifi = True      
6871                 elif(arg == '-wifitrace'):       
6872                         sysvals.wifitrace = T    
6873                 elif(arg == '-netfix'):          
6874                         sysvals.netfix = True    
6875                 elif(arg == '-gzip'):            
6876                         sysvals.gzip = True      
6877                 elif(arg == '-info'):            
6878                         try:                     
6879                                 val = next(ar    
6880                         except:                  
6881                                 doError('-inf    
6882                 elif(arg == '-desc'):            
6883                         try:                     
6884                                 val = next(ar    
6885                         except:                  
6886                                 doError('-des    
6887                 elif(arg == '-rs'):              
6888                         try:                     
6889                                 val = next(ar    
6890                         except:                  
6891                                 doError('-rs     
6892                         if val.lower() in swi    
6893                                 if val.lower(    
6894                                         sysva    
6895                                 else:            
6896                                         sysva    
6897                         else:                    
6898                                 doError('inva    
6899                 elif(arg == '-display'):         
6900                         try:                     
6901                                 val = next(ar    
6902                         except:                  
6903                                 doError('-dis    
6904                         disopt = ['on', 'off'    
6905                         if val.lower() not in    
6906                                 doError('vali    
6907                         sysvals.display = val    
6908                 elif(arg == '-maxdepth'):        
6909                         sysvals.max_graph_dep    
6910                 elif(arg == '-rtcwake'):         
6911                         try:                     
6912                                 val = next(ar    
6913                         except:                  
6914                                 doError('No r    
6915                         if val.lower() in swi    
6916                                 sysvals.rtcwa    
6917                         else:                    
6918                                 sysvals.rtcwa    
6919                                 sysvals.rtcwa    
6920                 elif(arg == '-timeprec'):        
6921                         sysvals.setPrecision(    
6922                 elif(arg == '-mindev'):          
6923                         sysvals.mindevlen = g    
6924                 elif(arg == '-mincg'):           
6925                         sysvals.mincglen = ge    
6926                 elif(arg == '-bufsize'):         
6927                         sysvals.bufsize = get    
6928                 elif(arg == '-cgtest'):          
6929                         sysvals.cgtest = getA    
6930                 elif(arg == '-cgphase'):         
6931                         try:                     
6932                                 val = next(ar    
6933                         except:                  
6934                                 doError('No p    
6935                         d = Data(0)              
6936                         if val not in d.phase    
6937                                 doError('inva    
6938                                         % (ar    
6939                         sysvals.cgphase = val    
6940                 elif(arg == '-cgfilter'):        
6941                         try:                     
6942                                 val = next(ar    
6943                         except:                  
6944                                 doError('No c    
6945                         sysvals.setCallgraphF    
6946                 elif(arg == '-skipkprobe'):      
6947                         try:                     
6948                                 val = next(ar    
6949                         except:                  
6950                                 doError('No k    
6951                         sysvals.skipKprobes(v    
6952                 elif(arg == '-cgskip'):          
6953                         try:                     
6954                                 val = next(ar    
6955                         except:                  
6956                                 doError('No f    
6957                         if val.lower() in swi    
6958                                 sysvals.cgski    
6959                         else:                    
6960                                 sysvals.cgski    
6961                                 if(not sysval    
6962                                         doErr    
6963                 elif(arg == '-callloop-maxgap    
6964                         sysvals.callloopmaxga    
6965                 elif(arg == '-callloop-maxlen    
6966                         sysvals.callloopmaxle    
6967                 elif(arg == '-cmd'):             
6968                         try:                     
6969                                 val = next(ar    
6970                         except:                  
6971                                 doError('No c    
6972                         sysvals.testcommand =    
6973                         sysvals.suspendmode =    
6974                 elif(arg == '-expandcg'):        
6975                         sysvals.cgexp = True     
6976                 elif(arg == '-srgap'):           
6977                         sysvals.srgap = 5        
6978                 elif(arg == '-maxfail'):         
6979                         sysvals.maxfail = get    
6980                 elif(arg == '-multi'):           
6981                         try:                     
6982                                 c, d = next(a    
6983                         except:                  
6984                                 doError('-mul    
6985                         sysvals.multiinit(c,     
6986                 elif(arg == '-o'):               
6987                         try:                     
6988                                 val = next(ar    
6989                         except:                  
6990                                 doError('No s    
6991                         sysvals.outdir = sysv    
6992                 elif(arg == '-config'):          
6993                         try:                     
6994                                 val = next(ar    
6995                         except:                  
6996                                 doError('No t    
6997                         file = sysvals.config    
6998                         if(not file):            
6999                                 doError('%s d    
7000                         configFromFile(file)     
7001                 elif(arg == '-fadd'):            
7002                         try:                     
7003                                 val = next(ar    
7004                         except:                  
7005                                 doError('No t    
7006                         file = sysvals.config    
7007                         if(not file):            
7008                                 doError('%s d    
7009                         sysvals.addFtraceFilt    
7010                 elif(arg == '-dmesg'):           
7011                         try:                     
7012                                 val = next(ar    
7013                         except:                  
7014                                 doError('No d    
7015                         sysvals.notestrun = T    
7016                         sysvals.dmesgfile = v    
7017                         if(os.path.exists(sys    
7018                                 doError('%s d    
7019                 elif(arg == '-ftrace'):          
7020                         try:                     
7021                                 val = next(ar    
7022                         except:                  
7023                                 doError('No f    
7024                         sysvals.notestrun = T    
7025                         sysvals.ftracefile =     
7026                         if(os.path.exists(sys    
7027                                 doError('%s d    
7028                 elif(arg == '-summary'):         
7029                         try:                     
7030                                 val = next(ar    
7031                         except:                  
7032                                 doError('No d    
7033                         cmd = 'summary'          
7034                         sysvals.outdir = val     
7035                         sysvals.notestrun = T    
7036                         if(os.path.isdir(val)    
7037                                 doError('%s i    
7038                 elif(arg == '-filter'):          
7039                         try:                     
7040                                 val = next(ar    
7041                         except:                  
7042                                 doError('No d    
7043                         sysvals.setDeviceFilt    
7044                 elif(arg == '-result'):          
7045                         try:                     
7046                                 val = next(ar    
7047                         except:                  
7048                                 doError('No r    
7049                         sysvals.result = val     
7050                         sysvals.signalHandler    
7051                 else:                            
7052                         doError('Invalid argu    
7053                                                  
7054         # compatibility errors                   
7055         if(sysvals.usecallgraph and sysvals.u    
7056                 doError('-dev is not compatib    
7057         if(sysvals.usecallgraph and sysvals.u    
7058                 doError('-proc is not compati    
7059                                                  
7060         if sysvals.usecallgraph and sysvals.c    
7061                 sysvals.vprint('Using cgskip     
7062                 sysvals.setCallgraphBlacklist    
7063                                                  
7064         # callgraph size cannot exceed device    
7065         if sysvals.mincglen < sysvals.mindevl    
7066                 sysvals.mincglen = sysvals.mi    
7067                                                  
7068         # remove existing buffers before calc    
7069         if(sysvals.usecallgraph or sysvals.us    
7070                 sysvals.fsetVal('16', 'buffer    
7071         sysvals.cpuInfo()                        
7072                                                  
7073         # just run a utility command and exit    
7074         if(cmd != ''):                           
7075                 ret = 0                          
7076                 if(cmd == 'status'):             
7077                         if not statusCheck(Tr    
7078                                 ret = 1          
7079                 elif(cmd == 'fpdt'):             
7080                         if not getFPDT(True):    
7081                                 ret = 1          
7082                 elif(cmd == 'sysinfo'):          
7083                         sysvals.printSystemIn    
7084                 elif(cmd == 'devinfo'):          
7085                         deviceInfo()             
7086                 elif(cmd == 'modes'):            
7087                         pprint(getModes())       
7088                 elif(cmd == 'flist'):            
7089                         sysvals.getFtraceFilt    
7090                 elif(cmd == 'flistall'):         
7091                         sysvals.getFtraceFilt    
7092                 elif(cmd == 'summary'):          
7093                         runSummary(sysvals.ou    
7094                 elif(cmd in ['xon', 'xoff', '    
7095                         sysvals.verbose = Tru    
7096                         ret = sysvals.display    
7097                 elif(cmd == 'xstat'):            
7098                         pprint('Display Statu    
7099                 elif(cmd == 'wificheck'):        
7100                         dev = sysvals.checkWi    
7101                         if dev:                  
7102                                 print('%s is     
7103                         else:                    
7104                                 print('No wif    
7105                 elif(cmd == 'cmdinfo'):          
7106                         for out in sysvals.cm    
7107                                 print('[%s -     
7108                 sys.exit(ret)                    
7109                                                  
7110         # if instructed, re-analyze existing     
7111         if(sysvals.notestrun):                   
7112                 stamp = rerunTest(sysvals.out    
7113                 sysvals.outputResult(stamp)      
7114                 sys.exit(0)                      
7115                                                  
7116         # verify that we can run a test          
7117         error = statusCheck()                    
7118         if(error):                               
7119                 doError(error)                   
7120                                                  
7121         # extract mem/disk extra modes and co    
7122         mode = sysvals.suspendmode               
7123         if mode.startswith('mem'):               
7124                 memmode = mode.split('-', 1)[    
7125                 if memmode == 'shallow':         
7126                         mode = 'standby'         
7127                 elif memmode ==  's2idle':       
7128                         mode = 'freeze'          
7129                 else:                            
7130                         mode = 'mem'             
7131                 sysvals.memmode = memmode        
7132                 sysvals.suspendmode = mode       
7133         if mode.startswith('disk-'):             
7134                 sysvals.diskmode = mode.split    
7135                 sysvals.suspendmode = 'disk'     
7136         sysvals.systemInfo(dmidecode(sysvals.    
7137                                                  
7138         failcnt, ret = 0, 0                      
7139         if sysvals.multitest['run']:             
7140                 # run multiple tests in a sep    
7141                 if not sysvals.outdir:           
7142                         if 'time' in sysvals.    
7143                                 s = '-%dm' %     
7144                         else:                    
7145                                 s = '-x%d' %     
7146                         sysvals.outdir = date    
7147                 if not os.path.isdir(sysvals.    
7148                         os.makedirs(sysvals.o    
7149                 sysvals.sudoUserchown(sysvals    
7150                 finish = datetime.now()          
7151                 if 'time' in sysvals.multites    
7152                         finish += timedelta(m    
7153                 for i in range(sysvals.multit    
7154                         sysvals.multistat(Tru    
7155                         if i != 0 and sysvals    
7156                                 pprint('Waiti    
7157                                 time.sleep(sy    
7158                         fmt = 'suspend-%y%m%d    
7159                         sysvals.testdir = os.    
7160                         ret = runTest(i+1, no    
7161                         failcnt = 0 if not re    
7162                         if sysvals.maxfail >     
7163                                 pprint('Maxim    
7164                                 break            
7165                         sysvals.resetlog()       
7166                         sysvals.multistat(Fal    
7167                         if 'time' in sysvals.    
7168                                 break            
7169                 if not sysvals.skiphtml:         
7170                         runSummary(sysvals.ou    
7171                 sysvals.sudoUserchown(sysvals    
7172         else:                                    
7173                 if sysvals.outdir:               
7174                         sysvals.testdir = sys    
7175                 # run the test in the current    
7176                 ret = runTest()                  
7177                                                  
7178         # reset to default values after testi    
7179         if sysvals.display:                      
7180                 sysvals.displayControl('reset    
7181         if sysvals.rs != 0:                      
7182                 sysvals.setRuntimeSuspend(Fal    
7183         sys.exit(ret)                            
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php