~ [ 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-4.18.20)


  1 #!/usr/bin/env python3                         !!   1 #!/usr/bin/python2
  2 # SPDX-License-Identifier: GPL-2.0-only        << 
  3 #                                                   2 #
  4 # Tool for analyzing suspend/resume timing          3 # Tool for analyzing suspend/resume timing
  5 # Copyright (c) 2013, Intel Corporation.            4 # Copyright (c) 2013, Intel Corporation.
  6 #                                                   5 #
  7 # This program is free software; you can redis      6 # This program is free software; you can redistribute it and/or modify it
  8 # under the terms and conditions of the GNU Ge      7 # under the terms and conditions of the GNU General Public License,
  9 # version 2, as published by the Free Software      8 # version 2, as published by the Free Software Foundation.
 10 #                                                   9 #
 11 # This program is distributed in the hope it w     10 # This program is distributed in the hope it will be useful, but WITHOUT
 12 # ANY WARRANTY; without even the implied warra     11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13 # FITNESS FOR A PARTICULAR PURPOSE.  See the G     12 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 14 # more details.                                    13 # more details.
 15 #                                                  14 #
 16 # Authors:                                         15 # Authors:
 17 #        Todd Brandt <todd.e.brandt@linux.intel     16 #        Todd Brandt <todd.e.brandt@linux.intel.com>
 18 #                                                  17 #
 19 # Links:                                           18 # Links:
 20 #        Home Page                                 19 #        Home Page
 21 #          https://01.org/pm-graph             !!  20 #          https://01.org/suspendresume
 22 #        Source repo                               21 #        Source repo
 23 #          git@github.com:intel/pm-graph       !!  22 #          git@github.com:01org/pm-graph
 24 #                                                  23 #
 25 # Description:                                     24 # Description:
 26 #        This tool is designed to assist kerne     25 #        This tool is designed to assist kernel and OS developers in optimizing
 27 #        their linux stack's suspend/resume ti     26 #        their linux stack's suspend/resume time. Using a kernel image built
 28 #        with a few extra options enabled, the     27 #        with a few extra options enabled, the tool will execute a suspend and
 29 #        will capture dmesg and ftrace data un     28 #        will capture dmesg and ftrace data until resume is complete. This data
 30 #        is transformed into a device timeline     29 #        is transformed into a device timeline and a callgraph to give a quick
 31 #        and detailed view of which devices an     30 #        and detailed view of which devices and callbacks are taking the most
 32 #        time in suspend/resume. The output is     31 #        time in suspend/resume. The output is a single html file which can be
 33 #        viewed in firefox or chrome.              32 #        viewed in firefox or chrome.
 34 #                                                  33 #
 35 #        The following kernel build options ar     34 #        The following kernel build options are required:
 36 #                CONFIG_DEVMEM=y               << 
 37 #                CONFIG_PM_DEBUG=y                 35 #                CONFIG_PM_DEBUG=y
 38 #                CONFIG_PM_SLEEP_DEBUG=y           36 #                CONFIG_PM_SLEEP_DEBUG=y
 39 #                CONFIG_FTRACE=y                   37 #                CONFIG_FTRACE=y
 40 #                CONFIG_FUNCTION_TRACER=y          38 #                CONFIG_FUNCTION_TRACER=y
 41 #                CONFIG_FUNCTION_GRAPH_TRACER=     39 #                CONFIG_FUNCTION_GRAPH_TRACER=y
 42 #                CONFIG_KPROBES=y                  40 #                CONFIG_KPROBES=y
 43 #                CONFIG_KPROBES_ON_FTRACE=y        41 #                CONFIG_KPROBES_ON_FTRACE=y
 44 #                                                  42 #
 45 #        For kernel versions older than 3.15:      43 #        For kernel versions older than 3.15:
 46 #        The following additional kernel param     44 #        The following additional kernel parameters are required:
 47 #                (e.g. in file /etc/default/gr     45 #                (e.g. in file /etc/default/grub)
 48 #                GRUB_CMDLINE_LINUX_DEFAULT=".     46 #                GRUB_CMDLINE_LINUX_DEFAULT="... initcall_debug log_buf_len=16M ..."
 49 #                                                  47 #
 50                                                    48 
 51 # ----------------- LIBRARIES ----------------     49 # ----------------- LIBRARIES --------------------
 52                                                    50 
 53 import sys                                         51 import sys
 54 import time                                        52 import time
 55 import os                                          53 import os
 56 import string                                      54 import string
 57 import re                                          55 import re
 58 import platform                                    56 import platform
 59 import signal                                  !!  57 from datetime import datetime
 60 import codecs                                  << 
 61 from datetime import datetime, timedelta       << 
 62 import struct                                      58 import struct
 63 import configparser                            !!  59 import ConfigParser
 64 import gzip                                        60 import gzip
 65 from threading import Thread                       61 from threading import Thread
 66 from subprocess import call, Popen, PIPE           62 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                                                    63 
 81 # ----------------- CLASSES ------------------     64 # ----------------- CLASSES --------------------
 82                                                    65 
 83 # Class: SystemValues                              66 # Class: SystemValues
 84 # Description:                                     67 # Description:
 85 #        A global, single-instance container u     68 #        A global, single-instance container used to
 86 #        store system values and test paramete     69 #        store system values and test parameters
 87 class SystemValues:                                70 class SystemValues:
 88         title = 'SleepGraph'                       71         title = 'SleepGraph'
 89         version = '5.12'                       !!  72         version = '5.1'
 90         ansi = False                               73         ansi = False
 91         rs = 0                                     74         rs = 0
 92         display = ''                           !!  75         display = 0
 93         gzip = False                               76         gzip = False
 94         sync = False                               77         sync = False
 95         wifi = False                           << 
 96         netfix = False                         << 
 97         verbose = False                            78         verbose = False
 98         testlog = True                             79         testlog = True
 99         dmesglog = True                        !!  80         dmesglog = False
100         ftracelog = False                          81         ftracelog = False
101         acpidebug = True                       !!  82         mindevlen = 0.0
102         tstat = True                           << 
103         wifitrace = False                      << 
104         mindevlen = 0.0001                     << 
105         mincglen = 0.0                             83         mincglen = 0.0
106         cgphase = ''                               84         cgphase = ''
107         cgtest = -1                                85         cgtest = -1
108         cgskip = ''                                86         cgskip = ''
109         maxfail = 0                            !!  87         multitest = {'run': False, 'count': 0, 'delay': 0}
110         multitest = {'run': False, 'count': 10 << 
111         max_graph_depth = 0                        88         max_graph_depth = 0
112         callloopmaxgap = 0.0001                    89         callloopmaxgap = 0.0001
113         callloopmaxlen = 0.005                     90         callloopmaxlen = 0.005
114         bufsize = 0                                91         bufsize = 0
115         cpucount = 0                               92         cpucount = 0
116         memtotal = 204800                          93         memtotal = 204800
117         memfree = 204800                           94         memfree = 204800
118         osversion = ''                         << 
119         srgap = 0                                  95         srgap = 0
120         cgexp = False                              96         cgexp = False
121         testdir = ''                               97         testdir = ''
122         outdir = ''                                98         outdir = ''
123         tpath = '/sys/kernel/tracing/'         !!  99         tpath = '/sys/kernel/debug/tracing/'
124         fpdtpath = '/sys/firmware/acpi/tables/    100         fpdtpath = '/sys/firmware/acpi/tables/FPDT'
125         epath = '/sys/kernel/tracing/events/po !! 101         epath = '/sys/kernel/debug/tracing/events/power/'
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 = [                           102         traceevents = [
131                 'suspend_resume',                 103                 'suspend_resume',
132                 'wakeup_source_activate',      << 
133                 'wakeup_source_deactivate',    << 
134                 'device_pm_callback_end',         104                 'device_pm_callback_end',
135                 'device_pm_callback_start'        105                 'device_pm_callback_start'
136         ]                                         106         ]
137         logmsg = ''                               107         logmsg = ''
138         testcommand = ''                          108         testcommand = ''
139         mempath = '/dev/mem'                      109         mempath = '/dev/mem'
140         powerfile = '/sys/power/state'            110         powerfile = '/sys/power/state'
141         mempowerfile = '/sys/power/mem_sleep'     111         mempowerfile = '/sys/power/mem_sleep'
142         diskpowerfile = '/sys/power/disk'      << 
143         suspendmode = 'mem'                       112         suspendmode = 'mem'
144         memmode = ''                              113         memmode = ''
145         diskmode = ''                          << 
146         hostname = 'localhost'                    114         hostname = 'localhost'
147         prefix = 'test'                           115         prefix = 'test'
148         teststamp = ''                            116         teststamp = ''
149         sysstamp = ''                             117         sysstamp = ''
150         dmesgstart = 0.0                          118         dmesgstart = 0.0
151         dmesgfile = ''                            119         dmesgfile = ''
152         ftracefile = ''                           120         ftracefile = ''
153         htmlfile = 'output.html'                  121         htmlfile = 'output.html'
154         result = ''                               122         result = ''
155         rtcwake = True                            123         rtcwake = True
156         rtcwaketime = 15                          124         rtcwaketime = 15
157         rtcpath = ''                              125         rtcpath = ''
158         devicefilter = []                         126         devicefilter = []
159         cgfilter = []                             127         cgfilter = []
160         stamp = 0                                 128         stamp = 0
161         execcount = 1                             129         execcount = 1
162         x2delay = 0                               130         x2delay = 0
163         skiphtml = False                          131         skiphtml = False
164         usecallgraph = False                      132         usecallgraph = False
165         ftopfunc = 'pm_suspend'                << 
166         ftop = False                           << 
167         usetraceevents = False                    133         usetraceevents = False
168         usetracemarkers = True                    134         usetracemarkers = True
169         useftrace = True                       << 
170         usekprobes = True                         135         usekprobes = True
171         usedevsrc = False                         136         usedevsrc = False
172         useprocmon = False                        137         useprocmon = False
173         notestrun = False                         138         notestrun = False
174         cgdump = False                            139         cgdump = False
175         devdump = False                        << 
176         mixedphaseheight = True                   140         mixedphaseheight = True
177         devprops = dict()                         141         devprops = dict()
178         cfgdef = dict()                        << 
179         platinfo = []                          << 
180         predelay = 0                              142         predelay = 0
181         postdelay = 0                             143         postdelay = 0
182         tmstart = 'SUSPEND START %Y%m%d-%H:%M: !! 144         procexecfmt = 'ps - (?P<ps>.*)$'
183         tmend = 'RESUME COMPLETE %Y%m%d-%H:%M: !! 145         devpropfmt = '# Device Properties: .*'
                                                   >> 146         tracertypefmt = '# tracer: (?P<t>.*)'
                                                   >> 147         firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$'
184         tracefuncs = {                            148         tracefuncs = {
185                 'async_synchronize_full': {},  << 
186                 'sys_sync': {},                   149                 'sys_sync': {},
187                 'ksys_sync': {},               << 
188                 '__pm_notifier_call_chain': {}    150                 '__pm_notifier_call_chain': {},
189                 'pm_prepare_console': {},         151                 'pm_prepare_console': {},
190                 'pm_notifier_call_chain': {},     152                 'pm_notifier_call_chain': {},
191                 'freeze_processes': {},           153                 'freeze_processes': {},
192                 'freeze_kernel_threads': {},      154                 'freeze_kernel_threads': {},
193                 'pm_restrict_gfp_mask': {},       155                 'pm_restrict_gfp_mask': {},
194                 'acpi_suspend_begin': {},         156                 'acpi_suspend_begin': {},
195                 'acpi_hibernation_begin': {},     157                 'acpi_hibernation_begin': {},
196                 'acpi_hibernation_enter': {},     158                 'acpi_hibernation_enter': {},
197                 'acpi_hibernation_leave': {},     159                 'acpi_hibernation_leave': {},
198                 'acpi_pm_freeze': {},             160                 'acpi_pm_freeze': {},
199                 'acpi_pm_thaw': {},               161                 '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'    162                 'hibernate_preallocate_memory': {},
210                 'create_basic_memory_bitmaps':    163                 'create_basic_memory_bitmaps': {},
211                 'swsusp_write': {},               164                 'swsusp_write': {},
212                 'suspend_console': {},            165                 'suspend_console': {},
213                 'acpi_pm_prepare': {},            166                 'acpi_pm_prepare': {},
214                 'syscore_suspend': {},            167                 'syscore_suspend': {},
215                 'arch_enable_nonboot_cpus_end'    168                 'arch_enable_nonboot_cpus_end': {},
216                 'syscore_resume': {},             169                 'syscore_resume': {},
217                 'acpi_pm_finish': {},             170                 'acpi_pm_finish': {},
218                 'resume_console': {},             171                 'resume_console': {},
219                 'acpi_pm_end': {},                172                 'acpi_pm_end': {},
220                 'pm_restore_gfp_mask': {},        173                 'pm_restore_gfp_mask': {},
221                 'thaw_processes': {},             174                 'thaw_processes': {},
222                 'pm_restore_console': {},         175                 'pm_restore_console': {},
223                 'CPU_OFF': {                      176                 'CPU_OFF': {
224                         'func':'_cpu_down',       177                         'func':'_cpu_down',
225                         'args_x86_64': {'cpu':    178                         'args_x86_64': {'cpu':'%di:s32'},
226                         'format': 'CPU_OFF[{cp    179                         'format': 'CPU_OFF[{cpu}]'
227                 },                                180                 },
228                 'CPU_ON': {                       181                 'CPU_ON': {
229                         'func':'_cpu_up',         182                         'func':'_cpu_up',
230                         'args_x86_64': {'cpu':    183                         'args_x86_64': {'cpu':'%di:s32'},
231                         'format': 'CPU_ON[{cpu    184                         'format': 'CPU_ON[{cpu}]'
232                 },                                185                 },
233         }                                         186         }
234         dev_tracefuncs = {                        187         dev_tracefuncs = {
235                 # general wait/delay/sleep        188                 # general wait/delay/sleep
236                 'msleep': { 'args_x86_64': {'t    189                 'msleep': { 'args_x86_64': {'time':'%di:s32'}, 'ub': 1 },
                                                   >> 190                 'schedule_timeout_uninterruptible': { 'args_x86_64': {'timeout':'%di:s32'}, 'ub': 1 },
237                 'schedule_timeout': { 'args_x8    191                 'schedule_timeout': { 'args_x86_64': {'timeout':'%di:s32'}, 'ub': 1 },
238                 'udelay': { 'func':'__const_ud    192                 'udelay': { 'func':'__const_udelay', 'args_x86_64': {'loops':'%di:s32'}, 'ub': 1 },
239                 'usleep_range': { 'args_x86_64    193                 'usleep_range': { 'args_x86_64': {'min':'%di:s32', 'max':'%si:s32'}, 'ub': 1 },
240                 'mutex_lock_slowpath': { 'func    194                 'mutex_lock_slowpath': { 'func':'__mutex_lock_slowpath', 'ub': 1 },
241                 'acpi_os_stall': {'ub': 1},       195                 'acpi_os_stall': {'ub': 1},
242                 'rt_mutex_slowlock': {'ub': 1} << 
243                 # ACPI                            196                 # ACPI
244                 'acpi_resume_power_resources':    197                 'acpi_resume_power_resources': {},
245                 'acpi_ps_execute_method': { 'a !! 198                 'acpi_ps_parse_aml': {},
246                         'fullpath':'+0(+40(%di << 
247                 }},                            << 
248                 # mei_me                       << 
249                 'mei_reset': {},               << 
250                 # filesystem                      199                 # filesystem
251                 'ext4_sync_fs': {},               200                 'ext4_sync_fs': {},
252                 # 80211                           201                 # 80211
253                 'ath10k_bmi_read_memory': { 'a << 
254                 'ath10k_bmi_write_memory': { ' << 
255                 'ath10k_bmi_fast_download': {  << 
256                 'iwlagn_mac_start': {},           202                 'iwlagn_mac_start': {},
257                 'iwlagn_alloc_bcast_station':     203                 'iwlagn_alloc_bcast_station': {},
258                 'iwl_trans_pcie_start_hw': {},    204                 'iwl_trans_pcie_start_hw': {},
259                 'iwl_trans_pcie_start_fw': {},    205                 'iwl_trans_pcie_start_fw': {},
260                 'iwl_run_init_ucode': {},         206                 'iwl_run_init_ucode': {},
261                 'iwl_load_ucode_wait_alive': {    207                 'iwl_load_ucode_wait_alive': {},
262                 'iwl_alive_start': {},            208                 'iwl_alive_start': {},
263                 'iwlagn_mac_stop': {},            209                 'iwlagn_mac_stop': {},
264                 'iwlagn_mac_suspend': {},         210                 'iwlagn_mac_suspend': {},
265                 'iwlagn_mac_resume': {},          211                 'iwlagn_mac_resume': {},
266                 'iwlagn_mac_add_interface': {}    212                 'iwlagn_mac_add_interface': {},
267                 'iwlagn_mac_remove_interface':    213                 'iwlagn_mac_remove_interface': {},
268                 'iwlagn_mac_change_interface':    214                 'iwlagn_mac_change_interface': {},
269                 'iwlagn_mac_config': {},          215                 'iwlagn_mac_config': {},
270                 'iwlagn_configure_filter': {},    216                 'iwlagn_configure_filter': {},
271                 'iwlagn_mac_hw_scan': {},         217                 'iwlagn_mac_hw_scan': {},
272                 'iwlagn_bss_info_changed': {},    218                 'iwlagn_bss_info_changed': {},
273                 'iwlagn_mac_channel_switch': {    219                 'iwlagn_mac_channel_switch': {},
274                 'iwlagn_mac_flush': {},           220                 'iwlagn_mac_flush': {},
275                 # ATA                             221                 # ATA
276                 'ata_eh_recover': { 'args_x86_    222                 'ata_eh_recover': { 'args_x86_64': {'port':'+36(%di):s32'} },
277                 # i915                            223                 # i915
278                 'i915_gem_resume': {},            224                 'i915_gem_resume': {},
279                 'i915_restore_state': {},         225                 'i915_restore_state': {},
280                 'intel_opregion_setup': {},       226                 'intel_opregion_setup': {},
281                 'g4x_pre_enable_dp': {},          227                 'g4x_pre_enable_dp': {},
282                 'vlv_pre_enable_dp': {},          228                 'vlv_pre_enable_dp': {},
283                 'chv_pre_enable_dp': {},          229                 'chv_pre_enable_dp': {},
284                 'g4x_enable_dp': {},              230                 'g4x_enable_dp': {},
285                 'vlv_enable_dp': {},              231                 'vlv_enable_dp': {},
286                 'intel_hpd_init': {},             232                 'intel_hpd_init': {},
287                 'intel_opregion_register': {},    233                 'intel_opregion_register': {},
288                 'intel_dp_detect': {},            234                 'intel_dp_detect': {},
289                 'intel_hdmi_detect': {},          235                 'intel_hdmi_detect': {},
290                 'intel_opregion_init': {},        236                 'intel_opregion_init': {},
291                 'intel_fbdev_set_suspend': {},    237                 'intel_fbdev_set_suspend': {},
292         }                                         238         }
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 = []                          239         cgblacklist = []
314         kprobes = dict()                          240         kprobes = dict()
315         timeformat = '%.3f'                       241         timeformat = '%.3f'
316         cmdline = '%s %s' % \                     242         cmdline = '%s %s' % \
317                         (os.path.basename(sys.    243                         (os.path.basename(sys.argv[0]), ' '.join(sys.argv[1:]))
318         sudouser = ''                          << 
319         def __init__(self):                       244         def __init__(self):
320                 self.archargs = 'args_'+platfo    245                 self.archargs = 'args_'+platform.machine()
321                 self.hostname = platform.node(    246                 self.hostname = platform.node()
322                 if(self.hostname == ''):          247                 if(self.hostname == ''):
323                         self.hostname = 'local    248                         self.hostname = 'localhost'
324                 rtc = "rtc0"                      249                 rtc = "rtc0"
325                 if os.path.exists('/dev/rtc'):    250                 if os.path.exists('/dev/rtc'):
326                         rtc = os.readlink('/de    251                         rtc = os.readlink('/dev/rtc')
327                 rtc = '/sys/class/rtc/'+rtc       252                 rtc = '/sys/class/rtc/'+rtc
328                 if os.path.exists(rtc) and os.    253                 if os.path.exists(rtc) and os.path.exists(rtc+'/date') and \
329                         os.path.exists(rtc+'/t    254                         os.path.exists(rtc+'/time') and os.path.exists(rtc+'/wakealarm'):
330                         self.rtcpath = rtc        255                         self.rtcpath = rtc
331                 if (hasattr(sys.stdout, 'isatt    256                 if (hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()):
332                         self.ansi = True          257                         self.ansi = True
333                 self.testdir = datetime.now().    258                 self.testdir = datetime.now().strftime('suspend-%y%m%d-%H%M%S')
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):                    259         def vprint(self, msg):
341                 self.logmsg += msg+'\n'           260                 self.logmsg += msg+'\n'
342                 if self.verbose or msg.startsw !! 261                 if(self.verbose):
343                         pprint(msg)            !! 262                         print(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):          263         def rootCheck(self, fatal=True):
364                 if(os.access(self.powerfile, o    264                 if(os.access(self.powerfile, os.W_OK)):
365                         return True               265                         return True
366                 if fatal:                         266                 if fatal:
367                         msg = 'This command re    267                         msg = 'This command requires sysfs mount and root access'
368                         pprint('ERROR: %s\n' % !! 268                         print('ERROR: %s\n') % msg
369                         self.outputResult({'er    269                         self.outputResult({'error':msg})
370                         sys.exit(1)            !! 270                         sys.exit()
371                 return False                      271                 return False
372         def rootUser(self, fatal=False):          272         def rootUser(self, fatal=False):
373                 if 'USER' in os.environ and os    273                 if 'USER' in os.environ and os.environ['USER'] == 'root':
374                         return True               274                         return True
375                 if fatal:                         275                 if fatal:
376                         msg = 'This command mu    276                         msg = 'This command must be run as root'
377                         pprint('ERROR: %s\n' % !! 277                         print('ERROR: %s\n') % msg
378                         self.outputResult({'er    278                         self.outputResult({'error':msg})
379                         sys.exit(1)            !! 279                         sys.exit()
380                 return False                      280                 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):                   281         def getExec(self, cmd):
395                 try:                           !! 282                 dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin',
396                         fp = Popen(['which', c !! 283                         '/usr/local/sbin', '/usr/local/bin']
397                         out = ascii(fp.read()) !! 284                 for path in dirlist:
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    285                         cmdfull = os.path.join(path, cmd)
406                         if os.path.exists(cmdf    286                         if os.path.exists(cmdfull):
407                                 return cmdfull    287                                 return cmdfull
408                 return out                     !! 288                 return ''
409         def setPrecision(self, num):              289         def setPrecision(self, num):
410                 if num < 0 or num > 6:            290                 if num < 0 or num > 6:
411                         return                    291                         return
412                 self.timeformat = '%.{0}f'.for    292                 self.timeformat = '%.{0}f'.format(num)
413         def setOutputFolder(self, value):         293         def setOutputFolder(self, value):
414                 args = dict()                     294                 args = dict()
415                 n = datetime.now()                295                 n = datetime.now()
416                 args['date'] = n.strftime('%y%    296                 args['date'] = n.strftime('%y%m%d')
417                 args['time'] = n.strftime('%H%    297                 args['time'] = n.strftime('%H%M%S')
418                 args['hostname'] = args['host'    298                 args['hostname'] = args['host'] = self.hostname
419                 args['mode'] = self.suspendmod << 
420                 return value.format(**args)       299                 return value.format(**args)
421         def setOutputFile(self):                  300         def setOutputFile(self):
422                 if self.dmesgfile != '':          301                 if self.dmesgfile != '':
423                         m = re.match(r'(?P<nam !! 302                         m = re.match('(?P<name>.*)_dmesg\.txt.*', self.dmesgfile)
424                         if(m):                    303                         if(m):
425                                 self.htmlfile     304                                 self.htmlfile = m.group('name')+'.html'
426                 if self.ftracefile != '':         305                 if self.ftracefile != '':
427                         m = re.match(r'(?P<nam !! 306                         m = re.match('(?P<name>.*)_ftrace\.txt.*', self.ftracefile)
428                         if(m):                    307                         if(m):
429                                 self.htmlfile     308                                 self.htmlfile = m.group('name')+'.html'
430         def systemInfo(self, info):               309         def systemInfo(self, info):
431                 p = m = ''                     !! 310                 p = c = m = b = ''
432                 if 'baseboard-manufacturer' in    311                 if 'baseboard-manufacturer' in info:
433                         m = info['baseboard-ma    312                         m = info['baseboard-manufacturer']
434                 elif 'system-manufacturer' in     313                 elif 'system-manufacturer' in info:
435                         m = info['system-manuf    314                         m = info['system-manufacturer']
436                 if 'system-product-name' in in !! 315                 if 'baseboard-product-name' in info:
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    316                         p = info['baseboard-product-name']
442                 c = info['processor-version']  !! 317                 elif 'system-product-name' in info:
443                 b = info['bios-version'] if 'b !! 318                         p = info['system-product-name']
444                 r = info['bios-release-date']  !! 319                 if 'processor-version' in info:
445                 self.sysstamp = '# sysinfo | m !! 320                         c = info['processor-version']
446                         (m, p, c, b, r, self.c !! 321                 if 'bios-version' in info:
447                 if self.osversion:             !! 322                         b = info['bios-version']
448                         self.sysstamp += ' | o !! 323                 self.sysstamp = '# sysinfo | man:%s | plat:%s | cpu:%s | bios:%s | numcpu:%d | memsz:%d | memfr:%d' % \
                                                   >> 324                         (m, p, c, b, self.cpucount, self.memtotal, self.memfree)
449         def printSystemInfo(self, fatal=False)    325         def printSystemInfo(self, fatal=False):
450                 self.rootCheck(True)              326                 self.rootCheck(True)
451                 out = dmidecode(self.mempath,     327                 out = dmidecode(self.mempath, fatal)
452                 if len(out) < 1:                  328                 if len(out) < 1:
453                         return                    329                         return
454                 fmt = '%-24s: %s'                 330                 fmt = '%-24s: %s'
455                 if self.osversion:             << 
456                         print(fmt % ('os-versi << 
457                 for name in sorted(out):          331                 for name in sorted(out):
458                         print(fmt % (name, out !! 332                         print fmt % (name, out[name])
459                 print(fmt % ('cpucount', ('%d' !! 333                 print fmt % ('cpucount', ('%d' % self.cpucount))
460                 print(fmt % ('memtotal', ('%d  !! 334                 print fmt % ('memtotal', ('%d kB' % self.memtotal))
461                 print(fmt % ('memfree', ('%d k !! 335                 print fmt % ('memfree', ('%d kB' % self.memfree))
462         def cpuInfo(self):                        336         def cpuInfo(self):
463                 self.cpucount = 0                 337                 self.cpucount = 0
464                 if os.path.exists('/proc/cpuin !! 338                 fp = open('/proc/cpuinfo', 'r')
465                         with open('/proc/cpuin !! 339                 for line in fp:
466                                 for line in fp !! 340                         if re.match('^processor[ \t]*:[ \t]*[0-9]*', line):
467                                         if re. !! 341                                 self.cpucount += 1
468                                                !! 342                 fp.close()
469                 if os.path.exists('/proc/memin !! 343                 fp = open('/proc/meminfo', 'r')
470                         with open('/proc/memin !! 344                 for line in fp:
471                                 for line in fp !! 345                         m = re.match('^MemTotal:[ \t]*(?P<sz>[0-9]*) *kB', line)
472                                         m = re !! 346                         if m:
473                                         if m:  !! 347                                 self.memtotal = int(m.group('sz'))
474                                                !! 348                         m = re.match('^MemFree:[ \t]*(?P<sz>[0-9]*) *kB', line)
475                                         m = re !! 349                         if m:
476                                         if m:  !! 350                                 self.memfree = int(m.group('sz'))
477                                                !! 351                 fp.close()
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):           352         def initTestOutput(self, name):
484                 self.prefix = self.hostname       353                 self.prefix = self.hostname
485                 v = open('/proc/version', 'r')    354                 v = open('/proc/version', 'r').read().strip()
486                 kver = v.split()[2]            !! 355                 kver = string.split(v)[2]
487                 fmt = name+'-%m%d%y-%H%M%S'       356                 fmt = name+'-%m%d%y-%H%M%S'
488                 testtime = datetime.now().strf    357                 testtime = datetime.now().strftime(fmt)
489                 self.teststamp = \                358                 self.teststamp = \
490                         '# '+testtime+' '+self    359                         '# '+testtime+' '+self.prefix+' '+self.suspendmode+' '+kver
491                 ext = ''                          360                 ext = ''
492                 if self.gzip:                     361                 if self.gzip:
493                         ext = '.gz'               362                         ext = '.gz'
494                 self.dmesgfile = \                363                 self.dmesgfile = \
495                         self.testdir+'/'+self.    364                         self.testdir+'/'+self.prefix+'_'+self.suspendmode+'_dmesg.txt'+ext
496                 self.ftracefile = \               365                 self.ftracefile = \
497                         self.testdir+'/'+self.    366                         self.testdir+'/'+self.prefix+'_'+self.suspendmode+'_ftrace.txt'+ext
498                 self.htmlfile = \                 367                 self.htmlfile = \
499                         self.testdir+'/'+self.    368                         self.testdir+'/'+self.prefix+'_'+self.suspendmode+'.html'
500                 if not os.path.isdir(self.test    369                 if not os.path.isdir(self.testdir):
501                         os.makedirs(self.testd !! 370                         os.mkdir(self.testdir)
502                 self.sudoUserchown(self.testdi << 
503         def getValueList(self, value):            371         def getValueList(self, value):
504                 out = []                          372                 out = []
505                 for i in value.split(','):        373                 for i in value.split(','):
506                         if i.strip():             374                         if i.strip():
507                                 out.append(i.s    375                                 out.append(i.strip())
508                 return out                        376                 return out
509         def setDeviceFilter(self, value):         377         def setDeviceFilter(self, value):
510                 self.devicefilter = self.getVa    378                 self.devicefilter = self.getValueList(value)
511         def setCallgraphFilter(self, value):      379         def setCallgraphFilter(self, value):
512                 self.cgfilter = self.getValueL    380                 self.cgfilter = self.getValueList(value)
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):    381         def setCallgraphBlacklist(self, file):
520                 self.cgblacklist = self.listFr    382                 self.cgblacklist = self.listFromFile(file)
521         def rtcWakeAlarmOn(self):                 383         def rtcWakeAlarmOn(self):
522                 call('echo 0 > '+self.rtcpath+    384                 call('echo 0 > '+self.rtcpath+'/wakealarm', shell=True)
523                 nowtime = open(self.rtcpath+'/    385                 nowtime = open(self.rtcpath+'/since_epoch', 'r').read().strip()
524                 if nowtime:                       386                 if nowtime:
525                         nowtime = int(nowtime)    387                         nowtime = int(nowtime)
526                 else:                             388                 else:
527                         # if hardware time fai    389                         # if hardware time fails, use the software time
528                         nowtime = int(datetime    390                         nowtime = int(datetime.now().strftime('%s'))
529                 alarm = nowtime + self.rtcwake    391                 alarm = nowtime + self.rtcwaketime
530                 call('echo %d > %s/wakealarm'     392                 call('echo %d > %s/wakealarm' % (alarm, self.rtcpath), shell=True)
531         def rtcWakeAlarmOff(self):                393         def rtcWakeAlarmOff(self):
532                 call('echo 0 > %s/wakealarm' %    394                 call('echo 0 > %s/wakealarm' % self.rtcpath, shell=True)
533         def initdmesg(self):                      395         def initdmesg(self):
534                 # get the latest time stamp fr    396                 # get the latest time stamp from the dmesg log
535                 lines = Popen('dmesg', stdout= !! 397                 fp = Popen('dmesg', stdout=PIPE).stdout
536                 ktime = '0'                       398                 ktime = '0'
537                 for line in reversed(lines):   !! 399                 for line in fp:
538                         line = ascii(line).rep !! 400                         line = line.replace('\r\n', '')
539                         idx = line.find('[')      401                         idx = line.find('[')
540                         if idx > 1:               402                         if idx > 1:
541                                 line = line[id    403                                 line = line[idx:]
542                         m = re.match(r'[ \t]*( !! 404                         m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
543                         if(m):                    405                         if(m):
544                                 ktime = m.grou    406                                 ktime = m.group('ktime')
545                                 break          !! 407                 fp.close()
546                 self.dmesgstart = float(ktime)    408                 self.dmesgstart = float(ktime)
547         def getdmesg(self, testdata):          !! 409         def getdmesg(self, fwdata=[]):
548                 op = self.writeDatafileHeader( !! 410                 op = self.writeDatafileHeader(sysvals.dmesgfile, fwdata)
549                 # store all new dmesg lines si    411                 # store all new dmesg lines since initdmesg was called
550                 fp = Popen('dmesg', stdout=PIP    412                 fp = Popen('dmesg', stdout=PIPE).stdout
551                 for line in fp:                   413                 for line in fp:
552                         line = ascii(line).rep !! 414                         line = line.replace('\r\n', '')
553                         idx = line.find('[')      415                         idx = line.find('[')
554                         if idx > 1:               416                         if idx > 1:
555                                 line = line[id    417                                 line = line[idx:]
556                         m = re.match(r'[ \t]*( !! 418                         m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
557                         if(not m):                419                         if(not m):
558                                 continue          420                                 continue
559                         ktime = float(m.group(    421                         ktime = float(m.group('ktime'))
560                         if ktime > self.dmesgs    422                         if ktime > self.dmesgstart:
561                                 op.write(line)    423                                 op.write(line)
562                 fp.close()                        424                 fp.close()
563                 op.close()                        425                 op.close()
564         def listFromFile(self, file):             426         def listFromFile(self, file):
565                 list = []                         427                 list = []
566                 fp = open(file)                   428                 fp = open(file)
567                 for i in fp.read().split('\n')    429                 for i in fp.read().split('\n'):
568                         i = i.strip()             430                         i = i.strip()
569                         if i and i[0] != '#':     431                         if i and i[0] != '#':
570                                 list.append(i)    432                                 list.append(i)
571                 fp.close()                        433                 fp.close()
572                 return list                       434                 return list
573         def addFtraceFilterFunctions(self, fil    435         def addFtraceFilterFunctions(self, file):
574                 for i in self.listFromFile(fil    436                 for i in self.listFromFile(file):
575                         if len(i) < 2:            437                         if len(i) < 2:
576                                 continue          438                                 continue
577                         self.tracefuncs[i] = d    439                         self.tracefuncs[i] = dict()
578         def getFtraceFilterFunctions(self, cur    440         def getFtraceFilterFunctions(self, current):
579                 self.rootCheck(True)              441                 self.rootCheck(True)
580                 if not current:                   442                 if not current:
581                         call('cat '+self.tpath    443                         call('cat '+self.tpath+'available_filter_functions', shell=True)
582                         return                    444                         return
583                 master = self.listFromFile(sel    445                 master = self.listFromFile(self.tpath+'available_filter_functions')
584                 for i in sorted(self.tracefunc !! 446                 for i in self.tracefuncs:
585                         if 'func' in self.trac    447                         if 'func' in self.tracefuncs[i]:
586                                 i = self.trace    448                                 i = self.tracefuncs[i]['func']
587                         if i in master:           449                         if i in master:
588                                 print(i)       !! 450                                 print i
589                         else:                     451                         else:
590                                 print(self.col !! 452                                 print self.colorText(i)
591         def setFtraceFilterFunctions(self, lis    453         def setFtraceFilterFunctions(self, list):
592                 master = self.listFromFile(sel    454                 master = self.listFromFile(self.tpath+'available_filter_functions')
593                 flist = ''                        455                 flist = ''
594                 for i in list:                    456                 for i in list:
595                         if i not in master:       457                         if i not in master:
596                                 continue          458                                 continue
597                         if ' [' in i:             459                         if ' [' in i:
598                                 flist += i.spl    460                                 flist += i.split(' ')[0]+'\n'
599                         else:                     461                         else:
600                                 flist += i+'\n    462                                 flist += i+'\n'
601                 fp = open(self.tpath+'set_grap    463                 fp = open(self.tpath+'set_graph_function', 'w')
602                 fp.write(flist)                   464                 fp.write(flist)
603                 fp.close()                        465                 fp.close()
604         def basicKprobe(self, name):              466         def basicKprobe(self, name):
605                 self.kprobes[name] = {'name':     467                 self.kprobes[name] = {'name': name,'func': name,'args': dict(),'format': name}
606         def defaultKprobe(self, name, kdata):     468         def defaultKprobe(self, name, kdata):
607                 k = kdata                         469                 k = kdata
608                 for field in ['name', 'format'    470                 for field in ['name', 'format', 'func']:
609                         if field not in k:        471                         if field not in k:
610                                 k[field] = nam    472                                 k[field] = name
611                 if self.archargs in k:            473                 if self.archargs in k:
612                         k['args'] = k[self.arc    474                         k['args'] = k[self.archargs]
613                 else:                             475                 else:
614                         k['args'] = dict()        476                         k['args'] = dict()
615                         k['format'] = name        477                         k['format'] = name
616                 self.kprobes[name] = k            478                 self.kprobes[name] = k
617         def kprobeColor(self, name):              479         def kprobeColor(self, name):
618                 if name not in self.kprobes or    480                 if name not in self.kprobes or 'color' not in self.kprobes[name]:
619                         return ''                 481                         return ''
620                 return self.kprobes[name]['col    482                 return self.kprobes[name]['color']
621         def kprobeDisplayName(self, name, data    483         def kprobeDisplayName(self, name, dataraw):
622                 if name not in self.kprobes:      484                 if name not in self.kprobes:
623                         self.basicKprobe(name)    485                         self.basicKprobe(name)
624                 data = ''                         486                 data = ''
625                 quote=0                           487                 quote=0
626                 # first remvoe any spaces insi    488                 # first remvoe any spaces inside quotes, and the quotes
627                 for c in dataraw:                 489                 for c in dataraw:
628                         if c == '"':              490                         if c == '"':
629                                 quote = (quote    491                                 quote = (quote + 1) % 2
630                         if quote and c == ' ':    492                         if quote and c == ' ':
631                                 data += '_'       493                                 data += '_'
632                         elif c != '"':            494                         elif c != '"':
633                                 data += c         495                                 data += c
634                 fmt, args = self.kprobes[name]    496                 fmt, args = self.kprobes[name]['format'], self.kprobes[name]['args']
635                 arglist = dict()                  497                 arglist = dict()
636                 # now process the args            498                 # now process the args
637                 for arg in sorted(args):          499                 for arg in sorted(args):
638                         arglist[arg] = ''         500                         arglist[arg] = ''
639                         m = re.match(r'.* '+ar !! 501                         m = re.match('.* '+arg+'=(?P<arg>.*) ', data);
640                         if m:                     502                         if m:
641                                 arglist[arg] =    503                                 arglist[arg] = m.group('arg')
642                         else:                     504                         else:
643                                 m = re.match(r !! 505                                 m = re.match('.* '+arg+'=(?P<arg>.*)', data);
644                                 if m:             506                                 if m:
645                                         arglis    507                                         arglist[arg] = m.group('arg')
646                 out = fmt.format(**arglist)       508                 out = fmt.format(**arglist)
647                 out = out.replace(' ', '_').re    509                 out = out.replace(' ', '_').replace('"', '')
648                 return out                        510                 return out
649         def kprobeText(self, kname, kprobe):      511         def kprobeText(self, kname, kprobe):
650                 name = fmt = func = kname         512                 name = fmt = func = kname
651                 args = dict()                     513                 args = dict()
652                 if 'name' in kprobe:              514                 if 'name' in kprobe:
653                         name = kprobe['name']     515                         name = kprobe['name']
654                 if 'format' in kprobe:            516                 if 'format' in kprobe:
655                         fmt = kprobe['format']    517                         fmt = kprobe['format']
656                 if 'func' in kprobe:              518                 if 'func' in kprobe:
657                         func = kprobe['func']     519                         func = kprobe['func']
658                 if self.archargs in kprobe:       520                 if self.archargs in kprobe:
659                         args = kprobe[self.arc    521                         args = kprobe[self.archargs]
660                 if 'args' in kprobe:              522                 if 'args' in kprobe:
661                         args = kprobe['args']     523                         args = kprobe['args']
662                 if re.findall('{(?P<n>[a-z,A-Z    524                 if re.findall('{(?P<n>[a-z,A-Z,0-9]*)}', func):
663                         doError('Kprobe "%s" h    525                         doError('Kprobe "%s" has format info in the function name "%s"' % (name, func))
664                 for arg in re.findall('{(?P<n>    526                 for arg in re.findall('{(?P<n>[a-z,A-Z,0-9]*)}', fmt):
665                         if arg not in args:       527                         if arg not in args:
666                                 doError('Kprob    528                                 doError('Kprobe "%s" is missing argument "%s"' % (name, arg))
667                 val = 'p:%s_cal %s' % (name, f    529                 val = 'p:%s_cal %s' % (name, func)
668                 for i in sorted(args):            530                 for i in sorted(args):
669                         val += ' %s=%s' % (i,     531                         val += ' %s=%s' % (i, args[i])
670                 val += '\nr:%s_ret %s $retval\    532                 val += '\nr:%s_ret %s $retval\n' % (name, func)
671                 return val                        533                 return val
672         def addKprobes(self, output=False):       534         def addKprobes(self, output=False):
673                 if len(self.kprobes) < 1:         535                 if len(self.kprobes) < 1:
674                         return                    536                         return
675                 if output:                        537                 if output:
676                         pprint('    kprobe fun !! 538                         print('    kprobe functions in this kernel:')
677                 # first test each kprobe          539                 # first test each kprobe
678                 rejects = []                      540                 rejects = []
679                 # sort kprobes: trace, ub-dev,    541                 # sort kprobes: trace, ub-dev, custom, dev
680                 kpl = [[], [], [], []]            542                 kpl = [[], [], [], []]
681                 linesout = len(self.kprobes)      543                 linesout = len(self.kprobes)
682                 for name in sorted(self.kprobe    544                 for name in sorted(self.kprobes):
683                         res = self.colorText('    545                         res = self.colorText('YES', 32)
684                         if not self.testKprobe    546                         if not self.testKprobe(name, self.kprobes[name]):
685                                 res = self.col    547                                 res = self.colorText('NO')
686                                 rejects.append    548                                 rejects.append(name)
687                         else:                     549                         else:
688                                 if name in sel    550                                 if name in self.tracefuncs:
689                                         kpl[0]    551                                         kpl[0].append(name)
690                                 elif name in s    552                                 elif name in self.dev_tracefuncs:
691                                         if 'ub    553                                         if 'ub' in self.dev_tracefuncs[name]:
692                                                   554                                                 kpl[1].append(name)
693                                         else:     555                                         else:
694                                                   556                                                 kpl[3].append(name)
695                                 else:             557                                 else:
696                                         kpl[2]    558                                         kpl[2].append(name)
697                         if output:                559                         if output:
698                                 pprint('       !! 560                                 print('         %s: %s' % (name, res))
699                 kplist = kpl[0] + kpl[1] + kpl    561                 kplist = kpl[0] + kpl[1] + kpl[2] + kpl[3]
700                 # remove all failed ones from     562                 # remove all failed ones from the list
701                 for name in rejects:              563                 for name in rejects:
702                         self.kprobes.pop(name)    564                         self.kprobes.pop(name)
703                 # set the kprobes all at once     565                 # set the kprobes all at once
704                 self.fsetVal('', 'kprobe_event    566                 self.fsetVal('', 'kprobe_events')
705                 kprobeevents = ''                 567                 kprobeevents = ''
706                 for kp in kplist:                 568                 for kp in kplist:
707                         kprobeevents += self.k    569                         kprobeevents += self.kprobeText(kp, self.kprobes[kp])
708                 self.fsetVal(kprobeevents, 'kp    570                 self.fsetVal(kprobeevents, 'kprobe_events')
709                 if output:                        571                 if output:
710                         check = self.fgetVal('    572                         check = self.fgetVal('kprobe_events')
711                         linesack = (len(check. !! 573                         linesack = (len(check.split('\n')) - 1) / 2
712                         pprint('    kprobe fun !! 574                         print('    kprobe functions enabled: %d/%d' % (linesack, linesout))
713                 self.fsetVal('1', 'events/kpro    575                 self.fsetVal('1', 'events/kprobes/enable')
714         def testKprobe(self, kname, kprobe):      576         def testKprobe(self, kname, kprobe):
715                 self.fsetVal('0', 'events/kpro    577                 self.fsetVal('0', 'events/kprobes/enable')
716                 kprobeevents = self.kprobeText    578                 kprobeevents = self.kprobeText(kname, kprobe)
717                 if not kprobeevents:              579                 if not kprobeevents:
718                         return False              580                         return False
719                 try:                              581                 try:
720                         self.fsetVal(kprobeeve    582                         self.fsetVal(kprobeevents, 'kprobe_events')
721                         check = self.fgetVal('    583                         check = self.fgetVal('kprobe_events')
722                 except:                           584                 except:
723                         return False              585                         return False
724                 linesout = len(kprobeevents.sp    586                 linesout = len(kprobeevents.split('\n'))
725                 linesack = len(check.split('\n    587                 linesack = len(check.split('\n'))
726                 if linesack < linesout:           588                 if linesack < linesout:
727                         return False              589                         return False
728                 return True                       590                 return True
729         def setVal(self, val, file):           !! 591         def setVal(self, val, file, mode='w'):
730                 if not os.path.exists(file):      592                 if not os.path.exists(file):
731                         return False              593                         return False
732                 try:                              594                 try:
733                         fp = open(file, 'wb',  !! 595                         fp = open(file, mode, 0)
734                         fp.write(val.encode()) !! 596                         fp.write(val)
735                         fp.flush()                597                         fp.flush()
736                         fp.close()                598                         fp.close()
737                 except:                           599                 except:
738                         return False              600                         return False
739                 return True                       601                 return True
740         def fsetVal(self, val, path):          !! 602         def fsetVal(self, val, path, mode='w'):
741                 if not self.useftrace:         !! 603                 return self.setVal(val, self.tpath+path, mode)
742                         return False           << 
743                 return self.setVal(val, self.t << 
744         def getVal(self, file):                   604         def getVal(self, file):
745                 res = ''                          605                 res = ''
746                 if not os.path.exists(file):      606                 if not os.path.exists(file):
747                         return res                607                         return res
748                 try:                              608                 try:
749                         fp = open(file, 'r')      609                         fp = open(file, 'r')
750                         res = fp.read()           610                         res = fp.read()
751                         fp.close()                611                         fp.close()
752                 except:                           612                 except:
753                         pass                      613                         pass
754                 return res                        614                 return res
755         def fgetVal(self, path):                  615         def fgetVal(self, path):
756                 if not self.useftrace:         << 
757                         return ''              << 
758                 return self.getVal(self.tpath+    616                 return self.getVal(self.tpath+path)
759         def cleanupFtrace(self):                  617         def cleanupFtrace(self):
760                 if self.useftrace:             !! 618                 if(self.usecallgraph or self.usetraceevents or self.usedevsrc):
761                         self.fsetVal('0', 'eve    619                         self.fsetVal('0', 'events/kprobes/enable')
762                         self.fsetVal('', 'kpro    620                         self.fsetVal('', 'kprobe_events')
763                         self.fsetVal('1024', '    621                         self.fsetVal('1024', 'buffer_size_kb')
764         def setupAllKprobes(self):                622         def setupAllKprobes(self):
765                 for name in self.tracefuncs:      623                 for name in self.tracefuncs:
766                         self.defaultKprobe(nam    624                         self.defaultKprobe(name, self.tracefuncs[name])
767                 for name in self.dev_tracefunc    625                 for name in self.dev_tracefuncs:
768                         self.defaultKprobe(nam    626                         self.defaultKprobe(name, self.dev_tracefuncs[name])
769         def isCallgraphFunc(self, name):          627         def isCallgraphFunc(self, name):
770                 if len(self.tracefuncs) < 1 an    628                 if len(self.tracefuncs) < 1 and self.suspendmode == 'command':
771                         return True               629                         return True
772                 for i in self.tracefuncs:         630                 for i in self.tracefuncs:
773                         if 'func' in self.trac    631                         if 'func' in self.tracefuncs[i]:
774                                 f = self.trace    632                                 f = self.tracefuncs[i]['func']
775                         else:                     633                         else:
776                                 f = i             634                                 f = i
777                         if name == f:             635                         if name == f:
778                                 return True       636                                 return True
779                 return False                      637                 return False
780         def initFtrace(self, quiet=False):     !! 638         def initFtrace(self):
781                 if not self.useftrace:         !! 639                 self.printSystemInfo(False)
782                         return                 !! 640                 print('INITIALIZING FTRACE...')
783                 if not quiet:                  << 
784                         sysvals.printSystemInf << 
785                         pprint('INITIALIZING F << 
786                 # turn trace off                  641                 # turn trace off
787                 self.fsetVal('0', 'tracing_on'    642                 self.fsetVal('0', 'tracing_on')
788                 self.cleanupFtrace()              643                 self.cleanupFtrace()
789                 # set the trace clock to globa    644                 # set the trace clock to global
790                 self.fsetVal('global', 'trace_    645                 self.fsetVal('global', 'trace_clock')
791                 self.fsetVal('nop', 'current_t    646                 self.fsetVal('nop', 'current_tracer')
792                 # set trace buffer to an appro    647                 # set trace buffer to an appropriate value
793                 cpus = max(1, self.cpucount)      648                 cpus = max(1, self.cpucount)
794                 if self.bufsize > 0:              649                 if self.bufsize > 0:
795                         tgtsize = self.bufsize    650                         tgtsize = self.bufsize
796                 elif self.usecallgraph or self    651                 elif self.usecallgraph or self.usedevsrc:
797                         bmax = (1*1024*1024) i !! 652                         tgtsize = min(self.memfree, 3*1024*1024)
798                                 else (3*1024*1 << 
799                         tgtsize = min(self.mem << 
800                 else:                             653                 else:
801                         tgtsize = 65536           654                         tgtsize = 65536
802                 while not self.fsetVal('%d' %  !! 655                 while not self.fsetVal('%d' % (tgtsize / cpus), 'buffer_size_kb'):
803                         # if the size failed t    656                         # if the size failed to set, lower it and keep trying
804                         tgtsize -= 65536          657                         tgtsize -= 65536
805                         if tgtsize < 65536:       658                         if tgtsize < 65536:
806                                 tgtsize = int(    659                                 tgtsize = int(self.fgetVal('buffer_size_kb')) * cpus
807                                 break             660                                 break
808                 self.vprint('Setting trace buf !! 661                 print 'Setting trace buffers to %d kB (%d kB per cpu)' % (tgtsize, tgtsize/cpus)
809                 # initialize the callgraph tra    662                 # initialize the callgraph trace
810                 if(self.usecallgraph):            663                 if(self.usecallgraph):
811                         # set trace type          664                         # set trace type
812                         self.fsetVal('function    665                         self.fsetVal('function_graph', 'current_tracer')
813                         self.fsetVal('', 'set_    666                         self.fsetVal('', 'set_ftrace_filter')
814                         # temporary hack to fi << 
815                         fp = open(self.tpath+' << 
816                         fp.write('native_queue << 
817                         fp.close()             << 
818                         # set trace format opt    667                         # set trace format options
819                         self.fsetVal('print-pa    668                         self.fsetVal('print-parent', 'trace_options')
820                         self.fsetVal('funcgrap    669                         self.fsetVal('funcgraph-abstime', 'trace_options')
821                         self.fsetVal('funcgrap    670                         self.fsetVal('funcgraph-cpu', 'trace_options')
822                         self.fsetVal('funcgrap    671                         self.fsetVal('funcgraph-duration', 'trace_options')
823                         self.fsetVal('funcgrap    672                         self.fsetVal('funcgraph-proc', 'trace_options')
824                         self.fsetVal('funcgrap    673                         self.fsetVal('funcgraph-tail', 'trace_options')
825                         self.fsetVal('nofuncgr    674                         self.fsetVal('nofuncgraph-overhead', 'trace_options')
826                         self.fsetVal('context-    675                         self.fsetVal('context-info', 'trace_options')
827                         self.fsetVal('graph-ti    676                         self.fsetVal('graph-time', 'trace_options')
828                         self.fsetVal('%d' % se    677                         self.fsetVal('%d' % self.max_graph_depth, 'max_graph_depth')
829                         cf = ['dpm_run_callbac    678                         cf = ['dpm_run_callback']
830                         if(self.usetraceevents    679                         if(self.usetraceevents):
831                                 cf += ['dpm_pr    680                                 cf += ['dpm_prepare', 'dpm_complete']
832                         for fn in self.tracefu    681                         for fn in self.tracefuncs:
833                                 if 'func' in s    682                                 if 'func' in self.tracefuncs[fn]:
834                                         cf.app    683                                         cf.append(self.tracefuncs[fn]['func'])
835                                 else:             684                                 else:
836                                         cf.app    685                                         cf.append(fn)
837                         if self.ftop:          !! 686                         self.setFtraceFilterFunctions(cf)
838                                 self.setFtrace << 
839                         else:                  << 
840                                 self.setFtrace << 
841                 # initialize the kprobe trace     687                 # initialize the kprobe trace
842                 elif self.usekprobes:             688                 elif self.usekprobes:
843                         for name in self.trace    689                         for name in self.tracefuncs:
844                                 self.defaultKp    690                                 self.defaultKprobe(name, self.tracefuncs[name])
845                         if self.usedevsrc:        691                         if self.usedevsrc:
846                                 for name in se    692                                 for name in self.dev_tracefuncs:
847                                         self.d    693                                         self.defaultKprobe(name, self.dev_tracefuncs[name])
848                         if not quiet:          !! 694                         print('INITIALIZING KPROBES...')
849                                 pprint('INITIA << 
850                         self.addKprobes(self.v    695                         self.addKprobes(self.verbose)
851                 if(self.usetraceevents):          696                 if(self.usetraceevents):
852                         # turn trace events on    697                         # turn trace events on
853                         events = iter(self.tra    698                         events = iter(self.traceevents)
854                         for e in events:          699                         for e in events:
855                                 self.fsetVal('    700                                 self.fsetVal('1', 'events/power/'+e+'/enable')
856                 # clear the trace buffer          701                 # clear the trace buffer
857                 self.fsetVal('', 'trace')         702                 self.fsetVal('', 'trace')
858         def verifyFtrace(self):                   703         def verifyFtrace(self):
859                 # files needed for any trace d    704                 # files needed for any trace data
860                 files = ['buffer_size_kb', 'cu    705                 files = ['buffer_size_kb', 'current_tracer', 'trace', 'trace_clock',
861                                  'trace_marker    706                                  'trace_marker', 'trace_options', 'tracing_on']
862                 # files needed for callgraph t    707                 # files needed for callgraph trace data
863                 tp = self.tpath                   708                 tp = self.tpath
864                 if(self.usecallgraph):            709                 if(self.usecallgraph):
865                         files += [                710                         files += [
866                                 'available_fil    711                                 'available_filter_functions',
867                                 'set_ftrace_fi    712                                 'set_ftrace_filter',
868                                 'set_graph_fun    713                                 'set_graph_function'
869                         ]                         714                         ]
870                 for f in files:                   715                 for f in files:
871                         if(os.path.exists(tp+f    716                         if(os.path.exists(tp+f) == False):
872                                 return False      717                                 return False
873                 return True                       718                 return True
874         def verifyKprobes(self):                  719         def verifyKprobes(self):
875                 # files needed for kprobes to     720                 # files needed for kprobes to work
876                 files = ['kprobe_events', 'eve    721                 files = ['kprobe_events', 'events']
877                 tp = self.tpath                   722                 tp = self.tpath
878                 for f in files:                   723                 for f in files:
879                         if(os.path.exists(tp+f    724                         if(os.path.exists(tp+f) == False):
880                                 return False      725                                 return False
881                 return True                       726                 return True
882         def colorText(self, str, color=31):       727         def colorText(self, str, color=31):
883                 if not self.ansi:                 728                 if not self.ansi:
884                         return str                729                         return str
885                 return '\x1B[%d;40m%s\x1B[m' %    730                 return '\x1B[%d;40m%s\x1B[m' % (color, str)
886         def writeDatafileHeader(self, filename !! 731         def writeDatafileHeader(self, filename, fwdata=[]):
887                 fp = self.openlog(filename, 'w    732                 fp = self.openlog(filename, 'w')
888                 fp.write('%s\n%s\n# command |     733                 fp.write('%s\n%s\n# command | %s\n' % (self.teststamp, self.sysstamp, self.cmdline))
889                 for test in testdata:          !! 734                 if(self.suspendmode == 'mem' or self.suspendmode == 'command'):
890                         if 'fw' in test:       !! 735                         for fw in fwdata:
891                                 fw = test['fw' << 
892                                 if(fw):           736                                 if(fw):
893                                         fp.wri    737                                         fp.write('# fwsuspend %u fwresume %u\n' % (fw[0], fw[1]))
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                         738                 return fp
903         def sudoUserchown(self, dir):          !! 739         def sudouser(self, dir):
904                 if os.path.exists(dir) and sel !! 740                 if os.path.exists(dir) and os.getuid() == 0 and \
                                                   >> 741                         'SUDO_USER' in os.environ:
905                         cmd = 'chown -R {0}:{0    742                         cmd = 'chown -R {0}:{0} {1} > /dev/null 2>&1'
906                         call(cmd.format(self.s !! 743                         call(cmd.format(os.environ['SUDO_USER'], dir), shell=True)
907         def outputResult(self, testdata, num=0    744         def outputResult(self, testdata, num=0):
908                 if not self.result:               745                 if not self.result:
909                         return                    746                         return
910                 n = ''                            747                 n = ''
911                 if num > 0:                       748                 if num > 0:
912                         n = '%d' % num            749                         n = '%d' % num
913                 fp = open(self.result, 'a')       750                 fp = open(self.result, 'a')
914                 if 'error' in testdata:           751                 if 'error' in testdata:
915                         fp.write('result%s: fa    752                         fp.write('result%s: fail\n' % n)
916                         fp.write('error%s: %s\    753                         fp.write('error%s: %s\n' % (n, testdata['error']))
917                 else:                             754                 else:
918                         fp.write('result%s: pa    755                         fp.write('result%s: pass\n' % n)
919                 if 'mode' in testdata:         << 
920                         fp.write('mode%s: %s\n << 
921                 for v in ['suspend', 'resume',    756                 for v in ['suspend', 'resume', 'boot', 'lastinit']:
922                         if v in testdata:         757                         if v in testdata:
923                                 fp.write('%s%s    758                                 fp.write('%s%s: %.3f\n' % (v, n, testdata[v]))
924                 for v in ['fwsuspend', 'fwresu    759                 for v in ['fwsuspend', 'fwresume']:
925                         if v in testdata:         760                         if v in testdata:
926                                 fp.write('%s%s    761                                 fp.write('%s%s: %.3f\n' % (v, n, testdata[v] / 1000000.0))
927                 if 'bugurl' in testdata:          762                 if 'bugurl' in testdata:
928                         fp.write('url%s: %s\n'    763                         fp.write('url%s: %s\n' % (n, testdata['bugurl']))
929                 fp.close()                        764                 fp.close()
930                 self.sudoUserchown(self.result !! 765                 self.sudouser(self.result)
931         def configFile(self, file):               766         def configFile(self, file):
932                 dir = os.path.dirname(os.path.    767                 dir = os.path.dirname(os.path.realpath(__file__))
933                 if os.path.exists(file):          768                 if os.path.exists(file):
934                         return file               769                         return file
935                 elif os.path.exists(dir+'/'+fi    770                 elif os.path.exists(dir+'/'+file):
936                         return dir+'/'+file       771                         return dir+'/'+file
937                 elif os.path.exists(dir+'/conf    772                 elif os.path.exists(dir+'/config/'+file):
938                         return dir+'/config/'+    773                         return dir+'/config/'+file
939                 return ''                         774                 return ''
940         def openlog(self, filename, mode):        775         def openlog(self, filename, mode):
941                 isgz = self.gzip                  776                 isgz = self.gzip
942                 if mode == 'r':                   777                 if mode == 'r':
943                         try:                      778                         try:
944                                 with gzip.open !! 779                                 with gzip.open(filename, mode+'b') as fp:
945                                         test =    780                                         test = fp.read(64)
946                                 isgz = True       781                                 isgz = True
947                         except:                   782                         except:
948                                 isgz = False      783                                 isgz = False
949                 if isgz:                          784                 if isgz:
950                         return gzip.open(filen !! 785                         return gzip.open(filename, mode+'b')
951                 return open(filename, mode)       786                 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                                                  787 
1384 sysvals = SystemValues()                         788 sysvals = SystemValues()
1385 switchvalues = ['enable', 'disable', 'on', 'o    789 switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0']
1386 switchoff = ['disable', 'off', 'false', '0']     790 switchoff = ['disable', 'off', 'false', '0']
1387 suspendmodename = {                              791 suspendmodename = {
1388         'standby': 'standby (S1)',            !! 792         'freeze': 'Freeze (S0)',
1389         'freeze': 'freeze (S2idle)',          !! 793         'standby': 'Standby (S1)',
1390         'mem': 'suspend (S3)',                !! 794         'mem': 'Suspend (S3)',
1391         'disk': 'hibernate (S4)'              !! 795         'disk': 'Hibernate (S4)'
1392 }                                                796 }
1393                                                  797 
1394 # Class: DevProps                                798 # Class: DevProps
1395 # Description:                                   799 # Description:
1396 #        Simple class which holds property va    800 #        Simple class which holds property values collected
1397 #        for all the devices used in the time    801 #        for all the devices used in the timeline.
1398 class DevProps:                                  802 class DevProps:
1399         def __init__(self):                   !! 803         syspath = ''
1400                 self.syspath = ''             !! 804         altname = ''
1401                 self.altname = ''             !! 805         async = True
1402                 self.isasync = True           !! 806         xtraclass = ''
1403                 self.xtraclass = ''           !! 807         xtrainfo = ''
1404                 self.xtrainfo = ''            << 
1405         def out(self, dev):                      808         def out(self, dev):
1406                 return '%s,%s,%d;' % (dev, se !! 809                 return '%s,%s,%d;' % (dev, self.altname, self.async)
1407         def debug(self, dev):                    810         def debug(self, dev):
1408                 pprint('%s:\n\taltname = %s\n !! 811                 print '%s:\n\taltname = %s\n\t  async = %s' % (dev, self.altname, self.async)
1409         def altName(self, dev):                  812         def altName(self, dev):
1410                 if not self.altname or self.a    813                 if not self.altname or self.altname == dev:
1411                         return dev               814                         return dev
1412                 return '%s [%s]' % (self.altn    815                 return '%s [%s]' % (self.altname, dev)
1413         def xtraClass(self):                     816         def xtraClass(self):
1414                 if self.xtraclass:               817                 if self.xtraclass:
1415                         return ' '+self.xtrac    818                         return ' '+self.xtraclass
1416                 if not self.isasync:          !! 819                 if not self.async:
1417                         return ' sync'           820                         return ' sync'
1418                 return ''                        821                 return ''
1419         def xtraInfo(self):                      822         def xtraInfo(self):
1420                 if self.xtraclass:               823                 if self.xtraclass:
1421                         return ' '+self.xtrac    824                         return ' '+self.xtraclass
1422                 if self.isasync:              !! 825                 if self.async:
1423                         return ' (async)'     !! 826                         return ' async_device'
1424                 return ' (sync)'              !! 827                 return ' sync_device'
1425                                                  828 
1426 # Class: DeviceNode                              829 # Class: DeviceNode
1427 # Description:                                   830 # Description:
1428 #        A container used to create a device     831 #        A container used to create a device hierachy, with a single root node
1429 #        and a tree of child nodes. Used by D    832 #        and a tree of child nodes. Used by Data.deviceTopology()
1430 class DeviceNode:                                833 class DeviceNode:
                                                   >> 834         name = ''
                                                   >> 835         children = 0
                                                   >> 836         depth = 0
1431         def __init__(self, nodename, nodedept    837         def __init__(self, nodename, nodedepth):
1432                 self.name = nodename             838                 self.name = nodename
1433                 self.children = []               839                 self.children = []
1434                 self.depth = nodedepth           840                 self.depth = nodedepth
1435                                                  841 
1436 # Class: Data                                    842 # Class: Data
1437 # Description:                                   843 # Description:
1438 #        The primary container for suspend/re    844 #        The primary container for suspend/resume test data. There is one for
1439 #        each test run. The data is organized    845 #        each test run. The data is organized into a cronological hierarchy:
1440 #        Data.dmesg {                            846 #        Data.dmesg {
1441 #               phases {                         847 #               phases {
1442 #                       10 sequential, non-ov    848 #                       10 sequential, non-overlapping phases of S/R
1443 #                       contents: times for p    849 #                       contents: times for phase start/end, order/color data for html
1444 #                       devlist {                850 #                       devlist {
1445 #                               device callba    851 #                               device callback or action list for this phase
1446 #                               device {         852 #                               device {
1447 #                                       a sin    853 #                                       a single device callback or generic action
1448 #                                       conte    854 #                                       contents: start/stop times, pid/cpu/driver info
1449 #                                                855 #                                               parents/children, html id for timeline/callgraph
1450 #                                                856 #                                               optionally includes an ftrace callgraph
1451 #                                                857 #                                               optionally includes dev/ps data
1452 #                               }                858 #                               }
1453 #                       }                        859 #                       }
1454 #               }                                860 #               }
1455 #       }                                        861 #       }
1456 #                                                862 #
1457 class Data:                                      863 class Data:
1458         phasedef = {                          !! 864         dmesg = {}  # root data structure
1459                 'suspend_prepare': {'order':  !! 865         phases = [] # ordered list of phases
1460                         'suspend': {'order':  !! 866         start = 0.0 # test start
1461                    'suspend_late': {'order':  !! 867         end = 0.0   # test end
1462                   'suspend_noirq': {'order':  !! 868         tSuspended = 0.0 # low-level suspend start
1463                 'suspend_machine': {'order':  !! 869         tResumed = 0.0   # low-level resume start
1464                  'resume_machine': {'order':  !! 870         tKernSus = 0.0   # kernel level suspend start
1465                    'resume_noirq': {'order':  !! 871         tKernRes = 0.0   # kernel level resume end
1466                    'resume_early': {'order':  !! 872         tLow = 0.0       # time spent in low-level suspend (standby/freeze)
1467                          'resume': {'order':  !! 873         fwValid = False  # is firmware data available
1468                 'resume_complete': {'order':  !! 874         fwSuspend = 0    # time spent in firmware suspend
1469         }                                     !! 875         fwResume = 0     # time spent in firmware resume
1470         errlist = {                           !! 876         dmesgtext = []   # dmesg text file in memory
1471                 'HWERROR' : r'.*\[ *Hardware  !! 877         pstl = 0         # process timeline
1472                 'FWBUG'   : r'.*\[ *Firmware  !! 878         testnumber = 0
1473                 'TASKFAIL': r'.*Freezing .*af !! 879         idstr = ''
1474                 'BUG'     : r'(?i).*\bBUG\b.* !! 880         html_device_id = 0
1475                 'ERROR'   : r'(?i).*\bERROR\b !! 881         stamp = 0
1476                 'WARNING' : r'(?i).*\bWARNING !! 882         outfile = ''
1477                 'FAULT'   : r'(?i).*\bFAULT\b !! 883         devpids = []
1478                 'FAIL'    : r'(?i).*\bFAILED\ !! 884         kerror = False
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):                 885         def __init__(self, num):
1492                 idchar = 'abcdefghij'            886                 idchar = 'abcdefghij'
1493                 self.start = 0.0 # test start !! 887                 self.pstl = dict()
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            888                 self.testnumber = num
1514                 self.idstr = idchar[num]         889                 self.idstr = idchar[num]
1515                 self.dmesgtext = []   # dmesg !! 890                 self.dmesgtext = []
1516                 self.dmesg = dict()   # root  !! 891                 self.phases = []
1517                 self.errorinfo = {'suspend':[ !! 892                 self.dmesg = { # fixed list of 10 phases
1518                 self.tLow = []        # time  !! 893                         'suspend_prepare': {'list': dict(), 'start': -1.0, 'end': -1.0,
1519                 self.devpids = []             !! 894                                                                 'row': 0, 'color': '#CCFFCC', 'order': 0},
1520                 self.devicegroups = 0         !! 895                                 'suspend': {'list': dict(), 'start': -1.0, 'end': -1.0,
1521         def sortedPhases(self):               !! 896                                                                 'row': 0, 'color': '#88FF88', 'order': 1},
1522                 return sorted(self.dmesg, key !! 897                            'suspend_late': {'list': dict(), 'start': -1.0, 'end': -1.0,
1523         def initDevicegroups(self):           !! 898                                                                 'row': 0, 'color': '#00AA00', 'order': 2},
1524                 # called when phases are all  !! 899                           'suspend_noirq': {'list': dict(), 'start': -1.0, 'end': -1.0,
1525                 for phase in sorted(self.dmes !! 900                                                                 'row': 0, 'color': '#008888', 'order': 3},
1526                         if '*' in phase:      !! 901                     'suspend_machine': {'list': dict(), 'start': -1.0, 'end': -1.0,
1527                                 p = phase.spl !! 902                                                                 'row': 0, 'color': '#0000FF', 'order': 4},
1528                                 pnew = '%s%d' !! 903                          'resume_machine': {'list': dict(), 'start': -1.0, 'end': -1.0,
1529                                 self.dmesg[pn !! 904                                                                 'row': 0, 'color': '#FF0000', 'order': 5},
                                                   >> 905                            'resume_noirq': {'list': dict(), 'start': -1.0, 'end': -1.0,
                                                   >> 906                                                                 'row': 0, 'color': '#FF9900', 'order': 6},
                                                   >> 907                            'resume_early': {'list': dict(), 'start': -1.0, 'end': -1.0,
                                                   >> 908                                                                 'row': 0, 'color': '#FFCC00', 'order': 7},
                                                   >> 909                                  'resume': {'list': dict(), 'start': -1.0, 'end': -1.0,
                                                   >> 910                                                                 'row': 0, 'color': '#FFFF88', 'order': 8},
                                                   >> 911                         'resume_complete': {'list': dict(), 'start': -1.0, 'end': -1.0,
                                                   >> 912                                                                 'row': 0, 'color': '#FFFFCC', 'order': 9}
                                                   >> 913                 }
                                                   >> 914                 self.phases = self.sortedPhases()
1530                 self.devicegroups = []           915                 self.devicegroups = []
1531                 for phase in self.sortedPhase !! 916                 for phase in self.phases:
1532                         self.devicegroups.app    917                         self.devicegroups.append([phase])
1533         def nextPhase(self, phase, offset):   !! 918                 self.errorinfo = {'suspend':[],'resume':[]}
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):              919         def extractErrorInfo(self):
1559                 lf = self.dmesgtext           !! 920                 elist = {
1560                 if len(self.dmesgtext) < 1 an !! 921                         'HWERROR' : '.*\[ *Hardware Error *\].*',
1561                         lf = sysvals.openlog( !! 922                         'FWBUG'   : '.*\[ *Firmware Bug *\].*',
                                                   >> 923                         'BUG'     : '.*BUG.*',
                                                   >> 924                         'ERROR'   : '.*ERROR.*',
                                                   >> 925                         'WARNING' : '.*WARNING.*',
                                                   >> 926                         'IRQ'     : '.*genirq: .*',
                                                   >> 927                         'TASKFAIL': '.*Freezing of tasks failed.*',
                                                   >> 928                 }
                                                   >> 929                 lf = sysvals.openlog(sysvals.dmesgfile, 'r')
1562                 i = 0                            930                 i = 0
1563                 tp = TestProps()              << 
1564                 list = []                        931                 list = []
1565                 for line in lf:                  932                 for line in lf:
1566                         i += 1                   933                         i += 1
1567                         if tp.stampInfo(line, !! 934                         m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
1568                                 continue      << 
1569                         m = re.match(r'[ \t]* << 
1570                         if not m:                935                         if not m:
1571                                 continue         936                                 continue
1572                         t = float(m.group('kt    937                         t = float(m.group('ktime'))
1573                         if t < self.start or     938                         if t < self.start or t > self.end:
1574                                 continue         939                                 continue
1575                         dir = 'suspend' if t     940                         dir = 'suspend' if t < self.tSuspended else 'resume'
1576                         msg = m.group('msg')     941                         msg = m.group('msg')
1577                         if re.match(r'capabil !! 942                         for err in elist:
1578                                 continue      !! 943                                 if re.match(elist[err], msg):
1579                         for err in self.errli !! 944                                         list.append((err, dir, t, i, i))
1580                                 if re.match(s << 
1581                                         list. << 
1582                                         self.    945                                         self.kerror = True
1583                                         break    946                                         break
1584                 tp.msglist = []               !! 947                 for e in list:
1585                 for msg, type, dir, t, idx1,  !! 948                         type, dir, t, idx1, idx2 = e
1586                         tp.msglist.append(msg !! 949                         sysvals.vprint('kernel %s found in %s at %f' % (type, dir, t))
1587                         self.errorinfo[dir].a    950                         self.errorinfo[dir].append((type, t, idx1, idx2))
1588                 if self.kerror:                  951                 if self.kerror:
1589                         sysvals.dmesglog = Tr    952                         sysvals.dmesglog = True
1590                 if len(self.dmesgtext) < 1 an !! 953                 lf.close()
1591                         lf.close()            !! 954         def setStart(self, time):
1592                 return tp                     << 
1593         def setStart(self, time, msg=''):     << 
1594                 self.start = time                955                 self.start = time
1595                 if msg:                       !! 956         def setEnd(self, time):
1596                         try:                  << 
1597                                 self.hwstart  << 
1598                         except:               << 
1599                                 self.hwstart  << 
1600         def setEnd(self, time, msg=''):       << 
1601                 self.end = time                  957                 self.end = time
1602                 if msg:                       << 
1603                         try:                  << 
1604                                 self.hwend =  << 
1605                         except:               << 
1606                                 self.hwend =  << 
1607         def isTraceEventOutsideDeviceCalls(se    958         def isTraceEventOutsideDeviceCalls(self, pid, time):
1608                 for phase in self.sortedPhase !! 959                 for phase in self.phases:
1609                         list = self.dmesg[pha    960                         list = self.dmesg[phase]['list']
1610                         for dev in list:         961                         for dev in list:
1611                                 d = list[dev]    962                                 d = list[dev]
1612                                 if(d['pid'] =    963                                 if(d['pid'] == pid and time >= d['start'] and
1613                                         time     964                                         time < d['end']):
1614                                         retur    965                                         return False
1615                 return True                      966                 return True
                                                   >> 967         def phaseCollision(self, phase, isbegin, line):
                                                   >> 968                 key = 'end'
                                                   >> 969                 if isbegin:
                                                   >> 970                         key = 'start'
                                                   >> 971                 if self.dmesg[phase][key] >= 0:
                                                   >> 972                         sysvals.vprint('IGNORE: %s' % line.strip())
                                                   >> 973                         return True
                                                   >> 974                 return False
1616         def sourcePhase(self, start):            975         def sourcePhase(self, start):
1617                 for phase in self.sortedPhase !! 976                 for phase in self.phases:
1618                         if 'machine' in phase << 
1619                                 continue      << 
1620                         pend = self.dmesg[pha    977                         pend = self.dmesg[phase]['end']
1621                         if start <= pend:        978                         if start <= pend:
1622                                 return phase     979                                 return phase
1623                 return 'resume_complete' if ' !! 980                 return 'resume_complete'
1624         def sourceDevice(self, phaselist, sta    981         def sourceDevice(self, phaselist, start, end, pid, type):
1625                 tgtdev = ''                      982                 tgtdev = ''
1626                 for phase in phaselist:          983                 for phase in phaselist:
1627                         list = self.dmesg[pha    984                         list = self.dmesg[phase]['list']
1628                         for devname in list:     985                         for devname in list:
1629                                 dev = list[de    986                                 dev = list[devname]
1630                                 # pid must ma    987                                 # pid must match
1631                                 if dev['pid']    988                                 if dev['pid'] != pid:
1632                                         conti    989                                         continue
1633                                 devS = dev['s    990                                 devS = dev['start']
1634                                 devE = dev['e    991                                 devE = dev['end']
1635                                 if type == 'd    992                                 if type == 'device':
1636                                         # dev    993                                         # device target event is entirely inside the source boundary
1637                                         if(st    994                                         if(start < devS or start >= devE or end <= devS or end > devE):
1638                                                  995                                                 continue
1639                                 elif type ==     996                                 elif type == 'thread':
1640                                         # thr    997                                         # thread target event will expand the source boundary
1641                                         if st    998                                         if start < devS:
1642                                                  999                                                 dev['start'] = start
1643                                         if en    1000                                         if end > devE:
1644                                                  1001                                                 dev['end'] = end
1645                                 tgtdev = dev     1002                                 tgtdev = dev
1646                                 break            1003                                 break
1647                 return tgtdev                    1004                 return tgtdev
1648         def addDeviceFunctionCall(self, displ    1005         def addDeviceFunctionCall(self, displayname, kprobename, proc, pid, start, end, cdata, rdata):
1649                 # try to place the call in a     1006                 # try to place the call in a device
1650                 phases = self.sortedPhases()  !! 1007                 tgtdev = self.sourceDevice(self.phases, start, end, pid, 'device')
1651                 tgtdev = self.sourceDevice(ph << 
1652                 # calls with device pids that    1008                 # calls with device pids that occur outside device bounds are dropped
1653                 # TODO: include these somehow    1009                 # TODO: include these somehow
1654                 if not tgtdev and pid in self    1010                 if not tgtdev and pid in self.devpids:
1655                         return False             1011                         return False
1656                 # try to place the call in a     1012                 # try to place the call in a thread
1657                 if not tgtdev:                   1013                 if not tgtdev:
1658                         tgtdev = self.sourceD !! 1014                         tgtdev = self.sourceDevice(self.phases, start, end, pid, 'thread')
1659                 # create new thread blocks, e    1015                 # create new thread blocks, expand as new calls are found
1660                 if not tgtdev:                   1016                 if not tgtdev:
1661                         if proc == '<...>':      1017                         if proc == '<...>':
1662                                 threadname =     1018                                 threadname = 'kthread-%d' % (pid)
1663                         else:                    1019                         else:
1664                                 threadname =     1020                                 threadname = '%s-%d' % (proc, pid)
1665                         tgtphase = self.sourc    1021                         tgtphase = self.sourcePhase(start)
1666                         if not tgtphase:      << 
1667                                 return False  << 
1668                         self.newAction(tgtpha    1022                         self.newAction(tgtphase, threadname, pid, '', start, end, '', ' kth', '')
1669                         return self.addDevice    1023                         return self.addDeviceFunctionCall(displayname, kprobename, proc, pid, start, end, cdata, rdata)
1670                 # this should not happen         1024                 # this should not happen
1671                 if not tgtdev:                   1025                 if not tgtdev:
1672                         sysvals.vprint('[%f -    1026                         sysvals.vprint('[%f - %f] %s-%d %s %s %s' % \
1673                                 (start, end,     1027                                 (start, end, proc, pid, kprobename, cdata, rdata))
1674                         return False             1028                         return False
1675                 # place the call data inside     1029                 # place the call data inside the src element of the tgtdev
1676                 if('src' not in tgtdev):         1030                 if('src' not in tgtdev):
1677                         tgtdev['src'] = []       1031                         tgtdev['src'] = []
1678                 dtf = sysvals.dev_tracefuncs     1032                 dtf = sysvals.dev_tracefuncs
1679                 ubiquitous = False               1033                 ubiquitous = False
1680                 if kprobename in dtf and 'ub'    1034                 if kprobename in dtf and 'ub' in dtf[kprobename]:
1681                         ubiquitous = True        1035                         ubiquitous = True
1682                 mc = re.match(r'\(.*\) *(?P<a !! 1036                 title = cdata+' '+rdata
1683                 mr = re.match(r'\((?P<caller> !! 1037                 mstr = '\(.*\) *(?P<args>.*) *\((?P<caller>.*)\+.* arg1=(?P<ret>.*)'
1684                 if mc and mr:                 !! 1038                 m = re.match(mstr, title)
1685                         c = mr.group('caller' !! 1039                 if m:
1686                         a = mc.group('args'). !! 1040                         c = m.group('caller')
1687                         r = mr.group('ret')   !! 1041                         a = m.group('args').strip()
                                                   >> 1042                         r = m.group('ret')
1688                         if len(r) > 6:           1043                         if len(r) > 6:
1689                                 r = ''           1044                                 r = ''
1690                         else:                    1045                         else:
1691                                 r = 'ret=%s '    1046                                 r = 'ret=%s ' % r
1692                         if ubiquitous and c i    1047                         if ubiquitous and c in dtf and 'ub' in dtf[c]:
1693                                 return False     1048                                 return False
1694                 else:                         << 
1695                         return False          << 
1696                 color = sysvals.kprobeColor(k    1049                 color = sysvals.kprobeColor(kprobename)
1697                 e = DevFunction(displayname,     1050                 e = DevFunction(displayname, a, c, r, start, end, ubiquitous, proc, pid, color)
1698                 tgtdev['src'].append(e)          1051                 tgtdev['src'].append(e)
1699                 return True                      1052                 return True
1700         def overflowDevices(self):               1053         def overflowDevices(self):
1701                 # get a list of devices that     1054                 # get a list of devices that extend beyond the end of this test run
1702                 devlist = []                     1055                 devlist = []
1703                 for phase in self.sortedPhase !! 1056                 for phase in self.phases:
1704                         list = self.dmesg[pha    1057                         list = self.dmesg[phase]['list']
1705                         for devname in list:     1058                         for devname in list:
1706                                 dev = list[de    1059                                 dev = list[devname]
1707                                 if dev['end']    1060                                 if dev['end'] > self.end:
1708                                         devli    1061                                         devlist.append(dev)
1709                 return devlist                   1062                 return devlist
1710         def mergeOverlapDevices(self, devlist    1063         def mergeOverlapDevices(self, devlist):
1711                 # merge any devices that over    1064                 # merge any devices that overlap devlist
1712                 for dev in devlist:              1065                 for dev in devlist:
1713                         devname = dev['name']    1066                         devname = dev['name']
1714                         for phase in self.sor !! 1067                         for phase in self.phases:
1715                                 list = self.d    1068                                 list = self.dmesg[phase]['list']
1716                                 if devname no    1069                                 if devname not in list:
1717                                         conti    1070                                         continue
1718                                 tdev = list[d    1071                                 tdev = list[devname]
1719                                 o = min(dev['    1072                                 o = min(dev['end'], tdev['end']) - max(dev['start'], tdev['start'])
1720                                 if o <= 0:       1073                                 if o <= 0:
1721                                         conti    1074                                         continue
1722                                 dev['end'] =     1075                                 dev['end'] = tdev['end']
1723                                 if 'src' not     1076                                 if 'src' not in dev or 'src' not in tdev:
1724                                         conti    1077                                         continue
1725                                 dev['src'] +=    1078                                 dev['src'] += tdev['src']
1726                                 del list[devn    1079                                 del list[devname]
1727         def usurpTouchingThread(self, name, d    1080         def usurpTouchingThread(self, name, dev):
1728                 # the caller test has priorit    1081                 # the caller test has priority of this thread, give it to him
1729                 for phase in self.sortedPhase !! 1082                 for phase in self.phases:
1730                         list = self.dmesg[pha    1083                         list = self.dmesg[phase]['list']
1731                         if name in list:         1084                         if name in list:
1732                                 tdev = list[n    1085                                 tdev = list[name]
1733                                 if tdev['star    1086                                 if tdev['start'] - dev['end'] < 0.1:
1734                                         dev['    1087                                         dev['end'] = tdev['end']
1735                                         if 's    1088                                         if 'src' not in dev:
1736                                                  1089                                                 dev['src'] = []
1737                                         if 's    1090                                         if 'src' in tdev:
1738                                                  1091                                                 dev['src'] += tdev['src']
1739                                         del l    1092                                         del list[name]
1740                                 break            1093                                 break
1741         def stitchTouchingThreads(self, testl    1094         def stitchTouchingThreads(self, testlist):
1742                 # merge any threads between t    1095                 # merge any threads between tests that touch
1743                 for phase in self.sortedPhase !! 1096                 for phase in self.phases:
1744                         list = self.dmesg[pha    1097                         list = self.dmesg[phase]['list']
1745                         for devname in list:     1098                         for devname in list:
1746                                 dev = list[de    1099                                 dev = list[devname]
1747                                 if 'htmlclass    1100                                 if 'htmlclass' not in dev or 'kth' not in dev['htmlclass']:
1748                                         conti    1101                                         continue
1749                                 for data in t    1102                                 for data in testlist:
1750                                         data.    1103                                         data.usurpTouchingThread(devname, dev)
1751         def optimizeDevSrc(self):                1104         def optimizeDevSrc(self):
1752                 # merge any src call loops to    1105                 # merge any src call loops to reduce timeline size
1753                 for phase in self.sortedPhase !! 1106                 for phase in self.phases:
1754                         list = self.dmesg[pha    1107                         list = self.dmesg[phase]['list']
1755                         for dev in list:         1108                         for dev in list:
1756                                 if 'src' not     1109                                 if 'src' not in list[dev]:
1757                                         conti    1110                                         continue
1758                                 src = list[de    1111                                 src = list[dev]['src']
1759                                 p = 0            1112                                 p = 0
1760                                 for e in sort    1113                                 for e in sorted(src, key=lambda event: event.time):
1761                                         if no    1114                                         if not p or not e.repeat(p):
1762                                                  1115                                                 p = e
1763                                                  1116                                                 continue
1764                                         # e i    1117                                         # e is another iteration of p, move it into p
1765                                         p.end    1118                                         p.end = e.end
1766                                         p.len    1119                                         p.length = p.end - p.time
1767                                         p.cou    1120                                         p.count += 1
1768                                         src.r    1121                                         src.remove(e)
1769         def trimTimeVal(self, t, t0, dT, left    1122         def trimTimeVal(self, t, t0, dT, left):
1770                 if left:                         1123                 if left:
1771                         if(t > t0):              1124                         if(t > t0):
1772                                 if(t - dT < t    1125                                 if(t - dT < t0):
1773                                         retur    1126                                         return t0
1774                                 return t - dT    1127                                 return t - dT
1775                         else:                    1128                         else:
1776                                 return t         1129                                 return t
1777                 else:                            1130                 else:
1778                         if(t < t0 + dT):         1131                         if(t < t0 + dT):
1779                                 if(t > t0):      1132                                 if(t > t0):
1780                                         retur    1133                                         return t0 + dT
1781                                 return t + dT    1134                                 return t + dT
1782                         else:                    1135                         else:
1783                                 return t         1136                                 return t
1784         def trimTime(self, t0, dT, left):        1137         def trimTime(self, t0, dT, left):
1785                 self.tSuspended = self.trimTi    1138                 self.tSuspended = self.trimTimeVal(self.tSuspended, t0, dT, left)
1786                 self.tResumed = self.trimTime    1139                 self.tResumed = self.trimTimeVal(self.tResumed, t0, dT, left)
1787                 self.start = self.trimTimeVal    1140                 self.start = self.trimTimeVal(self.start, t0, dT, left)
1788                 self.tKernSus = self.trimTime    1141                 self.tKernSus = self.trimTimeVal(self.tKernSus, t0, dT, left)
1789                 self.tKernRes = self.trimTime    1142                 self.tKernRes = self.trimTimeVal(self.tKernRes, t0, dT, left)
1790                 self.end = self.trimTimeVal(s    1143                 self.end = self.trimTimeVal(self.end, t0, dT, left)
1791                 for phase in self.sortedPhase !! 1144                 for phase in self.phases:
1792                         p = self.dmesg[phase]    1145                         p = self.dmesg[phase]
1793                         p['start'] = self.tri    1146                         p['start'] = self.trimTimeVal(p['start'], t0, dT, left)
1794                         p['end'] = self.trimT    1147                         p['end'] = self.trimTimeVal(p['end'], t0, dT, left)
1795                         list = p['list']         1148                         list = p['list']
1796                         for name in list:        1149                         for name in list:
1797                                 d = list[name    1150                                 d = list[name]
1798                                 d['start'] =     1151                                 d['start'] = self.trimTimeVal(d['start'], t0, dT, left)
1799                                 d['end'] = se    1152                                 d['end'] = self.trimTimeVal(d['end'], t0, dT, left)
1800                                 d['length'] = << 
1801                                 if('ftrace' i    1153                                 if('ftrace' in d):
1802                                         cg =     1154                                         cg = d['ftrace']
1803                                         cg.st    1155                                         cg.start = self.trimTimeVal(cg.start, t0, dT, left)
1804                                         cg.en    1156                                         cg.end = self.trimTimeVal(cg.end, t0, dT, left)
1805                                         for l    1157                                         for line in cg.list:
1806                                                  1158                                                 line.time = self.trimTimeVal(line.time, t0, dT, left)
1807                                 if('src' in d    1159                                 if('src' in d):
1808                                         for e    1160                                         for e in d['src']:
1809                                                  1161                                                 e.time = self.trimTimeVal(e.time, t0, dT, left)
1810                                               << 
1811                                               << 
1812                                 if('cpuexec'  << 
1813                                         cpuex << 
1814                                         for e << 
1815                                               << 
1816                                               << 
1817                                               << 
1818                                               << 
1819                                         d['cp << 
1820                 for dir in ['suspend', 'resum    1162                 for dir in ['suspend', 'resume']:
1821                         list = []                1163                         list = []
1822                         for e in self.errorin    1164                         for e in self.errorinfo[dir]:
1823                                 type, tm, idx    1165                                 type, tm, idx1, idx2 = e
1824                                 tm = self.tri    1166                                 tm = self.trimTimeVal(tm, t0, dT, left)
1825                                 list.append((    1167                                 list.append((type, tm, idx1, idx2))
1826                         self.errorinfo[dir] =    1168                         self.errorinfo[dir] = list
1827         def trimFreezeTime(self, tZero):      !! 1169         def normalizeTime(self, tZero):
1828                 # trim out any standby or fre    1170                 # trim out any standby or freeze clock time
1829                 lp = ''                       !! 1171                 if(self.tSuspended != self.tResumed):
1830                 for phase in self.sortedPhase !! 1172                         if(self.tResumed > tZero):
1831                         if 'resume_machine' i !! 1173                                 self.trimTime(self.tSuspended, \
1832                                 tS, tR = self !! 1174                                         self.tResumed-self.tSuspended, True)
1833                                 tL = tR - tS  !! 1175                         else:
1834                                 if tL <= 0:   !! 1176                                 self.trimTime(self.tSuspended, \
1835                                         conti !! 1177                                         self.tResumed-self.tSuspended, False)
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):                 1178         def getTimeValues(self):
1858                 s = (self.tSuspended - self.t !! 1179                 sktime = (self.dmesg['suspend_machine']['end'] - \
1859                 r = (self.tKernRes - self.tRe !! 1180                         self.tKernSus) * 1000
1860                 return (max(s, 0), max(r, 0)) !! 1181                 rktime = (self.dmesg['resume_complete']['end'] - \
1861         def setPhase(self, phase, ktime, isbe !! 1182                         self.dmesg['resume_machine']['start']) * 1000
                                                   >> 1183                 return (sktime, rktime)
                                                   >> 1184         def setPhase(self, phase, ktime, isbegin):
1862                 if(isbegin):                     1185                 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    1186                         self.dmesg[phase]['start'] = ktime
1877                         self.currphase = phas << 
1878                 else:                            1187                 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    1188                         self.dmesg[phase]['end'] = ktime
1888                         self.currphase = ''   !! 1189         def dmesgSortVal(self, phase):
1889                 return phase                  !! 1190                 return self.dmesg[phase]['order']
                                                   >> 1191         def sortedPhases(self):
                                                   >> 1192                 return sorted(self.dmesg, key=self.dmesgSortVal)
1890         def sortedDevices(self, phase):          1193         def sortedDevices(self, phase):
1891                 list = self.dmesg[phase]['lis    1194                 list = self.dmesg[phase]['list']
1892                 return sorted(list, key=lambd !! 1195                 slist = []
                                                   >> 1196                 tmp = dict()
                                                   >> 1197                 for devname in list:
                                                   >> 1198                         dev = list[devname]
                                                   >> 1199                         if dev['length'] == 0:
                                                   >> 1200                                 continue
                                                   >> 1201                         tmp[dev['start']] = devname
                                                   >> 1202                 for t in sorted(tmp):
                                                   >> 1203                         slist.append(tmp[t])
                                                   >> 1204                 return slist
1893         def fixupInitcalls(self, phase):         1205         def fixupInitcalls(self, phase):
1894                 # if any calls never returned    1206                 # if any calls never returned, clip them at system resume end
1895                 phaselist = self.dmesg[phase]    1207                 phaselist = self.dmesg[phase]['list']
1896                 for devname in phaselist:        1208                 for devname in phaselist:
1897                         dev = phaselist[devna    1209                         dev = phaselist[devname]
1898                         if(dev['end'] < 0):      1210                         if(dev['end'] < 0):
1899                                 for p in self !! 1211                                 for p in self.phases:
1900                                         if se    1212                                         if self.dmesg[p]['end'] > dev['start']:
1901                                                  1213                                                 dev['end'] = self.dmesg[p]['end']
1902                                                  1214                                                 break
1903                                 sysvals.vprin    1215                                 sysvals.vprint('%s (%s): callback didnt return' % (devname, phase))
1904         def deviceFilter(self, devicefilter):    1216         def deviceFilter(self, devicefilter):
1905                 for phase in self.sortedPhase !! 1217                 for phase in self.phases:
1906                         list = self.dmesg[pha    1218                         list = self.dmesg[phase]['list']
1907                         rmlist = []              1219                         rmlist = []
1908                         for name in list:        1220                         for name in list:
1909                                 keep = False     1221                                 keep = False
1910                                 for filter in    1222                                 for filter in devicefilter:
1911                                         if fi    1223                                         if filter in name or \
1912                                                  1224                                                 ('drv' in list[name] and filter in list[name]['drv']):
1913                                                  1225                                                 keep = True
1914                                 if not keep:     1226                                 if not keep:
1915                                         rmlis    1227                                         rmlist.append(name)
1916                         for name in rmlist:      1228                         for name in rmlist:
1917                                 del list[name    1229                                 del list[name]
1918         def fixupInitcallsThatDidntReturn(sel    1230         def fixupInitcallsThatDidntReturn(self):
1919                 # if any calls never returned    1231                 # if any calls never returned, clip them at system resume end
1920                 for phase in self.sortedPhase !! 1232                 for phase in self.phases:
1921                         self.fixupInitcalls(p    1233                         self.fixupInitcalls(phase)
1922         def phaseOverlap(self, phases):          1234         def phaseOverlap(self, phases):
1923                 rmgroups = []                    1235                 rmgroups = []
1924                 newgroup = []                    1236                 newgroup = []
1925                 for group in self.devicegroup    1237                 for group in self.devicegroups:
1926                         for phase in phases:     1238                         for phase in phases:
1927                                 if phase not     1239                                 if phase not in group:
1928                                         conti    1240                                         continue
1929                                 for p in grou    1241                                 for p in group:
1930                                         if p     1242                                         if p not in newgroup:
1931                                                  1243                                                 newgroup.append(p)
1932                                 if group not     1244                                 if group not in rmgroups:
1933                                         rmgro    1245                                         rmgroups.append(group)
1934                 for group in rmgroups:           1246                 for group in rmgroups:
1935                         self.devicegroups.rem    1247                         self.devicegroups.remove(group)
1936                 self.devicegroups.append(newg    1248                 self.devicegroups.append(newgroup)
1937         def newActionGlobal(self, name, start    1249         def newActionGlobal(self, name, start, end, pid=-1, color=''):
1938                 # which phase is this device     1250                 # which phase is this device callback or action in
1939                 phases = self.sortedPhases()  << 
1940                 targetphase = 'none'             1251                 targetphase = 'none'
1941                 htmlclass = ''                   1252                 htmlclass = ''
1942                 overlap = 0.0                    1253                 overlap = 0.0
1943                 myphases = []                 !! 1254                 phases = []
1944                 for phase in phases:          !! 1255                 for phase in self.phases:
1945                         pstart = self.dmesg[p    1256                         pstart = self.dmesg[phase]['start']
1946                         pend = self.dmesg[pha    1257                         pend = self.dmesg[phase]['end']
1947                         # see if the action o    1258                         # see if the action overlaps this phase
1948                         o = max(0, min(end, p    1259                         o = max(0, min(end, pend) - max(start, pstart))
1949                         if o > 0:                1260                         if o > 0:
1950                                 myphases.appe !! 1261                                 phases.append(phase)
1951                         # set the target phas    1262                         # set the target phase to the one that overlaps most
1952                         if o > overlap:          1263                         if o > overlap:
1953                                 if overlap >     1264                                 if overlap > 0 and phase == 'post_resume':
1954                                         conti    1265                                         continue
1955                                 targetphase =    1266                                 targetphase = phase
1956                                 overlap = o      1267                                 overlap = o
1957                 # if no target phase was foun    1268                 # if no target phase was found, pin it to the edge
1958                 if targetphase == 'none':        1269                 if targetphase == 'none':
1959                         p0start = self.dmesg[ !! 1270                         p0start = self.dmesg[self.phases[0]]['start']
1960                         if start <= p0start:     1271                         if start <= p0start:
1961                                 targetphase = !! 1272                                 targetphase = self.phases[0]
1962                         else:                    1273                         else:
1963                                 targetphase = !! 1274                                 targetphase = self.phases[-1]
1964                 if pid == -2:                    1275                 if pid == -2:
1965                         htmlclass = ' bg'        1276                         htmlclass = ' bg'
1966                 elif pid == -3:                  1277                 elif pid == -3:
1967                         htmlclass = ' ps'        1278                         htmlclass = ' ps'
1968                 if len(myphases) > 1:         !! 1279                 if len(phases) > 1:
1969                         htmlclass = ' bg'        1280                         htmlclass = ' bg'
1970                         self.phaseOverlap(myp !! 1281                         self.phaseOverlap(phases)
1971                 if targetphase in phases:     !! 1282                 if targetphase in self.phases:
1972                         newname = self.newAct    1283                         newname = self.newAction(targetphase, name, pid, '', start, end, '', htmlclass, color)
1973                         return (targetphase,     1284                         return (targetphase, newname)
1974                 return False                     1285                 return False
1975         def newAction(self, phase, name, pid,    1286         def newAction(self, phase, name, pid, parent, start, end, drv, htmlclass='', color=''):
1976                 # new device callback for a s    1287                 # new device callback for a specific phase
1977                 self.html_device_id += 1         1288                 self.html_device_id += 1
1978                 devid = '%s%d' % (self.idstr,    1289                 devid = '%s%d' % (self.idstr, self.html_device_id)
1979                 list = self.dmesg[phase]['lis    1290                 list = self.dmesg[phase]['list']
1980                 length = -1.0                    1291                 length = -1.0
1981                 if(start >= 0 and end >= 0):     1292                 if(start >= 0 and end >= 0):
1982                         length = end - start     1293                         length = end - start
1983                 if pid == -2 or name not in s !! 1294                 if pid == -2:
1984                         i = 2                    1295                         i = 2
1985                         origname = name          1296                         origname = name
1986                         while(name in list):     1297                         while(name in list):
1987                                 name = '%s[%d    1298                                 name = '%s[%d]' % (origname, i)
1988                                 i += 1           1299                                 i += 1
1989                 list[name] = {'name': name, '    1300                 list[name] = {'name': name, 'start': start, 'end': end, 'pid': pid,
1990                         'par': parent, 'lengt    1301                         'par': parent, 'length': length, 'row': 0, 'id': devid, 'drv': drv }
1991                 if htmlclass:                    1302                 if htmlclass:
1992                         list[name]['htmlclass    1303                         list[name]['htmlclass'] = htmlclass
1993                 if color:                        1304                 if color:
1994                         list[name]['color'] =    1305                         list[name]['color'] = color
1995                 return name                      1306                 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    1307         def deviceChildren(self, devname, phase):
2006                 devlist = []                     1308                 devlist = []
2007                 list = self.dmesg[phase]['lis    1309                 list = self.dmesg[phase]['list']
2008                 for child in list:               1310                 for child in list:
2009                         if(list[child]['par']    1311                         if(list[child]['par'] == devname):
2010                                 devlist.appen    1312                                 devlist.append(child)
2011                 return devlist                   1313                 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):                  1314         def printDetails(self):
2019                 sysvals.vprint('Timeline Deta    1315                 sysvals.vprint('Timeline Details:')
2020                 sysvals.vprint('          tes    1316                 sysvals.vprint('          test start: %f' % self.start)
2021                 sysvals.vprint('kernel suspen    1317                 sysvals.vprint('kernel suspend start: %f' % self.tKernSus)
2022                 tS = tR = False               !! 1318                 for phase in self.phases:
2023                 for phase in self.sortedPhase !! 1319                         dc = len(self.dmesg[phase]['list'])
2024                         devlist = self.dmesg[ !! 1320                         sysvals.vprint('    %16s: %f - %f (%d devices)' % (phase, \
2025                         dc, ps, pe = len(devl !! 1321                                 self.dmesg[phase]['start'], self.dmesg[phase]['end'], dc))
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    1322                 sysvals.vprint('   kernel resume end: %f' % self.tKernRes)
2045                 sysvals.vprint('            t    1323                 sysvals.vprint('            test end: %f' % self.end)
2046         def deviceChildrenAllPhases(self, dev    1324         def deviceChildrenAllPhases(self, devname):
2047                 devlist = []                     1325                 devlist = []
2048                 for phase in self.sortedPhase !! 1326                 for phase in self.phases:
2049                         list = self.deviceChi    1327                         list = self.deviceChildren(devname, phase)
2050                         for dev in sorted(lis !! 1328                         for dev in list:
2051                                 if dev not in    1329                                 if dev not in devlist:
2052                                         devli    1330                                         devlist.append(dev)
2053                 return devlist                   1331                 return devlist
2054         def masterTopology(self, name, list,     1332         def masterTopology(self, name, list, depth):
2055                 node = DeviceNode(name, depth    1333                 node = DeviceNode(name, depth)
2056                 for cname in list:               1334                 for cname in list:
2057                         # avoid recursions       1335                         # avoid recursions
2058                         if name == cname:        1336                         if name == cname:
2059                                 continue         1337                                 continue
2060                         clist = self.deviceCh    1338                         clist = self.deviceChildrenAllPhases(cname)
2061                         cnode = self.masterTo    1339                         cnode = self.masterTopology(cname, clist, depth+1)
2062                         node.children.append(    1340                         node.children.append(cnode)
2063                 return node                      1341                 return node
2064         def printTopology(self, node):           1342         def printTopology(self, node):
2065                 html = ''                        1343                 html = ''
2066                 if node.name:                    1344                 if node.name:
2067                         info = ''                1345                         info = ''
2068                         drv = ''                 1346                         drv = ''
2069                         for phase in self.sor !! 1347                         for phase in self.phases:
2070                                 list = self.d    1348                                 list = self.dmesg[phase]['list']
2071                                 if node.name     1349                                 if node.name in list:
2072                                         s = l    1350                                         s = list[node.name]['start']
2073                                         e = l    1351                                         e = list[node.name]['end']
2074                                         if li    1352                                         if list[node.name]['drv']:
2075                                                  1353                                                 drv = ' {'+list[node.name]['drv']+'}'
2076                                         info     1354                                         info += ('<li>%s: %.3fms</li>' % (phase, (e-s)*1000))
2077                         html += '<li><b>'+nod    1355                         html += '<li><b>'+node.name+drv+'</b>'
2078                         if info:                 1356                         if info:
2079                                 html += '<ul>    1357                                 html += '<ul>'+info+'</ul>'
2080                         html += '</li>'          1358                         html += '</li>'
2081                 if len(node.children) > 0:       1359                 if len(node.children) > 0:
2082                         html += '<ul>'           1360                         html += '<ul>'
2083                         for cnode in node.chi    1361                         for cnode in node.children:
2084                                 html += self.    1362                                 html += self.printTopology(cnode)
2085                         html += '</ul>'          1363                         html += '</ul>'
2086                 return html                      1364                 return html
2087         def rootDeviceList(self):                1365         def rootDeviceList(self):
2088                 # list of devices graphed        1366                 # list of devices graphed
2089                 real = []                        1367                 real = []
2090                 for phase in self.sortedPhase !! 1368                 for phase in self.dmesg:
2091                         list = self.dmesg[pha    1369                         list = self.dmesg[phase]['list']
2092                         for dev in sorted(lis !! 1370                         for dev in list:
2093                                 if list[dev][    1371                                 if list[dev]['pid'] >= 0 and dev not in real:
2094                                         real.    1372                                         real.append(dev)
2095                 # list of top-most root devic    1373                 # list of top-most root devices
2096                 rootlist = []                    1374                 rootlist = []
2097                 for phase in self.sortedPhase !! 1375                 for phase in self.dmesg:
2098                         list = self.dmesg[pha    1376                         list = self.dmesg[phase]['list']
2099                         for dev in sorted(lis !! 1377                         for dev in list:
2100                                 pdev = list[d    1378                                 pdev = list[dev]['par']
2101                                 pid = list[de    1379                                 pid = list[dev]['pid']
2102                                 if(pid < 0 or !! 1380                                 if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)):
2103                                         conti    1381                                         continue
2104                                 if pdev and p    1382                                 if pdev and pdev not in real and pdev not in rootlist:
2105                                         rootl    1383                                         rootlist.append(pdev)
2106                 return rootlist                  1384                 return rootlist
2107         def deviceTopology(self):                1385         def deviceTopology(self):
2108                 rootlist = self.rootDeviceLis    1386                 rootlist = self.rootDeviceList()
2109                 master = self.masterTopology(    1387                 master = self.masterTopology('', rootlist, 0)
2110                 return self.printTopology(mas    1388                 return self.printTopology(master)
2111         def selectTimelineDevices(self, widfm    1389         def selectTimelineDevices(self, widfmt, tTotal, mindevlen):
2112                 # only select devices that wi    1390                 # only select devices that will actually show up in html
2113                 self.tdevlist = dict()           1391                 self.tdevlist = dict()
2114                 for phase in self.dmesg:         1392                 for phase in self.dmesg:
2115                         devlist = []             1393                         devlist = []
2116                         list = self.dmesg[pha    1394                         list = self.dmesg[phase]['list']
2117                         for dev in list:         1395                         for dev in list:
2118                                 length = (lis    1396                                 length = (list[dev]['end'] - list[dev]['start']) * 1000
2119                                 width = widfm    1397                                 width = widfmt % (((list[dev]['end']-list[dev]['start'])*100)/tTotal)
2120                                 if length >=  !! 1398                                 if width != '0.000000' and length >= mindevlen:
2121                                         devli    1399                                         devlist.append(dev)
2122                         self.tdevlist[phase]     1400                         self.tdevlist[phase] = devlist
2123         def addHorizontalDivider(self, devnam    1401         def addHorizontalDivider(self, devname, devend):
2124                 phase = 'suspend_prepare'        1402                 phase = 'suspend_prepare'
2125                 self.newAction(phase, devname    1403                 self.newAction(phase, devname, -2, '', \
2126                         self.start, devend, '    1404                         self.start, devend, '', ' sec', '')
2127                 if phase not in self.tdevlist    1405                 if phase not in self.tdevlist:
2128                         self.tdevlist[phase]     1406                         self.tdevlist[phase] = []
2129                 self.tdevlist[phase].append(d    1407                 self.tdevlist[phase].append(devname)
2130                 d = DevItem(0, phase, self.dm    1408                 d = DevItem(0, phase, self.dmesg[phase]['list'][devname])
2131                 return d                         1409                 return d
2132         def addProcessUsageEvent(self, name,     1410         def addProcessUsageEvent(self, name, times):
2133                 # get the start and end times    1411                 # get the start and end times for this process
2134                 cpuexec = dict()              !! 1412                 maxC = 0
2135                 tlast = start = end = -1      !! 1413                 tlast = 0
                                                   >> 1414                 start = -1
                                                   >> 1415                 end = -1
2136                 for t in sorted(times):          1416                 for t in sorted(times):
2137                         if tlast < 0:         !! 1417                         if tlast == 0:
2138                                 tlast = t        1418                                 tlast = t
2139                                 continue         1419                                 continue
2140                         if name in self.pstl[ !! 1420                         if name in self.pstl[t]:
2141                                 if start < 0: !! 1421                                 if start == -1 or tlast < start:
2142                                         start    1422                                         start = tlast
2143                                 end, key = t, !! 1423                                 if end == -1 or t > end:
2144                                 maxj = (t - t !! 1424                                         end = t
2145                                 cpuexec[key]  << 
2146                         tlast = t                1425                         tlast = t
2147                 if start < 0 or end < 0:      !! 1426                 if start == -1 or end == -1:
2148                         return                !! 1427                         return 0
2149                 # add a new action for this p    1428                 # add a new action for this process and get the object
2150                 out = self.newActionGlobal(na    1429                 out = self.newActionGlobal(name, start, end, -3)
2151                 if out:                       !! 1430                 if not out:
2152                         phase, devname = out  !! 1431                         return 0
2153                         dev = self.dmesg[phas !! 1432                 phase, devname = out
2154                         dev['cpuexec'] = cpue !! 1433                 dev = self.dmesg[phase]['list'][devname]
                                                   >> 1434                 # get the cpu exec data
                                                   >> 1435                 tlast = 0
                                                   >> 1436                 clast = 0
                                                   >> 1437                 cpuexec = dict()
                                                   >> 1438                 for t in sorted(times):
                                                   >> 1439                         if tlast == 0 or t <= start or t > end:
                                                   >> 1440                                 tlast = t
                                                   >> 1441                                 continue
                                                   >> 1442                         list = self.pstl[t]
                                                   >> 1443                         c = 0
                                                   >> 1444                         if name in list:
                                                   >> 1445                                 c = list[name]
                                                   >> 1446                         if c > maxC:
                                                   >> 1447                                 maxC = c
                                                   >> 1448                         if c != clast:
                                                   >> 1449                                 key = (tlast, t)
                                                   >> 1450                                 cpuexec[key] = c
                                                   >> 1451                                 tlast = t
                                                   >> 1452                                 clast = c
                                                   >> 1453                 dev['cpuexec'] = cpuexec
                                                   >> 1454                 return maxC
2155         def createProcessUsageEvents(self):      1455         def createProcessUsageEvents(self):
2156                 # get an array of process nam !! 1456                 # get an array of process names
2157                 proclist = {'sus': dict(), 'r !! 1457                 proclist = []
2158                 tdata = {'sus': [], 'res': [] !! 1458                 for t in self.pstl:
                                                   >> 1459                         pslist = self.pstl[t]
                                                   >> 1460                         for ps in pslist:
                                                   >> 1461                                 if ps not in proclist:
                                                   >> 1462                                         proclist.append(ps)
                                                   >> 1463                 # get a list of data points for suspend and resume
                                                   >> 1464                 tsus = []
                                                   >> 1465                 tres = []
2159                 for t in sorted(self.pstl):      1466                 for t in sorted(self.pstl):
2160                         dir = 'sus' if t < se !! 1467                         if t < self.tSuspended:
2161                         for ps in sorted(self !! 1468                                 tsus.append(t)
2162                                 if ps not in  !! 1469                         else:
2163                                         procl !! 1470                                 tres.append(t)
2164                         tdata[dir].append(t)  << 
2165                 # process the events for susp    1471                 # process the events for suspend and resume
2166                 if len(proclist['sus']) > 0 o !! 1472                 if len(proclist) > 0:
2167                         sysvals.vprint('Proce    1473                         sysvals.vprint('Process Execution:')
2168                 for dir in ['sus', 'res']:    !! 1474                 for ps in proclist:
2169                         for ps in sorted(proc !! 1475                         c = self.addProcessUsageEvent(ps, tsus)
2170                                 self.addProce !! 1476                         if c > 0:
2171         def handleEndMarker(self, time, msg=' !! 1477                                 sysvals.vprint('%25s (sus): %d' % (ps, c))
2172                 dm = self.dmesg               !! 1478                         c = self.addProcessUsageEvent(ps, tres)
2173                 self.setEnd(time, msg)        !! 1479                         if c > 0:
2174                 self.initDevicegroups()       !! 1480                                 sysvals.vprint('%25s (res): %d' % (ps, c))
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):                    1481         def debugPrint(self):
2217                 for p in self.sortedPhases(): !! 1482                 for p in self.phases:
2218                         list = self.dmesg[p][    1483                         list = self.dmesg[p]['list']
2219                         for devname in sorted !! 1484                         for devname in list:
2220                                 dev = list[de    1485                                 dev = list[devname]
2221                                 if 'ftrace' i    1486                                 if 'ftrace' in dev:
2222                                         dev['    1487                                         dev['ftrace'].debugPrint(' [%s]' % devname)
2223                                                  1488 
2224 # Class: DevFunction                             1489 # Class: DevFunction
2225 # Description:                                   1490 # Description:
2226 #        A container for kprobe function data    1491 #        A container for kprobe function data we want in the dev timeline
2227 class DevFunction:                               1492 class DevFunction:
                                                   >> 1493         row = 0
                                                   >> 1494         count = 1
2228         def __init__(self, name, args, caller    1495         def __init__(self, name, args, caller, ret, start, end, u, proc, pid, color):
2229                 self.row = 0                  << 
2230                 self.count = 1                << 
2231                 self.name = name                 1496                 self.name = name
2232                 self.args = args                 1497                 self.args = args
2233                 self.caller = caller             1498                 self.caller = caller
2234                 self.ret = ret                   1499                 self.ret = ret
2235                 self.time = start                1500                 self.time = start
2236                 self.length = end - start        1501                 self.length = end - start
2237                 self.end = end                   1502                 self.end = end
2238                 self.ubiquitous = u              1503                 self.ubiquitous = u
2239                 self.proc = proc                 1504                 self.proc = proc
2240                 self.pid = pid                   1505                 self.pid = pid
2241                 self.color = color               1506                 self.color = color
2242         def title(self):                         1507         def title(self):
2243                 cnt = ''                         1508                 cnt = ''
2244                 if self.count > 1:               1509                 if self.count > 1:
2245                         cnt = '(x%d)' % self.    1510                         cnt = '(x%d)' % self.count
2246                 l = '%0.3fms' % (self.length     1511                 l = '%0.3fms' % (self.length * 1000)
2247                 if self.ubiquitous:              1512                 if self.ubiquitous:
2248                         title = '%s(%s)%s <-     1513                         title = '%s(%s)%s <- %s, %s(%s)' % \
2249                                 (self.name, s    1514                                 (self.name, self.args, cnt, self.caller, self.ret, l)
2250                 else:                            1515                 else:
2251                         title = '%s(%s) %s%s(    1516                         title = '%s(%s) %s%s(%s)' % (self.name, self.args, self.ret, cnt, l)
2252                 return title.replace('"', '')    1517                 return title.replace('"', '')
2253         def text(self):                          1518         def text(self):
2254                 if self.count > 1:               1519                 if self.count > 1:
2255                         text = '%s(x%d)' % (s    1520                         text = '%s(x%d)' % (self.name, self.count)
2256                 else:                            1521                 else:
2257                         text = self.name         1522                         text = self.name
2258                 return text                      1523                 return text
2259         def repeat(self, tgt):                   1524         def repeat(self, tgt):
2260                 # is the tgt call just a repe    1525                 # is the tgt call just a repeat of this call (e.g. are we in a loop)
2261                 dt = self.time - tgt.end         1526                 dt = self.time - tgt.end
2262                 # only combine calls if -all-    1527                 # only combine calls if -all- attributes are identical
2263                 if tgt.caller == self.caller     1528                 if tgt.caller == self.caller and \
2264                         tgt.name == self.name    1529                         tgt.name == self.name and tgt.args == self.args and \
2265                         tgt.proc == self.proc    1530                         tgt.proc == self.proc and tgt.pid == self.pid and \
2266                         tgt.ret == self.ret a    1531                         tgt.ret == self.ret and dt >= 0 and \
2267                         dt <= sysvals.callloo    1532                         dt <= sysvals.callloopmaxgap and \
2268                         self.length < sysvals    1533                         self.length < sysvals.callloopmaxlen:
2269                         return True              1534                         return True
2270                 return False                     1535                 return False
2271                                                  1536 
2272 # Class: FTraceLine                              1537 # Class: FTraceLine
2273 # Description:                                   1538 # Description:
2274 #        A container for a single line of ftr    1539 #        A container for a single line of ftrace data. There are six basic types:
2275 #                callgraph line:                 1540 #                callgraph line:
2276 #                         call: "  dpm_run_ca    1541 #                         call: "  dpm_run_callback() {"
2277 #                       return: "  }"            1542 #                       return: "  }"
2278 #                         leaf: " dpm_run_cal    1543 #                         leaf: " dpm_run_callback();"
2279 #                trace event:                    1544 #                trace event:
2280 #                        tracing_mark_write:     1545 #                        tracing_mark_write: SUSPEND START or RESUME COMPLETE
2281 #                        suspend_resume: phas    1546 #                        suspend_resume: phase or custom exec block data
2282 #                        device_pm_callback:     1547 #                        device_pm_callback: device callback info
2283 class FTraceLine:                                1548 class FTraceLine:
                                                   >> 1549         time = 0.0
                                                   >> 1550         length = 0.0
                                                   >> 1551         fcall = False
                                                   >> 1552         freturn = False
                                                   >> 1553         fevent = False
                                                   >> 1554         fkprobe = False
                                                   >> 1555         depth = 0
                                                   >> 1556         name = ''
                                                   >> 1557         type = ''
2284         def __init__(self, t, m='', d=''):       1558         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)             1559                 self.time = float(t)
2294                 if not m and not d:              1560                 if not m and not d:
2295                         return                   1561                         return
2296                 # is this a trace event          1562                 # is this a trace event
2297                 if(d == 'traceevent' or re.ma !! 1563                 if(d == 'traceevent' or re.match('^ *\/\* *(?P<msg>.*) \*\/ *$', m)):
2298                         if(d == 'traceevent')    1564                         if(d == 'traceevent'):
2299                                 # nop format     1565                                 # nop format trace event
2300                                 msg = m          1566                                 msg = m
2301                         else:                    1567                         else:
2302                                 # function_gr    1568                                 # function_graph format trace event
2303                                 em = re.match !! 1569                                 em = re.match('^ *\/\* *(?P<msg>.*) \*\/ *$', m)
2304                                 msg = em.grou    1570                                 msg = em.group('msg')
2305                                                  1571 
2306                         emm = re.match(r'^(?P !! 1572                         emm = re.match('^(?P<call>.*?): (?P<msg>.*)', msg)
2307                         if(emm):                 1573                         if(emm):
2308                                 self.name = e    1574                                 self.name = emm.group('msg')
2309                                 self.type = e    1575                                 self.type = emm.group('call')
2310                         else:                    1576                         else:
2311                                 self.name = m    1577                                 self.name = msg
2312                         km = re.match(r'^(?P< !! 1578                         km = re.match('^(?P<n>.*)_cal$', self.type)
2313                         if km:                   1579                         if km:
2314                                 self.fcall =     1580                                 self.fcall = True
2315                                 self.fkprobe     1581                                 self.fkprobe = True
2316                                 self.type = k    1582                                 self.type = km.group('n')
2317                                 return           1583                                 return
2318                         km = re.match(r'^(?P< !! 1584                         km = re.match('^(?P<n>.*)_ret$', self.type)
2319                         if km:                   1585                         if km:
2320                                 self.freturn     1586                                 self.freturn = True
2321                                 self.fkprobe     1587                                 self.fkprobe = True
2322                                 self.type = k    1588                                 self.type = km.group('n')
2323                                 return           1589                                 return
2324                         self.fevent = True       1590                         self.fevent = True
2325                         return                   1591                         return
2326                 # convert the duration to sec    1592                 # convert the duration to seconds
2327                 if(d):                           1593                 if(d):
2328                         self.length = float(d    1594                         self.length = float(d)/1000000
2329                 # the indentation determines     1595                 # the indentation determines the depth
2330                 match = re.match(r'^(?P<d> *) !! 1596                 match = re.match('^(?P<d> *)(?P<o>.*)$', m)
2331                 if(not match):                   1597                 if(not match):
2332                         return                   1598                         return
2333                 self.depth = self.getDepth(ma    1599                 self.depth = self.getDepth(match.group('d'))
2334                 m = match.group('o')             1600                 m = match.group('o')
2335                 # function return                1601                 # function return
2336                 if(m[0] == '}'):                 1602                 if(m[0] == '}'):
2337                         self.freturn = True      1603                         self.freturn = True
2338                         if(len(m) > 1):          1604                         if(len(m) > 1):
2339                                 # includes co    1605                                 # includes comment with function name
2340                                 match = re.ma !! 1606                                 match = re.match('^} *\/\* *(?P<n>.*) *\*\/$', m)
2341                                 if(match):       1607                                 if(match):
2342                                         self.    1608                                         self.name = match.group('n').strip()
2343                 # function call                  1609                 # function call
2344                 else:                            1610                 else:
2345                         self.fcall = True        1611                         self.fcall = True
2346                         # function call with     1612                         # function call with children
2347                         if(m[-1] == '{'):        1613                         if(m[-1] == '{'):
2348                                 match = re.ma !! 1614                                 match = re.match('^(?P<n>.*) *\(.*', m)
2349                                 if(match):       1615                                 if(match):
2350                                         self.    1616                                         self.name = match.group('n').strip()
2351                         # function call with     1617                         # function call with no children (leaf)
2352                         elif(m[-1] == ';'):      1618                         elif(m[-1] == ';'):
2353                                 self.freturn     1619                                 self.freturn = True
2354                                 match = re.ma !! 1620                                 match = re.match('^(?P<n>.*) *\(.*', m)
2355                                 if(match):       1621                                 if(match):
2356                                         self.    1622                                         self.name = match.group('n').strip()
2357                         # something else (pos    1623                         # something else (possibly a trace marker)
2358                         else:                    1624                         else:
2359                                 self.name = m    1625                                 self.name = m
2360         def isCall(self):                        1626         def isCall(self):
2361                 return self.fcall and not sel    1627                 return self.fcall and not self.freturn
2362         def isReturn(self):                      1628         def isReturn(self):
2363                 return self.freturn and not s    1629                 return self.freturn and not self.fcall
2364         def isLeaf(self):                        1630         def isLeaf(self):
2365                 return self.fcall and self.fr    1631                 return self.fcall and self.freturn
2366         def getDepth(self, str):                 1632         def getDepth(self, str):
2367                 return len(str)/2                1633                 return len(str)/2
2368         def debugPrint(self, info=''):           1634         def debugPrint(self, info=''):
2369                 if self.isLeaf():                1635                 if self.isLeaf():
2370                         pprint(' -- %12.6f (d !! 1636                         print(' -- %12.6f (depth=%02d): %s(); (%.3f us) %s' % (self.time, \
2371                                 self.depth, s    1637                                 self.depth, self.name, self.length*1000000, info))
2372                 elif self.freturn:               1638                 elif self.freturn:
2373                         pprint(' -- %12.6f (d !! 1639                         print(' -- %12.6f (depth=%02d): %s} (%.3f us) %s' % (self.time, \
2374                                 self.depth, s    1640                                 self.depth, self.name, self.length*1000000, info))
2375                 else:                            1641                 else:
2376                         pprint(' -- %12.6f (d !! 1642                         print(' -- %12.6f (depth=%02d): %s() { (%.3f us) %s' % (self.time, \
2377                                 self.depth, s    1643                                 self.depth, self.name, self.length*1000000, info))
2378         def startMarker(self):                   1644         def startMarker(self):
2379                 # Is this the starting line o    1645                 # Is this the starting line of a suspend?
2380                 if not self.fevent:              1646                 if not self.fevent:
2381                         return False             1647                         return False
2382                 if sysvals.usetracemarkers:      1648                 if sysvals.usetracemarkers:
2383                         if(self.name.startswi !! 1649                         if(self.name == 'SUSPEND START'):
2384                                 return True      1650                                 return True
2385                         return False             1651                         return False
2386                 else:                            1652                 else:
2387                         if(self.type == 'susp    1653                         if(self.type == 'suspend_resume' and
2388                                 re.match(r'su !! 1654                                 re.match('suspend_enter\[.*\] begin', self.name)):
2389                                 return True      1655                                 return True
2390                         return False             1656                         return False
2391         def endMarker(self):                     1657         def endMarker(self):
2392                 # Is this the ending line of     1658                 # Is this the ending line of a resume?
2393                 if not self.fevent:              1659                 if not self.fevent:
2394                         return False             1660                         return False
2395                 if sysvals.usetracemarkers:      1661                 if sysvals.usetracemarkers:
2396                         if(self.name.startswi !! 1662                         if(self.name == 'RESUME COMPLETE'):
2397                                 return True      1663                                 return True
2398                         return False             1664                         return False
2399                 else:                            1665                 else:
2400                         if(self.type == 'susp    1666                         if(self.type == 'suspend_resume' and
2401                                 re.match(r'th !! 1667                                 re.match('thaw_processes\[.*\] end', self.name)):
2402                                 return True      1668                                 return True
2403                         return False             1669                         return False
2404                                                  1670 
2405 # Class: FTraceCallGraph                         1671 # Class: FTraceCallGraph
2406 # Description:                                   1672 # Description:
2407 #        A container for the ftrace callgraph    1673 #        A container for the ftrace callgraph of a single recursive function.
2408 #        This can be a dpm_run_callback, dpm_    1674 #        This can be a dpm_run_callback, dpm_prepare, or dpm_complete callgraph
2409 #        Each instance is tied to a single de    1675 #        Each instance is tied to a single device in a single phase, and is
2410 #        comprised of an ordered list of FTra    1676 #        comprised of an ordered list of FTraceLine objects
2411 class FTraceCallGraph:                           1677 class FTraceCallGraph:
                                                   >> 1678         id = ''
                                                   >> 1679         start = -1.0
                                                   >> 1680         end = -1.0
                                                   >> 1681         list = []
                                                   >> 1682         invalid = False
                                                   >> 1683         depth = 0
                                                   >> 1684         pid = 0
                                                   >> 1685         name = ''
                                                   >> 1686         partial = False
2412         vfname = 'missing_function_name'         1687         vfname = 'missing_function_name'
                                                   >> 1688         ignore = False
                                                   >> 1689         sv = 0
2413         def __init__(self, pid, sv):             1690         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                1691                 self.start = -1.0
2420                 self.end = -1.0                  1692                 self.end = -1.0
2421                 self.list = []                   1693                 self.list = []
2422                 self.depth = 0                   1694                 self.depth = 0
2423                 self.pid = pid                   1695                 self.pid = pid
2424                 self.sv = sv                     1696                 self.sv = sv
2425         def addLine(self, line):                 1697         def addLine(self, line):
2426                 # if this is already invalid,    1698                 # if this is already invalid, just leave
2427                 if(self.invalid):                1699                 if(self.invalid):
2428                         if(line.depth == 0 an    1700                         if(line.depth == 0 and line.freturn):
2429                                 return 1         1701                                 return 1
2430                         return 0                 1702                         return 0
2431                 # invalidate on bad depth        1703                 # invalidate on bad depth
2432                 if(self.depth < 0):              1704                 if(self.depth < 0):
2433                         self.invalidate(line)    1705                         self.invalidate(line)
2434                         return 0                 1706                         return 0
2435                 # ignore data til we return t    1707                 # ignore data til we return to the current depth
2436                 if self.ignore:                  1708                 if self.ignore:
2437                         if line.depth > self.    1709                         if line.depth > self.depth:
2438                                 return 0         1710                                 return 0
2439                         else:                    1711                         else:
2440                                 self.list[-1]    1712                                 self.list[-1].freturn = True
2441                                 self.list[-1]    1713                                 self.list[-1].length = line.time - self.list[-1].time
2442                                 self.ignore =    1714                                 self.ignore = False
2443                                 # if this is     1715                                 # if this is a return at self.depth, no more work is needed
2444                                 if line.depth    1716                                 if line.depth == self.depth and line.isReturn():
2445                                         if li    1717                                         if line.depth == 0:
2446                                                  1718                                                 self.end = line.time
2447                                                  1719                                                 return 1
2448                                         retur    1720                                         return 0
2449                 # compare current depth with     1721                 # compare current depth with this lines pre-call depth
2450                 prelinedep = line.depth          1722                 prelinedep = line.depth
2451                 if line.isReturn():              1723                 if line.isReturn():
2452                         prelinedep += 1          1724                         prelinedep += 1
2453                 last = 0                         1725                 last = 0
2454                 lasttime = line.time             1726                 lasttime = line.time
2455                 if len(self.list) > 0:           1727                 if len(self.list) > 0:
2456                         last = self.list[-1]     1728                         last = self.list[-1]
2457                         lasttime = last.time     1729                         lasttime = last.time
2458                         if last.isLeaf():        1730                         if last.isLeaf():
2459                                 lasttime += l    1731                                 lasttime += last.length
2460                 # handle low misalignments by    1732                 # handle low misalignments by inserting returns
2461                 mismatch = prelinedep - self.    1733                 mismatch = prelinedep - self.depth
2462                 warning = self.sv.verbose and    1734                 warning = self.sv.verbose and abs(mismatch) > 1
2463                 info = []                        1735                 info = []
2464                 if mismatch < 0:                 1736                 if mismatch < 0:
2465                         idx = 0                  1737                         idx = 0
2466                         # add return calls to    1738                         # add return calls to get the depth down
2467                         while prelinedep < se    1739                         while prelinedep < self.depth:
2468                                 self.depth -=    1740                                 self.depth -= 1
2469                                 if idx == 0 a    1741                                 if idx == 0 and last and last.isCall():
2470                                         # spe    1742                                         # special case, turn last call into a leaf
2471                                         last.    1743                                         last.depth = self.depth
2472                                         last.    1744                                         last.freturn = True
2473                                         last.    1745                                         last.length = line.time - last.time
2474                                         if wa    1746                                         if warning:
2475                                                  1747                                                 info.append(('[make leaf]', last))
2476                                 else:            1748                                 else:
2477                                         vline    1749                                         vline = FTraceLine(lasttime)
2478                                         vline    1750                                         vline.depth = self.depth
2479                                         vline    1751                                         vline.name = self.vfname
2480                                         vline    1752                                         vline.freturn = True
2481                                         self.    1753                                         self.list.append(vline)
2482                                         if wa    1754                                         if warning:
2483                                                  1755                                                 if idx == 0:
2484                                                  1756                                                         info.append(('', last))
2485                                                  1757                                                 info.append(('[add return]', vline))
2486                                 idx += 1         1758                                 idx += 1
2487                         if warning:              1759                         if warning:
2488                                 info.append((    1760                                 info.append(('', line))
2489                 # handle high misalignments b    1761                 # handle high misalignments by inserting calls
2490                 elif mismatch > 0:               1762                 elif mismatch > 0:
2491                         idx = 0                  1763                         idx = 0
2492                         if warning:              1764                         if warning:
2493                                 info.append((    1765                                 info.append(('', last))
2494                         # add calls to get th    1766                         # add calls to get the depth up
2495                         while prelinedep > se    1767                         while prelinedep > self.depth:
2496                                 if idx == 0 a    1768                                 if idx == 0 and line.isReturn():
2497                                         # spe    1769                                         # special case, turn this return into a leaf
2498                                         line.    1770                                         line.fcall = True
2499                                         preli    1771                                         prelinedep -= 1
2500                                         if wa    1772                                         if warning:
2501                                                  1773                                                 info.append(('[make leaf]', line))
2502                                 else:            1774                                 else:
2503                                         vline    1775                                         vline = FTraceLine(lasttime)
2504                                         vline    1776                                         vline.depth = self.depth
2505                                         vline    1777                                         vline.name = self.vfname
2506                                         vline    1778                                         vline.fcall = True
2507                                         self.    1779                                         self.list.append(vline)
2508                                         self.    1780                                         self.depth += 1
2509                                         if no    1781                                         if not last:
2510                                                  1782                                                 self.start = vline.time
2511                                         if wa    1783                                         if warning:
2512                                                  1784                                                 info.append(('[add call]', vline))
2513                                 idx += 1         1785                                 idx += 1
2514                         if warning and ('[mak    1786                         if warning and ('[make leaf]', line) not in info:
2515                                 info.append((    1787                                 info.append(('', line))
2516                 if warning:                      1788                 if warning:
2517                         pprint('WARNING: ftra !! 1789                         print 'WARNING: ftrace data missing, corrections made:'
2518                         for i in info:           1790                         for i in info:
2519                                 t, obj = i       1791                                 t, obj = i
2520                                 if obj:          1792                                 if obj:
2521                                         obj.d    1793                                         obj.debugPrint(t)
2522                 # process the call and set th    1794                 # process the call and set the new depth
2523                 skipadd = False                  1795                 skipadd = False
2524                 md = self.sv.max_graph_depth     1796                 md = self.sv.max_graph_depth
2525                 if line.isCall():                1797                 if line.isCall():
2526                         # ignore blacklisted/    1798                         # ignore blacklisted/overdepth funcs
2527                         if (md and self.depth    1799                         if (md and self.depth >= md - 1) or (line.name in self.sv.cgblacklist):
2528                                 self.ignore =    1800                                 self.ignore = True
2529                         else:                    1801                         else:
2530                                 self.depth +=    1802                                 self.depth += 1
2531                 elif line.isReturn():            1803                 elif line.isReturn():
2532                         self.depth -= 1          1804                         self.depth -= 1
2533                         # remove blacklisted/    1805                         # remove blacklisted/overdepth/empty funcs that slipped through
2534                         if (last and last.isC    1806                         if (last and last.isCall() and last.depth == line.depth) or \
2535                                 (md and last     1807                                 (md and last and last.depth >= md) or \
2536                                 (line.name in    1808                                 (line.name in self.sv.cgblacklist):
2537                                 while len(sel    1809                                 while len(self.list) > 0 and self.list[-1].depth > line.depth:
2538                                         self.    1810                                         self.list.pop(-1)
2539                                 if len(self.l    1811                                 if len(self.list) == 0:
2540                                         self.    1812                                         self.invalid = True
2541                                         retur    1813                                         return 1
2542                                 self.list[-1]    1814                                 self.list[-1].freturn = True
2543                                 self.list[-1]    1815                                 self.list[-1].length = line.time - self.list[-1].time
2544                                 self.list[-1]    1816                                 self.list[-1].name = line.name
2545                                 skipadd = Tru    1817                                 skipadd = True
2546                 if len(self.list) < 1:           1818                 if len(self.list) < 1:
2547                         self.start = line.tim    1819                         self.start = line.time
2548                 # check for a mismatch that r    1820                 # check for a mismatch that returned all the way to callgraph end
2549                 res = 1                          1821                 res = 1
2550                 if mismatch < 0 and self.list    1822                 if mismatch < 0 and self.list[-1].depth == 0 and self.list[-1].freturn:
2551                         line = self.list[-1]     1823                         line = self.list[-1]
2552                         skipadd = True           1824                         skipadd = True
2553                         res = -1                 1825                         res = -1
2554                 if not skipadd:                  1826                 if not skipadd:
2555                         self.list.append(line    1827                         self.list.append(line)
2556                 if(line.depth == 0 and line.f    1828                 if(line.depth == 0 and line.freturn):
2557                         if(self.start < 0):      1829                         if(self.start < 0):
2558                                 self.start =     1830                                 self.start = line.time
2559                         self.end = line.time     1831                         self.end = line.time
2560                         if line.fcall:           1832                         if line.fcall:
2561                                 self.end += l    1833                                 self.end += line.length
2562                         if self.list[0].name     1834                         if self.list[0].name == self.vfname:
2563                                 self.invalid     1835                                 self.invalid = True
2564                         if res == -1:            1836                         if res == -1:
2565                                 self.partial     1837                                 self.partial = True
2566                         return res               1838                         return res
2567                 return 0                         1839                 return 0
2568         def invalidate(self, line):              1840         def invalidate(self, line):
2569                 if(len(self.list) > 0):          1841                 if(len(self.list) > 0):
2570                         first = self.list[0]     1842                         first = self.list[0]
2571                         self.list = []           1843                         self.list = []
2572                         self.list.append(firs    1844                         self.list.append(first)
2573                 self.invalid = True              1845                 self.invalid = True
2574                 id = 'task %s' % (self.pid)      1846                 id = 'task %s' % (self.pid)
2575                 window = '(%f - %f)' % (self.    1847                 window = '(%f - %f)' % (self.start, line.time)
2576                 if(self.depth < 0):              1848                 if(self.depth < 0):
2577                         pprint('Data misalign !! 1849                         print('Data misalignment for '+id+\
2578                                 ' (buffer ove    1850                                 ' (buffer overflow), ignoring this callback')
2579                 else:                            1851                 else:
2580                         pprint('Too much data !! 1852                         print('Too much data for '+id+\
2581                                 ' '+window+',    1853                                 ' '+window+', ignoring this callback')
2582         def slice(self, dev):                    1854         def slice(self, dev):
2583                 minicg = FTraceCallGraph(dev[    1855                 minicg = FTraceCallGraph(dev['pid'], self.sv)
2584                 minicg.name = self.name          1856                 minicg.name = self.name
2585                 mydepth = -1                     1857                 mydepth = -1
2586                 good = False                     1858                 good = False
2587                 for l in self.list:              1859                 for l in self.list:
2588                         if(l.time < dev['star    1860                         if(l.time < dev['start'] or l.time > dev['end']):
2589                                 continue         1861                                 continue
2590                         if mydepth < 0:          1862                         if mydepth < 0:
2591                                 if l.name ==     1863                                 if l.name == 'mutex_lock' and l.freturn:
2592                                         mydep    1864                                         mydepth = l.depth
2593                                 continue         1865                                 continue
2594                         elif l.depth == mydep    1866                         elif l.depth == mydepth and l.name == 'mutex_unlock' and l.fcall:
2595                                 good = True      1867                                 good = True
2596                                 break            1868                                 break
2597                         l.depth -= mydepth       1869                         l.depth -= mydepth
2598                         minicg.addLine(l)        1870                         minicg.addLine(l)
2599                 if not good or len(minicg.lis    1871                 if not good or len(minicg.list) < 1:
2600                         return 0                 1872                         return 0
2601                 return minicg                    1873                 return minicg
2602         def repair(self, enddepth):              1874         def repair(self, enddepth):
2603                 # bring the depth back to 0 w    1875                 # bring the depth back to 0 with additional returns
2604                 fixed = False                    1876                 fixed = False
2605                 last = self.list[-1]             1877                 last = self.list[-1]
2606                 for i in reversed(range(endde    1878                 for i in reversed(range(enddepth)):
2607                         t = FTraceLine(last.t    1879                         t = FTraceLine(last.time)
2608                         t.depth = i              1880                         t.depth = i
2609                         t.freturn = True         1881                         t.freturn = True
2610                         fixed = self.addLine(    1882                         fixed = self.addLine(t)
2611                         if fixed != 0:           1883                         if fixed != 0:
2612                                 self.end = la    1884                                 self.end = last.time
2613                                 return True      1885                                 return True
2614                 return False                     1886                 return False
2615         def postProcess(self):                   1887         def postProcess(self):
2616                 if len(self.list) > 0:           1888                 if len(self.list) > 0:
2617                         self.name = self.list    1889                         self.name = self.list[0].name
2618                 stack = dict()                   1890                 stack = dict()
2619                 cnt = 0                          1891                 cnt = 0
2620                 last = 0                         1892                 last = 0
2621                 for l in self.list:              1893                 for l in self.list:
2622                         # ftrace bug: reporte    1894                         # ftrace bug: reported duration is not reliable
2623                         # check each leaf and    1895                         # check each leaf and clip it at max possible length
2624                         if last and last.isLe    1896                         if last and last.isLeaf():
2625                                 if last.lengt    1897                                 if last.length > l.time - last.time:
2626                                         last.    1898                                         last.length = l.time - last.time
2627                         if l.isCall():           1899                         if l.isCall():
2628                                 stack[l.depth    1900                                 stack[l.depth] = l
2629                                 cnt += 1         1901                                 cnt += 1
2630                         elif l.isReturn():       1902                         elif l.isReturn():
2631                                 if(l.depth no    1903                                 if(l.depth not in stack):
2632                                         if se    1904                                         if self.sv.verbose:
2633                                               !! 1905                                                 print 'Post Process Error: Depth missing'
2634                                                  1906                                                 l.debugPrint()
2635                                         retur    1907                                         return False
2636                                 # calculate c    1908                                 # calculate call length from call/return lines
2637                                 cl = stack[l.    1909                                 cl = stack[l.depth]
2638                                 cl.length = l    1910                                 cl.length = l.time - cl.time
2639                                 if cl.name ==    1911                                 if cl.name == self.vfname:
2640                                         cl.na    1912                                         cl.name = l.name
2641                                 stack.pop(l.d    1913                                 stack.pop(l.depth)
2642                                 l.length = 0     1914                                 l.length = 0
2643                                 cnt -= 1         1915                                 cnt -= 1
2644                         last = l                 1916                         last = l
2645                 if(cnt == 0):                    1917                 if(cnt == 0):
2646                         # trace caught the wh    1918                         # trace caught the whole call tree
2647                         return True              1919                         return True
2648                 elif(cnt < 0):                   1920                 elif(cnt < 0):
2649                         if self.sv.verbose:      1921                         if self.sv.verbose:
2650                                 pprint('Post  !! 1922                                 print 'Post Process Error: Depth is less than 0'
2651                         return False             1923                         return False
2652                 # trace ended before call tre    1924                 # trace ended before call tree finished
2653                 return self.repair(cnt)          1925                 return self.repair(cnt)
2654         def deviceMatch(self, pid, data):        1926         def deviceMatch(self, pid, data):
2655                 found = ''                       1927                 found = ''
2656                 # add the callgraph data to t    1928                 # add the callgraph data to the device hierarchy
2657                 borderphase = {                  1929                 borderphase = {
2658                         'dpm_prepare': 'suspe    1930                         'dpm_prepare': 'suspend_prepare',
2659                         'dpm_complete': 'resu    1931                         'dpm_complete': 'resume_complete'
2660                 }                                1932                 }
2661                 if(self.name in borderphase):    1933                 if(self.name in borderphase):
2662                         p = borderphase[self.    1934                         p = borderphase[self.name]
2663                         list = data.dmesg[p][    1935                         list = data.dmesg[p]['list']
2664                         for devname in list:     1936                         for devname in list:
2665                                 dev = list[de    1937                                 dev = list[devname]
2666                                 if(pid == dev    1938                                 if(pid == dev['pid'] and
2667                                         self.    1939                                         self.start <= dev['start'] and
2668                                         self.    1940                                         self.end >= dev['end']):
2669                                         cg =     1941                                         cg = self.slice(dev)
2670                                         if cg    1942                                         if cg:
2671                                                  1943                                                 dev['ftrace'] = cg
2672                                         found    1944                                         found = devname
2673                         return found             1945                         return found
2674                 for p in data.sortedPhases(): !! 1946                 for p in data.phases:
2675                         if(data.dmesg[p]['sta    1947                         if(data.dmesg[p]['start'] <= self.start and
2676                                 self.start <=    1948                                 self.start <= data.dmesg[p]['end']):
2677                                 list = data.d    1949                                 list = data.dmesg[p]['list']
2678                                 for devname i !! 1950                                 for devname in list:
2679                                         dev =    1951                                         dev = list[devname]
2680                                         if(pi    1952                                         if(pid == dev['pid'] and
2681                                                  1953                                                 self.start <= dev['start'] and
2682                                                  1954                                                 self.end >= dev['end']):
2683                                                  1955                                                 dev['ftrace'] = self
2684                                                  1956                                                 found = devname
2685                                                  1957                                                 break
2686                                 break            1958                                 break
2687                 return found                     1959                 return found
2688         def newActionFromFunction(self, data)    1960         def newActionFromFunction(self, data):
2689                 name = self.name                 1961                 name = self.name
2690                 if name in ['dpm_run_callback    1962                 if name in ['dpm_run_callback', 'dpm_prepare', 'dpm_complete']:
2691                         return                   1963                         return
2692                 fs = self.start                  1964                 fs = self.start
2693                 fe = self.end                    1965                 fe = self.end
2694                 if fs < data.start or fe > da    1966                 if fs < data.start or fe > data.end:
2695                         return                   1967                         return
2696                 phase = ''                       1968                 phase = ''
2697                 for p in data.sortedPhases(): !! 1969                 for p in data.phases:
2698                         if(data.dmesg[p]['sta    1970                         if(data.dmesg[p]['start'] <= self.start and
2699                                 self.start <     1971                                 self.start < data.dmesg[p]['end']):
2700                                 phase = p        1972                                 phase = p
2701                                 break            1973                                 break
2702                 if not phase:                    1974                 if not phase:
2703                         return                   1975                         return
2704                 out = data.newActionGlobal(na    1976                 out = data.newActionGlobal(name, fs, fe, -2)
2705                 if out:                          1977                 if out:
2706                         phase, myname = out      1978                         phase, myname = out
2707                         data.dmesg[phase]['li    1979                         data.dmesg[phase]['list'][myname]['ftrace'] = self
2708         def debugPrint(self, info=''):           1980         def debugPrint(self, info=''):
2709                 pprint('%s pid=%d [%f - %f] % !! 1981                 print('%s pid=%d [%f - %f] %.3f us') % \
2710                         (self.name, self.pid,    1982                         (self.name, self.pid, self.start, self.end,
2711                         (self.end - self.star !! 1983                         (self.end - self.start)*1000000)
2712                 for l in self.list:              1984                 for l in self.list:
2713                         if l.isLeaf():           1985                         if l.isLeaf():
2714                                 pprint('%f (% !! 1986                                 print('%f (%02d): %s(); (%.3f us)%s' % (l.time, \
2715                                         l.dep    1987                                         l.depth, l.name, l.length*1000000, info))
2716                         elif l.freturn:          1988                         elif l.freturn:
2717                                 pprint('%f (% !! 1989                                 print('%f (%02d): %s} (%.3f us)%s' % (l.time, \
2718                                         l.dep    1990                                         l.depth, l.name, l.length*1000000, info))
2719                         else:                    1991                         else:
2720                                 pprint('%f (% !! 1992                                 print('%f (%02d): %s() { (%.3f us)%s' % (l.time, \
2721                                         l.dep    1993                                         l.depth, l.name, l.length*1000000, info))
2722                 pprint(' ')                   !! 1994                 print(' ')
2723                                                  1995 
2724 class DevItem:                                   1996 class DevItem:
2725         def __init__(self, test, phase, dev):    1997         def __init__(self, test, phase, dev):
2726                 self.test = test                 1998                 self.test = test
2727                 self.phase = phase               1999                 self.phase = phase
2728                 self.dev = dev                   2000                 self.dev = dev
2729         def isa(self, cls):                      2001         def isa(self, cls):
2730                 if 'htmlclass' in self.dev an    2002                 if 'htmlclass' in self.dev and cls in self.dev['htmlclass']:
2731                         return True              2003                         return True
2732                 return False                     2004                 return False
2733                                                  2005 
2734 # Class: Timeline                                2006 # Class: Timeline
2735 # Description:                                   2007 # Description:
2736 #        A container for a device timeline wh    2008 #        A container for a device timeline which calculates
2737 #        all the html properties to display i    2009 #        all the html properties to display it correctly
2738 class Timeline:                                  2010 class Timeline:
                                                   >> 2011         html = ''
                                                   >> 2012         height = 0      # total timeline height
                                                   >> 2013         scaleH = 20     # timescale (top) row height
                                                   >> 2014         rowH = 30       # device row height
                                                   >> 2015         bodyH = 0       # body height
                                                   >> 2016         rows = 0        # total timeline rows
                                                   >> 2017         rowlines = dict()
                                                   >> 2018         rowheight = dict()
2739         html_tblock = '<div id="block{0}" cla    2019         html_tblock = '<div id="block{0}" class="tblock" style="left:{1}%;width:{2}%;"><div class="tback" style="height:{3}px"></div>\n'
2740         html_device = '<div id="{0}" title="{    2020         html_device = '<div id="{0}" title="{1}" class="thread{7}" style="left:{2}%;top:{3}px;height:{4}px;width:{5}%;{8}">{6}</div>\n'
2741         html_phase = '<div class="phase" styl    2021         html_phase = '<div class="phase" style="left:{0}%;width:{1}%;top:{2}px;height:{3}px;background:{4}">{5}</div>\n'
2742         html_phaselet = '<div id="{0}" class=    2022         html_phaselet = '<div id="{0}" class="phaselet" style="left:{1}%;width:{2}%;background:{3}"></div>\n'
2743         html_legend = '<div id="p{3}" class="    2023         html_legend = '<div id="p{3}" class="square" style="left:{0}%;background:{1}">&nbsp;{2}</div>\n'
2744         def __init__(self, rowheight, scalehe    2024         def __init__(self, rowheight, scaleheight):
                                                   >> 2025                 self.rowH = rowheight
                                                   >> 2026                 self.scaleH = scaleheight
2745                 self.html = ''                   2027                 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):       2028         def createHeader(self, sv, stamp):
2754                 if(not stamp['time']):           2029                 if(not stamp['time']):
2755                         return                   2030                         return
2756                 self.html += '<div class="ver !! 2031                 self.html += '<div class="version"><a href="https://01.org/suspendresume">%s v%s</a></div>' \
2757                         % (sv.title, sv.versi    2032                         % (sv.title, sv.version)
2758                 if sv.logmsg and sv.testlog:     2033                 if sv.logmsg and sv.testlog:
2759                         self.html += '<button    2034                         self.html += '<button id="showtest" class="logbtn btnfmt">log</button>'
2760                 if sv.dmesglog:                  2035                 if sv.dmesglog:
2761                         self.html += '<button    2036                         self.html += '<button id="showdmesg" class="logbtn btnfmt">dmesg</button>'
2762                 if sv.ftracelog:                 2037                 if sv.ftracelog:
2763                         self.html += '<button    2038                         self.html += '<button id="showftrace" class="logbtn btnfmt">ftrace</button>'
2764                 headline_stamp = '<div class=    2039                 headline_stamp = '<div class="stamp">{0} {1} {2} {3}</div>\n'
2765                 self.html += headline_stamp.f    2040                 self.html += headline_stamp.format(stamp['host'], stamp['kernel'],
2766                         stamp['mode'], stamp[    2041                         stamp['mode'], stamp['time'])
2767                 if 'man' in stamp and 'plat'     2042                 if 'man' in stamp and 'plat' in stamp and 'cpu' in stamp and \
2768                         stamp['man'] and stam    2043                         stamp['man'] and stamp['plat'] and stamp['cpu']:
2769                         headline_sysinfo = '<    2044                         headline_sysinfo = '<div class="stamp sysinfo">{0} {1} <i>with</i> {2}</div>\n'
2770                         self.html += headline    2045                         self.html += headline_sysinfo.format(stamp['man'], stamp['plat'], stamp['cpu'])
2771                                                  2046 
2772         # Function: getDeviceRows                2047         # Function: getDeviceRows
2773         # Description:                           2048         # Description:
2774         #    determine how may rows the devic    2049         #    determine how may rows the device funcs will take
2775         # Arguments:                             2050         # Arguments:
2776         #        rawlist: the list of devices    2051         #        rawlist: the list of devices/actions for a single phase
2777         # Output:                                2052         # Output:
2778         #        The total number of rows nee    2053         #        The total number of rows needed to display this phase of the timeline
2779         def getDeviceRows(self, rawlist):        2054         def getDeviceRows(self, rawlist):
2780                 # clear all rows and set them    2055                 # clear all rows and set them to undefined
2781                 sortdict = dict()                2056                 sortdict = dict()
2782                 for item in rawlist:             2057                 for item in rawlist:
2783                         item.row = -1            2058                         item.row = -1
2784                         sortdict[item] = item    2059                         sortdict[item] = item.length
2785                 sortlist = sorted(sortdict, k    2060                 sortlist = sorted(sortdict, key=sortdict.get, reverse=True)
2786                 remaining = len(sortlist)        2061                 remaining = len(sortlist)
2787                 rowdata = dict()                 2062                 rowdata = dict()
2788                 row = 1                          2063                 row = 1
2789                 # try to pack each row with a    2064                 # try to pack each row with as many ranges as possible
2790                 while(remaining > 0):            2065                 while(remaining > 0):
2791                         if(row not in rowdata    2066                         if(row not in rowdata):
2792                                 rowdata[row]     2067                                 rowdata[row] = []
2793                         for i in sortlist:       2068                         for i in sortlist:
2794                                 if(i.row >= 0    2069                                 if(i.row >= 0):
2795                                         conti    2070                                         continue
2796                                 s = i.time       2071                                 s = i.time
2797                                 e = i.time +     2072                                 e = i.time + i.length
2798                                 valid = True     2073                                 valid = True
2799                                 for ritem in     2074                                 for ritem in rowdata[row]:
2800                                         rs =     2075                                         rs = ritem.time
2801                                         re =     2076                                         re = ritem.time + ritem.length
2802                                         if(no    2077                                         if(not (((s <= rs) and (e <= rs)) or
2803                                                  2078                                                 ((s >= re) and (e >= re)))):
2804                                                  2079                                                 valid = False
2805                                                  2080                                                 break
2806                                 if(valid):       2081                                 if(valid):
2807                                         rowda    2082                                         rowdata[row].append(i)
2808                                         i.row    2083                                         i.row = row
2809                                         remai    2084                                         remaining -= 1
2810                         row += 1                 2085                         row += 1
2811                 return row                       2086                 return row
2812         # Function: getPhaseRows                 2087         # Function: getPhaseRows
2813         # Description:                           2088         # Description:
2814         #        Organize the timeline entrie    2089         #        Organize the timeline entries into the smallest
2815         #        number of rows possible, wit    2090         #        number of rows possible, with no entry overlapping
2816         # Arguments:                             2091         # Arguments:
2817         #        devlist: the list of devices    2092         #        devlist: the list of devices/actions in a group of contiguous phases
2818         # Output:                                2093         # Output:
2819         #        The total number of rows nee    2094         #        The total number of rows needed to display this phase of the timeline
2820         def getPhaseRows(self, devlist, row=0    2095         def getPhaseRows(self, devlist, row=0, sortby='length'):
2821                 # clear all rows and set them    2096                 # clear all rows and set them to undefined
2822                 remaining = len(devlist)         2097                 remaining = len(devlist)
2823                 rowdata = dict()                 2098                 rowdata = dict()
2824                 sortdict = dict()                2099                 sortdict = dict()
2825                 myphases = []                    2100                 myphases = []
2826                 # initialize all device rows     2101                 # initialize all device rows to -1 and calculate devrows
2827                 for item in devlist:             2102                 for item in devlist:
2828                         dev = item.dev           2103                         dev = item.dev
2829                         tp = (item.test, item    2104                         tp = (item.test, item.phase)
2830                         if tp not in myphases    2105                         if tp not in myphases:
2831                                 myphases.appe    2106                                 myphases.append(tp)
2832                         dev['row'] = -1          2107                         dev['row'] = -1
2833                         if sortby == 'start':    2108                         if sortby == 'start':
2834                                 # sort by sta    2109                                 # sort by start 1st, then length 2nd
2835                                 sortdict[item    2110                                 sortdict[item] = (-1*float(dev['start']), float(dev['end']) - float(dev['start']))
2836                         else:                    2111                         else:
2837                                 # sort by len    2112                                 # sort by length 1st, then name 2nd
2838                                 sortdict[item    2113                                 sortdict[item] = (float(dev['end']) - float(dev['start']), item.dev['name'])
2839                         if 'src' in dev:         2114                         if 'src' in dev:
2840                                 dev['devrows'    2115                                 dev['devrows'] = self.getDeviceRows(dev['src'])
2841                 # sort the devlist by length     2116                 # sort the devlist by length so that large items graph on top
2842                 sortlist = sorted(sortdict, k    2117                 sortlist = sorted(sortdict, key=sortdict.get, reverse=True)
2843                 orderedlist = []                 2118                 orderedlist = []
2844                 for item in sortlist:            2119                 for item in sortlist:
2845                         if item.dev['pid'] ==    2120                         if item.dev['pid'] == -2:
2846                                 orderedlist.a    2121                                 orderedlist.append(item)
2847                 for item in sortlist:            2122                 for item in sortlist:
2848                         if item not in ordere    2123                         if item not in orderedlist:
2849                                 orderedlist.a    2124                                 orderedlist.append(item)
2850                 # try to pack each row with a    2125                 # try to pack each row with as many devices as possible
2851                 while(remaining > 0):            2126                 while(remaining > 0):
2852                         rowheight = 1            2127                         rowheight = 1
2853                         if(row not in rowdata    2128                         if(row not in rowdata):
2854                                 rowdata[row]     2129                                 rowdata[row] = []
2855                         for item in orderedli    2130                         for item in orderedlist:
2856                                 dev = item.de    2131                                 dev = item.dev
2857                                 if(dev['row']    2132                                 if(dev['row'] < 0):
2858                                         s = d    2133                                         s = dev['start']
2859                                         e = d    2134                                         e = dev['end']
2860                                         valid    2135                                         valid = True
2861                                         for r    2136                                         for ritem in rowdata[row]:
2862                                                  2137                                                 rs = ritem.dev['start']
2863                                                  2138                                                 re = ritem.dev['end']
2864                                                  2139                                                 if(not (((s <= rs) and (e <= rs)) or
2865                                                  2140                                                         ((s >= re) and (e >= re)))):
2866                                                  2141                                                         valid = False
2867                                                  2142                                                         break
2868                                         if(va    2143                                         if(valid):
2869                                                  2144                                                 rowdata[row].append(item)
2870                                                  2145                                                 dev['row'] = row
2871                                                  2146                                                 remaining -= 1
2872                                                  2147                                                 if 'devrows' in dev and dev['devrows'] > rowheight:
2873                                                  2148                                                         rowheight = dev['devrows']
2874                         for t, p in myphases:    2149                         for t, p in myphases:
2875                                 if t not in s    2150                                 if t not in self.rowlines or t not in self.rowheight:
2876                                         self.    2151                                         self.rowlines[t] = dict()
2877                                         self.    2152                                         self.rowheight[t] = dict()
2878                                 if p not in s    2153                                 if p not in self.rowlines[t] or p not in self.rowheight[t]:
2879                                         self.    2154                                         self.rowlines[t][p] = dict()
2880                                         self.    2155                                         self.rowheight[t][p] = dict()
2881                                 rh = self.row    2156                                 rh = self.rowH
2882                                 # section hea    2157                                 # section headers should use a different row height
2883                                 if len(rowdat    2158                                 if len(rowdata[row]) == 1 and \
2884                                         'html    2159                                         'htmlclass' in rowdata[row][0].dev and \
2885                                         'sec'    2160                                         'sec' in rowdata[row][0].dev['htmlclass']:
2886                                         rh =     2161                                         rh = 15
2887                                 self.rowlines    2162                                 self.rowlines[t][p][row] = rowheight
2888                                 self.rowheigh    2163                                 self.rowheight[t][p][row] = rowheight * rh
2889                         row += 1                 2164                         row += 1
2890                 if(row > self.rows):             2165                 if(row > self.rows):
2891                         self.rows = int(row)     2166                         self.rows = int(row)
2892                 return row                       2167                 return row
2893         def phaseRowHeight(self, test, phase,    2168         def phaseRowHeight(self, test, phase, row):
2894                 return self.rowheight[test][p    2169                 return self.rowheight[test][phase][row]
2895         def phaseRowTop(self, test, phase, ro    2170         def phaseRowTop(self, test, phase, row):
2896                 top = 0                          2171                 top = 0
2897                 for i in sorted(self.rowheigh    2172                 for i in sorted(self.rowheight[test][phase]):
2898                         if i >= row:             2173                         if i >= row:
2899                                 break            2174                                 break
2900                         top += self.rowheight    2175                         top += self.rowheight[test][phase][i]
2901                 return top                       2176                 return top
2902         def calcTotalRows(self):                 2177         def calcTotalRows(self):
2903                 # Calculate the heights and o    2178                 # Calculate the heights and offsets for the header and rows
2904                 maxrows = 0                      2179                 maxrows = 0
2905                 standardphases = []              2180                 standardphases = []
2906                 for t in self.rowlines:          2181                 for t in self.rowlines:
2907                         for p in self.rowline    2182                         for p in self.rowlines[t]:
2908                                 total = 0        2183                                 total = 0
2909                                 for i in sort    2184                                 for i in sorted(self.rowlines[t][p]):
2910                                         total    2185                                         total += self.rowlines[t][p][i]
2911                                 if total > ma    2186                                 if total > maxrows:
2912                                         maxro    2187                                         maxrows = total
2913                                 if total == l    2188                                 if total == len(self.rowlines[t][p]):
2914                                         stand    2189                                         standardphases.append((t, p))
2915                 self.height = self.scaleH + (    2190                 self.height = self.scaleH + (maxrows*self.rowH)
2916                 self.bodyH = self.height - se    2191                 self.bodyH = self.height - self.scaleH
2917                 # if there is 1 line per row,    2192                 # if there is 1 line per row, draw them the standard way
2918                 for t, p in standardphases:      2193                 for t, p in standardphases:
2919                         for i in sorted(self.    2194                         for i in sorted(self.rowheight[t][p]):
2920                                 self.rowheigh !! 2195                                 self.rowheight[t][p][i] = self.bodyH/len(self.rowlines[t][p])
2921         def createZoomBox(self, mode='command    2196         def createZoomBox(self, mode='command', testcount=1):
2922                 # Create bounding box, add bu    2197                 # Create bounding box, add buttons
2923                 html_zoombox = '<center><butt    2198                 html_zoombox = '<center><button id="zoomin">ZOOM IN +</button><button id="zoomout">ZOOM OUT -</button><button id="zoomdef">ZOOM 1:1</button></center>\n'
2924                 html_timeline = '<div id="dme    2199                 html_timeline = '<div id="dmesgzoombox" class="zoombox">\n<div id="{0}" class="timeline" style="height:{1}px">\n'
2925                 html_devlist1 = '<button id="    2200                 html_devlist1 = '<button id="devlist1" class="devlist" style="float:left;">Device Detail{0}</button>'
2926                 html_devlist2 = '<button id="    2201                 html_devlist2 = '<button id="devlist2" class="devlist" style="float:right;">Device Detail2</button>\n'
2927                 if mode != 'command':            2202                 if mode != 'command':
2928                         if testcount > 1:        2203                         if testcount > 1:
2929                                 self.html +=     2204                                 self.html += html_devlist2
2930                                 self.html +=     2205                                 self.html += html_devlist1.format('1')
2931                         else:                    2206                         else:
2932                                 self.html +=     2207                                 self.html += html_devlist1.format('')
2933                 self.html += html_zoombox        2208                 self.html += html_zoombox
2934                 self.html += html_timeline.fo    2209                 self.html += html_timeline.format('dmesg', self.height)
2935         # Function: createTimeScale              2210         # Function: createTimeScale
2936         # Description:                           2211         # Description:
2937         #        Create the timescale for a t    2212         #        Create the timescale for a timeline block
2938         # Arguments:                             2213         # Arguments:
2939         #        m0: start time (mode begin)     2214         #        m0: start time (mode begin)
2940         #        mMax: end time (mode end)       2215         #        mMax: end time (mode end)
2941         #        tTotal: total timeline time     2216         #        tTotal: total timeline time
2942         #        mode: suspend or resume         2217         #        mode: suspend or resume
2943         # Output:                                2218         # Output:
2944         #        The html code needed to disp    2219         #        The html code needed to display the time scale
2945         def createTimeScale(self, m0, mMax, t    2220         def createTimeScale(self, m0, mMax, tTotal, mode):
2946                 timescale = '<div class="t" s    2221                 timescale = '<div class="t" style="right:{0}%">{1}</div>\n'
2947                 rline = '<div class="t" style    2222                 rline = '<div class="t" style="left:0;border-left:1px solid black;border-right:0;">{0}</div>\n'
2948                 output = '<div class="timesca    2223                 output = '<div class="timescale">\n'
2949                 # set scale for timeline         2224                 # set scale for timeline
2950                 mTotal = mMax - m0               2225                 mTotal = mMax - m0
2951                 tS = 0.1                         2226                 tS = 0.1
2952                 if(tTotal <= 0):                 2227                 if(tTotal <= 0):
2953                         return output+'</div>    2228                         return output+'</div>\n'
2954                 if(tTotal > 4):                  2229                 if(tTotal > 4):
2955                         tS = 1                   2230                         tS = 1
2956                 divTotal = int(mTotal/tS) + 1    2231                 divTotal = int(mTotal/tS) + 1
2957                 divEdge = (mTotal - tS*(divTo    2232                 divEdge = (mTotal - tS*(divTotal-1))*100/mTotal
2958                 for i in range(divTotal):        2233                 for i in range(divTotal):
2959                         htmlline = ''            2234                         htmlline = ''
2960                         if(mode == 'suspend')    2235                         if(mode == 'suspend'):
2961                                 pos = '%0.3f'    2236                                 pos = '%0.3f' % (100 - ((float(i)*tS*100)/mTotal) - divEdge)
2962                                 val = '%0.fms    2237                                 val = '%0.fms' % (float(i-divTotal+1)*tS*1000)
2963                                 if(i == divTo    2238                                 if(i == divTotal - 1):
2964                                         val =    2239                                         val = mode
2965                                 htmlline = ti    2240                                 htmlline = timescale.format(pos, val)
2966                         else:                    2241                         else:
2967                                 pos = '%0.3f'    2242                                 pos = '%0.3f' % (100 - ((float(i)*tS*100)/mTotal))
2968                                 val = '%0.fms    2243                                 val = '%0.fms' % (float(i)*tS*1000)
2969                                 htmlline = ti    2244                                 htmlline = timescale.format(pos, val)
2970                                 if(i == 0):      2245                                 if(i == 0):
2971                                         htmll    2246                                         htmlline = rline.format(mode)
2972                         output += htmlline       2247                         output += htmlline
2973                 self.html += output+'</div>\n    2248                 self.html += output+'</div>\n'
2974                                                  2249 
2975 # Class: TestProps                               2250 # Class: TestProps
2976 # Description:                                   2251 # Description:
2977 #        A list of values describing the prop    2252 #        A list of values describing the properties of these test runs
2978 class TestProps:                                 2253 class TestProps:
2979         stampfmt = r'# [a-z]*-(?P<m>[0-9]{2}) !! 2254         stamp = ''
2980                                 r'(?P<H>[0-9] !! 2255         sysinfo = ''
2981                                 r' (?P<host>. !! 2256         cmdline = ''
2982         wififmt    = r'^# wifi *(?P<d>\S*) *( !! 2257         kparams = ''
2983         tstatfmt   = r'^# turbostat (?P<t>\S* !! 2258         S0i3 = False
2984         testerrfmt = r'^# enter_sleep_error ( !! 2259         fwdata = []
2985         sysinfofmt = r'^# sysinfo .*'         !! 2260         stampfmt = '# [a-z]*-(?P<m>[0-9]{2})(?P<d>[0-9]{2})(?P<y>[0-9]{2})-'+\
2986         cmdlinefmt = r'^# command \| (?P<cmd> !! 2261                                 '(?P<H>[0-9]{2})(?P<M>[0-9]{2})(?P<S>[0-9]{2})'+\
2987         kparamsfmt = r'^# kparams \| (?P<kp>. !! 2262                                 ' (?P<host>.*) (?P<mode>.*) (?P<kernel>.*)$'
2988         devpropfmt = r'# Device Properties: . !! 2263         sysinfofmt = '^# sysinfo .*'
2989         pinfofmt   = r'# platform-(?P<val>[a- !! 2264         cmdlinefmt = '^# command \| (?P<cmd>.*)'
2990         tracertypefmt = r'# tracer: (?P<t>.*) !! 2265         kparamsfmt = '^# kparams \| (?P<kp>.*)'
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 = \                   2266         ftrace_line_fmt_fg = \
2995                 r'^ *(?P<time>[0-9\.]*) *\| * !! 2267                 '^ *(?P<time>[0-9\.]*) *\| *(?P<cpu>[0-9]*)\)'+\
2996                 r' *(?P<proc>.*)-(?P<pid>[0-9 !! 2268                 ' *(?P<proc>.*)-(?P<pid>[0-9]*) *\|'+\
2997                 r'[ +!#\*@$]*(?P<dur>[0-9\.]* !! 2269                 '[ +!#\*@$]*(?P<dur>[0-9\.]*) .*\|  (?P<msg>.*)'
2998         ftrace_line_fmt_nop = \                  2270         ftrace_line_fmt_nop = \
2999                 r' *(?P<proc>.*)-(?P<pid>[0-9 !! 2271                 ' *(?P<proc>.*)-(?P<pid>[0-9]*) *\[(?P<cpu>[0-9]*)\] *'+\
3000                 r'(?P<flags>\S*) *(?P<time>[0 !! 2272                 '(?P<flags>.{4}) *(?P<time>[0-9\.]*): *'+\
3001                 r'(?P<msg>.*)'                !! 2273                 '(?P<msg>.*)'
3002         machinesuspend = r'machine_suspend\[. !! 2274         ftrace_line_fmt = ftrace_line_fmt_nop
3003         multiproclist = dict()                !! 2275         cgformat = False
3004         multiproctime = 0.0                   !! 2276         data = 0
3005         multiproccnt = 0                      !! 2277         ktemp = dict()
3006         def __init__(self):                      2278         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()              2279                 self.ktemp = dict()
3018         def setTracerType(self, tracer):         2280         def setTracerType(self, tracer):
3019                 if(tracer == 'function_graph'    2281                 if(tracer == 'function_graph'):
3020                         self.cgformat = True     2282                         self.cgformat = True
3021                         self.ftrace_line_fmt     2283                         self.ftrace_line_fmt = self.ftrace_line_fmt_fg
3022                 elif(tracer == 'nop'):           2284                 elif(tracer == 'nop'):
3023                         self.ftrace_line_fmt     2285                         self.ftrace_line_fmt = self.ftrace_line_fmt_nop
3024                 else:                            2286                 else:
3025                         doError('Invalid trac    2287                         doError('Invalid tracer format: [%s]' % tracer)
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):          2288         def parseStamp(self, data, sv):
3061                 # global test data            << 
3062                 m = re.match(self.stampfmt, s    2289                 m = re.match(self.stampfmt, self.stamp)
3063                 if not self.stamp or not m:   << 
3064                         doError('data does no << 
3065                 data.stamp = {'time': '', 'ho    2290                 data.stamp = {'time': '', 'host': '', 'mode': ''}
3066                 dt = datetime(int(m.group('y'    2291                 dt = datetime(int(m.group('y'))+2000, int(m.group('m')),
3067                         int(m.group('d')), in    2292                         int(m.group('d')), int(m.group('H')), int(m.group('M')),
3068                         int(m.group('S')))       2293                         int(m.group('S')))
3069                 data.stamp['time'] = dt.strft    2294                 data.stamp['time'] = dt.strftime('%B %d %Y, %I:%M:%S %p')
3070                 data.stamp['host'] = m.group(    2295                 data.stamp['host'] = m.group('host')
3071                 data.stamp['mode'] = m.group(    2296                 data.stamp['mode'] = m.group('mode')
3072                 data.stamp['kernel'] = m.grou    2297                 data.stamp['kernel'] = m.group('kernel')
3073                 if re.match(self.sysinfofmt,     2298                 if re.match(self.sysinfofmt, self.sysinfo):
3074                         for f in self.sysinfo    2299                         for f in self.sysinfo.split('|'):
3075                                 if '#' in f:     2300                                 if '#' in f:
3076                                         conti    2301                                         continue
3077                                 tmp = f.strip    2302                                 tmp = f.strip().split(':', 1)
3078                                 key = tmp[0]     2303                                 key = tmp[0]
3079                                 val = tmp[1]     2304                                 val = tmp[1]
3080                                 data.stamp[ke    2305                                 data.stamp[key] = val
3081                 sv.hostname = data.stamp['hos    2306                 sv.hostname = data.stamp['host']
3082                 sv.suspendmode = data.stamp['    2307                 sv.suspendmode = data.stamp['mode']
3083                 if sv.suspendmode == 'freeze' << 
3084                         self.machinesuspend = << 
3085                 else:                         << 
3086                         self.machinesuspend = << 
3087                 if sv.suspendmode == 'command    2308                 if sv.suspendmode == 'command' and sv.ftracefile != '':
3088                         modes = ['on', 'freez    2309                         modes = ['on', 'freeze', 'standby', 'mem', 'disk']
3089                         fp = sv.openlog(sv.ft !! 2310                         fp = sysvals.openlog(sv.ftracefile, 'r')
3090                         for line in fp:          2311                         for line in fp:
3091                                 m = re.match( !! 2312                                 m = re.match('.* machine_suspend\[(?P<mode>.*)\]', line)
3092                                 if m and m.gr    2313                                 if m and m.group('mode') in ['1', '2', '3', '4']:
3093                                         sv.su    2314                                         sv.suspendmode = modes[int(m.group('mode'))]
3094                                         data.    2315                                         data.stamp['mode'] = sv.suspendmode
3095                                         break    2316                                         break
3096                         fp.close()               2317                         fp.close()
3097                 sv.cmdline = self.cmdline     !! 2318                 m = re.match(self.cmdlinefmt, self.cmdline)
                                                   >> 2319                 if m:
                                                   >> 2320                         sv.cmdline = m.group('cmd')
                                                   >> 2321                 if self.kparams:
                                                   >> 2322                         m = re.match(self.kparamsfmt, self.kparams)
                                                   >> 2323                         if m:
                                                   >> 2324                                 sv.kparams = m.group('kp')
3098                 if not sv.stamp:                 2325                 if not sv.stamp:
3099                         sv.stamp = data.stamp    2326                         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                                                  2327 
3165 # Class: TestRun                                 2328 # Class: TestRun
3166 # Description:                                   2329 # Description:
3167 #        A container for a suspend/resume tes    2330 #        A container for a suspend/resume test run. This is necessary as
3168 #        there could be more than one, and th    2331 #        there could be more than one, and they need to be separate.
3169 class TestRun:                                   2332 class TestRun:
                                                   >> 2333         ftemp = dict()
                                                   >> 2334         ttemp = dict()
                                                   >> 2335         data = 0
3170         def __init__(self, dataobj):             2336         def __init__(self, dataobj):
3171                 self.data = dataobj              2337                 self.data = dataobj
3172                 self.ftemp = dict()              2338                 self.ftemp = dict()
3173                 self.ttemp = dict()              2339                 self.ttemp = dict()
3174                                                  2340 
3175 class ProcessMonitor:                            2341 class ProcessMonitor:
3176         maxchars = 512                        !! 2342         proclist = dict()
3177         def __init__(self):                   !! 2343         running = False
3178                 self.proclist = dict()        << 
3179                 self.running = False          << 
3180         def procstat(self):                      2344         def procstat(self):
3181                 c = ['cat /proc/[1-9]*/stat 2    2345                 c = ['cat /proc/[1-9]*/stat 2>/dev/null']
3182                 process = Popen(c, shell=True    2346                 process = Popen(c, shell=True, stdout=PIPE)
3183                 running = dict()                 2347                 running = dict()
3184                 for line in process.stdout:      2348                 for line in process.stdout:
3185                         data = ascii(line).sp !! 2349                         data = line.split()
3186                         pid = data[0]            2350                         pid = data[0]
3187                         name = re.sub('[()]',    2351                         name = re.sub('[()]', '', data[1])
3188                         user = int(data[13])     2352                         user = int(data[13])
3189                         kern = int(data[14])     2353                         kern = int(data[14])
3190                         kjiff = ujiff = 0        2354                         kjiff = ujiff = 0
3191                         if pid not in self.pr    2355                         if pid not in self.proclist:
3192                                 self.proclist    2356                                 self.proclist[pid] = {'name' : name, 'user' : user, 'kern' : kern}
3193                         else:                    2357                         else:
3194                                 val = self.pr    2358                                 val = self.proclist[pid]
3195                                 ujiff = user     2359                                 ujiff = user - val['user']
3196                                 kjiff = kern     2360                                 kjiff = kern - val['kern']
3197                                 val['user'] =    2361                                 val['user'] = user
3198                                 val['kern'] =    2362                                 val['kern'] = kern
3199                         if ujiff > 0 or kjiff    2363                         if ujiff > 0 or kjiff > 0:
3200                                 running[pid]     2364                                 running[pid] = ujiff + kjiff
3201                 process.wait()                   2365                 process.wait()
3202                 out = ['']                    !! 2366                 out = ''
3203                 for pid in running:              2367                 for pid in running:
3204                         jiffies = running[pid    2368                         jiffies = running[pid]
3205                         val = self.proclist[p    2369                         val = self.proclist[pid]
3206                         if len(out[-1]) > sel !! 2370                         if out:
3207                                 out.append('' !! 2371                                 out += ','
3208                         elif len(out[-1]) > 0 !! 2372                         out += '%s-%s %d' % (val['name'], pid, jiffies)
3209                                 out[-1] += ', !! 2373                 return 'ps - '+out
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):           2374         def processMonitor(self, tid):
3217                 while self.running:              2375                 while self.running:
3218                         self.procstat()       !! 2376                         out = self.procstat()
                                                   >> 2377                         if out:
                                                   >> 2378                                 sysvals.fsetVal(out, 'trace_marker')
3219         def start(self):                         2379         def start(self):
3220                 self.thread = Thread(target=s    2380                 self.thread = Thread(target=self.processMonitor, args=(0,))
3221                 self.running = True              2381                 self.running = True
3222                 self.thread.start()              2382                 self.thread.start()
3223         def stop(self):                          2383         def stop(self):
3224                 self.running = False             2384                 self.running = False
3225                                                  2385 
3226 # ----------------- FUNCTIONS ---------------    2386 # ----------------- FUNCTIONS --------------------
3227                                                  2387 
3228 # Function: doesTraceLogHaveTraceEvents          2388 # Function: doesTraceLogHaveTraceEvents
3229 # Description:                                   2389 # Description:
3230 #        Quickly determine if the ftrace log     2390 #        Quickly determine if the ftrace log has all of the trace events,
3231 #        markers, and/or kprobes required for    2391 #        markers, and/or kprobes required for primary parsing.
3232 def doesTraceLogHaveTraceEvents():               2392 def doesTraceLogHaveTraceEvents():
3233         kpcheck = ['_cal: (', '_ret: (']      !! 2393         kpcheck = ['_cal: (', '_cpu_down()']
3234         techeck = ['suspend_resume', 'device_ !! 2394         techeck = ['suspend_resume']
3235         tmcheck = ['SUSPEND START', 'RESUME C    2395         tmcheck = ['SUSPEND START', 'RESUME COMPLETE']
3236         sysvals.usekprobes = False               2396         sysvals.usekprobes = False
3237         fp = sysvals.openlog(sysvals.ftracefi    2397         fp = sysvals.openlog(sysvals.ftracefile, 'r')
3238         for line in fp:                          2398         for line in fp:
3239                 # check for kprobes              2399                 # check for kprobes
3240                 if not sysvals.usekprobes:       2400                 if not sysvals.usekprobes:
3241                         for i in kpcheck:        2401                         for i in kpcheck:
3242                                 if i in line:    2402                                 if i in line:
3243                                         sysva    2403                                         sysvals.usekprobes = True
3244                 # check for all necessary tra    2404                 # check for all necessary trace events
3245                 check = techeck[:]               2405                 check = techeck[:]
3246                 for i in techeck:                2406                 for i in techeck:
3247                         if i in line:            2407                         if i in line:
3248                                 check.remove(    2408                                 check.remove(i)
3249                 techeck = check                  2409                 techeck = check
3250                 # check for all necessary tra    2410                 # check for all necessary trace markers
3251                 check = tmcheck[:]               2411                 check = tmcheck[:]
3252                 for i in tmcheck:                2412                 for i in tmcheck:
3253                         if i in line:            2413                         if i in line:
3254                                 check.remove(    2414                                 check.remove(i)
3255                 tmcheck = check                  2415                 tmcheck = check
3256         fp.close()                               2416         fp.close()
3257         sysvals.usetraceevents = True if len( !! 2417         if len(techeck) == 0:
3258         sysvals.usetracemarkers = True if len !! 2418                 sysvals.usetraceevents = True
                                                   >> 2419         else:
                                                   >> 2420                 sysvals.usetraceevents = False
                                                   >> 2421         if len(tmcheck) == 0:
                                                   >> 2422                 sysvals.usetracemarkers = True
                                                   >> 2423         else:
                                                   >> 2424                 sysvals.usetracemarkers = False
3259                                                  2425 
3260 # Function: appendIncompleteTraceLog             2426 # Function: appendIncompleteTraceLog
3261 # Description:                                   2427 # Description:
3262 #        Adds callgraph data which lacks trac !! 2428 #        [deprecated for kernel 3.15 or newer]
3263 #        for timelines generated from 3.15 or !! 2429 #        Legacy support of ftrace outputs that lack the device_pm_callback
                                                   >> 2430 #        and/or suspend_resume trace events. The primary data should be
                                                   >> 2431 #        taken from dmesg, and this ftrace is used only for callgraph data
                                                   >> 2432 #        or custom actions in the timeline. The data is appended to the Data
                                                   >> 2433 #        objects provided.
3264 # Arguments:                                     2434 # Arguments:
3265 #        testruns: the array of Data objects     2435 #        testruns: the array of Data objects obtained from parseKernelLog
3266 def appendIncompleteTraceLog(testruns):          2436 def appendIncompleteTraceLog(testruns):
3267         # create TestRun vessels for ftrace p    2437         # create TestRun vessels for ftrace parsing
3268         testcnt = len(testruns)                  2438         testcnt = len(testruns)
3269         testidx = 0                              2439         testidx = 0
3270         testrun = []                             2440         testrun = []
3271         for data in testruns:                    2441         for data in testruns:
3272                 testrun.append(TestRun(data))    2442                 testrun.append(TestRun(data))
3273                                                  2443 
3274         # extract the callgraph and traceeven    2444         # extract the callgraph and traceevent data
3275         sysvals.vprint('Analyzing the ftrace     2445         sysvals.vprint('Analyzing the ftrace data (%s)...' % \
3276                 os.path.basename(sysvals.ftra    2446                 os.path.basename(sysvals.ftracefile))
3277         tp = TestProps()                         2447         tp = TestProps()
3278         tf = sysvals.openlog(sysvals.ftracefi    2448         tf = sysvals.openlog(sysvals.ftracefile, 'r')
3279         data = 0                                 2449         data = 0
3280         for line in tf:                          2450         for line in tf:
3281                 # remove any latent carriage     2451                 # remove any latent carriage returns
3282                 line = line.replace('\r\n', '    2452                 line = line.replace('\r\n', '')
3283                 if tp.stampInfo(line, sysvals !! 2453                 # grab the stamp and sysinfo
                                                   >> 2454                 if re.match(tp.stampfmt, line):
                                                   >> 2455                         tp.stamp = line
                                                   >> 2456                         continue
                                                   >> 2457                 elif re.match(tp.sysinfofmt, line):
                                                   >> 2458                         tp.sysinfo = line
                                                   >> 2459                         continue
                                                   >> 2460                 elif re.match(tp.cmdlinefmt, line):
                                                   >> 2461                         tp.cmdline = line
                                                   >> 2462                         continue
                                                   >> 2463                 # determine the trace data type (required for further parsing)
                                                   >> 2464                 m = re.match(sysvals.tracertypefmt, line)
                                                   >> 2465                 if(m):
                                                   >> 2466                         tp.setTracerType(m.group('t'))
                                                   >> 2467                         continue
                                                   >> 2468                 # device properties line
                                                   >> 2469                 if(re.match(sysvals.devpropfmt, line)):
                                                   >> 2470                         devProps(line)
3284                         continue                 2471                         continue
3285                 # parse only valid lines, if     2472                 # parse only valid lines, if this is not one move on
3286                 m = re.match(tp.ftrace_line_f    2473                 m = re.match(tp.ftrace_line_fmt, line)
3287                 if(not m):                       2474                 if(not m):
3288                         continue                 2475                         continue
3289                 # gather the basic message da    2476                 # gather the basic message data from the line
3290                 m_time = m.group('time')         2477                 m_time = m.group('time')
3291                 m_pid = m.group('pid')           2478                 m_pid = m.group('pid')
3292                 m_msg = m.group('msg')           2479                 m_msg = m.group('msg')
3293                 if(tp.cgformat):                 2480                 if(tp.cgformat):
3294                         m_param3 = m.group('d    2481                         m_param3 = m.group('dur')
3295                 else:                            2482                 else:
3296                         m_param3 = 'traceeven    2483                         m_param3 = 'traceevent'
3297                 if(m_time and m_pid and m_msg    2484                 if(m_time and m_pid and m_msg):
3298                         t = FTraceLine(m_time    2485                         t = FTraceLine(m_time, m_msg, m_param3)
3299                         pid = int(m_pid)         2486                         pid = int(m_pid)
3300                 else:                            2487                 else:
3301                         continue                 2488                         continue
3302                 # the line should be a call,     2489                 # the line should be a call, return, or event
3303                 if(not t.fcall and not t.fret    2490                 if(not t.fcall and not t.freturn and not t.fevent):
3304                         continue                 2491                         continue
3305                 # look for the suspend start     2492                 # look for the suspend start marker
3306                 if(t.startMarker()):             2493                 if(t.startMarker()):
3307                         data = testrun[testid    2494                         data = testrun[testidx].data
3308                         tp.parseStamp(data, s    2495                         tp.parseStamp(data, sysvals)
3309                         data.setStart(t.time, !! 2496                         data.setStart(t.time)
3310                         continue                 2497                         continue
3311                 if(not data):                    2498                 if(not data):
3312                         continue                 2499                         continue
3313                 # find the end of resume         2500                 # find the end of resume
3314                 if(t.endMarker()):               2501                 if(t.endMarker()):
3315                         data.setEnd(t.time, t !! 2502                         data.setEnd(t.time)
3316                         testidx += 1             2503                         testidx += 1
3317                         if(testidx >= testcnt    2504                         if(testidx >= testcnt):
3318                                 break            2505                                 break
3319                         continue                 2506                         continue
3320                 # trace event processing         2507                 # trace event processing
3321                 if(t.fevent):                    2508                 if(t.fevent):
3322                         continue              !! 2509                         # general trace events have two types, begin and end
                                                   >> 2510                         if(re.match('(?P<name>.*) begin$', t.name)):
                                                   >> 2511                                 isbegin = True
                                                   >> 2512                         elif(re.match('(?P<name>.*) end$', t.name)):
                                                   >> 2513                                 isbegin = False
                                                   >> 2514                         else:
                                                   >> 2515                                 continue
                                                   >> 2516                         m = re.match('(?P<name>.*)\[(?P<val>[0-9]*)\] .*', t.name)
                                                   >> 2517                         if(m):
                                                   >> 2518                                 val = m.group('val')
                                                   >> 2519                                 if val == '0':
                                                   >> 2520                                         name = m.group('name')
                                                   >> 2521                                 else:
                                                   >> 2522                                         name = m.group('name')+'['+val+']'
                                                   >> 2523                         else:
                                                   >> 2524                                 m = re.match('(?P<name>.*) .*', t.name)
                                                   >> 2525                                 name = m.group('name')
                                                   >> 2526                         # special processing for trace events
                                                   >> 2527                         if re.match('dpm_prepare\[.*', name):
                                                   >> 2528                                 continue
                                                   >> 2529                         elif re.match('machine_suspend.*', name):
                                                   >> 2530                                 continue
                                                   >> 2531                         elif re.match('suspend_enter\[.*', name):
                                                   >> 2532                                 if(not isbegin):
                                                   >> 2533                                         data.dmesg['suspend_prepare']['end'] = t.time
                                                   >> 2534                                 continue
                                                   >> 2535                         elif re.match('dpm_suspend\[.*', name):
                                                   >> 2536                                 if(not isbegin):
                                                   >> 2537                                         data.dmesg['suspend']['end'] = t.time
                                                   >> 2538                                 continue
                                                   >> 2539                         elif re.match('dpm_suspend_late\[.*', name):
                                                   >> 2540                                 if(isbegin):
                                                   >> 2541                                         data.dmesg['suspend_late']['start'] = t.time
                                                   >> 2542                                 else:
                                                   >> 2543                                         data.dmesg['suspend_late']['end'] = t.time
                                                   >> 2544                                 continue
                                                   >> 2545                         elif re.match('dpm_suspend_noirq\[.*', name):
                                                   >> 2546                                 if(isbegin):
                                                   >> 2547                                         data.dmesg['suspend_noirq']['start'] = t.time
                                                   >> 2548                                 else:
                                                   >> 2549                                         data.dmesg['suspend_noirq']['end'] = t.time
                                                   >> 2550                                 continue
                                                   >> 2551                         elif re.match('dpm_resume_noirq\[.*', name):
                                                   >> 2552                                 if(isbegin):
                                                   >> 2553                                         data.dmesg['resume_machine']['end'] = t.time
                                                   >> 2554                                         data.dmesg['resume_noirq']['start'] = t.time
                                                   >> 2555                                 else:
                                                   >> 2556                                         data.dmesg['resume_noirq']['end'] = t.time
                                                   >> 2557                                 continue
                                                   >> 2558                         elif re.match('dpm_resume_early\[.*', name):
                                                   >> 2559                                 if(isbegin):
                                                   >> 2560                                         data.dmesg['resume_early']['start'] = t.time
                                                   >> 2561                                 else:
                                                   >> 2562                                         data.dmesg['resume_early']['end'] = t.time
                                                   >> 2563                                 continue
                                                   >> 2564                         elif re.match('dpm_resume\[.*', name):
                                                   >> 2565                                 if(isbegin):
                                                   >> 2566                                         data.dmesg['resume']['start'] = t.time
                                                   >> 2567                                 else:
                                                   >> 2568                                         data.dmesg['resume']['end'] = t.time
                                                   >> 2569                                 continue
                                                   >> 2570                         elif re.match('dpm_complete\[.*', name):
                                                   >> 2571                                 if(isbegin):
                                                   >> 2572                                         data.dmesg['resume_complete']['start'] = t.time
                                                   >> 2573                                 else:
                                                   >> 2574                                         data.dmesg['resume_complete']['end'] = t.time
                                                   >> 2575                                 continue
                                                   >> 2576                         # skip trace events inside devices calls
                                                   >> 2577                         if(not data.isTraceEventOutsideDeviceCalls(pid, t.time)):
                                                   >> 2578                                 continue
                                                   >> 2579                         # global events (outside device calls) are simply graphed
                                                   >> 2580                         if(isbegin):
                                                   >> 2581                                 # store each trace event in ttemp
                                                   >> 2582                                 if(name not in testrun[testidx].ttemp):
                                                   >> 2583                                         testrun[testidx].ttemp[name] = []
                                                   >> 2584                                 testrun[testidx].ttemp[name].append(\
                                                   >> 2585                                         {'begin': t.time, 'end': t.time})
                                                   >> 2586                         else:
                                                   >> 2587                                 # finish off matching trace event in ttemp
                                                   >> 2588                                 if(name in testrun[testidx].ttemp):
                                                   >> 2589                                         testrun[testidx].ttemp[name][-1]['end'] = t.time
3323                 # call/return processing         2590                 # call/return processing
3324                 elif sysvals.usecallgraph:       2591                 elif sysvals.usecallgraph:
3325                         # create a callgraph     2592                         # create a callgraph object for the data
3326                         if(pid not in testrun    2593                         if(pid not in testrun[testidx].ftemp):
3327                                 testrun[testi    2594                                 testrun[testidx].ftemp[pid] = []
3328                                 testrun[testi    2595                                 testrun[testidx].ftemp[pid].append(FTraceCallGraph(pid, sysvals))
3329                         # when the call is fi    2596                         # when the call is finished, see which device matches it
3330                         cg = testrun[testidx]    2597                         cg = testrun[testidx].ftemp[pid][-1]
3331                         res = cg.addLine(t)      2598                         res = cg.addLine(t)
3332                         if(res != 0):            2599                         if(res != 0):
3333                                 testrun[testi    2600                                 testrun[testidx].ftemp[pid].append(FTraceCallGraph(pid, sysvals))
3334                         if(res == -1):           2601                         if(res == -1):
3335                                 testrun[testi    2602                                 testrun[testidx].ftemp[pid][-1].addLine(t)
3336         tf.close()                               2603         tf.close()
3337                                                  2604 
3338         for test in testrun:                     2605         for test in testrun:
                                                   >> 2606                 # add the traceevent data to the device hierarchy
                                                   >> 2607                 if(sysvals.usetraceevents):
                                                   >> 2608                         for name in test.ttemp:
                                                   >> 2609                                 for event in test.ttemp[name]:
                                                   >> 2610                                         test.data.newActionGlobal(name, event['begin'], event['end'])
                                                   >> 2611 
3339                 # add the callgraph data to t    2612                 # add the callgraph data to the device hierarchy
3340                 for pid in test.ftemp:           2613                 for pid in test.ftemp:
3341                         for cg in test.ftemp[    2614                         for cg in test.ftemp[pid]:
3342                                 if len(cg.lis    2615                                 if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0):
3343                                         conti    2616                                         continue
3344                                 if(not cg.pos    2617                                 if(not cg.postProcess()):
3345                                         id =     2618                                         id = 'task %s cpu %s' % (pid, m.group('cpu'))
3346                                         sysva    2619                                         sysvals.vprint('Sanity check failed for '+\
3347                                                  2620                                                 id+', ignoring this callback')
3348                                         conti    2621                                         continue
3349                                 callstart = c    2622                                 callstart = cg.start
3350                                 callend = cg.    2623                                 callend = cg.end
3351                                 for p in test !! 2624                                 for p in test.data.phases:
3352                                         if(te    2625                                         if(test.data.dmesg[p]['start'] <= callstart and
3353                                                  2626                                                 callstart <= test.data.dmesg[p]['end']):
3354                                                  2627                                                 list = test.data.dmesg[p]['list']
3355                                                  2628                                                 for devname in list:
3356                                                  2629                                                         dev = list[devname]
3357                                                  2630                                                         if(pid == dev['pid'] and
3358                                                  2631                                                                 callstart <= dev['start'] and
3359                                                  2632                                                                 callend >= dev['end']):
3360                                                  2633                                                                 dev['ftrace'] = cg
3361                                                  2634                                                 break
3362                                                  2635 
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                        2636 # Function: parseTraceLog
3419 # Description:                                   2637 # Description:
3420 #        Analyze an ftrace log output file ge    2638 #        Analyze an ftrace log output file generated from this app during
3421 #        the execution phase. Used when the f    2639 #        the execution phase. Used when the ftrace log is the primary data source
3422 #        and includes the suspend_resume and     2640 #        and includes the suspend_resume and device_pm_callback trace events
3423 #        The ftrace filename is taken from sy    2641 #        The ftrace filename is taken from sysvals
3424 # Output:                                        2642 # Output:
3425 #        An array of Data objects                2643 #        An array of Data objects
3426 def parseTraceLog(live=False):                   2644 def parseTraceLog(live=False):
3427         sysvals.vprint('Analyzing the ftrace     2645         sysvals.vprint('Analyzing the ftrace data (%s)...' % \
3428                 os.path.basename(sysvals.ftra    2646                 os.path.basename(sysvals.ftracefile))
3429         if(os.path.exists(sysvals.ftracefile)    2647         if(os.path.exists(sysvals.ftracefile) == False):
3430                 doError('%s does not exist' %    2648                 doError('%s does not exist' % sysvals.ftracefile)
3431         if not live:                             2649         if not live:
3432                 sysvals.setupAllKprobes()        2650                 sysvals.setupAllKprobes()
3433         ksuscalls = ['ksys_sync', 'pm_prepare !! 2651         tracewatch = []
3434         krescalls = ['pm_restore_console']    << 
3435         tracewatch = ['irq_wakeup']           << 
3436         if sysvals.usekprobes:                   2652         if sysvals.usekprobes:
3437                 tracewatch += ['sync_filesyst    2653                 tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend',
3438                         'syscore_resume', 're !! 2654                         'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON', 'CPU_OFF']
3439                         'CPU_OFF', 'acpi_susp << 
3440                                                  2655 
3441         # extract the callgraph and traceeven    2656         # extract the callgraph and traceevent data
3442         s2idle_enter = hwsus = False          !! 2657         tp = TestProps()
3443         testruns, testdata = [], []           !! 2658         testruns = []
3444         testrun, data, limbo = 0, 0, True     !! 2659         testdata = []
                                                   >> 2660         testrun = 0
                                                   >> 2661         data = 0
                                                   >> 2662         tf = sysvals.openlog(sysvals.ftracefile, 'r')
3445         phase = 'suspend_prepare'                2663         phase = 'suspend_prepare'
3446         tp, tf = loadTraceLog()               !! 2664         for line in tf:
3447         for m_time, m_proc, m_pid, m_msg, m_p !! 2665                 # remove any latent carriage returns
                                                   >> 2666                 line = line.replace('\r\n', '')
                                                   >> 2667                 # stamp and sysinfo lines
                                                   >> 2668                 if re.match(tp.stampfmt, line):
                                                   >> 2669                         tp.stamp = line
                                                   >> 2670                         continue
                                                   >> 2671                 elif re.match(tp.sysinfofmt, line):
                                                   >> 2672                         tp.sysinfo = line
                                                   >> 2673                         continue
                                                   >> 2674                 elif re.match(tp.cmdlinefmt, line):
                                                   >> 2675                         tp.cmdline = line
                                                   >> 2676                         continue
                                                   >> 2677                 # firmware line: pull out any firmware data
                                                   >> 2678                 m = re.match(sysvals.firmwarefmt, line)
                                                   >> 2679                 if(m):
                                                   >> 2680                         tp.fwdata.append((int(m.group('s')), int(m.group('r'))))
                                                   >> 2681                         continue
                                                   >> 2682                 # tracer type line: determine the trace data type
                                                   >> 2683                 m = re.match(sysvals.tracertypefmt, line)
                                                   >> 2684                 if(m):
                                                   >> 2685                         tp.setTracerType(m.group('t'))
                                                   >> 2686                         continue
                                                   >> 2687                 # device properties line
                                                   >> 2688                 if(re.match(sysvals.devpropfmt, line)):
                                                   >> 2689                         devProps(line)
                                                   >> 2690                         continue
                                                   >> 2691                 # ignore all other commented lines
                                                   >> 2692                 if line[0] == '#':
                                                   >> 2693                         continue
                                                   >> 2694                 # ftrace line: parse only valid lines
                                                   >> 2695                 m = re.match(tp.ftrace_line_fmt, line)
                                                   >> 2696                 if(not m):
                                                   >> 2697                         continue
3448                 # gather the basic message da    2698                 # gather the basic message data from the line
                                                   >> 2699                 m_time = m.group('time')
                                                   >> 2700                 m_proc = m.group('proc')
                                                   >> 2701                 m_pid = m.group('pid')
                                                   >> 2702                 m_msg = m.group('msg')
                                                   >> 2703                 if(tp.cgformat):
                                                   >> 2704                         m_param3 = m.group('dur')
                                                   >> 2705                 else:
                                                   >> 2706                         m_param3 = 'traceevent'
3449                 if(m_time and m_pid and m_msg    2707                 if(m_time and m_pid and m_msg):
3450                         t = FTraceLine(m_time    2708                         t = FTraceLine(m_time, m_msg, m_param3)
3451                         pid = int(m_pid)         2709                         pid = int(m_pid)
3452                 else:                            2710                 else:
3453                         continue                 2711                         continue
3454                 # the line should be a call,     2712                 # the line should be a call, return, or event
3455                 if(not t.fcall and not t.fret    2713                 if(not t.fcall and not t.freturn and not t.fevent):
3456                         continue                 2714                         continue
3457                 # find the start of suspend      2715                 # find the start of suspend
3458                 if(t.startMarker()):             2716                 if(t.startMarker()):
3459                         data, limbo = Data(le !! 2717                         phase = 'suspend_prepare'
                                                   >> 2718                         data = Data(len(testdata))
3460                         testdata.append(data)    2719                         testdata.append(data)
3461                         testrun = TestRun(dat    2720                         testrun = TestRun(data)
3462                         testruns.append(testr    2721                         testruns.append(testrun)
3463                         tp.parseStamp(data, s    2722                         tp.parseStamp(data, sysvals)
3464                         data.setStart(t.time, !! 2723                         data.setStart(t.time)
3465                         data.first_suspend_pr !! 2724                         data.tKernSus = t.time
3466                         phase = data.setPhase << 
3467                         continue                 2725                         continue
3468                 if(not data or limbo):        !! 2726                 if(not data):
3469                         continue                 2727                         continue
3470                 # process cpu exec line          2728                 # process cpu exec line
3471                 if t.type == 'tracing_mark_wr    2729                 if t.type == 'tracing_mark_write':
3472                         if t.name == 'CMD COM !! 2730                         m = re.match(sysvals.procexecfmt, t.name)
3473                                 data.tKernRes << 
3474                         m = re.match(tp.proce << 
3475                         if(m):                   2731                         if(m):
3476                                 parts, msg =  !! 2732                                 proclist = dict()
3477                                 m = re.match( !! 2733                                 for ps in m.group('ps').split(','):
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 =    2734                                         val = ps.split()
3490                                         if no !! 2735                                         if not val:
3491                                                  2736                                                 continue
3492                                         name     2737                                         name = val[0].replace('--', '-')
3493                                         procl    2738                                         proclist[name] = int(val[1])
3494                                 if parts == 1 !! 2739                                 data.pstl[t.time] = proclist
3495                                         data. << 
3496                                 elif parts == << 
3497                                         data. << 
3498                                         tp.mu << 
3499                                 continue         2740                                 continue
3500                 # find the end of resume         2741                 # find the end of resume
3501                 if(t.endMarker()):               2742                 if(t.endMarker()):
3502                         if data.tKernRes == 0 !! 2743                         data.setEnd(t.time)
                                                   >> 2744                         if data.tKernRes == 0.0:
3503                                 data.tKernRes    2745                                 data.tKernRes = t.time
3504                         data.handleEndMarker( !! 2746                         if data.dmesg['resume_complete']['end'] < 0:
                                                   >> 2747                                 data.dmesg['resume_complete']['end'] = t.time
                                                   >> 2748                         if sysvals.suspendmode == 'mem' and len(tp.fwdata) > data.testnumber:
                                                   >> 2749                                 data.fwSuspend, data.fwResume = tp.fwdata[data.testnumber]
                                                   >> 2750                                 if(data.tSuspended != 0 and data.tResumed != 0 and \
                                                   >> 2751                                         (data.fwSuspend > 0 or data.fwResume > 0)):
                                                   >> 2752                                         data.fwValid = True
3505                         if(not sysvals.usetra    2753                         if(not sysvals.usetracemarkers):
3506                                 # no trace ma    2754                                 # no trace markers? then quit and be sure to finish recording
3507                                 # the event w    2755                                 # the event we used to trigger resume end
3508                                 if('thaw_proc !! 2756                                 if(len(testrun.ttemp['thaw_processes']) > 0):
3509                                         # if     2757                                         # if an entry exists, assume this is its end
3510                                         testr    2758                                         testrun.ttemp['thaw_processes'][-1]['end'] = t.time
3511                         limbo = True          !! 2759                                 break
3512                         continue                 2760                         continue
3513                 # trace event processing         2761                 # trace event processing
3514                 if(t.fevent):                    2762                 if(t.fevent):
                                                   >> 2763                         if(phase == 'post_resume'):
                                                   >> 2764                                 data.setEnd(t.time)
3515                         if(t.type == 'suspend    2765                         if(t.type == 'suspend_resume'):
3516                                 # suspend_res    2766                                 # suspend_resume trace events have two types, begin and end
3517                                 if(re.match(r !! 2767                                 if(re.match('(?P<name>.*) begin$', t.name)):
3518                                         isbeg    2768                                         isbegin = True
3519                                 elif(re.match !! 2769                                 elif(re.match('(?P<name>.*) end$', t.name)):
3520                                         isbeg    2770                                         isbegin = False
3521                                 else:            2771                                 else:
3522                                         conti    2772                                         continue
3523                                 if '[' in t.n !! 2773                                 m = re.match('(?P<name>.*)\[(?P<val>[0-9]*)\] .*', t.name)
3524                                         m = r !! 2774                                 if(m):
                                                   >> 2775                                         val = m.group('val')
                                                   >> 2776                                         if val == '0':
                                                   >> 2777                                                 name = m.group('name')
                                                   >> 2778                                         else:
                                                   >> 2779                                                 name = m.group('name')+'['+val+']'
3525                                 else:            2780                                 else:
3526                                         m = r !! 2781                                         m = re.match('(?P<name>.*) .*', t.name)
3527                                 name = m.grou !! 2782                                         name = m.group('name')
3528                                 # ignore thes    2783                                 # ignore these events
3529                                 if(name.split    2784                                 if(name.split('[')[0] in tracewatch):
3530                                         conti    2785                                         continue
3531                                 # -- phase ch    2786                                 # -- phase changes --
3532                                 # start of ke    2787                                 # start of kernel suspend
3533                                 if(re.match(r !! 2788                                 if(re.match('suspend_enter\[.*', t.name)):
3534                                         if(is !! 2789                                         if(isbegin and data.start == data.tKernSus):
                                                   >> 2790                                                 data.dmesg[phase]['start'] = t.time
3535                                                  2791                                                 data.tKernSus = t.time
3536                                         conti    2792                                         continue
3537                                 # suspend_pre    2793                                 # suspend_prepare start
3538                                 elif(re.match !! 2794                                 elif(re.match('dpm_prepare\[.*', t.name)):
3539                                         if is !! 2795                                         phase = 'suspend_prepare'
3540                                               !! 2796                                         if(not isbegin):
3541                                               !! 2797                                                 data.dmesg[phase]['end'] = t.time
3542                                               !! 2798                                                 if data.dmesg[phase]['start'] < 0:
3543                                               !! 2799                                                         data.dmesg[phase]['start'] = data.start
3544                                         phase << 
3545                                         conti    2800                                         continue
3546                                 # suspend sta    2801                                 # suspend start
3547                                 elif(re.match !! 2802                                 elif(re.match('dpm_suspend\[.*', t.name)):
3548                                         phase !! 2803                                         phase = 'suspend'
                                                   >> 2804                                         data.setPhase(phase, t.time, isbegin)
3549                                         conti    2805                                         continue
3550                                 # suspend_lat    2806                                 # suspend_late start
3551                                 elif(re.match !! 2807                                 elif(re.match('dpm_suspend_late\[.*', t.name)):
3552                                         phase !! 2808                                         phase = 'suspend_late'
                                                   >> 2809                                         data.setPhase(phase, t.time, isbegin)
3553                                         conti    2810                                         continue
3554                                 # suspend_noi    2811                                 # suspend_noirq start
3555                                 elif(re.match !! 2812                                 elif(re.match('dpm_suspend_noirq\[.*', t.name)):
3556                                         phase !! 2813                                         if data.phaseCollision('suspend_noirq', isbegin, line):
                                                   >> 2814                                                 continue
                                                   >> 2815                                         phase = 'suspend_noirq'
                                                   >> 2816                                         data.setPhase(phase, t.time, isbegin)
                                                   >> 2817                                         if(not isbegin):
                                                   >> 2818                                                 phase = 'suspend_machine'
                                                   >> 2819                                                 data.dmesg[phase]['start'] = t.time
3557                                         conti    2820                                         continue
3558                                 # suspend_mac    2821                                 # suspend_machine/resume_machine
3559                                 elif(re.match !! 2822                                 elif(re.match('machine_suspend\[.*', t.name)):
3560                                         lp =  << 
3561                                         if(is    2823                                         if(isbegin):
3562                                               !! 2824                                                 phase = 'suspend_machine'
3563                                               !! 2825                                                 data.dmesg[phase]['end'] = t.time
3564                                               !! 2826                                                 data.tSuspended = t.time
3565                                               << 
3566                                               << 
3567                                               << 
3568                                               << 
3569                                               << 
3570                                               << 
3571                                               << 
3572                                               << 
3573                                               << 
3574                                               << 
3575                                               << 
3576                                               << 
3577                                               << 
3578                                               << 
3579                                         else:    2827                                         else:
3580                                               !! 2828                                                 if(sysvals.suspendmode in ['mem', 'disk'] and not tp.S0i3):
3581                                               !! 2829                                                         data.dmesg['suspend_machine']['end'] = t.time
3582                                               << 
3583                                               << 
3584                                               << 
3585                                               << 
3586                                               << 
3587                                               << 
3588                                                  2830                                                         data.tSuspended = t.time
                                                   >> 2831                                                 phase = 'resume_machine'
                                                   >> 2832                                                 data.dmesg[phase]['start'] = t.time
3589                                                  2833                                                 data.tResumed = t.time
                                                   >> 2834                                                 data.tLow = data.tResumed - data.tSuspended
                                                   >> 2835                                         continue
                                                   >> 2836                                 # acpi_suspend
                                                   >> 2837                                 elif(re.match('acpi_suspend\[.*', t.name)):
                                                   >> 2838                                         # acpi_suspend[0] S0i3
                                                   >> 2839                                         if(re.match('acpi_suspend\[0\] begin', t.name)):
                                                   >> 2840                                                 if(sysvals.suspendmode == 'mem'):
                                                   >> 2841                                                         tp.S0i3 = True
                                                   >> 2842                                                         data.dmesg['suspend_machine']['end'] = t.time
                                                   >> 2843                                                         data.tSuspended = t.time
3590                                         conti    2844                                         continue
3591                                 # resume_noir    2845                                 # resume_noirq start
3592                                 elif(re.match !! 2846                                 elif(re.match('dpm_resume_noirq\[.*', t.name)):
3593                                         phase !! 2847                                         if data.phaseCollision('resume_noirq', isbegin, line):
                                                   >> 2848                                                 continue
                                                   >> 2849                                         phase = 'resume_noirq'
                                                   >> 2850                                         data.setPhase(phase, t.time, isbegin)
                                                   >> 2851                                         if(isbegin):
                                                   >> 2852                                                 data.dmesg['resume_machine']['end'] = t.time
3594                                         conti    2853                                         continue
3595                                 # resume_earl    2854                                 # resume_early start
3596                                 elif(re.match !! 2855                                 elif(re.match('dpm_resume_early\[.*', t.name)):
3597                                         phase !! 2856                                         phase = 'resume_early'
                                                   >> 2857                                         data.setPhase(phase, t.time, isbegin)
3598                                         conti    2858                                         continue
3599                                 # resume star    2859                                 # resume start
3600                                 elif(re.match !! 2860                                 elif(re.match('dpm_resume\[.*', t.name)):
3601                                         phase !! 2861                                         phase = 'resume'
                                                   >> 2862                                         data.setPhase(phase, t.time, isbegin)
3602                                         conti    2863                                         continue
3603                                 # resume comp    2864                                 # resume complete start
3604                                 elif(re.match !! 2865                                 elif(re.match('dpm_complete\[.*', t.name)):
3605                                         phase !! 2866                                         phase = 'resume_complete'
                                                   >> 2867                                         if(isbegin):
                                                   >> 2868                                                 data.dmesg[phase]['start'] = t.time
3606                                         conti    2869                                         continue
3607                                 # skip trace     2870                                 # skip trace events inside devices calls
3608                                 if(not data.i    2871                                 if(not data.isTraceEventOutsideDeviceCalls(pid, t.time)):
3609                                         conti    2872                                         continue
3610                                 # global even    2873                                 # global events (outside device calls) are graphed
3611                                 if(name not i    2874                                 if(name not in testrun.ttemp):
3612                                         testr    2875                                         testrun.ttemp[name] = []
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):     2876                                 if(isbegin):
3627                                         # cre    2877                                         # create a new list entry
3628                                         testr    2878                                         testrun.ttemp[name].append(\
3629                                                  2879                                                 {'begin': t.time, 'end': t.time, 'pid': pid})
3630                                 else:            2880                                 else:
3631                                         if(le    2881                                         if(len(testrun.ttemp[name]) > 0):
3632                                                  2882                                                 # if an entry exists, assume this is its end
3633                                                  2883                                                 testrun.ttemp[name][-1]['end'] = t.time
                                                   >> 2884                                         elif(phase == 'post_resume'):
                                                   >> 2885                                                 # post resume events can just have ends
                                                   >> 2886                                                 testrun.ttemp[name].append({
                                                   >> 2887                                                         'begin': data.dmesg[phase]['start'],
                                                   >> 2888                                                         'end': t.time})
3634                         # device callback sta    2889                         # device callback start
3635                         elif(t.type == 'devic    2890                         elif(t.type == 'device_pm_callback_start'):
3636                                 if phase not  !! 2891                                 m = re.match('(?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*',\
3637                                         conti << 
3638                                 m = re.match( << 
3639                                         t.nam    2892                                         t.name);
3640                                 if(not m):       2893                                 if(not m):
3641                                         conti    2894                                         continue
3642                                 drv = m.group    2895                                 drv = m.group('drv')
3643                                 n = m.group('    2896                                 n = m.group('d')
3644                                 p = m.group('    2897                                 p = m.group('p')
3645                                 if(n and p):     2898                                 if(n and p):
3646                                         data.    2899                                         data.newAction(phase, n, pid, p, t.time, -1, drv)
3647                                         if pi    2900                                         if pid not in data.devpids:
3648                                                  2901                                                 data.devpids.append(pid)
3649                         # device callback fin    2902                         # device callback finish
3650                         elif(t.type == 'devic    2903                         elif(t.type == 'device_pm_callback_end'):
3651                                 if phase not  !! 2904                                 m = re.match('(?P<drv>.*) (?P<d>.*), err.*', t.name);
3652                                         conti << 
3653                                 m = re.match( << 
3654                                 if(not m):       2905                                 if(not m):
3655                                         conti    2906                                         continue
3656                                 n = m.group('    2907                                 n = m.group('d')
3657                                 dev = data.fi !! 2908                                 list = data.dmesg[phase]['list']
3658                                 if dev:       !! 2909                                 if(n in list):
                                                   >> 2910                                         dev = list[n]
3659                                         dev['    2911                                         dev['length'] = t.time - dev['start']
3660                                         dev['    2912                                         dev['end'] = t.time
3661                 # kprobe event processing        2913                 # kprobe event processing
3662                 elif(t.fkprobe):                 2914                 elif(t.fkprobe):
3663                         kprobename = t.type      2915                         kprobename = t.type
3664                         kprobedata = t.name      2916                         kprobedata = t.name
3665                         key = (kprobename, pi    2917                         key = (kprobename, pid)
3666                         # displayname is gene    2918                         # displayname is generated from kprobe data
3667                         displayname = ''         2919                         displayname = ''
3668                         if(t.fcall):             2920                         if(t.fcall):
3669                                 displayname =    2921                                 displayname = sysvals.kprobeDisplayName(kprobename, kprobedata)
3670                                 if not displa    2922                                 if not displayname:
3671                                         conti    2923                                         continue
3672                                 if(key not in    2924                                 if(key not in tp.ktemp):
3673                                         tp.kt    2925                                         tp.ktemp[key] = []
3674                                 tp.ktemp[key]    2926                                 tp.ktemp[key].append({
3675                                         'pid'    2927                                         'pid': pid,
3676                                         'begi    2928                                         'begin': t.time,
3677                                         'end' !! 2929                                         'end': t.time,
3678                                         'name    2930                                         'name': displayname,
3679                                         'cdat    2931                                         'cdata': kprobedata,
3680                                         'proc    2932                                         'proc': m_proc,
3681                                 })               2933                                 })
3682                                 # start of ke << 
3683                                 if(data.tKern << 
3684                                         and k << 
3685                                         data. << 
3686                         elif(t.freturn):         2934                         elif(t.freturn):
3687                                 if(key not in    2935                                 if(key not in tp.ktemp) or len(tp.ktemp[key]) < 1:
3688                                         conti    2936                                         continue
3689                                 e = next((x f !! 2937                                 e = tp.ktemp[key][-1]
3690                                 if not e:     !! 2938                                 if e['begin'] < 0.0 or t.time - e['begin'] < 0.000001:
3691                                         conti << 
3692                                 if (t.time -  << 
3693                                         tp.kt    2939                                         tp.ktemp[key].pop()
3694                                         conti !! 2940                                 else:
3695                                 e['end'] = t. !! 2941                                         e['end'] = t.time
3696                                 e['rdata'] =  !! 2942                                         e['rdata'] = kprobedata
3697                                 # end of kern    2943                                 # end of kernel resume
3698                                 if(phase != ' !! 2944                                 if(kprobename == 'pm_notifier_call_chain' or \
3699                                         if ph !! 2945                                         kprobename == 'pm_restore_console'):
3700                                               !! 2946                                         data.dmesg[phase]['end'] = t.time
3701                                         data.    2947                                         data.tKernRes = t.time
3702                                                  2948 
3703                 # callgraph processing           2949                 # callgraph processing
3704                 elif sysvals.usecallgraph:       2950                 elif sysvals.usecallgraph:
3705                         # create a callgraph     2951                         # create a callgraph object for the data
3706                         key = (m_proc, pid)      2952                         key = (m_proc, pid)
3707                         if(key not in testrun    2953                         if(key not in testrun.ftemp):
3708                                 testrun.ftemp    2954                                 testrun.ftemp[key] = []
3709                                 testrun.ftemp    2955                                 testrun.ftemp[key].append(FTraceCallGraph(pid, sysvals))
3710                         # when the call is fi    2956                         # when the call is finished, see which device matches it
3711                         cg = testrun.ftemp[ke    2957                         cg = testrun.ftemp[key][-1]
3712                         res = cg.addLine(t)      2958                         res = cg.addLine(t)
3713                         if(res != 0):            2959                         if(res != 0):
3714                                 testrun.ftemp    2960                                 testrun.ftemp[key].append(FTraceCallGraph(pid, sysvals))
3715                         if(res == -1):           2961                         if(res == -1):
3716                                 testrun.ftemp    2962                                 testrun.ftemp[key][-1].addLine(t)
3717         if len(testdata) < 1:                 !! 2963         tf.close()
3718                 sysvals.vprint('WARNING: ftra << 
3719         if data and not data.devicegroups:    << 
3720                 sysvals.vprint('WARNING: ftra << 
3721                 data.handleEndMarker(t.time,  << 
3722                                                  2964 
3723         if sysvals.suspendmode == 'command':     2965         if sysvals.suspendmode == 'command':
3724                 for test in testruns:            2966                 for test in testruns:
3725                         for p in test.data.so !! 2967                         for p in test.data.phases:
3726                                 if p == 'susp    2968                                 if p == 'suspend_prepare':
3727                                         test.    2969                                         test.data.dmesg[p]['start'] = test.data.start
3728                                         test.    2970                                         test.data.dmesg[p]['end'] = test.data.end
3729                                 else:            2971                                 else:
3730                                         test.    2972                                         test.data.dmesg[p]['start'] = test.data.end
3731                                         test.    2973                                         test.data.dmesg[p]['end'] = test.data.end
3732                         test.data.tSuspended     2974                         test.data.tSuspended = test.data.end
3733                         test.data.tResumed =     2975                         test.data.tResumed = test.data.end
                                                   >> 2976                         test.data.tLow = 0
3734                         test.data.fwValid = F    2977                         test.data.fwValid = False
3735                                                  2978 
3736         # dev source and procmon events can b    2979         # dev source and procmon events can be unreadable with mixed phase height
3737         if sysvals.usedevsrc or sysvals.usepr    2980         if sysvals.usedevsrc or sysvals.useprocmon:
3738                 sysvals.mixedphaseheight = Fa    2981                 sysvals.mixedphaseheight = False
3739                                                  2982 
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)):           2983         for i in range(len(testruns)):
3749                 test = testruns[i]               2984                 test = testruns[i]
3750                 data = test.data                 2985                 data = test.data
3751                 # find the total time range f    2986                 # find the total time range for this test (begin, end)
3752                 tlb, tle = data.start, data.e    2987                 tlb, tle = data.start, data.end
3753                 if i < len(testruns) - 1:        2988                 if i < len(testruns) - 1:
3754                         tle = testruns[i+1].d    2989                         tle = testruns[i+1].data.start
3755                 # add the process usage data     2990                 # add the process usage data to the timeline
3756                 if sysvals.useprocmon:           2991                 if sysvals.useprocmon:
3757                         data.createProcessUsa    2992                         data.createProcessUsageEvents()
3758                 # add the traceevent data to     2993                 # add the traceevent data to the device hierarchy
3759                 if(sysvals.usetraceevents):      2994                 if(sysvals.usetraceevents):
3760                         # add actual trace fu    2995                         # add actual trace funcs
3761                         for name in sorted(te !! 2996                         for name in test.ttemp:
3762                                 for event in     2997                                 for event in test.ttemp[name]:
3763                                         if ev !! 2998                                         data.newActionGlobal(name, event['begin'], event['end'], event['pid'])
3764                                               << 
3765                                         title << 
3766                                         if na << 
3767                                               << 
3768                                         data. << 
3769                         # add the kprobe base    2999                         # add the kprobe based virtual tracefuncs as actual devices
3770                         for key in sorted(tp. !! 3000                         for key in tp.ktemp:
3771                                 name, pid = k    3001                                 name, pid = key
3772                                 if name not i    3002                                 if name not in sysvals.tracefuncs:
3773                                         conti    3003                                         continue
3774                                 if pid not in << 
3775                                         data. << 
3776                                 for e in tp.k    3004                                 for e in tp.ktemp[key]:
3777                                         kb, k    3005                                         kb, ke = e['begin'], e['end']
3778                                         if ke !! 3006                                         if kb == ke or tlb > kb or tle <= kb:
3779                                                  3007                                                 continue
3780                                         color    3008                                         color = sysvals.kprobeColor(name)
3781                                         data.    3009                                         data.newActionGlobal(e['name'], kb, ke, pid, color)
3782                         # add config base kpr    3010                         # add config base kprobes and dev kprobes
3783                         if sysvals.usedevsrc:    3011                         if sysvals.usedevsrc:
3784                                 for key in so !! 3012                                 for key in tp.ktemp:
3785                                         name,    3013                                         name, pid = key
3786                                         if na    3014                                         if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs:
3787                                                  3015                                                 continue
3788                                         for e    3016                                         for e in tp.ktemp[key]:
3789                                                  3017                                                 kb, ke = e['begin'], e['end']
3790                                               !! 3018                                                 if kb == ke or tlb > kb or tle <= kb:
3791                                                  3019                                                         continue
3792                                                  3020                                                 data.addDeviceFunctionCall(e['name'], name, e['proc'], pid, kb,
3793                                                  3021                                                         ke, e['cdata'], e['rdata'])
3794                 if sysvals.usecallgraph:         3022                 if sysvals.usecallgraph:
3795                         # add the callgraph d    3023                         # add the callgraph data to the device hierarchy
3796                         sortlist = dict()        3024                         sortlist = dict()
3797                         for key in sorted(tes !! 3025                         for key in test.ftemp:
3798                                 proc, pid = k    3026                                 proc, pid = key
3799                                 for cg in tes    3027                                 for cg in test.ftemp[key]:
3800                                         if le    3028                                         if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0):
3801                                                  3029                                                 continue
3802                                         if(no    3030                                         if(not cg.postProcess()):
3803                                                  3031                                                 id = 'task %s' % (pid)
3804                                                  3032                                                 sysvals.vprint('Sanity check failed for '+\
3805                                                  3033                                                         id+', ignoring this callback')
3806                                                  3034                                                 continue
3807                                         # mat    3035                                         # match cg data to devices
3808                                         devna    3036                                         devname = ''
3809                                         if sy    3037                                         if sysvals.suspendmode != 'command':
3810                                                  3038                                                 devname = cg.deviceMatch(pid, data)
3811                                         if no    3039                                         if not devname:
3812                                                  3040                                                 sortkey = '%f%f%d' % (cg.start, cg.end, pid)
3813                                                  3041                                                 sortlist[sortkey] = cg
3814                                         elif  !! 3042                                         elif len(cg.list) > 1000000:
3815                                               !! 3043                                                 print 'WARNING: the callgraph for %s is massive (%d lines)' %\
3816                                               !! 3044                                                         (devname, len(cg.list))
3817                         # create blocks for o    3045                         # create blocks for orphan cg data
3818                         for sortkey in sorted    3046                         for sortkey in sorted(sortlist):
3819                                 cg = sortlist    3047                                 cg = sortlist[sortkey]
3820                                 name = cg.nam    3048                                 name = cg.name
3821                                 if sysvals.is    3049                                 if sysvals.isCallgraphFunc(name):
3822                                         sysva    3050                                         sysvals.vprint('Callgraph found for task %d: %.3fms, %s' % (cg.pid, (cg.end - cg.start)*1000, name))
3823                                         cg.ne    3051                                         cg.newActionFromFunction(data)
3824         if sysvals.suspendmode == 'command':     3052         if sysvals.suspendmode == 'command':
3825                 return (testdata, '')            3053                 return (testdata, '')
3826                                                  3054 
3827         # fill in any missing phases             3055         # fill in any missing phases
3828         error = []                               3056         error = []
3829         for data in testdata:                    3057         for data in testdata:
3830                 tn = '' if len(testdata) == 1    3058                 tn = '' if len(testdata) == 1 else ('%d' % (data.testnumber + 1))
3831                 terr = ''                        3059                 terr = ''
3832                 phasedef = data.phasedef      !! 3060                 lp = data.phases[0]
3833                 lp = 'suspend_prepare'        !! 3061                 for p in data.phases:
3834                 for p in sorted(phasedef, key !! 3062                         if(data.dmesg[p]['start'] < 0 and data.dmesg[p]['end'] < 0):
3835                         if p not in data.dmes << 
3836                                 if not terr:     3063                                 if not terr:
3837                                         ph =  !! 3064                                         print 'TEST%s FAILED: %s failed in %s phase' % (tn, sysvals.suspendmode, lp)
3838                                         if p  !! 3065                                         terr = '%s%s failed in %s phase' % (sysvals.suspendmode, tn, lp)
3839                                               << 
3840                                               << 
3841                                               << 
3842                                               << 
3843                                         else: << 
3844                                               << 
3845                                         pprin << 
3846                                         error    3066                                         error.append(terr)
3847                                         if da << 
3848                                               << 
3849                                         if da << 
3850                                               << 
3851                                         data. << 
3852                                 sysvals.vprin    3067                                 sysvals.vprint('WARNING: phase "%s" is missing!' % p)
                                                   >> 3068                         if(data.dmesg[p]['start'] < 0):
                                                   >> 3069                                 data.dmesg[p]['start'] = data.dmesg[lp]['end']
                                                   >> 3070                                 if(p == 'resume_machine'):
                                                   >> 3071                                         data.tSuspended = data.dmesg[lp]['end']
                                                   >> 3072                                         data.tResumed = data.dmesg[lp]['end']
                                                   >> 3073                                         data.tLow = 0
                                                   >> 3074                         if(data.dmesg[p]['end'] < 0):
                                                   >> 3075                                 data.dmesg[p]['end'] = data.dmesg[p]['start']
                                                   >> 3076                         if(p != lp and not ('machine' in p and 'machine' in lp)):
                                                   >> 3077                                 data.dmesg[lp]['end'] = data.dmesg[p]['start']
3853                         lp = p                   3078                         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                                                  3079 
3867                 if(len(sysvals.devicefilter)     3080                 if(len(sysvals.devicefilter) > 0):
3868                         data.deviceFilter(sys    3081                         data.deviceFilter(sysvals.devicefilter)
3869                 data.fixupInitcallsThatDidntR    3082                 data.fixupInitcallsThatDidntReturn()
3870                 if sysvals.usedevsrc:            3083                 if sysvals.usedevsrc:
3871                         data.optimizeDevSrc()    3084                         data.optimizeDevSrc()
3872                                                  3085 
3873         # x2: merge any overlapping devices b    3086         # x2: merge any overlapping devices between test runs
3874         if sysvals.usedevsrc and len(testdata    3087         if sysvals.usedevsrc and len(testdata) > 1:
3875                 tc = len(testdata)               3088                 tc = len(testdata)
3876                 for i in range(tc - 1):          3089                 for i in range(tc - 1):
3877                         devlist = testdata[i]    3090                         devlist = testdata[i].overflowDevices()
3878                         for j in range(i + 1,    3091                         for j in range(i + 1, tc):
3879                                 testdata[j].m    3092                                 testdata[j].mergeOverlapDevices(devlist)
3880                 testdata[0].stitchTouchingThr    3093                 testdata[0].stitchTouchingThreads(testdata[1:])
3881         return (testdata, ', '.join(error))      3094         return (testdata, ', '.join(error))
3882                                                  3095 
3883 # Function: loadKernelLog                        3096 # Function: loadKernelLog
3884 # Description:                                   3097 # Description:
                                                   >> 3098 #        [deprecated for kernel 3.15.0 or newer]
3885 #        load the dmesg file into memory and     3099 #        load the dmesg file into memory and fix up any ordering issues
                                                   >> 3100 #        The dmesg filename is taken from sysvals
3886 # Output:                                        3101 # Output:
3887 #        An array of empty Data objects with     3102 #        An array of empty Data objects with only their dmesgtext attributes set
3888 def loadKernelLog():                             3103 def loadKernelLog():
3889         sysvals.vprint('Analyzing the dmesg d    3104         sysvals.vprint('Analyzing the dmesg data (%s)...' % \
3890                 os.path.basename(sysvals.dmes    3105                 os.path.basename(sysvals.dmesgfile))
3891         if(os.path.exists(sysvals.dmesgfile)     3106         if(os.path.exists(sysvals.dmesgfile) == False):
3892                 doError('%s does not exist' %    3107                 doError('%s does not exist' % sysvals.dmesgfile)
3893                                                  3108 
3894         # there can be multiple test runs in     3109         # there can be multiple test runs in a single file
3895         tp = TestProps()                         3110         tp = TestProps()
3896         tp.stamp = datetime.now().strftime('#    3111         tp.stamp = datetime.now().strftime('# suspend-%m%d%y-%H%M%S localhost mem unknown')
3897         testruns = []                            3112         testruns = []
3898         data = 0                                 3113         data = 0
3899         lf = sysvals.openlog(sysvals.dmesgfil    3114         lf = sysvals.openlog(sysvals.dmesgfile, 'r')
3900         for line in lf:                          3115         for line in lf:
3901                 line = line.replace('\r\n', '    3116                 line = line.replace('\r\n', '')
3902                 idx = line.find('[')             3117                 idx = line.find('[')
3903                 if idx > 1:                      3118                 if idx > 1:
3904                         line = line[idx:]        3119                         line = line[idx:]
3905                 if tp.stampInfo(line, sysvals !! 3120                 # grab the stamp and sysinfo
                                                   >> 3121                 if re.match(tp.stampfmt, line):
                                                   >> 3122                         tp.stamp = line
                                                   >> 3123                         continue
                                                   >> 3124                 elif re.match(tp.sysinfofmt, line):
                                                   >> 3125                         tp.sysinfo = line
                                                   >> 3126                         continue
                                                   >> 3127                 elif re.match(tp.cmdlinefmt, line):
                                                   >> 3128                         tp.cmdline = line
                                                   >> 3129                         continue
                                                   >> 3130                 m = re.match(sysvals.firmwarefmt, line)
                                                   >> 3131                 if(m):
                                                   >> 3132                         tp.fwdata.append((int(m.group('s')), int(m.group('r'))))
3906                         continue                 3133                         continue
3907                 m = re.match(r'[ \t]*(\[ *)(? !! 3134                 m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
3908                 if(not m):                       3135                 if(not m):
3909                         continue                 3136                         continue
3910                 msg = m.group("msg")             3137                 msg = m.group("msg")
3911                 if re.match(r'PM: Syncing fil !! 3138                 if(re.match('PM: Syncing filesystems.*', msg)):
3912                         re.match(r'PM: suspen << 
3913                         if(data):                3139                         if(data):
3914                                 testruns.appe    3140                                 testruns.append(data)
3915                         data = Data(len(testr    3141                         data = Data(len(testruns))
3916                         tp.parseStamp(data, s    3142                         tp.parseStamp(data, sysvals)
                                                   >> 3143                         if len(tp.fwdata) > data.testnumber:
                                                   >> 3144                                 data.fwSuspend, data.fwResume = tp.fwdata[data.testnumber]
                                                   >> 3145                                 if(data.fwSuspend > 0 or data.fwResume > 0):
                                                   >> 3146                                         data.fwValid = True
3917                 if(not data):                    3147                 if(not data):
3918                         continue                 3148                         continue
3919                 m = re.match(r'.* *(?P<k>[0-9 !! 3149                 m = re.match('.* *(?P<k>[0-9]\.[0-9]{2}\.[0-9]-.*) .*', msg)
3920                 if(m):                           3150                 if(m):
3921                         sysvals.stamp['kernel    3151                         sysvals.stamp['kernel'] = m.group('k')
3922                 m = re.match(r'PM: Preparing  !! 3152                 m = re.match('PM: Preparing system for (?P<m>.*) sleep', msg)
3923                 if not m:                     !! 3153                 if(m):
3924                         m = re.match(r'PM: Pr << 
3925                 if m:                         << 
3926                         sysvals.stamp['mode']    3154                         sysvals.stamp['mode'] = sysvals.suspendmode = m.group('m')
3927                 data.dmesgtext.append(line)      3155                 data.dmesgtext.append(line)
3928         lf.close()                               3156         lf.close()
3929                                                  3157 
3930         if sysvals.suspendmode == 's2idle':   << 
3931                 sysvals.suspendmode = 'freeze << 
3932         elif sysvals.suspendmode == 'deep':   << 
3933                 sysvals.suspendmode = 'mem'   << 
3934         if data:                                 3158         if data:
3935                 testruns.append(data)            3159                 testruns.append(data)
3936         if len(testruns) < 1:                    3160         if len(testruns) < 1:
3937                 doError('dmesg log has no sus !! 3161                 print('ERROR: dmesg log has no suspend/resume data: %s' \
3938                         % sysvals.dmesgfile)     3162                         % sysvals.dmesgfile)
3939                                                  3163 
3940         # fix lines with same timestamp/funct    3164         # fix lines with same timestamp/function with the call and return swapped
3941         for data in testruns:                    3165         for data in testruns:
3942                 last = ''                        3166                 last = ''
3943                 for line in data.dmesgtext:      3167                 for line in data.dmesgtext:
3944                         ct, cf, n, p = data.i !! 3168                         mc = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) calling  '+\
3945                         rt, rf, l = data.init !! 3169                                 '(?P<f>.*)\+ @ .*, parent: .*', line)
3946                         if ct and rt and ct = !! 3170                         mr = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) call '+\
                                                   >> 3171                                 '(?P<f>.*)\+ returned .* after (?P<dt>.*) usecs', last)
                                                   >> 3172                         if(mc and mr and (mc.group('t') == mr.group('t')) and
                                                   >> 3173                                 (mc.group('f') == mr.group('f'))):
3947                                 i = data.dmes    3174                                 i = data.dmesgtext.index(last)
3948                                 j = data.dmes    3175                                 j = data.dmesgtext.index(line)
3949                                 data.dmesgtex    3176                                 data.dmesgtext[i] = line
3950                                 data.dmesgtex    3177                                 data.dmesgtext[j] = last
3951                         last = line              3178                         last = line
3952         return testruns                          3179         return testruns
3953                                                  3180 
3954 # Function: parseKernelLog                       3181 # Function: parseKernelLog
3955 # Description:                                   3182 # Description:
                                                   >> 3183 #        [deprecated for kernel 3.15.0 or newer]
3956 #        Analyse a dmesg log output file gene    3184 #        Analyse a dmesg log output file generated from this app during
3957 #        the execution phase. Create a set of    3185 #        the execution phase. Create a set of device structures in memory
3958 #        for subsequent formatting in the htm    3186 #        for subsequent formatting in the html output file
3959 #        This call is only for legacy support    3187 #        This call is only for legacy support on kernels where the ftrace
3960 #        data lacks the suspend_resume or dev    3188 #        data lacks the suspend_resume or device_pm_callbacks trace events.
3961 # Arguments:                                     3189 # Arguments:
3962 #        data: an empty Data object (with dme    3190 #        data: an empty Data object (with dmesgtext) obtained from loadKernelLog
3963 # Output:                                        3191 # Output:
3964 #        The filled Data object                  3192 #        The filled Data object
3965 def parseKernelLog(data):                        3193 def parseKernelLog(data):
3966         phase = 'suspend_runtime'                3194         phase = 'suspend_runtime'
3967                                                  3195 
3968         if(data.fwValid):                        3196         if(data.fwValid):
3969                 sysvals.vprint('Firmware Susp    3197                 sysvals.vprint('Firmware Suspend = %u ns, Firmware Resume = %u ns' % \
3970                         (data.fwSuspend, data    3198                         (data.fwSuspend, data.fwResume))
3971                                                  3199 
3972         # dmesg phase match table                3200         # dmesg phase match table
3973         dm = {                                   3201         dm = {
3974                 'suspend_prepare': ['PM: Sync !! 3202                 'suspend_prepare': 'PM: Syncing filesystems.*',
3975                         'suspend': ['PM: Ente !! 3203                         'suspend': 'PM: Entering [a-z]* sleep.*',
3976                                     'PM: Susp !! 3204                    'suspend_late': 'PM: suspend of devices complete after.*',
3977                    'suspend_late': ['PM: susp !! 3205                   'suspend_noirq': 'PM: late suspend of devices complete after.*',
3978                                               !! 3206                 'suspend_machine': 'PM: noirq suspend of devices complete after.*',
3979                   'suspend_noirq': ['PM: late !! 3207                  'resume_machine': 'ACPI: Low-level resume complete.*',
3980                                               !! 3208                    'resume_noirq': 'ACPI: Waking up from system sleep state.*',
3981                 'suspend_machine': ['PM: susp !! 3209                    'resume_early': 'PM: noirq resume of devices complete after.*',
3982                                               !! 3210                          'resume': 'PM: early resume of devices complete after.*',
3983                                               !! 3211                 'resume_complete': 'PM: resume of devices complete after.*',
3984                  'resume_machine': ['[PM: ]*T !! 3212                     'post_resume': '.*Restarting tasks \.\.\..*',
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         }                                        3213         }
                                                   >> 3214         if(sysvals.suspendmode == 'standby'):
                                                   >> 3215                 dm['resume_machine'] = 'PM: Restoring platform NVS memory'
                                                   >> 3216         elif(sysvals.suspendmode == 'disk'):
                                                   >> 3217                 dm['suspend_late'] = 'PM: freeze of devices complete after.*'
                                                   >> 3218                 dm['suspend_noirq'] = 'PM: late freeze of devices complete after.*'
                                                   >> 3219                 dm['suspend_machine'] = 'PM: noirq freeze of devices complete after.*'
                                                   >> 3220                 dm['resume_machine'] = 'PM: Restoring platform NVS memory'
                                                   >> 3221                 dm['resume_early'] = 'PM: noirq restore of devices complete after.*'
                                                   >> 3222                 dm['resume'] = 'PM: early restore of devices complete after.*'
                                                   >> 3223                 dm['resume_complete'] = 'PM: restore of devices complete after.*'
                                                   >> 3224         elif(sysvals.suspendmode == 'freeze'):
                                                   >> 3225                 dm['resume_machine'] = 'ACPI: resume from mwait'
3998                                                  3226 
3999         # action table (expected events that     3227         # action table (expected events that occur and show up in dmesg)
4000         at = {                                   3228         at = {
4001                 'sync_filesystems': {            3229                 'sync_filesystems': {
4002                         'smsg': '.*[Ff]+ilesy !! 3230                         'smsg': 'PM: Syncing filesystems.*',
4003                         'emsg': 'PM: Preparin !! 3231                         'emsg': 'PM: Preparing system for mem sleep.*' },
4004                 'freeze_user_processes': {       3232                 'freeze_user_processes': {
4005                         'smsg': 'Freezing use !! 3233                         'smsg': 'Freezing user space processes .*',
4006                         'emsg': 'Freezing rem    3234                         'emsg': 'Freezing remaining freezable tasks.*' },
4007                 'freeze_tasks': {                3235                 'freeze_tasks': {
4008                         'smsg': 'Freezing rem    3236                         'smsg': 'Freezing remaining freezable tasks.*',
4009                         'emsg': 'PM: Suspendi !! 3237                         'emsg': 'PM: Entering (?P<mode>[a-z,A-Z]*) sleep.*' },
4010                 'ACPI prepare': {                3238                 'ACPI prepare': {
4011                         'smsg': 'ACPI: Prepar    3239                         'smsg': 'ACPI: Preparing to enter system sleep state.*',
4012                         'emsg': 'PM: Saving p    3240                         'emsg': 'PM: Saving platform NVS memory.*' },
4013                 'PM vns': {                      3241                 'PM vns': {
4014                         'smsg': 'PM: Saving p    3242                         'smsg': 'PM: Saving platform NVS memory.*',
4015                         'emsg': 'Disabling no    3243                         'emsg': 'Disabling non-boot CPUs .*' },
4016         }                                        3244         }
4017                                                  3245 
4018         t0 = -1.0                                3246         t0 = -1.0
4019         cpu_start = -1.0                         3247         cpu_start = -1.0
4020         prevktime = -1.0                         3248         prevktime = -1.0
4021         actions = dict()                         3249         actions = dict()
4022         for line in data.dmesgtext:              3250         for line in data.dmesgtext:
4023                 # parse each dmesg line into     3251                 # parse each dmesg line into the time and message
4024                 m = re.match(r'[ \t]*(\[ *)(? !! 3252                 m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
4025                 if(m):                           3253                 if(m):
4026                         val = m.group('ktime'    3254                         val = m.group('ktime')
4027                         try:                     3255                         try:
4028                                 ktime = float    3256                                 ktime = float(val)
4029                         except:                  3257                         except:
4030                                 continue         3258                                 continue
4031                         msg = m.group('msg')     3259                         msg = m.group('msg')
4032                         # initialize data sta    3260                         # initialize data start to first line time
4033                         if t0 < 0:               3261                         if t0 < 0:
4034                                 data.setStart    3262                                 data.setStart(ktime)
4035                                 t0 = ktime       3263                                 t0 = ktime
4036                 else:                            3264                 else:
4037                         continue                 3265                         continue
4038                                                  3266 
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    3267                 # hack for determining resume_machine end for freeze
4049                 if(not sysvals.usetraceevents    3268                 if(not sysvals.usetraceevents and sysvals.suspendmode == 'freeze' \
4050                         and phase == 'resume_    3269                         and phase == 'resume_machine' and \
4051                         data.initcall_debug_c !! 3270                         re.match('calling  (?P<f>.*)\+ @ .*, parent: .*', msg)):
4052                         data.setPhase(phase,  !! 3271                         data.dmesg['resume_machine']['end'] = ktime
4053                         phase = 'resume_noirq    3272                         phase = 'resume_noirq'
4054                         data.setPhase(phase,  !! 3273                         data.dmesg[phase]['start'] = ktime
4055                                                  3274 
4056                 if phasechange:               !! 3275                 # suspend start
4057                         if phase == 'suspend_ !! 3276                 if(re.match(dm['suspend_prepare'], msg)):
4058                                 data.setPhase !! 3277                         phase = 'suspend_prepare'
4059                                 data.setStart !! 3278                         data.dmesg[phase]['start'] = ktime
4060                                 data.tKernSus !! 3279                         data.setStart(ktime)
4061                         elif phase == 'suspen !! 3280                         data.tKernSus = ktime
4062                                 lp = data.las !! 3281                 # suspend start
4063                                 if lp:        !! 3282                 elif(re.match(dm['suspend'], msg)):
4064                                         data. !! 3283                         data.dmesg['suspend_prepare']['end'] = ktime
4065                                 data.setPhase !! 3284                         phase = 'suspend'
4066                         elif phase == 'suspen !! 3285                         data.dmesg[phase]['start'] = ktime
4067                                 lp = data.las !! 3286                 # suspend_late start
4068                                 if lp:        !! 3287                 elif(re.match(dm['suspend_late'], msg)):
4069                                         data. !! 3288                         data.dmesg['suspend']['end'] = ktime
4070                                 data.setPhase !! 3289                         phase = 'suspend_late'
4071                         elif phase == 'suspen !! 3290                         data.dmesg[phase]['start'] = ktime
4072                                 lp = data.las !! 3291                 # suspend_noirq start
4073                                 if lp:        !! 3292                 elif(re.match(dm['suspend_noirq'], msg)):
4074                                         data. !! 3293                         data.dmesg['suspend_late']['end'] = ktime
4075                                 data.setPhase !! 3294                         phase = 'suspend_noirq'
4076                         elif phase == 'suspen !! 3295                         data.dmesg[phase]['start'] = ktime
4077                                 lp = data.las !! 3296                 # suspend_machine start
4078                                 if lp:        !! 3297                 elif(re.match(dm['suspend_machine'], msg)):
4079                                         data. !! 3298                         data.dmesg['suspend_noirq']['end'] = ktime
4080                                 data.setPhase !! 3299                         phase = 'suspend_machine'
4081                         elif phase == 'resume !! 3300                         data.dmesg[phase]['start'] = ktime
4082                                 lp = data.las !! 3301                 # resume_machine start
4083                                 if(sysvals.su !! 3302                 elif(re.match(dm['resume_machine'], msg)):
4084                                         data. !! 3303                         if(sysvals.suspendmode in ['freeze', 'standby']):
4085                                         if lp !! 3304                                 data.tSuspended = prevktime
4086                                               !! 3305                                 data.dmesg['suspend_machine']['end'] = prevktime
4087                                 else:         !! 3306                         else:
4088                                         data. !! 3307                                 data.tSuspended = ktime
4089                                         if lp !! 3308                                 data.dmesg['suspend_machine']['end'] = ktime
4090                                               !! 3309                         phase = 'resume_machine'
4091                                 data.tResumed !! 3310                         data.tResumed = ktime
4092                                 data.setPhase !! 3311                         data.tLow = data.tResumed - data.tSuspended
4093                         elif phase == 'resume !! 3312                         data.dmesg[phase]['start'] = ktime
4094                                 lp = data.las !! 3313                 # resume_noirq start
4095                                 if lp:        !! 3314                 elif(re.match(dm['resume_noirq'], msg)):
4096                                         data. !! 3315                         data.dmesg['resume_machine']['end'] = ktime
4097                                 data.setPhase !! 3316                         phase = 'resume_noirq'
4098                         elif phase == 'resume !! 3317                         data.dmesg[phase]['start'] = ktime
4099                                 lp = data.las !! 3318                 # resume_early start
4100                                 if lp:        !! 3319                 elif(re.match(dm['resume_early'], msg)):
4101                                         data. !! 3320                         data.dmesg['resume_noirq']['end'] = ktime
4102                                 data.setPhase !! 3321                         phase = 'resume_early'
4103                         elif phase == 'resume !! 3322                         data.dmesg[phase]['start'] = ktime
4104                                 lp = data.las !! 3323                 # resume start
4105                                 if lp:        !! 3324                 elif(re.match(dm['resume'], msg)):
4106                                         data. !! 3325                         data.dmesg['resume_early']['end'] = ktime
4107                                 data.setPhase !! 3326                         phase = 'resume'
4108                         elif phase == 'resume !! 3327                         data.dmesg[phase]['start'] = ktime
4109                                 lp = data.las !! 3328                 # resume complete start
4110                                 if lp:        !! 3329                 elif(re.match(dm['resume_complete'], msg)):
4111                                         data. !! 3330                         data.dmesg['resume']['end'] = ktime
4112                                 data.setPhase !! 3331                         phase = 'resume_complete'
4113                         elif phase == 'post_r !! 3332                         data.dmesg[phase]['start'] = ktime
4114                                 lp = data.las !! 3333                 # post resume start
4115                                 if lp:        !! 3334                 elif(re.match(dm['post_resume'], msg)):
4116                                         data. !! 3335                         data.dmesg['resume_complete']['end'] = ktime
4117                                 data.setEnd(k !! 3336                         data.setEnd(ktime)
4118                                 data.tKernRes !! 3337                         data.tKernRes = ktime
4119                                 break         !! 3338                         break
4120                                                  3339 
4121                 # -- device callbacks --         3340                 # -- device callbacks --
4122                 if(phase in data.sortedPhases !! 3341                 if(phase in data.phases):
4123                         # device init call       3342                         # device init call
4124                         t, f, n, p = data.ini !! 3343                         if(re.match('calling  (?P<f>.*)\+ @ .*, parent: .*', msg)):
4125                         if t and f and n and  !! 3344                                 sm = re.match('calling  (?P<f>.*)\+ @ '+\
4126                                 data.newActio !! 3345                                         '(?P<n>.*), parent: (?P<p>.*)', msg);
4127                         else:                 !! 3346                                 f = sm.group('f')
4128                                 # device init !! 3347                                 n = sm.group('n')
4129                                 t, f, l = dat !! 3348                                 p = sm.group('p')
4130                                 if t and f an !! 3349                                 if(f and n and p):
4131                                         list  !! 3350                                         data.newAction(phase, f, int(n), p, ktime, -1, '')
4132                                         if(f  !! 3351                         # device init return
4133                                               !! 3352                         elif(re.match('call (?P<f>.*)\+ returned .* after '+\
4134                                               !! 3353                                 '(?P<t>.*) usecs', msg)):
4135                                               !! 3354                                 sm = re.match('call (?P<f>.*)\+ returned .* after '+\
                                                   >> 3355                                         '(?P<t>.*) usecs(?P<a>.*)', msg);
                                                   >> 3356                                 f = sm.group('f')
                                                   >> 3357                                 t = sm.group('t')
                                                   >> 3358                                 list = data.dmesg[phase]['list']
                                                   >> 3359                                 if(f in list):
                                                   >> 3360                                         dev = list[f]
                                                   >> 3361                                         dev['length'] = int(t)
                                                   >> 3362                                         dev['end'] = ktime
4136                                                  3363 
4137                 # if trace events are not ava    3364                 # if trace events are not available, these are better than nothing
4138                 if(not sysvals.usetraceevents    3365                 if(not sysvals.usetraceevents):
4139                         # look for known acti    3366                         # look for known actions
4140                         for a in sorted(at):  !! 3367                         for a in at:
4141                                 if(re.match(a    3368                                 if(re.match(at[a]['smsg'], msg)):
4142                                         if(a     3369                                         if(a not in actions):
4143                                               !! 3370                                                 actions[a] = []
                                                   >> 3371                                         actions[a].append({'begin': ktime, 'end': ktime})
4144                                 if(re.match(a    3372                                 if(re.match(at[a]['emsg'], msg)):
4145                                         if(a  !! 3373                                         if(a in actions):
4146                                                  3374                                                 actions[a][-1]['end'] = ktime
4147                         # now look for CPU on    3375                         # now look for CPU on/off events
4148                         if(re.match(r'Disabli !! 3376                         if(re.match('Disabling non-boot CPUs .*', msg)):
4149                                 # start of fi    3377                                 # start of first cpu suspend
4150                                 cpu_start = k    3378                                 cpu_start = ktime
4151                         elif(re.match(r'Enabl !! 3379                         elif(re.match('Enabling non-boot CPUs .*', msg)):
4152                                 # start of fi    3380                                 # start of first cpu resume
4153                                 cpu_start = k    3381                                 cpu_start = ktime
4154                         elif(re.match(r'smpbo !! 3382                         elif(re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)):
4155                                 or re.match(r << 
4156                                 # end of a cp    3383                                 # end of a cpu suspend, start of the next
4157                                 m = re.match( !! 3384                                 m = re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)
4158                                 if(not m):    << 
4159                                         m = r << 
4160                                 cpu = 'CPU'+m    3385                                 cpu = 'CPU'+m.group('cpu')
4161                                 if(cpu not in    3386                                 if(cpu not in actions):
4162                                         actio    3387                                         actions[cpu] = []
4163                                 actions[cpu].    3388                                 actions[cpu].append({'begin': cpu_start, 'end': ktime})
4164                                 cpu_start = k    3389                                 cpu_start = ktime
4165                         elif(re.match(r'CPU(? !! 3390                         elif(re.match('CPU(?P<cpu>[0-9]*) is up', msg)):
4166                                 # end of a cp    3391                                 # end of a cpu resume, start of the next
4167                                 m = re.match( !! 3392                                 m = re.match('CPU(?P<cpu>[0-9]*) is up', msg)
4168                                 cpu = 'CPU'+m    3393                                 cpu = 'CPU'+m.group('cpu')
4169                                 if(cpu not in    3394                                 if(cpu not in actions):
4170                                         actio    3395                                         actions[cpu] = []
4171                                 actions[cpu].    3396                                 actions[cpu].append({'begin': cpu_start, 'end': ktime})
4172                                 cpu_start = k    3397                                 cpu_start = ktime
4173                 prevktime = ktime                3398                 prevktime = ktime
4174         data.initDevicegroups()               << 
4175                                                  3399 
4176         # fill in any missing phases             3400         # fill in any missing phases
4177         phasedef = data.phasedef              !! 3401         lp = data.phases[0]
4178         terr, lp = '', 'suspend_prepare'      !! 3402         for p in data.phases:
4179         if lp not in data.dmesg:              !! 3403                 if(data.dmesg[p]['start'] < 0 and data.dmesg[p]['end'] < 0):
4180                 doError('dmesg log format has !! 3404                         print('WARNING: phase "%s" is missing, something went wrong!' % p)
4181         for p in sorted(phasedef, key=lambda  !! 3405                         print('    In %s, this dmesg line denotes the start of %s:' % \
4182                 if p not in data.dmesg:       !! 3406                                 (sysvals.suspendmode, p))
4183                         if not terr:          !! 3407                         print('        "%s"' % dm[p])
4184                                 pprint('TEST  !! 3408                 if(data.dmesg[p]['start'] < 0):
4185                                 terr = '%s fa !! 3409                         data.dmesg[p]['start'] = data.dmesg[lp]['end']
4186                                 if data.tSusp !! 3410                         if(p == 'resume_machine'):
4187                                         data. !! 3411                                 data.tSuspended = data.dmesg[lp]['end']
4188                                 if data.tResu !! 3412                                 data.tResumed = data.dmesg[lp]['end']
4189                                         data. !! 3413                                 data.tLow = 0
4190                         sysvals.vprint('WARNI !! 3414                 if(data.dmesg[p]['end'] < 0):
4191                 lp = p                        !! 3415                         data.dmesg[p]['end'] = data.dmesg[p]['start']
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                           3416                 lp = p
4197         if data.tSuspended == 0:              << 
4198                 data.tSuspended = data.tKernR << 
4199         if data.tResumed == 0:                << 
4200                 data.tResumed = data.tSuspend << 
4201                                                  3417 
4202         # fill in any actions we've found        3418         # fill in any actions we've found
4203         for name in sorted(actions):          !! 3419         for name in actions:
4204                 for event in actions[name]:      3420                 for event in actions[name]:
4205                         data.newActionGlobal(    3421                         data.newActionGlobal(name, event['begin'], event['end'])
4206                                                  3422 
4207         if(len(sysvals.devicefilter) > 0):       3423         if(len(sysvals.devicefilter) > 0):
4208                 data.deviceFilter(sysvals.dev    3424                 data.deviceFilter(sysvals.devicefilter)
4209         data.fixupInitcallsThatDidntReturn()     3425         data.fixupInitcallsThatDidntReturn()
4210         return True                              3426         return True
4211                                                  3427 
4212 def callgraphHTML(sv, hf, num, cg, title, col    3428 def callgraphHTML(sv, hf, num, cg, title, color, devid):
4213         html_func_top = '<article id="{0}" cl    3429         html_func_top = '<article id="{0}" class="atop" style="background:{1}">\n<input type="checkbox" class="pf" id="f{2}" checked/><label for="f{2}">{3} {4}</label>\n'
4214         html_func_start = '<article>\n<input     3430         html_func_start = '<article>\n<input type="checkbox" class="pf" id="f{0}" checked/><label for="f{0}">{1} {2}</label>\n'
4215         html_func_end = '</article>\n'           3431         html_func_end = '</article>\n'
4216         html_func_leaf = '<article>{0} {1}</a    3432         html_func_leaf = '<article>{0} {1}</article>\n'
4217                                                  3433 
4218         cgid = devid                             3434         cgid = devid
4219         if cg.id:                                3435         if cg.id:
4220                 cgid += cg.id                    3436                 cgid += cg.id
4221         cglen = (cg.end - cg.start) * 1000       3437         cglen = (cg.end - cg.start) * 1000
4222         if cglen < sv.mincglen:                  3438         if cglen < sv.mincglen:
4223                 return num                       3439                 return num
4224                                                  3440 
4225         fmt = '<r>(%.3f ms @ '+sv.timeformat+'    3441         fmt = '<r>(%.3f ms @ '+sv.timeformat+' to '+sv.timeformat+')</r>'
4226         flen = fmt % (cglen, cg.start, cg.end    3442         flen = fmt % (cglen, cg.start, cg.end)
4227         hf.write(html_func_top.format(cgid, c    3443         hf.write(html_func_top.format(cgid, color, num, title, flen))
4228         num += 1                                 3444         num += 1
4229         for line in cg.list:                     3445         for line in cg.list:
4230                 if(line.length < 0.000000001)    3446                 if(line.length < 0.000000001):
4231                         flen = ''                3447                         flen = ''
4232                 else:                            3448                 else:
4233                         fmt = '<n>(%.3f ms @ '    3449                         fmt = '<n>(%.3f ms @ '+sv.timeformat+')</n>'
4234                         flen = fmt % (line.le    3450                         flen = fmt % (line.length*1000, line.time)
4235                 if line.isLeaf():                3451                 if line.isLeaf():
4236                         if line.length * 1000 << 
4237                                 continue      << 
4238                         hf.write(html_func_le    3452                         hf.write(html_func_leaf.format(line.name, flen))
4239                 elif line.freturn:               3453                 elif line.freturn:
4240                         hf.write(html_func_en    3454                         hf.write(html_func_end)
4241                 else:                            3455                 else:
4242                         hf.write(html_func_st    3456                         hf.write(html_func_start.format(num, line.name, flen))
4243                         num += 1                 3457                         num += 1
4244         hf.write(html_func_end)                  3458         hf.write(html_func_end)
4245         return num                               3459         return num
4246                                                  3460 
4247 def addCallgraphs(sv, hf, data):                 3461 def addCallgraphs(sv, hf, data):
4248         hf.write('<section id="callgraphs" cl    3462         hf.write('<section id="callgraphs" class="callgraph">\n')
4249         # write out the ftrace data converted    3463         # write out the ftrace data converted to html
4250         num = 0                                  3464         num = 0
4251         for p in data.sortedPhases():         !! 3465         for p in data.phases:
4252                 if sv.cgphase and p != sv.cgp    3466                 if sv.cgphase and p != sv.cgphase:
4253                         continue                 3467                         continue
4254                 list = data.dmesg[p]['list']     3468                 list = data.dmesg[p]['list']
4255                 for d in data.sortedDevices(p !! 3469                 for devname in data.sortedDevices(p):
4256                         if len(sv.cgfilter) > !! 3470                         if len(sv.cgfilter) > 0 and devname not in sv.cgfilter:
4257                                 continue         3471                                 continue
4258                         dev = list[d]         !! 3472                         dev = list[devname]
4259                         color = 'white'          3473                         color = 'white'
4260                         if 'color' in data.dm    3474                         if 'color' in data.dmesg[p]:
4261                                 color = data.    3475                                 color = data.dmesg[p]['color']
4262                         if 'color' in dev:       3476                         if 'color' in dev:
4263                                 color = dev['    3477                                 color = dev['color']
4264                         name = d if '[' not i !! 3478                         name = devname
4265                         if(d in sv.devprops): !! 3479                         if(devname in sv.devprops):
4266                                 name = sv.dev !! 3480                                 name = sv.devprops[devname].altName(devname)
4267                         if 'drv' in dev and d << 
4268                                 name += ' {%s << 
4269                         if sv.suspendmode in     3481                         if sv.suspendmode in suspendmodename:
4270                                 name += ' '+p    3482                                 name += ' '+p
4271                         if('ftrace' in dev):     3483                         if('ftrace' in dev):
4272                                 cg = dev['ftr    3484                                 cg = dev['ftrace']
4273                                 if cg.name == << 
4274                                         name  << 
4275                                 num = callgra    3485                                 num = callgraphHTML(sv, hf, num, cg,
4276                                         name,    3486                                         name, color, dev['id'])
4277                         if('ftraces' in dev):    3487                         if('ftraces' in dev):
4278                                 for cg in dev    3488                                 for cg in dev['ftraces']:
4279                                         num =    3489                                         num = callgraphHTML(sv, hf, num, cg,
4280                                                  3490                                                 name+' &rarr; '+cg.name, color, dev['id'])
4281         hf.write('\n\n    </section>\n')         3491         hf.write('\n\n    </section>\n')
4282                                                  3492 
4283 def summaryCSS(title, center=True):           !! 3493 # Function: createHTMLSummarySimple
4284         tdcenter = 'text-align:center;' if ce !! 3494 # Description:
4285         out = '<!DOCTYPE html>\n<html>\n<head !! 3495 #        Create summary html file for a series of tests
                                                   >> 3496 # Arguments:
                                                   >> 3497 #        testruns: array of Data objects from parseTraceLog
                                                   >> 3498 def createHTMLSummarySimple(testruns, htmlfile, folder):
                                                   >> 3499         # write the html header first (html head, css code, up to body start)
                                                   >> 3500         html = '<!DOCTYPE html>\n<html>\n<head>\n\
4286         <meta http-equiv="content-type" conte    3501         <meta http-equiv="content-type" content="text/html; charset=UTF-8">\n\
4287         <title>'+title+'</title>\n\           !! 3502         <title>SleepGraph Summary</title>\n\
4288         <style type=\'text/css\'>\n\             3503         <style type=\'text/css\'>\n\
4289                 .stamp {width: 100%;text-alig    3504                 .stamp {width: 100%;text-align:center;background:#888;line-height:30px;color:white;font: 25px Arial;}\n\
4290                 table {width:100%;border-coll !! 3505                 table {width:100%;border-collapse: collapse;}\n\
                                                   >> 3506                 .summary {border:1px solid;}\n\
4291                 th {border: 1px solid black;b    3507                 th {border: 1px solid black;background:#222;color:white;}\n\
4292                 td {font: 14px "Times New Rom !! 3508                 td {font: 16px "Times New Roman";text-align: center;}\n\
4293                 tr.head td {border: 1px solid    3509                 tr.head td {border: 1px solid black;background:#aaa;}\n\
4294                 tr.alt {background-color:#ddd    3510                 tr.alt {background-color:#ddd;}\n\
4295                 tr.notice {color:red;}\n\        3511                 tr.notice {color:red;}\n\
4296                 .minval {background-color:#BB    3512                 .minval {background-color:#BBFFBB;}\n\
4297                 .medval {background-color:#BB    3513                 .medval {background-color:#BBBBFF;}\n\
4298                 .maxval {background-color:#FF    3514                 .maxval {background-color:#FFBBBB;}\n\
4299                 .head a {color:#000;text-deco    3515                 .head a {color:#000;text-decoration: none;}\n\
4300         </style>\n</head>\n<body>\n'             3516         </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                                                  3517 
4312         # extract the test data into list        3518         # extract the test data into list
4313         list = dict()                            3519         list = dict()
4314         tAvg, tMin, tMax, tMed = [0.0, 0.0],  !! 3520         tAvg, tMin, tMax, tMed = [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [[], []]
4315         iMin, iMed, iMax = [0, 0], [0, 0], [0    3521         iMin, iMed, iMax = [0, 0], [0, 0], [0, 0]
4316         num = 0                                  3522         num = 0
4317         useturbo = usewifi = False            << 
4318         lastmode = ''                            3523         lastmode = ''
4319         cnt = dict()                          !! 3524         cnt = {'pass':0, 'fail':0, 'hang':0}
4320         for data in sorted(testruns, key=lamb    3525         for data in sorted(testruns, key=lambda v:(v['mode'], v['host'], v['kernel'], v['time'])):
4321                 mode = data['mode']              3526                 mode = data['mode']
4322                 if mode not in list:             3527                 if mode not in list:
4323                         list[mode] = {'data':    3528                         list[mode] = {'data': [], 'avg': [0,0], 'min': [0,0], 'max': [0,0], 'med': [0,0]}
4324                 if lastmode and lastmode != m    3529                 if lastmode and lastmode != mode and num > 0:
4325                         for i in range(2):       3530                         for i in range(2):
4326                                 s = sorted(tM    3531                                 s = sorted(tMed[i])
4327                                 list[lastmode !! 3532                                 list[lastmode]['med'][i] = s[int(len(s)/2)]
4328                                 iMed[i] = tMe !! 3533                                 iMed[i] = tMed[i].index(list[lastmode]['med'][i])
4329                         list[lastmode]['avg']    3534                         list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num]
4330                         list[lastmode]['min']    3535                         list[lastmode]['min'] = tMin
4331                         list[lastmode]['max']    3536                         list[lastmode]['max'] = tMax
4332                         list[lastmode]['idx']    3537                         list[lastmode]['idx'] = (iMin, iMed, iMax)
4333                         tAvg, tMin, tMax, tMe !! 3538                         tAvg, tMin, tMax, tMed = [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [[], []]
4334                         iMin, iMed, iMax = [0    3539                         iMin, iMed, iMax = [0, 0], [0, 0], [0, 0]
4335                         num = 0                  3540                         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']    3541                 tVal = [float(data['suspend']), float(data['resume'])]
4343                 list[mode]['data'].append([da    3542                 list[mode]['data'].append([data['host'], data['kernel'],
4344                         data['time'], tVal[0] !! 3543                         data['time'], tVal[0], tVal[1], data['url'], data['result'],
4345                         data['issues'], data[ !! 3544                         data['issues']])
4346                         data['res_worst'], da << 
4347                         (data['fullmode'] if  << 
4348                 idx = len(list[mode]['data'])    3545                 idx = len(list[mode]['data']) - 1
4349                 if res.startswith('fail in'): !! 3546                 if data['result'] == 'pass':
4350                         res = 'fail'          !! 3547                         cnt['pass'] += 1
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):       3548                         for i in range(2):
4357                                 tMed[i][tVal[ !! 3549                                 tMed[i].append(tVal[i])
4358                                 tAvg[i] += tV    3550                                 tAvg[i] += tVal[i]
4359                                 if tMin[i] ==    3551                                 if tMin[i] == 0 or tVal[i] < tMin[i]:
4360                                         iMin[    3552                                         iMin[i] = idx
4361                                         tMin[    3553                                         tMin[i] = tVal[i]
4362                                 if tMax[i] ==    3554                                 if tMax[i] == 0 or tVal[i] > tMax[i]:
4363                                         iMax[    3555                                         iMax[i] = idx
4364                                         tMax[    3556                                         tMax[i] = tVal[i]
4365                         num += 1                 3557                         num += 1
                                                   >> 3558                 elif data['result'] == 'hang':
                                                   >> 3559                         cnt['hang'] += 1
                                                   >> 3560                 elif data['result'] == 'fail':
                                                   >> 3561                         cnt['fail'] += 1
4366                 lastmode = mode                  3562                 lastmode = mode
4367         if lastmode and num > 0:                 3563         if lastmode and num > 0:
4368                 for i in range(2):               3564                 for i in range(2):
4369                         s = sorted(tMed[i])      3565                         s = sorted(tMed[i])
4370                         list[lastmode]['med'] !! 3566                         list[lastmode]['med'][i] = s[int(len(s)/2)]
4371                         iMed[i] = tMed[i][lis !! 3567                         iMed[i] = tMed[i].index(list[lastmode]['med'][i])
4372                 list[lastmode]['avg'] = [tAvg    3568                 list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num]
4373                 list[lastmode]['min'] = tMin     3569                 list[lastmode]['min'] = tMin
4374                 list[lastmode]['max'] = tMax     3570                 list[lastmode]['max'] = tMax
4375                 list[lastmode]['idx'] = (iMin    3571                 list[lastmode]['idx'] = (iMin, iMed, iMax)
4376                                                  3572 
4377         # group test header                      3573         # group test header
4378         desc = []                                3574         desc = []
4379         for ilk in sorted(cnt, reverse=True):    3575         for ilk in sorted(cnt, reverse=True):
4380                 if cnt[ilk] > 0:                 3576                 if cnt[ilk] > 0:
4381                         desc.append('%d %s' %    3577                         desc.append('%d %s' % (cnt[ilk], ilk))
4382         html += '<div class="stamp">%s (%d te !! 3578         html += '<div class="stamp">%s (%d tests: %s)</div>\n' % (folder, len(testruns), ', '.join(desc))
4383         th = '\t<th>{0}</th>\n'                  3579         th = '\t<th>{0}</th>\n'
4384         td = '\t<td>{0}</td>\n'                  3580         td = '\t<td>{0}</td>\n'
4385         tdh = '\t<td{1}>{0}</td>\n'              3581         tdh = '\t<td{1}>{0}</td>\n'
4386         tdlink = '\t<td><a href="{0}">html</a    3582         tdlink = '\t<td><a href="{0}">html</a></td>\n'
4387         cols = 12                             << 
4388         if useturbo:                          << 
4389                 cols += 2                     << 
4390         if usewifi:                           << 
4391                 cols += 1                     << 
4392         colspan = '%d' % cols                 << 
4393                                                  3583 
4394         # table header                           3584         # table header
4395         html += '<table>\n<tr>\n' + th.format !! 3585         html += '<table class="summary">\n<tr>\n' + th.format('#') +\
4396                 th.format('Mode') + th.format    3586                 th.format('Mode') + th.format('Host') + th.format('Kernel') +\
4397                 th.format('Test Time') + th.f    3587                 th.format('Test Time') + th.format('Result') + th.format('Issues') +\
4398                 th.format('Suspend') + th.for !! 3588                 th.format('Suspend') + th.format('Resume') + th.format('Detail') + '</tr>\n'
4399                 th.format('Worst Suspend Devi !! 3589 
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                  3590         # export list into html
4407         head = '<tr class="head"><td>{0}</td>    3591         head = '<tr class="head"><td>{0}</td><td>{1}</td>'+\
4408                 '<td colspan='+colspan+' clas !! 3592                 '<td colspan=8 class="sus">Suspend Avg={2} '+\
4409                 '<span class=minval><a href="    3593                 '<span class=minval><a href="#s{10}min">Min={3}</a></span> '+\
4410                 '<span class=medval><a href="    3594                 '<span class=medval><a href="#s{10}med">Med={4}</a></span> '+\
4411                 '<span class=maxval><a href="    3595                 '<span class=maxval><a href="#s{10}max">Max={5}</a></span> '+\
4412                 'Resume Avg={6} '+\              3596                 'Resume Avg={6} '+\
4413                 '<span class=minval><a href="    3597                 '<span class=minval><a href="#r{10}min">Min={7}</a></span> '+\
4414                 '<span class=medval><a href="    3598                 '<span class=medval><a href="#r{10}med">Med={8}</a></span> '+\
4415                 '<span class=maxval><a href="    3599                 '<span class=maxval><a href="#r{10}max">Max={9}</a></span></td>'+\
4416                 '</tr>\n'                        3600                 '</tr>\n'
4417         headnone = '<tr class="head"><td>{0}< !! 3601         headnone = '<tr class="head"><td>{0}</td><td>{1}</td><td colspan=8></td></tr>\n'
4418                 colspan+'></td></tr>\n'       !! 3602         for mode in list:
4419         for mode in sorted(list):             << 
4420                 # header line for each suspen    3603                 # header line for each suspend mode
4421                 num = 0                          3604                 num = 0
4422                 tAvg, tMin, tMax, tMed = list    3605                 tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\
4423                         list[mode]['max'], li    3606                         list[mode]['max'], list[mode]['med']
4424                 count = len(list[mode]['data'    3607                 count = len(list[mode]['data'])
4425                 if 'idx' in list[mode]:          3608                 if 'idx' in list[mode]:
4426                         iMin, iMed, iMax = li    3609                         iMin, iMed, iMax = list[mode]['idx']
4427                         html += head.format('    3610                         html += head.format('%d' % count, mode.upper(),
4428                                 '%.3f' % tAvg    3611                                 '%.3f' % tAvg[0], '%.3f' % tMin[0], '%.3f' % tMed[0], '%.3f' % tMax[0],
4429                                 '%.3f' % tAvg    3612                                 '%.3f' % tAvg[1], '%.3f' % tMin[1], '%.3f' % tMed[1], '%.3f' % tMax[1],
4430                                 mode.lower()     3613                                 mode.lower()
4431                         )                        3614                         )
4432                 else:                            3615                 else:
4433                         iMin = iMed = iMax =     3616                         iMin = iMed = iMax = [-1, -1, -1]
4434                         html += headnone.form    3617                         html += headnone.format('%d' % count, mode.upper())
4435                 for d in list[mode]['data']:     3618                 for d in list[mode]['data']:
4436                         # row classes - alter    3619                         # row classes - alternate row color
4437                         rcls = ['alt'] if num    3620                         rcls = ['alt'] if num % 2 == 1 else []
4438                         if d[6] != 'pass':       3621                         if d[6] != 'pass':
4439                                 rcls.append('    3622                                 rcls.append('notice')
4440                         html += '<tr class="'    3623                         html += '<tr class="'+(' '.join(rcls))+'">\n' if len(rcls) > 0 else '<tr>\n'
4441                         # figure out if the l    3624                         # figure out if the line has sus or res highlighted
4442                         idx = list[mode]['dat    3625                         idx = list[mode]['data'].index(d)
4443                         tHigh = ['', '']         3626                         tHigh = ['', '']
4444                         for i in range(2):       3627                         for i in range(2):
4445                                 tag = 's%s' %    3628                                 tag = 's%s' % mode if i == 0 else 'r%s' % mode
4446                                 if idx == iMi    3629                                 if idx == iMin[i]:
4447                                         tHigh    3630                                         tHigh[i] = ' id="%smin" class=minval title="Minimum"' % tag
4448                                 elif idx == i    3631                                 elif idx == iMax[i]:
4449                                         tHigh    3632                                         tHigh[i] = ' id="%smax" class=maxval title="Maximum"' % tag
4450                                 elif idx == i    3633                                 elif idx == iMed[i]:
4451                                         tHigh    3634                                         tHigh[i] = ' id="%smed" class=medval title="Median"' % tag
4452                         html += td.format("%d    3635                         html += td.format("%d" % (list[mode]['data'].index(d) + 1)) # row
4453                         html += td.format(d[1 !! 3636                         html += td.format(mode)                                                                         # mode
4454                         html += td.format(d[0    3637                         html += td.format(d[0])                                                                         # host
4455                         html += td.format(d[1    3638                         html += td.format(d[1])                                                                         # kernel
4456                         html += td.format(d[2    3639                         html += td.format(d[2])                                                                         # time
4457                         html += td.format(d[6    3640                         html += td.format(d[6])                                                                         # result
4458                         html += td.format(d[7    3641                         html += td.format(d[7])                                                                         # issues
4459                         html += tdh.format('%    3642                         html += tdh.format('%.3f ms' % d[3], tHigh[0]) if d[3] else td.format('')       # suspend
4460                         html += tdh.format('%    3643                         html += tdh.format('%.3f ms' % d[4], tHigh[1]) if d[4] else td.format('')       # resume
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    3644                         html += tdlink.format(d[5]) if d[5] else td.format('')          # url
4471                         html += '</tr>\n'        3645                         html += '</tr>\n'
4472                         num += 1                 3646                         num += 1
4473                                                  3647 
4474         # flush the data to file                 3648         # flush the data to file
4475         hf = open(htmlfile, 'w')                 3649         hf = open(htmlfile, 'w')
4476         hf.write(html+'</table>\n</body>\n</h    3650         hf.write(html+'</table>\n</body>\n</html>\n')
4477         hf.close()                               3651         hf.close()
4478                                                  3652 
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):                              3653 def ordinal(value):
4590         suffix = 'th'                            3654         suffix = 'th'
4591         if value < 10 or value > 19:             3655         if value < 10 or value > 19:
4592                 if value % 10 == 1:              3656                 if value % 10 == 1:
4593                         suffix = 'st'            3657                         suffix = 'st'
4594                 elif value % 10 == 2:            3658                 elif value % 10 == 2:
4595                         suffix = 'nd'            3659                         suffix = 'nd'
4596                 elif value % 10 == 3:            3660                 elif value % 10 == 3:
4597                         suffix = 'rd'            3661                         suffix = 'rd'
4598         return '%d%s' % (value, suffix)          3662         return '%d%s' % (value, suffix)
4599                                                  3663 
4600 # Function: createHTML                           3664 # Function: createHTML
4601 # Description:                                   3665 # Description:
4602 #        Create the output html file from the    3666 #        Create the output html file from the resident test data
4603 # Arguments:                                     3667 # Arguments:
4604 #        testruns: array of Data objects from    3668 #        testruns: array of Data objects from parseKernelLog or parseTraceLog
4605 # Output:                                        3669 # Output:
4606 #        True if the html file was created, f    3670 #        True if the html file was created, false if it failed
4607 def createHTML(testruns, testfail):              3671 def createHTML(testruns, testfail):
4608         if len(testruns) < 1:                    3672         if len(testruns) < 1:
4609                 pprint('ERROR: Not enough tes !! 3673                 print('ERROR: Not enough test data to build a timeline')
4610                 return                           3674                 return
4611                                                  3675 
4612         kerror = False                           3676         kerror = False
4613         for data in testruns:                    3677         for data in testruns:
4614                 if data.kerror:                  3678                 if data.kerror:
4615                         kerror = True            3679                         kerror = True
4616                 if(sysvals.suspendmode in ['f !! 3680                 data.normalizeTime(testruns[-1].tSuspended)
4617                         data.trimFreezeTime(t << 
4618                 else:                         << 
4619                         data.getMemTime()     << 
4620                                                  3681 
4621         # html function templates                3682         # html function templates
4622         html_error = '<div id="{1}" title="ke    3683         html_error = '<div id="{1}" title="kernel error/warning" class="err" style="right:{0}%">{2}&rarr;</div>\n'
4623         html_traceevent = '<div title="{0}" c    3684         html_traceevent = '<div title="{0}" class="traceevent{6}" style="left:{1}%;top:{2}px;height:{3}px;width:{4}%;line-height:{3}px;{7}">{5}</div>\n'
4624         html_cpuexec = '<div class="jiffie" s    3685         html_cpuexec = '<div class="jiffie" style="left:{0}%;top:{1}px;height:{2}px;width:{3}%;background:{4};"></div>\n'
4625         html_timetotal = '<table class="time1    3686         html_timetotal = '<table class="time1">\n<tr>'\
4626                 '<td class="green" title="{3}    3687                 '<td class="green" title="{3}">{2} Suspend Time: <b>{0} ms</b></td>'\
4627                 '<td class="yellow" title="{4    3688                 '<td class="yellow" title="{4}">{2} Resume Time: <b>{1} ms</b></td>'\
4628                 '</tr>\n</table>\n'              3689                 '</tr>\n</table>\n'
4629         html_timetotal2 = '<table class="time    3690         html_timetotal2 = '<table class="time1">\n<tr>'\
4630                 '<td class="green" title="{4}    3691                 '<td class="green" title="{4}">{3} Suspend Time: <b>{0} ms</b></td>'\
4631                 '<td class="gray" title="time    3692                 '<td class="gray" title="time spent in low-power mode with clock running">'+sysvals.suspendmode+' time: <b>{1} ms</b></td>'\
4632                 '<td class="yellow" title="{5    3693                 '<td class="yellow" title="{5}">{3} Resume Time: <b>{2} ms</b></td>'\
4633                 '</tr>\n</table>\n'              3694                 '</tr>\n</table>\n'
4634         html_timetotal3 = '<table class="time    3695         html_timetotal3 = '<table class="time1">\n<tr>'\
4635                 '<td class="green">Execution     3696                 '<td class="green">Execution Time: <b>{0} ms</b></td>'\
4636                 '<td class="yellow">Command:     3697                 '<td class="yellow">Command: <b>{1}</b></td>'\
4637                 '</tr>\n</table>\n'              3698                 '</tr>\n</table>\n'
                                                   >> 3699         html_timegroups = '<table class="time2">\n<tr>'\
                                                   >> 3700                 '<td class="green" title="time from kernel enter_state({5}) to firmware mode [kernel time only]">{4}Kernel Suspend: {0} ms</td>'\
                                                   >> 3701                 '<td class="purple">{4}Firmware Suspend: {1} ms</td>'\
                                                   >> 3702                 '<td class="purple">{4}Firmware Resume: {2} ms</td>'\
                                                   >> 3703                 '<td class="yellow" title="time from firmware mode to return from kernel enter_state({5}) [kernel time only]">{4}Kernel Resume: {3} ms</td>'\
                                                   >> 3704                 '</tr>\n</table>\n'
4638         html_fail = '<table class="testfail">    3705         html_fail = '<table class="testfail"><tr><td>{0}</td></tr></table>\n'
4639         html_kdesc = '<td class="{3}" title=" << 
4640         html_fwdesc = '<td class="{3}" title= << 
4641         html_wifdesc = '<td class="yellow" ti << 
4642                                                  3706 
4643         # html format variables                  3707         # html format variables
4644         scaleH = 20                              3708         scaleH = 20
4645         if kerror:                               3709         if kerror:
4646                 scaleH = 40                      3710                 scaleH = 40
4647                                                  3711 
4648         # device timeline                        3712         # device timeline
4649         devtl = Timeline(30, scaleH)             3713         devtl = Timeline(30, scaleH)
4650                                                  3714 
4651         # write the test title and general in    3715         # write the test title and general info header
4652         devtl.createHeader(sysvals, testruns[    3716         devtl.createHeader(sysvals, testruns[0].stamp)
4653                                                  3717 
4654         # Generate the header for this timeli    3718         # Generate the header for this timeline
4655         for data in testruns:                    3719         for data in testruns:
4656                 tTotal = data.end - data.star    3720                 tTotal = data.end - data.start
                                                   >> 3721                 sktime, rktime = data.getTimeValues()
4657                 if(tTotal == 0):                 3722                 if(tTotal == 0):
4658                         doError('No timeline     3723                         doError('No timeline data')
                                                   >> 3724                 if(data.tLow > 0):
                                                   >> 3725                         low_time = '%.0f'%(data.tLow*1000)
4659                 if sysvals.suspendmode == 'co    3726                 if sysvals.suspendmode == 'command':
4660                         run_time = '%.0f' % ( !! 3727                         run_time = '%.0f'%((data.end-data.start)*1000)
4661                         if sysvals.testcomman    3728                         if sysvals.testcommand:
4662                                 testdesc = sy    3729                                 testdesc = sysvals.testcommand
4663                         else:                    3730                         else:
4664                                 testdesc = 'u    3731                                 testdesc = 'unknown'
4665                         if(len(testruns) > 1)    3732                         if(len(testruns) > 1):
4666                                 testdesc = or    3733                                 testdesc = ordinal(data.testnumber+1)+' '+testdesc
4667                         thtml = html_timetota    3734                         thtml = html_timetotal3.format(run_time, testdesc)
4668                         devtl.html += thtml      3735                         devtl.html += thtml
4669                         continue              !! 3736                 elif data.fwValid:
4670                 # typical full suspend/resume !! 3737                         suspend_time = '%.0f'%(sktime + (data.fwSuspend/1000000.0))
4671                 stot, rtot = sktime, rktime = !! 3738                         resume_time = '%.0f'%(rktime + (data.fwResume/1000000.0))
4672                 ssrc, rsrc, testdesc, testdes !! 3739                         testdesc1 = 'Total'
4673                 if data.fwValid:              !! 3740                         testdesc2 = ''
4674                         stot += (data.fwSuspe !! 3741                         stitle = 'time from kernel enter_state(%s) to low-power mode [kernel & firmware time]' % sysvals.suspendmode
4675                         rtot += (data.fwResum !! 3742                         rtitle = 'time from low-power mode to return from kernel enter_state(%s) [firmware & kernel time]' % sysvals.suspendmode
4676                         ssrc.append('firmware !! 3743                         if(len(testruns) > 1):
4677                         rsrc.append('firmware !! 3744                                 testdesc1 = testdesc2 = ordinal(data.testnumber+1)
4678                         testdesc = 'Total'    !! 3745                                 testdesc2 += ' '
4679                 if 'time' in data.wifi and da !! 3746                         if(data.tLow == 0):
4680                         rtot += data.end - da !! 3747                                 thtml = html_timetotal.format(suspend_time, \
4681                         rsrc.append('wifi')   !! 3748                                         resume_time, testdesc1, stitle, rtitle)
4682                         testdesc = 'Total'    !! 3749                         else:
4683                 suspend_time, resume_time = ' !! 3750                                 thtml = html_timetotal2.format(suspend_time, low_time, \
4684                 stitle = 'time from kernel su !! 3751                                         resume_time, testdesc1, stitle, rtitle)
4685                         (sysvals.suspendmode, !! 3752                         devtl.html += thtml
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    3753                         sftime = '%.3f'%(data.fwSuspend / 1000000.0)
4706                         rftime = '%.3f'%(data    3754                         rftime = '%.3f'%(data.fwResume / 1000000.0)
4707                         thtml += html_fwdesc. !! 3755                         devtl.html += html_timegroups.format('%.3f'%sktime, \
4708                         thtml += html_fwdesc. !! 3756                                 sftime, rftime, '%.3f'%rktime, testdesc2, sysvals.suspendmode)
4709                 thtml += html_kdesc.format(te !! 3757                 else:
4710                 if 'time' in data.wifi:       !! 3758                         suspend_time = '%.3f' % sktime
4711                         if data.wifi['stat']  !! 3759                         resume_time = '%.3f' % rktime
4712                                 wtime = '%.0f !! 3760                         testdesc = 'Kernel'
                                                   >> 3761                         stitle = 'time from kernel enter_state(%s) to firmware mode [kernel time only]' % sysvals.suspendmode
                                                   >> 3762                         rtitle = 'time from firmware mode to return from kernel enter_state(%s) [kernel time only]' % sysvals.suspendmode
                                                   >> 3763                         if(len(testruns) > 1):
                                                   >> 3764                                 testdesc = ordinal(data.testnumber+1)+' '+testdesc
                                                   >> 3765                         if(data.tLow == 0):
                                                   >> 3766                                 thtml = html_timetotal.format(suspend_time, \
                                                   >> 3767                                         resume_time, testdesc, stitle, rtitle)
4713                         else:                    3768                         else:
4714                                 wtime = 'TIME !! 3769                                 thtml = html_timetotal2.format(suspend_time, low_time, \
4715                         thtml += html_wifdesc !! 3770                                         resume_time, testdesc, stitle, rtitle)
4716                 thtml += '</tr>\n</table>\n'  !! 3771                         devtl.html += thtml
4717                 devtl.html += thtml           !! 3772 
4718         if testfail:                             3773         if testfail:
4719                 devtl.html += html_fail.forma    3774                 devtl.html += html_fail.format(testfail)
4720                                                  3775 
4721         # time scale for potentially multiple    3776         # time scale for potentially multiple datasets
4722         t0 = testruns[0].start                   3777         t0 = testruns[0].start
4723         tMax = testruns[-1].end                  3778         tMax = testruns[-1].end
4724         tTotal = tMax - t0                       3779         tTotal = tMax - t0
4725                                                  3780 
4726         # determine the maximum number of row    3781         # determine the maximum number of rows we need to draw
4727         fulllist = []                            3782         fulllist = []
4728         threadlist = []                          3783         threadlist = []
4729         pscnt = 0                                3784         pscnt = 0
4730         devcnt = 0                               3785         devcnt = 0
4731         for data in testruns:                    3786         for data in testruns:
4732                 data.selectTimelineDevices('%    3787                 data.selectTimelineDevices('%f', tTotal, sysvals.mindevlen)
4733                 for group in data.devicegroup    3788                 for group in data.devicegroups:
4734                         devlist = []             3789                         devlist = []
4735                         for phase in group:      3790                         for phase in group:
4736                                 for devname i !! 3791                                 for devname in data.tdevlist[phase]:
4737                                         d = D    3792                                         d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname])
4738                                         devli    3793                                         devlist.append(d)
4739                                         if d.    3794                                         if d.isa('kth'):
4740                                                  3795                                                 threadlist.append(d)
4741                                         else:    3796                                         else:
4742                                                  3797                                                 if d.isa('ps'):
4743                                                  3798                                                         pscnt += 1
4744                                                  3799                                                 else:
4745                                                  3800                                                         devcnt += 1
4746                                                  3801                                                 fulllist.append(d)
4747                         if sysvals.mixedphase    3802                         if sysvals.mixedphaseheight:
4748                                 devtl.getPhas    3803                                 devtl.getPhaseRows(devlist)
4749         if not sysvals.mixedphaseheight:         3804         if not sysvals.mixedphaseheight:
4750                 if len(threadlist) > 0 and le    3805                 if len(threadlist) > 0 and len(fulllist) > 0:
4751                         if pscnt > 0 and devc    3806                         if pscnt > 0 and devcnt > 0:
4752                                 msg = 'user p    3807                                 msg = 'user processes & device pm callbacks'
4753                         elif pscnt > 0:          3808                         elif pscnt > 0:
4754                                 msg = 'user p    3809                                 msg = 'user processes'
4755                         else:                    3810                         else:
4756                                 msg = 'device    3811                                 msg = 'device pm callbacks'
4757                         d = testruns[0].addHo    3812                         d = testruns[0].addHorizontalDivider(msg, testruns[-1].end)
4758                         fulllist.insert(0, d)    3813                         fulllist.insert(0, d)
4759                 devtl.getPhaseRows(fulllist)     3814                 devtl.getPhaseRows(fulllist)
4760                 if len(threadlist) > 0:          3815                 if len(threadlist) > 0:
4761                         d = testruns[0].addHo    3816                         d = testruns[0].addHorizontalDivider('asynchronous kernel threads', testruns[-1].end)
4762                         threadlist.insert(0,     3817                         threadlist.insert(0, d)
4763                         devtl.getPhaseRows(th    3818                         devtl.getPhaseRows(threadlist, devtl.rows)
4764         devtl.calcTotalRows()                    3819         devtl.calcTotalRows()
4765                                                  3820 
4766         # draw the full timeline                 3821         # draw the full timeline
4767         devtl.createZoomBox(sysvals.suspendmo    3822         devtl.createZoomBox(sysvals.suspendmode, len(testruns))
                                                   >> 3823         phases = {'suspend':[],'resume':[]}
                                                   >> 3824         for phase in data.dmesg:
                                                   >> 3825                 if 'resume' in phase:
                                                   >> 3826                         phases['resume'].append(phase)
                                                   >> 3827                 else:
                                                   >> 3828                         phases['suspend'].append(phase)
                                                   >> 3829 
                                                   >> 3830         # draw each test run chronologically
4768         for data in testruns:                    3831         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    3832                 # now draw the actual timeline blocks
4777                 for dir in phases:               3833                 for dir in phases:
4778                         # draw suspend and re    3834                         # draw suspend and resume blocks separately
4779                         bname = '%s%d' % (dir    3835                         bname = '%s%d' % (dir[0], data.testnumber)
4780                         if dir == 'suspend':     3836                         if dir == 'suspend':
4781                                 m0 = data.sta    3837                                 m0 = data.start
4782                                 mMax = data.t    3838                                 mMax = data.tSuspended
4783                                 left = '%f' %    3839                                 left = '%f' % (((m0-t0)*100.0)/tTotal)
4784                         else:                    3840                         else:
4785                                 m0 = data.tSu    3841                                 m0 = data.tSuspended
4786                                 mMax = data.e    3842                                 mMax = data.end
4787                                 # in an x2 ru    3843                                 # in an x2 run, remove any gap between blocks
4788                                 if len(testru    3844                                 if len(testruns) > 1 and data.testnumber == 0:
4789                                         mMax     3845                                         mMax = testruns[1].start
4790                                 left = '%f' %    3846                                 left = '%f' % ((((m0-t0)*100.0)+sysvals.srgap/2)/tTotal)
4791                         mTotal = mMax - m0       3847                         mTotal = mMax - m0
4792                         # if a timeline block    3848                         # if a timeline block is 0 length, skip altogether
4793                         if mTotal == 0:          3849                         if mTotal == 0:
4794                                 continue         3850                                 continue
4795                         width = '%f' % (((mTo    3851                         width = '%f' % (((mTotal*100.0)-sysvals.srgap/2)/tTotal)
4796                         devtl.html += devtl.h    3852                         devtl.html += devtl.html_tblock.format(bname, left, width, devtl.scaleH)
4797                         for b in phases[dir]: !! 3853                         for b in sorted(phases[dir]):
4798                                 # draw the ph    3854                                 # draw the phase color background
4799                                 phase = data.    3855                                 phase = data.dmesg[b]
4800                                 length = phas    3856                                 length = phase['end']-phase['start']
4801                                 left = '%f' %    3857                                 left = '%f' % (((phase['start']-m0)*100.0)/mTotal)
4802                                 width = '%f'     3858                                 width = '%f' % ((length*100.0)/mTotal)
4803                                 devtl.html +=    3859                                 devtl.html += devtl.html_phase.format(left, width, \
4804                                         '%.3f    3860                                         '%.3f'%devtl.scaleH, '%.3f'%devtl.bodyH, \
4805                                         data.    3861                                         data.dmesg[b]['color'], '')
4806                         for e in data.errorin    3862                         for e in data.errorinfo[dir]:
4807                                 # draw red li    3863                                 # draw red lines for any kernel errors found
4808                                 type, t, idx1    3864                                 type, t, idx1, idx2 = e
4809                                 id = '%d_%d'     3865                                 id = '%d_%d' % (idx1, idx2)
4810                                 right = '%f'     3866                                 right = '%f' % (((mMax-t)*100.0)/mTotal)
4811                                 devtl.html +=    3867                                 devtl.html += html_error.format(right, id, type)
4812                         for b in phases[dir]: !! 3868                         for b in sorted(phases[dir]):
4813                                 # draw the de    3869                                 # draw the devices for this phase
4814                                 phaselist = d    3870                                 phaselist = data.dmesg[b]['list']
4815                                 for d in sort !! 3871                                 for d in data.tdevlist[b]:
4816                                         dname !! 3872                                         name = d
4817                                         name, !! 3873                                         drv = ''
4818                                         drv = !! 3874                                         dev = phaselist[d]
                                                   >> 3875                                         xtraclass = ''
                                                   >> 3876                                         xtrainfo = ''
                                                   >> 3877                                         xtrastyle = ''
4819                                         if 'h    3878                                         if 'htmlclass' in dev:
4820                                                  3879                                                 xtraclass = dev['htmlclass']
4821                                         if 'c    3880                                         if 'color' in dev:
4822                                                  3881                                                 xtrastyle = 'background:%s;' % dev['color']
4823                                         if(d     3882                                         if(d in sysvals.devprops):
4824                                                  3883                                                 name = sysvals.devprops[d].altName(d)
4825                                                  3884                                                 xtraclass = sysvals.devprops[d].xtraClass()
4826                                                  3885                                                 xtrainfo = sysvals.devprops[d].xtraInfo()
4827                                         elif     3886                                         elif xtraclass == ' kth':
4828                                                  3887                                                 xtrainfo = ' kernel_thread'
4829                                         if('d    3888                                         if('drv' in dev and dev['drv']):
4830                                                  3889                                                 drv = ' {%s}' % dev['drv']
4831                                         rowhe    3890                                         rowheight = devtl.phaseRowHeight(data.testnumber, b, dev['row'])
4832                                         rowto    3891                                         rowtop = devtl.phaseRowTop(data.testnumber, b, dev['row'])
4833                                         top =    3892                                         top = '%.3f' % (rowtop + devtl.scaleH)
4834                                         left     3893                                         left = '%f' % (((dev['start']-m0)*100)/mTotal)
4835                                         width    3894                                         width = '%f' % (((dev['end']-dev['start'])*100)/mTotal)
4836                                         lengt    3895                                         length = ' (%0.3f ms) ' % ((dev['end']-dev['start'])*1000)
4837                                         title    3896                                         title = name+drv+xtrainfo+length
4838                                         if sy    3897                                         if sysvals.suspendmode == 'command':
4839                                                  3898                                                 title += sysvals.testcommand
4840                                         elif     3899                                         elif xtraclass == ' ps':
4841                                                  3900                                                 if 'suspend' in b:
4842                                                  3901                                                         title += 'pre_suspend_process'
4843                                                  3902                                                 else:
4844                                                  3903                                                         title += 'post_resume_process'
4845                                         else:    3904                                         else:
4846                                                  3905                                                 title += b
4847                                         devtl    3906                                         devtl.html += devtl.html_device.format(dev['id'], \
4848                                                  3907                                                 title, left, top, '%.3f'%rowheight, width, \
4849                                               !! 3908                                                 d+drv, xtraclass, xtrastyle)
4850                                         if('c    3909                                         if('cpuexec' in dev):
4851                                                  3910                                                 for t in sorted(dev['cpuexec']):
4852                                                  3911                                                         start, end = t
                                                   >> 3912                                                         j = float(dev['cpuexec'][t]) / 5
                                                   >> 3913                                                         if j > 1.0:
                                                   >> 3914                                                                 j = 1.0
4853                                                  3915                                                         height = '%.3f' % (rowheight/3)
4854                                                  3916                                                         top = '%.3f' % (rowtop + devtl.scaleH + 2*rowheight/3)
4855                                                  3917                                                         left = '%f' % (((start-m0)*100)/mTotal)
4856                                                  3918                                                         width = '%f' % ((end-start)*100/mTotal)
4857                                               !! 3919                                                         color = 'rgba(255, 0, 0, %f)' % j
4858                                                  3920                                                         devtl.html += \
4859                                                  3921                                                                 html_cpuexec.format(left, top, height, width, color)
4860                                         if('s    3922                                         if('src' not in dev):
4861                                                  3923                                                 continue
4862                                         # dra    3924                                         # draw any trace events for this device
4863                                         for e    3925                                         for e in dev['src']:
4864                                               << 
4865                                               << 
4866                                                  3926                                                 height = '%.3f' % devtl.rowH
4867                                                  3927                                                 top = '%.3f' % (rowtop + devtl.scaleH + (e.row*devtl.rowH))
4868                                                  3928                                                 left = '%f' % (((e.time-m0)*100)/mTotal)
4869                                                  3929                                                 width = '%f' % (e.length*100/mTotal)
4870                                                  3930                                                 xtrastyle = ''
4871                                                  3931                                                 if e.color:
4872                                                  3932                                                         xtrastyle = 'background:%s;' % e.color
4873                                                  3933                                                 devtl.html += \
4874                                                  3934                                                         html_traceevent.format(e.title(), \
4875                                                  3935                                                                 left, top, height, width, e.text(), '', xtrastyle)
4876                         # draw the time scale    3936                         # draw the time scale, try to make the number of labels readable
4877                         devtl.createTimeScale    3937                         devtl.createTimeScale(m0, mMax, tTotal, dir)
4878                         devtl.html += '</div>    3938                         devtl.html += '</div>\n'
4879                                                  3939 
4880         # timeline is finished                   3940         # timeline is finished
4881         devtl.html += '</div>\n</div>\n'         3941         devtl.html += '</div>\n</div>\n'
4882                                                  3942 
4883         # draw a legend which describes the p    3943         # draw a legend which describes the phases by color
4884         if sysvals.suspendmode != 'command':     3944         if sysvals.suspendmode != 'command':
4885                 phasedef = testruns[-1].phase !! 3945                 data = testruns[-1]
4886                 devtl.html += '<div class="le    3946                 devtl.html += '<div class="legend">\n'
4887                 pdelta = 100.0/len(phasedef.k !! 3947                 pdelta = 100.0/len(data.phases)
4888                 pmargin = pdelta / 4.0           3948                 pmargin = pdelta / 4.0
4889                 for phase in sorted(phasedef, !! 3949                 for phase in data.phases:
4890                         id, p = '', phasedef[ !! 3950                         tmp = phase.split('_')
4891                         for word in phase.spl !! 3951                         id = tmp[0][0]
4892                                 id += word[0] !! 3952                         if(len(tmp) > 1):
4893                         order = '%.2f' % ((p[ !! 3953                                 id += tmp[1][0]
4894                         name = phase.replace( !! 3954                         order = '%.2f' % ((data.dmesg[phase]['order'] * pdelta) + pmargin)
4895                         devtl.html += devtl.h !! 3955                         name = string.replace(phase, '_', ' &nbsp;')
                                                   >> 3956                         devtl.html += devtl.html_legend.format(order, \
                                                   >> 3957                                 data.dmesg[phase]['color'], name, id)
4896                 devtl.html += '</div>\n'         3958                 devtl.html += '</div>\n'
4897                                                  3959 
4898         hf = open(sysvals.htmlfile, 'w')         3960         hf = open(sysvals.htmlfile, 'w')
4899         addCSS(hf, sysvals, len(testruns), ke    3961         addCSS(hf, sysvals, len(testruns), kerror)
4900                                                  3962 
4901         # write the device timeline              3963         # write the device timeline
4902         hf.write(devtl.html)                     3964         hf.write(devtl.html)
4903         hf.write('<div id="devicedetailtitle"    3965         hf.write('<div id="devicedetailtitle"></div>\n')
4904         hf.write('<div id="devicedetail" styl    3966         hf.write('<div id="devicedetail" style="display:none;">\n')
4905         # draw the colored boxes for the devi    3967         # draw the colored boxes for the device detail section
4906         for data in testruns:                    3968         for data in testruns:
4907                 hf.write('<div id="devicedeta    3969                 hf.write('<div id="devicedetail%d">\n' % data.testnumber)
4908                 pscolor = 'linear-gradient(to    3970                 pscolor = 'linear-gradient(to top left, #ccc, #eee)'
4909                 hf.write(devtl.html_phaselet.    3971                 hf.write(devtl.html_phaselet.format('pre_suspend_process', \
4910                         '0', '0', pscolor))      3972                         '0', '0', pscolor))
4911                 for b in data.sortedPhases(): !! 3973                 for b in data.phases:
4912                         phase = data.dmesg[b]    3974                         phase = data.dmesg[b]
4913                         length = phase['end']    3975                         length = phase['end']-phase['start']
4914                         left = '%.3f' % (((ph    3976                         left = '%.3f' % (((phase['start']-t0)*100.0)/tTotal)
4915                         width = '%.3f' % ((le    3977                         width = '%.3f' % ((length*100.0)/tTotal)
4916                         hf.write(devtl.html_p    3978                         hf.write(devtl.html_phaselet.format(b, left, width, \
4917                                 data.dmesg[b]    3979                                 data.dmesg[b]['color']))
4918                 hf.write(devtl.html_phaselet.    3980                 hf.write(devtl.html_phaselet.format('post_resume_process', \
4919                         '0', '0', pscolor))      3981                         '0', '0', pscolor))
4920                 if sysvals.suspendmode == 'co    3982                 if sysvals.suspendmode == 'command':
4921                         hf.write(devtl.html_p    3983                         hf.write(devtl.html_phaselet.format('cmdexec', '0', '0', pscolor))
4922                 hf.write('</div>\n')             3984                 hf.write('</div>\n')
4923         hf.write('</div>\n')                     3985         hf.write('</div>\n')
4924                                                  3986 
4925         # write the ftrace data (callgraph)      3987         # write the ftrace data (callgraph)
4926         if sysvals.cgtest >= 0 and len(testru    3988         if sysvals.cgtest >= 0 and len(testruns) > sysvals.cgtest:
4927                 data = testruns[sysvals.cgtes    3989                 data = testruns[sysvals.cgtest]
4928         else:                                    3990         else:
4929                 data = testruns[-1]              3991                 data = testruns[-1]
4930         if sysvals.usecallgraph:                 3992         if sysvals.usecallgraph:
4931                 addCallgraphs(sysvals, hf, da    3993                 addCallgraphs(sysvals, hf, data)
4932                                                  3994 
4933         # add the test log as a hidden div       3995         # add the test log as a hidden div
4934         if sysvals.testlog and sysvals.logmsg    3996         if sysvals.testlog and sysvals.logmsg:
4935                 hf.write('<div id="testlog" s    3997                 hf.write('<div id="testlog" style="display:none;">\n'+sysvals.logmsg+'</div>\n')
4936         # add the dmesg log as a hidden div      3998         # add the dmesg log as a hidden div
4937         if sysvals.dmesglog and sysvals.dmesg    3999         if sysvals.dmesglog and sysvals.dmesgfile:
4938                 hf.write('<div id="dmesglog"     4000                 hf.write('<div id="dmesglog" style="display:none;">\n')
4939                 lf = sysvals.openlog(sysvals.    4001                 lf = sysvals.openlog(sysvals.dmesgfile, 'r')
4940                 for line in lf:                  4002                 for line in lf:
4941                         line = line.replace('    4003                         line = line.replace('<', '&lt').replace('>', '&gt')
4942                         hf.write(line)           4004                         hf.write(line)
4943                 lf.close()                       4005                 lf.close()
4944                 hf.write('</div>\n')             4006                 hf.write('</div>\n')
4945         # add the ftrace log as a hidden div     4007         # add the ftrace log as a hidden div
4946         if sysvals.ftracelog and sysvals.ftra    4008         if sysvals.ftracelog and sysvals.ftracefile:
4947                 hf.write('<div id="ftracelog"    4009                 hf.write('<div id="ftracelog" style="display:none;">\n')
4948                 lf = sysvals.openlog(sysvals.    4010                 lf = sysvals.openlog(sysvals.ftracefile, 'r')
4949                 for line in lf:                  4011                 for line in lf:
4950                         hf.write(line)           4012                         hf.write(line)
4951                 lf.close()                       4013                 lf.close()
4952                 hf.write('</div>\n')             4014                 hf.write('</div>\n')
4953                                                  4015 
4954         # write the footer and close             4016         # write the footer and close
4955         addScriptCode(hf, testruns)              4017         addScriptCode(hf, testruns)
4956         hf.write('</body>\n</html>\n')           4018         hf.write('</body>\n</html>\n')
4957         hf.close()                               4019         hf.close()
4958         return True                              4020         return True
4959                                                  4021 
4960 def addCSS(hf, sv, testcount=1, kerror=False,    4022 def addCSS(hf, sv, testcount=1, kerror=False, extra=''):
4961         kernel = sv.stamp['kernel']              4023         kernel = sv.stamp['kernel']
4962         host = sv.hostname[0].upper()+sv.host    4024         host = sv.hostname[0].upper()+sv.hostname[1:]
4963         mode = sv.suspendmode                    4025         mode = sv.suspendmode
4964         if sv.suspendmode in suspendmodename:    4026         if sv.suspendmode in suspendmodename:
4965                 mode = suspendmodename[sv.sus    4027                 mode = suspendmodename[sv.suspendmode]
4966         title = host+' '+mode+' '+kernel         4028         title = host+' '+mode+' '+kernel
4967                                                  4029 
4968         # various format changes by flags        4030         # various format changes by flags
4969         cgchk = 'checked'                        4031         cgchk = 'checked'
4970         cgnchk = 'not(:checked)'                 4032         cgnchk = 'not(:checked)'
4971         if sv.cgexp:                             4033         if sv.cgexp:
4972                 cgchk = 'not(:checked)'          4034                 cgchk = 'not(:checked)'
4973                 cgnchk = 'checked'               4035                 cgnchk = 'checked'
4974                                                  4036 
4975         hoverZ = 'z-index:8;'                    4037         hoverZ = 'z-index:8;'
4976         if sv.usedevsrc:                         4038         if sv.usedevsrc:
4977                 hoverZ = ''                      4039                 hoverZ = ''
4978                                                  4040 
4979         devlistpos = 'absolute'                  4041         devlistpos = 'absolute'
4980         if testcount > 1:                        4042         if testcount > 1:
4981                 devlistpos = 'relative'          4043                 devlistpos = 'relative'
4982                                                  4044 
4983         scaleTH = 20                             4045         scaleTH = 20
4984         if kerror:                               4046         if kerror:
4985                 scaleTH = 60                     4047                 scaleTH = 60
4986                                                  4048 
4987         # write the html header first (html h    4049         # write the html header first (html head, css code, up to body start)
4988         html_header = '<!DOCTYPE html>\n<html    4050         html_header = '<!DOCTYPE html>\n<html>\n<head>\n\
4989         <meta http-equiv="content-type" conte    4051         <meta http-equiv="content-type" content="text/html; charset=UTF-8">\n\
4990         <title>'+title+'</title>\n\              4052         <title>'+title+'</title>\n\
4991         <style type=\'text/css\'>\n\             4053         <style type=\'text/css\'>\n\
4992                 body {overflow-y:scroll;}\n\     4054                 body {overflow-y:scroll;}\n\
4993                 .stamp {width:100%;text-align    4055                 .stamp {width:100%;text-align:center;background:gray;line-height:30px;color:white;font:25px Arial;}\n\
4994                 .stamp.sysinfo {font:10px Ari    4056                 .stamp.sysinfo {font:10px Arial;}\n\
4995                 .callgraph {margin-top:30px;b    4057                 .callgraph {margin-top:30px;box-shadow:5px 5px 20px black;}\n\
4996                 .callgraph article * {padding    4058                 .callgraph article * {padding-left:28px;}\n\
4997                 h1 {color:black;font:bold 30p    4059                 h1 {color:black;font:bold 30px Times;}\n\
4998                 t0 {color:black;font:bold 30p    4060                 t0 {color:black;font:bold 30px Times;}\n\
4999                 t1 {color:black;font:30px Tim    4061                 t1 {color:black;font:30px Times;}\n\
5000                 t2 {color:black;font:25px Tim    4062                 t2 {color:black;font:25px Times;}\n\
5001                 t3 {color:black;font:20px Tim    4063                 t3 {color:black;font:20px Times;white-space:nowrap;}\n\
5002                 t4 {color:black;font:bold 30p    4064                 t4 {color:black;font:bold 30px Times;line-height:60px;white-space:nowrap;}\n\
5003                 cS {font:bold 13px Times;}\n\    4065                 cS {font:bold 13px Times;}\n\
5004                 table {width:100%;}\n\           4066                 table {width:100%;}\n\
5005                 .gray {background:rgba(80,80,    4067                 .gray {background:rgba(80,80,80,0.1);}\n\
5006                 .green {background:rgba(204,2    4068                 .green {background:rgba(204,255,204,0.4);}\n\
5007                 .purple {background:rgba(128,    4069                 .purple {background:rgba(128,0,128,0.2);}\n\
5008                 .yellow {background:rgba(255,    4070                 .yellow {background:rgba(255,255,204,0.4);}\n\
5009                 .blue {background:rgba(169,20    4071                 .blue {background:rgba(169,208,245,0.4);}\n\
5010                 .time1 {font:22px Arial;borde    4072                 .time1 {font:22px Arial;border:1px solid;}\n\
5011                 .time2 {font:15px Arial;borde    4073                 .time2 {font:15px Arial;border-bottom:1px solid;border-left:1px solid;border-right:1px solid;}\n\
5012                 .testfail {font:bold 22px Ari    4074                 .testfail {font:bold 22px Arial;color:red;border:1px dashed;}\n\
5013                 td {text-align:center;}\n\       4075                 td {text-align:center;}\n\
5014                 r {color:#500000;font:15px Ta    4076                 r {color:#500000;font:15px Tahoma;}\n\
5015                 n {color:#505050;font:15px Ta    4077                 n {color:#505050;font:15px Tahoma;}\n\
5016                 .tdhl {color:red;}\n\            4078                 .tdhl {color:red;}\n\
5017                 .hide {display:none;}\n\         4079                 .hide {display:none;}\n\
5018                 .pf {display:none;}\n\           4080                 .pf {display:none;}\n\
5019                 .pf:'+cgchk+' + label {backgr    4081                 .pf:'+cgchk+' + label {background:url(\'data:image/svg+xml;utf,<?xml version="1.0" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" height="18" width="18" version="1.1"><circle cx="9" cy="9" r="8" stroke="black" stroke-width="1" fill="white"/><rect x="4" y="8" width="10" height="2" style="fill:black;stroke-width:0"/><rect x="8" y="4" width="2" height="10" style="fill:black;stroke-width:0"/></svg>\') no-repeat left center;}\n\
5020                 .pf:'+cgnchk+' ~ label {backg    4082                 .pf:'+cgnchk+' ~ label {background:url(\'data:image/svg+xml;utf,<?xml version="1.0" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" height="18" width="18" version="1.1"><circle cx="9" cy="9" r="8" stroke="black" stroke-width="1" fill="white"/><rect x="4" y="8" width="10" height="2" style="fill:black;stroke-width:0"/></svg>\') no-repeat left center;}\n\
5021                 .pf:'+cgchk+' ~ *:not(:nth-ch    4083                 .pf:'+cgchk+' ~ *:not(:nth-child(2)) {display:none;}\n\
5022                 .zoombox {position:relative;w    4084                 .zoombox {position:relative;width:100%;overflow-x:scroll;-webkit-user-select:none;-moz-user-select:none;user-select:none;}\n\
5023                 .timeline {position:relative;    4085                 .timeline {position:relative;font-size:14px;cursor:pointer;width:100%; overflow:hidden;background:linear-gradient(#cccccc, white);}\n\
5024                 .thread {position:absolute;he    4086                 .thread {position:absolute;height:0%;overflow:hidden;z-index:7;line-height:30px;font-size:14px;border:1px solid;text-align:center;white-space:nowrap;}\n\
5025                 .thread.ps {border-radius:3px    4087                 .thread.ps {border-radius:3px;background:linear-gradient(to top, #ccc, #eee);}\n\
5026                 .thread:hover {background:whi    4088                 .thread:hover {background:white;border:1px solid red;'+hoverZ+'}\n\
5027                 .thread.sec,.thread.sec:hover    4089                 .thread.sec,.thread.sec:hover {background:black;border:0;color:white;line-height:15px;font-size:10px;}\n\
5028                 .hover {background:white;bord    4090                 .hover {background:white;border:1px solid red;'+hoverZ+'}\n\
5029                 .hover.sync {background:white    4091                 .hover.sync {background:white;}\n\
5030                 .hover.bg,.hover.kth,.hover.s    4092                 .hover.bg,.hover.kth,.hover.sync,.hover.ps {background:white;}\n\
5031                 .jiffie {position:absolute;po    4093                 .jiffie {position:absolute;pointer-events: none;z-index:8;}\n\
5032                 .traceevent {position:absolut    4094                 .traceevent {position:absolute;font-size:10px;z-index:7;overflow:hidden;color:black;text-align:center;white-space:nowrap;border-radius:5px;border:1px solid black;background:linear-gradient(to bottom right,#CCC,#969696);}\n\
5033                 .traceevent:hover {color:whit    4095                 .traceevent:hover {color:white;font-weight:bold;border:1px solid white;}\n\
5034                 .phase {position:absolute;ove    4096                 .phase {position:absolute;overflow:hidden;border:0px;text-align:center;}\n\
5035                 .phaselet {float:left;overflo    4097                 .phaselet {float:left;overflow:hidden;border:0px;text-align:center;min-height:100px;font-size:24px;}\n\
5036                 .t {position:absolute;line-he    4098                 .t {position:absolute;line-height:'+('%d'%scaleTH)+'px;pointer-events:none;top:0;height:100%;border-right:1px solid black;z-index:6;}\n\
5037                 .err {position:absolute;top:0    4099                 .err {position:absolute;top:0%;height:100%;border-right:3px solid red;color:red;font:bold 14px Times;line-height:18px;}\n\
5038                 .legend {position:relative; w    4100                 .legend {position:relative; width:100%; height:40px; text-align:center;margin-bottom:20px}\n\
5039                 .legend .square {position:abs    4101                 .legend .square {position:absolute;cursor:pointer;top:10px; width:0px;height:20px;border:1px solid;padding-left:20px;}\n\
5040                 button {height:40px;width:200    4102                 button {height:40px;width:200px;margin-bottom:20px;margin-top:20px;font-size:24px;}\n\
5041                 .btnfmt {position:relative;fl    4103                 .btnfmt {position:relative;float:right;height:25px;width:auto;margin-top:3px;margin-bottom:0;font-size:10px;text-align:center;}\n\
5042                 .devlist {position:'+devlistp    4104                 .devlist {position:'+devlistpos+';width:190px;}\n\
5043                 a:link {color:white;text-deco    4105                 a:link {color:white;text-decoration:none;}\n\
5044                 a:visited {color:white;}\n\      4106                 a:visited {color:white;}\n\
5045                 a:hover {color:white;}\n\        4107                 a:hover {color:white;}\n\
5046                 a:active {color:white;}\n\       4108                 a:active {color:white;}\n\
5047                 .version {position:relative;f    4109                 .version {position:relative;float:left;color:white;font-size:10px;line-height:30px;margin-left:10px;}\n\
5048                 #devicedetail {min-height:100    4110                 #devicedetail {min-height:100px;box-shadow:5px 5px 20px black;}\n\
5049                 .tblock {position:absolute;he    4111                 .tblock {position:absolute;height:100%;background:#ddd;}\n\
5050                 .tback {position:absolute;wid    4112                 .tback {position:absolute;width:100%;background:linear-gradient(#ccc, #ddd);}\n\
5051                 .bg {z-index:1;}\n\              4113                 .bg {z-index:1;}\n\
5052 '+extra+'\                                       4114 '+extra+'\
5053         </style>\n</head>\n<body>\n'             4115         </style>\n</head>\n<body>\n'
5054         hf.write(html_header)                    4116         hf.write(html_header)
5055                                                  4117 
5056 # Function: addScriptCode                        4118 # Function: addScriptCode
5057 # Description:                                   4119 # Description:
5058 #        Adds the javascript code to the outp    4120 #        Adds the javascript code to the output html
5059 # Arguments:                                     4121 # Arguments:
5060 #        hf: the open html file pointer          4122 #        hf: the open html file pointer
5061 #        testruns: array of Data objects from    4123 #        testruns: array of Data objects from parseKernelLog or parseTraceLog
5062 def addScriptCode(hf, testruns):                 4124 def addScriptCode(hf, testruns):
5063         t0 = testruns[0].start * 1000            4125         t0 = testruns[0].start * 1000
5064         tMax = testruns[-1].end * 1000           4126         tMax = testruns[-1].end * 1000
5065         hf.write('<script type="text/javascri << 
5066         # create an array in javascript memor    4127         # create an array in javascript memory with the device details
5067         detail = '      var devtable = [];\n'    4128         detail = '      var devtable = [];\n'
5068         for data in testruns:                    4129         for data in testruns:
5069                 topo = data.deviceTopology()     4130                 topo = data.deviceTopology()
5070                 detail += '     devtable[%d]     4131                 detail += '     devtable[%d] = "%s";\n' % (data.testnumber, topo)
5071         detail += '     var bounds = [%f,%f];    4132         detail += '     var bounds = [%f,%f];\n' % (t0, tMax)
5072         # add the code which will manipulate     4133         # add the code which will manipulate the data in the browser
5073         hf.write(detail);                     !! 4134         script_code = \
5074         script_code = r"""      var resolutio !! 4135         '<script type="text/javascript">\n'+detail+\
5075         var dragval = [0, 0];                 !! 4136         '       var resolution = -1;\n'\
5076         function redrawTimescale(t0, tMax, tS !! 4137         '       var dragval = [0, 0];\n'\
5077                 var rline = '<div class="t" s !! 4138         '       function redrawTimescale(t0, tMax, tS) {\n'\
5078                 var tTotal = tMax - t0;       !! 4139         '               var rline = \'<div class="t" style="left:0;border-left:1px solid black;border-right:0;">\';\n'\
5079                 var list = document.getElemen !! 4140         '               var tTotal = tMax - t0;\n'\
5080                 for (var i = 0; i < list.leng !! 4141         '               var list = document.getElementsByClassName("tblock");\n'\
5081                         var timescale = list[ !! 4142         '               for (var i = 0; i < list.length; i++) {\n'\
5082                         var m0 = t0 + (tTotal !! 4143         '                       var timescale = list[i].getElementsByClassName("timescale")[0];\n'\
5083                         var mTotal = tTotal*p !! 4144         '                       var m0 = t0 + (tTotal*parseFloat(list[i].style.left)/100);\n'\
5084                         var mMax = m0 + mTota !! 4145         '                       var mTotal = tTotal*parseFloat(list[i].style.width)/100;\n'\
5085                         var html = "";        !! 4146         '                       var mMax = m0 + mTotal;\n'\
5086                         var divTotal = Math.f !! 4147         '                       var html = "";\n'\
5087                         if(divTotal > 1000) c !! 4148         '                       var divTotal = Math.floor(mTotal/tS) + 1;\n'\
5088                         var divEdge = (mTotal !! 4149         '                       if(divTotal > 1000) continue;\n'\
5089                         var pos = 0.0, val =  !! 4150         '                       var divEdge = (mTotal - tS*(divTotal-1))*100/mTotal;\n'\
5090                         for (var j = 0; j < d !! 4151         '                       var pos = 0.0, val = 0.0;\n'\
5091                                 var htmlline  !! 4152         '                       for (var j = 0; j < divTotal; j++) {\n'\
5092                                 var mode = li !! 4153         '                               var htmlline = "";\n'\
5093                                 if(mode == "s !! 4154         '                               var mode = list[i].id[5];\n'\
5094                                         pos = !! 4155         '                               if(mode == "s") {\n'\
5095                                         val = !! 4156         '                                       pos = 100 - (((j)*tS*100)/mTotal) - divEdge;\n'\
5096                                         if(j  !! 4157         '                                       val = (j-divTotal+1)*tS;\n'\
5097                                               !! 4158         '                                       if(j == divTotal - 1)\n'\
5098                                         else  !! 4159         '                                               htmlline = \'<div class="t" style="right:\'+pos+\'%"><cS>S&rarr;</cS></div>\';\n'\
5099                                               !! 4160         '                                       else\n'\
5100                                 } else {      !! 4161         '                                               htmlline = \'<div class="t" style="right:\'+pos+\'%">\'+val+\'ms</div>\';\n'\
5101                                         pos = !! 4162         '                               } else {\n'\
5102                                         val = !! 4163         '                                       pos = 100 - (((j)*tS*100)/mTotal);\n'\
5103                                         htmll !! 4164         '                                       val = (j)*tS;\n'\
5104                                         if(j  !! 4165         '                                       htmlline = \'<div class="t" style="right:\'+pos+\'%">\'+val+\'ms</div>\';\n'\
5105                                               !! 4166         '                                       if(j == 0)\n'\
5106                                               !! 4167         '                                               if(mode == "r")\n'\
5107                                               !! 4168         '                                                       htmlline = rline+"<cS>&larr;R</cS></div>";\n'\
5108                                               !! 4169         '                                               else\n'\
5109                                 }             !! 4170         '                                                       htmlline = rline+"<cS>0ms</div>";\n'\
5110                                 html += htmll !! 4171         '                               }\n'\
5111                         }                     !! 4172         '                               html += htmlline;\n'\
5112                         timescale.innerHTML = !! 4173         '                       }\n'\
5113                 }                             !! 4174         '                       timescale.innerHTML = html;\n'\
5114         }                                     !! 4175         '               }\n'\
5115         function zoomTimeline() {             !! 4176         '       }\n'\
5116                 var dmesg = document.getEleme !! 4177         '       function zoomTimeline() {\n'\
5117                 var zoombox = document.getEle !! 4178         '               var dmesg = document.getElementById("dmesg");\n'\
5118                 var left = zoombox.scrollLeft !! 4179         '               var zoombox = document.getElementById("dmesgzoombox");\n'\
5119                 var val = parseFloat(dmesg.st !! 4180         '               var left = zoombox.scrollLeft;\n'\
5120                 var newval = 100;             !! 4181         '               var val = parseFloat(dmesg.style.width);\n'\
5121                 var sh = window.outerWidth /  !! 4182         '               var newval = 100;\n'\
5122                 if(this.id == "zoomin") {     !! 4183         '               var sh = window.outerWidth / 2;\n'\
5123                         newval = val * 1.2;   !! 4184         '               if(this.id == "zoomin") {\n'\
5124                         if(newval > 910034) n !! 4185         '                       newval = val * 1.2;\n'\
5125                         dmesg.style.width = n !! 4186         '                       if(newval > 910034) newval = 910034;\n'\
5126                         zoombox.scrollLeft =  !! 4187         '                       dmesg.style.width = newval+"%";\n'\
5127                 } else if (this.id == "zoomou !! 4188         '                       zoombox.scrollLeft = ((left + sh) * newval / val) - sh;\n'\
5128                         newval = val / 1.2;   !! 4189         '               } else if (this.id == "zoomout") {\n'\
5129                         if(newval < 100) newv !! 4190         '                       newval = val / 1.2;\n'\
5130                         dmesg.style.width = n !! 4191         '                       if(newval < 100) newval = 100;\n'\
5131                         zoombox.scrollLeft =  !! 4192         '                       dmesg.style.width = newval+"%";\n'\
5132                 } else {                      !! 4193         '                       zoombox.scrollLeft = ((left + sh) * newval / val) - sh;\n'\
5133                         zoombox.scrollLeft =  !! 4194         '               } else {\n'\
5134                         dmesg.style.width = " !! 4195         '                       zoombox.scrollLeft = 0;\n'\
5135                 }                             !! 4196         '                       dmesg.style.width = "100%";\n'\
5136                 var tS = [10000, 5000, 2000,  !! 4197         '               }\n'\
5137                 var t0 = bounds[0];           !! 4198         '               var tS = [10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1];\n'\
5138                 var tMax = bounds[1];         !! 4199         '               var t0 = bounds[0];\n'\
5139                 var tTotal = tMax - t0;       !! 4200         '               var tMax = bounds[1];\n'\
5140                 var wTotal = tTotal * 100.0 / !! 4201         '               var tTotal = tMax - t0;\n'\
5141                 var idx = 7*window.innerWidth !! 4202         '               var wTotal = tTotal * 100.0 / newval;\n'\
5142                 for(var i = 0; (i < tS.length !! 4203         '               var idx = 7*window.innerWidth/1100;\n'\
5143                 if(i >= tS.length) i = tS.len !! 4204         '               for(var i = 0; (i < tS.length)&&((wTotal / tS[i]) < idx); i++);\n'\
5144                 if(tS[i] == resolution) retur !! 4205         '               if(i >= tS.length) i = tS.length - 1;\n'\
5145                 resolution = tS[i];           !! 4206         '               if(tS[i] == resolution) return;\n'\
5146                 redrawTimescale(t0, tMax, tS[ !! 4207         '               resolution = tS[i];\n'\
5147         }                                     !! 4208         '               redrawTimescale(t0, tMax, tS[i]);\n'\
5148         function deviceName(title) {          !! 4209         '       }\n'\
5149                 var name = title.slice(0, tit !! 4210         '       function deviceName(title) {\n'\
5150                 return name;                  !! 4211         '               var name = title.slice(0, title.indexOf(" ("));\n'\
5151         }                                     !! 4212         '               return name;\n'\
5152         function deviceHover() {              !! 4213         '       }\n'\
5153                 var name = deviceName(this.ti !! 4214         '       function deviceHover() {\n'\
5154                 var dmesg = document.getEleme !! 4215         '               var name = deviceName(this.title);\n'\
5155                 var dev = dmesg.getElementsBy !! 4216         '               var dmesg = document.getElementById("dmesg");\n'\
5156                 var cpu = -1;                 !! 4217         '               var dev = dmesg.getElementsByClassName("thread");\n'\
5157                 if(name.match("CPU_ON\[[0-9]* !! 4218         '               var cpu = -1;\n'\
5158                         cpu = parseInt(name.s !! 4219         '               if(name.match("CPU_ON\[[0-9]*\]"))\n'\
5159                 else if(name.match("CPU_OFF\[ !! 4220         '                       cpu = parseInt(name.slice(7));\n'\
5160                         cpu = parseInt(name.s !! 4221         '               else if(name.match("CPU_OFF\[[0-9]*\]"))\n'\
5161                 for (var i = 0; i < dev.lengt !! 4222         '                       cpu = parseInt(name.slice(8));\n'\
5162                         dname = deviceName(de !! 4223         '               for (var i = 0; i < dev.length; i++) {\n'\
5163                         var cname = dev[i].cl !! 4224         '                       dname = deviceName(dev[i].title);\n'\
5164                         if((cpu >= 0 && dname !! 4225         '                       var cname = dev[i].className.slice(dev[i].className.indexOf("thread"));\n'\
5165                                 (name == dnam !! 4226         '                       if((cpu >= 0 && dname.match("CPU_O[NF]*\\\[*"+cpu+"\\\]")) ||\n'\
5166                         {                     !! 4227         '                               (name == dname))\n'\
5167                                 dev[i].classN !! 4228         '                       {\n'\
5168                         } else {              !! 4229         '                               dev[i].className = "hover "+cname;\n'\
5169                                 dev[i].classN !! 4230         '                       } else {\n'\
5170                         }                     !! 4231         '                               dev[i].className = cname;\n'\
5171                 }                             !! 4232         '                       }\n'\
5172         }                                     !! 4233         '               }\n'\
5173         function deviceUnhover() {            !! 4234         '       }\n'\
5174                 var dmesg = document.getEleme !! 4235         '       function deviceUnhover() {\n'\
5175                 var dev = dmesg.getElementsBy !! 4236         '               var dmesg = document.getElementById("dmesg");\n'\
5176                 for (var i = 0; i < dev.lengt !! 4237         '               var dev = dmesg.getElementsByClassName("thread");\n'\
5177                         dev[i].className = de !! 4238         '               for (var i = 0; i < dev.length; i++) {\n'\
5178                 }                             !! 4239         '                       dev[i].className = dev[i].className.slice(dev[i].className.indexOf("thread"));\n'\
5179         }                                     !! 4240         '               }\n'\
5180         function deviceTitle(title, total, cp !! 4241         '       }\n'\
5181                 var prefix = "Total";         !! 4242         '       function deviceTitle(title, total, cpu) {\n'\
5182                 if(total.length > 3) {        !! 4243         '               var prefix = "Total";\n'\
5183                         prefix = "Average";   !! 4244         '               if(total.length > 3) {\n'\
5184                         total[1] = (total[1]+ !! 4245         '                       prefix = "Average";\n'\
5185                         total[2] = (total[2]+ !! 4246         '                       total[1] = (total[1]+total[3])/2;\n'\
5186                 }                             !! 4247         '                       total[2] = (total[2]+total[4])/2;\n'\
5187                 var devtitle = document.getEl !! 4248         '               }\n'\
5188                 var name = deviceName(title); !! 4249         '               var devtitle = document.getElementById("devicedetailtitle");\n'\
5189                 if(cpu >= 0) name = "CPU"+cpu !! 4250         '               var name = deviceName(title);\n'\
5190                 var driver = "";              !! 4251         '               if(cpu >= 0) name = "CPU"+cpu;\n'\
5191                 var tS = "<t2>(</t2>";        !! 4252         '               var driver = "";\n'\
5192                 var tR = "<t2>)</t2>";        !! 4253         '               var tS = "<t2>(</t2>";\n'\
5193                 if(total[1] > 0)              !! 4254         '               var tR = "<t2>)</t2>";\n'\
5194                         tS = "<t2>("+prefix+" !! 4255         '               if(total[1] > 0)\n'\
5195                 if(total[2] > 0)              !! 4256         '                       tS = "<t2>("+prefix+" Suspend:</t2><t0> "+total[1].toFixed(3)+" ms</t0> ";\n'\
5196                         tR = " <t2>"+prefix+" !! 4257         '               if(total[2] > 0)\n'\
5197                 var s = title.indexOf("{");   !! 4258         '                       tR = " <t2>"+prefix+" Resume:</t2><t0> "+total[2].toFixed(3)+" ms<t2>)</t2></t0>";\n'\
5198                 var e = title.indexOf("}");   !! 4259         '               var s = title.indexOf("{");\n'\
5199                 if((s >= 0) && (e >= 0))      !! 4260         '               var e = title.indexOf("}");\n'\
5200                         driver = title.slice(< !! 4261         '               if((s >= 0) && (e >= 0))\n'\
5201                 if(total[1] > 0 && total[2] > !! 4262         '                       driver = title.slice(s+1, e) + " <t1>@</t1> ";\n'\
5202                         devtitle.innerHTML =  !! 4263         '               if(total[1] > 0 && total[2] > 0)\n'\
5203                 else                          !! 4264         '                       devtitle.innerHTML = "<t0>"+driver+name+"</t0> "+tS+tR;\n'\
5204                         devtitle.innerHTML =  !! 4265         '               else\n'\
5205                 return name;                  !! 4266         '                       devtitle.innerHTML = "<t0>"+title+"</t0>";\n'\
5206         }                                     !! 4267         '               return name;\n'\
5207         function deviceDetail() {             !! 4268         '       }\n'\
5208                 var devinfo = document.getEle !! 4269         '       function deviceDetail() {\n'\
5209                 devinfo.style.display = "bloc !! 4270         '               var devinfo = document.getElementById("devicedetail");\n'\
5210                 var name = deviceName(this.ti !! 4271         '               devinfo.style.display = "block";\n'\
5211                 var cpu = -1;                 !! 4272         '               var name = deviceName(this.title);\n'\
5212                 if(name.match("CPU_ON\[[0-9]* !! 4273         '               var cpu = -1;\n'\
5213                         cpu = parseInt(name.s !! 4274         '               if(name.match("CPU_ON\[[0-9]*\]"))\n'\
5214                 else if(name.match("CPU_OFF\[ !! 4275         '                       cpu = parseInt(name.slice(7));\n'\
5215                         cpu = parseInt(name.s !! 4276         '               else if(name.match("CPU_OFF\[[0-9]*\]"))\n'\
5216                 var dmesg = document.getEleme !! 4277         '                       cpu = parseInt(name.slice(8));\n'\
5217                 var dev = dmesg.getElementsBy !! 4278         '               var dmesg = document.getElementById("dmesg");\n'\
5218                 var idlist = [];              !! 4279         '               var dev = dmesg.getElementsByClassName("thread");\n'\
5219                 var pdata = [[]];             !! 4280         '               var idlist = [];\n'\
5220                 if(document.getElementById("d !! 4281         '               var pdata = [[]];\n'\
5221                         pdata = [[], []];     !! 4282         '               if(document.getElementById("devicedetail1"))\n'\
5222                 var pd = pdata[0];            !! 4283         '                       pdata = [[], []];\n'\
5223                 var total = [0.0, 0.0, 0.0];  !! 4284         '               var pd = pdata[0];\n'\
5224                 for (var i = 0; i < dev.lengt !! 4285         '               var total = [0.0, 0.0, 0.0];\n'\
5225                         dname = deviceName(de !! 4286         '               for (var i = 0; i < dev.length; i++) {\n'\
5226                         if((cpu >= 0 && dname !! 4287         '                       dname = deviceName(dev[i].title);\n'\
5227                                 (name == dnam !! 4288         '                       if((cpu >= 0 && dname.match("CPU_O[NF]*\\\[*"+cpu+"\\\]")) ||\n'\
5228                         {                     !! 4289         '                               (name == dname))\n'\
5229                                 idlist[idlist !! 4290         '                       {\n'\
5230                                 var tidx = 1; !! 4291         '                               idlist[idlist.length] = dev[i].id;\n'\
5231                                 if(dev[i].id[ !! 4292         '                               var tidx = 1;\n'\
5232                                         pd =  !! 4293         '                               if(dev[i].id[0] == "a") {\n'\
5233                                 } else {      !! 4294         '                                       pd = pdata[0];\n'\
5234                                         if(pd !! 4295         '                               } else {\n'\
5235                                         if(to !! 4296         '                                       if(pdata.length == 1) pdata[1] = [];\n'\
5236                                         pd =  !! 4297         '                                       if(total.length == 3) total[3]=total[4]=0.0;\n'\
5237                                         tidx  !! 4298         '                                       pd = pdata[1];\n'\
5238                                 }             !! 4299         '                                       tidx = 3;\n'\
5239                                 var info = de !! 4300         '                               }\n'\
5240                                 var pname = i !! 4301         '                               var info = dev[i].title.split(" ");\n'\
5241                                 pd[pname] = p !! 4302         '                               var pname = info[info.length-1];\n'\
5242                                 total[0] += p !! 4303         '                               pd[pname] = parseFloat(info[info.length-3].slice(1));\n'\
5243                                 if(pname.inde !! 4304         '                               total[0] += pd[pname];\n'\
5244                                         total !! 4305         '                               if(pname.indexOf("suspend") >= 0)\n'\
5245                                 else          !! 4306         '                                       total[tidx] += pd[pname];\n'\
5246                                         total !! 4307         '                               else\n'\
5247                         }                     !! 4308         '                                       total[tidx+1] += pd[pname];\n'\
5248                 }                             !! 4309         '                       }\n'\
5249                 var devname = deviceTitle(thi !! 4310         '               }\n'\
5250                 var left = 0.0;               !! 4311         '               var devname = deviceTitle(this.title, total, cpu);\n'\
5251                 for (var t = 0; t < pdata.len !! 4312         '               var left = 0.0;\n'\
5252                         pd = pdata[t];        !! 4313         '               for (var t = 0; t < pdata.length; t++) {\n'\
5253                         devinfo = document.ge !! 4314         '                       pd = pdata[t];\n'\
5254                         var phases = devinfo. !! 4315         '                       devinfo = document.getElementById("devicedetail"+t);\n'\
5255                         for (var i = 0; i < p !! 4316         '                       var phases = devinfo.getElementsByClassName("phaselet");\n'\
5256                                 if(phases[i]. !! 4317         '                       for (var i = 0; i < phases.length; i++) {\n'\
5257                                         var w !! 4318         '                               if(phases[i].id in pd) {\n'\
5258                                         var f !! 4319         '                                       var w = 100.0*pd[phases[i].id]/total[0];\n'\
5259                                         if(w  !! 4320         '                                       var fs = 32;\n'\
5260                                         var f !! 4321         '                                       if(w < 8) fs = 4*w | 0;\n'\
5261                                         phase !! 4322         '                                       var fs2 = fs*3/4;\n'\
5262                                         phase !! 4323         '                                       phases[i].style.width = w+"%";\n'\
5263                                         phase !! 4324         '                                       phases[i].style.left = left+"%";\n'\
5264                                         left  !! 4325         '                                       phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms";\n'\
5265                                         var t !! 4326         '                                       left += w;\n'\
5266                                         var p !! 4327         '                                       var time = "<t4 style=\\"font-size:"+fs+"px\\">"+pd[phases[i].id]+" ms<br></t4>";\n'\
5267                                         phase !! 4328         '                                       var pname = "<t3 style=\\"font-size:"+fs2+"px\\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>";\n'\
5268                                 } else {      !! 4329         '                                       phases[i].innerHTML = time+pname;\n'\
5269                                         phase !! 4330         '                               } else {\n'\
5270                                         phase !! 4331         '                                       phases[i].style.width = "0%";\n'\
5271                                 }             !! 4332         '                                       phases[i].style.left = left+"%";\n'\
5272                         }                     !! 4333         '                               }\n'\
5273                 }                             !! 4334         '                       }\n'\
5274                 if(typeof devstats !== 'undef !! 4335         '               }\n'\
5275                         callDetail(this.id, t !! 4336         '               if(typeof devstats !== \'undefined\')\n'\
5276                 var cglist = document.getElem !! 4337         '                       callDetail(this.id, this.title);\n'\
5277                 if(!cglist) return;           !! 4338         '               var cglist = document.getElementById("callgraphs");\n'\
5278                 var cg = cglist.getElementsBy !! 4339         '               if(!cglist) return;\n'\
5279                 if(cg.length < 10) return;    !! 4340         '               var cg = cglist.getElementsByClassName("atop");\n'\
5280                 for (var i = 0; i < cg.length !! 4341         '               if(cg.length < 10) return;\n'\
5281                         cgid = cg[i].id.split !! 4342         '               for (var i = 0; i < cg.length; i++) {\n'\
5282                         if(idlist.indexOf(cgi !! 4343         '                       cgid = cg[i].id.split("x")[0]\n'\
5283                                 cg[i].style.d !! 4344         '                       if(idlist.indexOf(cgid) >= 0) {\n'\
5284                         } else {              !! 4345         '                               cg[i].style.display = "block";\n'\
5285                                 cg[i].style.d !! 4346         '                       } else {\n'\
5286                         }                     !! 4347         '                               cg[i].style.display = "none";\n'\
5287                 }                             !! 4348         '                       }\n'\
5288         }                                     !! 4349         '               }\n'\
5289         function callDetail(devid, devtitle)  !! 4350         '       }\n'\
5290                 if(!(devid in devstats) || de !! 4351         '       function callDetail(devid, devtitle) {\n'\
5291                         return;               !! 4352         '               if(!(devid in devstats) || devstats[devid].length < 1)\n'\
5292                 var list = devstats[devid];   !! 4353         '                       return;\n'\
5293                 var tmp = devtitle.split(" ") !! 4354         '               var list = devstats[devid];\n'\
5294                 var name = tmp[0], phase = tm !! 4355         '               var tmp = devtitle.split(" ");\n'\
5295                 var dd = document.getElementB !! 4356         '               var name = tmp[0], phase = tmp[tmp.length-1];\n'\
5296                 var total = parseFloat(tmp[1] !! 4357         '               var dd = document.getElementById(phase);\n'\
5297                 var mlist = [];               !! 4358         '               var total = parseFloat(tmp[1].slice(1));\n'\
5298                 var maxlen = 0;               !! 4359         '               var mlist = [];\n'\
5299                 var info = []                 !! 4360         '               var maxlen = 0;\n'\
5300                 for(var i in list) {          !! 4361         '               var info = []\n'\
5301                         if(list[i][0] == "@") !! 4362         '               for(var i in list) {\n'\
5302                                 info = list[i !! 4363         '                       if(list[i][0] == "@") {\n'\
5303                                 continue;     !! 4364         '                               info = list[i].split("|");\n'\
5304                         }                     !! 4365         '                               continue;\n'\
5305                         var tmp = list[i].spl !! 4366         '                       }\n'\
5306                         var t = parseFloat(tm !! 4367         '                       var tmp = list[i].split("|");\n'\
5307                         var p = (t*100.0/tota !! 4368         '                       var t = parseFloat(tmp[0]), f = tmp[1], c = parseInt(tmp[2]);\n'\
5308                         mlist[mlist.length] = !! 4369         '                       var p = (t*100.0/total).toFixed(2);\n'\
5309                         if(f.length > maxlen) !! 4370         '                       mlist[mlist.length] = [f, c, t.toFixed(2), p+"%"];\n'\
5310                                 maxlen = f.le !! 4371         '                       if(f.length > maxlen)\n'\
5311                 }                             !! 4372         '                               maxlen = f.length;\n'\
5312                 var pad = 5;                  !! 4373         '               }\n'\
5313                 if(mlist.length == 0) pad = 3 !! 4374         '               var pad = 5;\n'\
5314                 var html = '<div style="paddi !! 4375         '               if(mlist.length == 0) pad = 30;\n'\
5315                 if(info.length > 2)           !! 4376         '               var html = \'<div style="padding-top:\'+pad+\'px"><t3> <b>\'+name+\':</b>\';\n'\
5316                         html += " start=<b>"+ !! 4377         '               if(info.length > 2)\n'\
5317                 if(info.length > 3)           !! 4378         '                       html += " start=<b>"+info[1]+"</b>, end=<b>"+info[2]+"</b>";\n'\
5318                         html += ", length<i>( !! 4379         '               if(info.length > 3)\n'\
5319                 if(info.length > 4)           !! 4380         '                       html += ", length<i>(w/o overhead)</i>=<b>"+info[3]+" ms</b>";\n'\
5320                         html += ", return=<b> !! 4381         '               if(info.length > 4)\n'\
5321                 html += "</t3></div>";        !! 4382         '                       html += ", return=<b>"+info[4]+"</b>";\n'\
5322                 if(mlist.length > 0) {        !! 4383         '               html += "</t3></div>";\n'\
5323                         html += '<table class !! 4384         '               if(mlist.length > 0) {\n'\
5324                         for(var i in mlist)   !! 4385         '                       html += \'<table class=fstat style="padding-top:\'+(maxlen*5)+\'px;"><tr><th>Function</th>\';\n'\
5325                                 html += "<td  !! 4386         '                       for(var i in mlist)\n'\
5326                         html += "</tr><tr><th !! 4387         '                               html += "<td class=vt>"+mlist[i][0]+"</td>";\n'\
5327                         for(var i in mlist)   !! 4388         '                       html += "</tr><tr><th>Calls</th>";\n'\
5328                                 html += "<td> !! 4389         '                       for(var i in mlist)\n'\
5329                         html += "</tr><tr><th !! 4390         '                               html += "<td>"+mlist[i][1]+"</td>";\n'\
5330                         for(var i in mlist)   !! 4391         '                       html += "</tr><tr><th>Time(ms)</th>";\n'\
5331                                 html += "<td> !! 4392         '                       for(var i in mlist)\n'\
5332                         html += "</tr><tr><th !! 4393         '                               html += "<td>"+mlist[i][2]+"</td>";\n'\
5333                         for(var i in mlist)   !! 4394         '                       html += "</tr><tr><th>Percent</th>";\n'\
5334                                 html += "<td> !! 4395         '                       for(var i in mlist)\n'\
5335                         html += "</tr></table !! 4396         '                               html += "<td>"+mlist[i][3]+"</td>";\n'\
5336                 }                             !! 4397         '                       html += "</tr></table>";\n'\
5337                 dd.innerHTML = html;          !! 4398         '               }\n'\
5338                 var height = (maxlen*5)+100;  !! 4399         '               dd.innerHTML = html;\n'\
5339                 dd.style.height = height+"px" !! 4400         '               var height = (maxlen*5)+100;\n'\
5340                 document.getElementById("devi !! 4401         '               dd.style.height = height+"px";\n'\
5341         }                                     !! 4402         '               document.getElementById("devicedetail").style.height = height+"px";\n'\
5342         function callSelect() {               !! 4403         '       }\n'\
5343                 var cglist = document.getElem !! 4404         '       function callSelect() {\n'\
5344                 if(!cglist) return;           !! 4405         '               var cglist = document.getElementById("callgraphs");\n'\
5345                 var cg = cglist.getElementsBy !! 4406         '               if(!cglist) return;\n'\
5346                 for (var i = 0; i < cg.length !! 4407         '               var cg = cglist.getElementsByClassName("atop");\n'\
5347                         if(this.id == cg[i].i !! 4408         '               for (var i = 0; i < cg.length; i++) {\n'\
5348                                 cg[i].style.d !! 4409         '                       if(this.id == cg[i].id) {\n'\
5349                         } else {              !! 4410         '                               cg[i].style.display = "block";\n'\
5350                                 cg[i].style.d !! 4411         '                       } else {\n'\
5351                         }                     !! 4412         '                               cg[i].style.display = "none";\n'\
5352                 }                             !! 4413         '                       }\n'\
5353         }                                     !! 4414         '               }\n'\
5354         function devListWindow(e) {           !! 4415         '       }\n'\
5355                 var win = window.open();      !! 4416         '       function devListWindow(e) {\n'\
5356                 var html = "<title>"+e.target !! 4417         '               var win = window.open();\n'\
5357                         "<style type=\"text/c !! 4418         '               var html = "<title>"+e.target.innerHTML+"</title>"+\n'\
5358                         "   ul {list-style-ty !! 4419         '                       "<style type=\\"text/css\\">"+\n'\
5359                         "</style>"            !! 4420         '                       "   ul {list-style-type:circle;padding-left:10px;margin-left:10px;}"+\n'\
5360                 var dt = devtable[0];         !! 4421         '                       "</style>"\n'\
5361                 if(e.target.id != "devlist1") !! 4422         '               var dt = devtable[0];\n'\
5362                         dt = devtable[1];     !! 4423         '               if(e.target.id != "devlist1")\n'\
5363                 win.document.write(html+dt);  !! 4424         '                       dt = devtable[1];\n'\
5364         }                                     !! 4425         '               win.document.write(html+dt);\n'\
5365         function errWindow() {                !! 4426         '       }\n'\
5366                 var range = this.id.split("_" !! 4427         '       function errWindow() {\n'\
5367                 var idx1 = parseInt(range[0]) !! 4428         '               var range = this.id.split("_");\n'\
5368                 var idx2 = parseInt(range[1]) !! 4429         '               var idx1 = parseInt(range[0]);\n'\
5369                 var win = window.open();      !! 4430         '               var idx2 = parseInt(range[1]);\n'\
5370                 var log = document.getElement !! 4431         '               var win = window.open();\n'\
5371                 var title = "<title>dmesg log !! 4432         '               var log = document.getElementById("dmesglog");\n'\
5372                 var text = log.innerHTML.spli !! 4433         '               var title = "<title>dmesg log</title>";\n'\
5373                 var html = "";                !! 4434         '               var text = log.innerHTML.split("\\n");\n'\
5374                 for(var i = 0; i < text.lengt !! 4435         '               var html = "";\n'\
5375                         if(i == idx1) {       !! 4436         '               for(var i = 0; i < text.length; i++) {\n'\
5376                                 html += "<e i !! 4437         '                       if(i == idx1) {\n'\
5377                         } else if(i > idx1 && !! 4438         '                               html += "<e id=target>"+text[i]+"</e>\\n";\n'\
5378                                 html += "<e>" !! 4439         '                       } else if(i > idx1 && i <= idx2) {\n'\
5379                         } else {              !! 4440         '                               html += "<e>"+text[i]+"</e>\\n";\n'\
5380                                 html += text[ !! 4441         '                       } else {\n'\
5381                         }                     !! 4442         '                               html += text[i]+"\\n";\n'\
5382                 }                             !! 4443         '                       }\n'\
5383                 win.document.write("<style>e{ !! 4444         '               }\n'\
5384                 win.location.hash = "#target" !! 4445         '               win.document.write("<style>e{color:red}</style>"+title+"<pre>"+html+"</pre>");\n'\
5385                 win.document.close();         !! 4446         '               win.location.hash = "#target";\n'\
5386         }                                     !! 4447         '               win.document.close();\n'\
5387         function logWindow(e) {               !! 4448         '       }\n'\
5388                 var name = e.target.id.slice( !! 4449         '       function logWindow(e) {\n'\
5389                 var win = window.open();      !! 4450         '               var name = e.target.id.slice(4);\n'\
5390                 var log = document.getElement !! 4451         '               var win = window.open();\n'\
5391                 var title = "<title>"+documen !! 4452         '               var log = document.getElementById(name+"log");\n'\
5392                 win.document.write(title+"<pr !! 4453         '               var title = "<title>"+document.title.split(" ")[0]+" "+name+" log</title>";\n'\
5393                 win.document.close();         !! 4454         '               win.document.write(title+"<pre>"+log.innerHTML+"</pre>");\n'\
5394         }                                     !! 4455         '               win.document.close();\n'\
5395         function onMouseDown(e) {             !! 4456         '       }\n'\
5396                 dragval[0] = e.clientX;       !! 4457         '       function onMouseDown(e) {\n'\
5397                 dragval[1] = document.getElem !! 4458         '               dragval[0] = e.clientX;\n'\
5398                 document.onmousemove = onMous !! 4459         '               dragval[1] = document.getElementById("dmesgzoombox").scrollLeft;\n'\
5399         }                                     !! 4460         '               document.onmousemove = onMouseMove;\n'\
5400         function onMouseMove(e) {             !! 4461         '       }\n'\
5401                 var zoombox = document.getEle !! 4462         '       function onMouseMove(e) {\n'\
5402                 zoombox.scrollLeft = dragval[ !! 4463         '               var zoombox = document.getElementById("dmesgzoombox");\n'\
5403         }                                     !! 4464         '               zoombox.scrollLeft = dragval[1] + dragval[0] - e.clientX;\n'\
5404         function onMouseUp(e) {               !! 4465         '       }\n'\
5405                 document.onmousemove = null;  !! 4466         '       function onMouseUp(e) {\n'\
5406         }                                     !! 4467         '               document.onmousemove = null;\n'\
5407         function onKeyPress(e) {              !! 4468         '       }\n'\
5408                 var c = e.charCode;           !! 4469         '       function onKeyPress(e) {\n'\
5409                 if(c != 42 && c != 43 && c != !! 4470         '               var c = e.charCode;\n'\
5410                 var click = document.createEv !! 4471         '               if(c != 42 && c != 43 && c != 45) return;\n'\
5411                 click.initEvent("click", true !! 4472         '               var click = document.createEvent("Events");\n'\
5412                 if(c == 43)                   !! 4473         '               click.initEvent("click", true, false);\n'\
5413                         document.getElementBy !! 4474         '               if(c == 43)  \n'\
5414                 else if(c == 45)              !! 4475         '                       document.getElementById("zoomin").dispatchEvent(click);\n'\
5415                         document.getElementBy !! 4476         '               else if(c == 45)\n'\
5416                 else if(c == 42)              !! 4477         '                       document.getElementById("zoomout").dispatchEvent(click);\n'\
5417                         document.getElementBy !! 4478         '               else if(c == 42)\n'\
5418         }                                     !! 4479         '                       document.getElementById("zoomdef").dispatchEvent(click);\n'\
5419         window.addEventListener("resize", fun !! 4480         '       }\n'\
5420         window.addEventListener("load", funct !! 4481         '       window.addEventListener("resize", function () {zoomTimeline();});\n'\
5421                 var dmesg = document.getEleme !! 4482         '       window.addEventListener("load", function () {\n'\
5422                 dmesg.style.width = "100%"    !! 4483         '               var dmesg = document.getElementById("dmesg");\n'\
5423                 dmesg.onmousedown = onMouseDo !! 4484         '               dmesg.style.width = "100%"\n'\
5424                 document.onmouseup = onMouseU !! 4485         '               dmesg.onmousedown = onMouseDown;\n'\
5425                 document.onkeypress = onKeyPr !! 4486         '               document.onmouseup = onMouseUp;\n'\
5426                 document.getElementById("zoom !! 4487         '               document.onkeypress = onKeyPress;\n'\
5427                 document.getElementById("zoom !! 4488         '               document.getElementById("zoomin").onclick = zoomTimeline;\n'\
5428                 document.getElementById("zoom !! 4489         '               document.getElementById("zoomout").onclick = zoomTimeline;\n'\
5429                 var list = document.getElemen !! 4490         '               document.getElementById("zoomdef").onclick = zoomTimeline;\n'\
5430                 for (var i = 0; i < list.leng !! 4491         '               var list = document.getElementsByClassName("err");\n'\
5431                         list[i].onclick = err !! 4492         '               for (var i = 0; i < list.length; i++)\n'\
5432                 var list = document.getElemen !! 4493         '                       list[i].onclick = errWindow;\n'\
5433                 for (var i = 0; i < list.leng !! 4494         '               var list = document.getElementsByClassName("logbtn");\n'\
5434                         list[i].onclick = log !! 4495         '               for (var i = 0; i < list.length; i++)\n'\
5435                 list = document.getElementsBy !! 4496         '                       list[i].onclick = logWindow;\n'\
5436                 for (var i = 0; i < list.leng !! 4497         '               list = document.getElementsByClassName("devlist");\n'\
5437                         list[i].onclick = dev !! 4498         '               for (var i = 0; i < list.length; i++)\n'\
5438                 var dev = dmesg.getElementsBy !! 4499         '                       list[i].onclick = devListWindow;\n'\
5439                 for (var i = 0; i < dev.lengt !! 4500         '               var dev = dmesg.getElementsByClassName("thread");\n'\
5440                         dev[i].onclick = devi !! 4501         '               for (var i = 0; i < dev.length; i++) {\n'\
5441                         dev[i].onmouseover =  !! 4502         '                       dev[i].onclick = deviceDetail;\n'\
5442                         dev[i].onmouseout = d !! 4503         '                       dev[i].onmouseover = deviceHover;\n'\
5443                 }                             !! 4504         '                       dev[i].onmouseout = deviceUnhover;\n'\
5444                 var dev = dmesg.getElementsBy !! 4505         '               }\n'\
5445                 for (var i = 0; i < dev.lengt !! 4506         '               var dev = dmesg.getElementsByClassName("srccall");\n'\
5446                         dev[i].onclick = call !! 4507         '               for (var i = 0; i < dev.length; i++)\n'\
5447                 zoomTimeline();               !! 4508         '                       dev[i].onclick = callSelect;\n'\
5448         });                                   !! 4509         '               zoomTimeline();\n'\
5449 </script> """                                 !! 4510         '       });\n'\
                                                   >> 4511         '</script>\n'
5450         hf.write(script_code);                   4512         hf.write(script_code);
5451                                                  4513 
                                                   >> 4514 def setRuntimeSuspend(before=True):
                                                   >> 4515         global sysvals
                                                   >> 4516         sv = sysvals
                                                   >> 4517         if sv.rs == 0:
                                                   >> 4518                 return
                                                   >> 4519         if before:
                                                   >> 4520                 # runtime suspend disable or enable
                                                   >> 4521                 if sv.rs > 0:
                                                   >> 4522                         sv.rstgt, sv.rsval, sv.rsdir = 'on', 'auto', 'enabled'
                                                   >> 4523                 else:
                                                   >> 4524                         sv.rstgt, sv.rsval, sv.rsdir = 'auto', 'on', 'disabled'
                                                   >> 4525                 print('CONFIGURING RUNTIME SUSPEND...')
                                                   >> 4526                 sv.rslist = deviceInfo(sv.rstgt)
                                                   >> 4527                 for i in sv.rslist:
                                                   >> 4528                         sv.setVal(sv.rsval, i)
                                                   >> 4529                 print('runtime suspend %s on all devices (%d changed)' % (sv.rsdir, len(sv.rslist)))
                                                   >> 4530                 print('waiting 5 seconds...')
                                                   >> 4531                 time.sleep(5)
                                                   >> 4532         else:
                                                   >> 4533                 # runtime suspend re-enable or re-disable
                                                   >> 4534                 for i in sv.rslist:
                                                   >> 4535                         sv.setVal(sv.rstgt, i)
                                                   >> 4536                 print('runtime suspend settings restored on %d devices' % len(sv.rslist))
                                                   >> 4537 
5452 # Function: executeSuspend                       4538 # Function: executeSuspend
5453 # Description:                                   4539 # Description:
5454 #        Execute system suspend through the s    4540 #        Execute system suspend through the sysfs interface, then copy the output
5455 #        dmesg and ftrace files to the test o    4541 #        dmesg and ftrace files to the test output directory.
5456 def executeSuspend(quiet=False):              !! 4542 def executeSuspend():
5457         sv, tp, pm = sysvals, sysvals.tpath,  !! 4543         pm = ProcessMonitor()
5458         if sv.wifi:                           !! 4544         tp = sysvals.tpath
5459                 wifi = sv.checkWifi()         !! 4545         fwdata = []
5460                 sv.dlog('wifi check, connecte << 
5461         testdata = []                         << 
5462         # run these commands to prepare the s    4546         # run these commands to prepare the system for suspend
5463         if sv.display:                        !! 4547         if sysvals.display:
5464                 if not quiet:                 !! 4548                 if sysvals.display > 0:
5465                         pprint('SET DISPLAY T !! 4549                         print('TURN DISPLAY ON')
5466                 ret = sv.displayControl(sv.di !! 4550                         call('xset -d :0.0 dpms force suspend', shell=True)
5467                 sv.dlog('xset display %s, ret !! 4551                         call('xset -d :0.0 dpms force on', shell=True)
                                                   >> 4552                 else:
                                                   >> 4553                         print('TURN DISPLAY OFF')
                                                   >> 4554                         call('xset -d :0.0 dpms force suspend', shell=True)
5468                 time.sleep(1)                    4555                 time.sleep(1)
5469         if sv.sync:                           !! 4556         if sysvals.sync:
5470                 if not quiet:                 !! 4557                 print('SYNCING FILESYSTEMS')
5471                         pprint('SYNCING FILES << 
5472                 sv.dlog('syncing filesystems' << 
5473                 call('sync', shell=True)         4558                 call('sync', shell=True)
5474         sv.dlog('read dmesg')                 !! 4559         # mark the start point in the kernel ring buffer just as we start
5475         sv.initdmesg()                        !! 4560         sysvals.initdmesg()
5476         sv.dlog('cmdinfo before')             !! 4561         # start ftrace
5477         sv.cmdinfo(True)                      !! 4562         if(sysvals.usecallgraph or sysvals.usetraceevents):
5478         sv.start(pm)                          !! 4563                 print('START TRACING')
                                                   >> 4564                 sysvals.fsetVal('1', 'tracing_on')
                                                   >> 4565                 if sysvals.useprocmon:
                                                   >> 4566                         pm.start()
5479         # execute however many s/r runs reque    4567         # execute however many s/r runs requested
5480         for count in range(1,sv.execcount+1): !! 4568         for count in range(1,sysvals.execcount+1):
5481                 # x2delay in between test run    4569                 # x2delay in between test runs
5482                 if(count > 1 and sv.x2delay > !! 4570                 if(count > 1 and sysvals.x2delay > 0):
5483                         sv.fsetVal('WAIT %d'  !! 4571                         sysvals.fsetVal('WAIT %d' % sysvals.x2delay, 'trace_marker')
5484                         time.sleep(sv.x2delay !! 4572                         time.sleep(sysvals.x2delay/1000.0)
5485                         sv.fsetVal('WAIT END' !! 4573                         sysvals.fsetVal('WAIT END', 'trace_marker')
5486                 # start message                  4574                 # start message
5487                 if sv.testcommand != '':      !! 4575                 if sysvals.testcommand != '':
5488                         pprint('COMMAND START !! 4576                         print('COMMAND START')
5489                 else:                            4577                 else:
5490                         if(sv.rtcwake):       !! 4578                         if(sysvals.rtcwake):
5491                                 pprint('SUSPE !! 4579                                 print('SUSPEND START')
5492                         else:                    4580                         else:
5493                                 pprint('SUSPE !! 4581                                 print('SUSPEND START (press a key to resume)')
5494                 # set rtcwake                    4582                 # set rtcwake
5495                 if(sv.rtcwake):               !! 4583                 if(sysvals.rtcwake):
5496                         if not quiet:         !! 4584                         print('will issue an rtcwake in %d seconds' % sysvals.rtcwaketime)
5497                                 pprint('will  !! 4585                         sysvals.rtcWakeAlarmOn()
5498                         sv.dlog('enable RTC w << 
5499                         sv.rtcWakeAlarmOn()   << 
5500                 # start of suspend trace mark    4586                 # start of suspend trace marker
5501                 sv.fsetVal(datetime.now().str !! 4587                 if(sysvals.usecallgraph or sysvals.usetraceevents):
                                                   >> 4588                         sysvals.fsetVal('SUSPEND START', 'trace_marker')
5502                 # predelay delay                 4589                 # predelay delay
5503                 if(count == 1 and sv.predelay !! 4590                 if(count == 1 and sysvals.predelay > 0):
5504                         sv.fsetVal('WAIT %d'  !! 4591                         sysvals.fsetVal('WAIT %d' % sysvals.predelay, 'trace_marker')
5505                         time.sleep(sv.predela !! 4592                         time.sleep(sysvals.predelay/1000.0)
5506                         sv.fsetVal('WAIT END' !! 4593                         sysvals.fsetVal('WAIT END', 'trace_marker')
5507                 # initiate suspend or command    4594                 # initiate suspend or command
5508                 sv.dlog('system executing a s !! 4595                 if sysvals.testcommand != '':
5509                 tdata = {'error': ''}         !! 4596                         call(sysvals.testcommand+' 2>&1', shell=True);
5510                 if sv.testcommand != '':      << 
5511                         res = call(sv.testcom << 
5512                         if res != 0:          << 
5513                                 tdata['error' << 
5514                 else:                            4597                 else:
5515                         s0ixready = sv.s0ixSu !! 4598                         mode = sysvals.suspendmode
5516                         mode = sv.suspendmode !! 4599                         if sysvals.memmode and os.path.exists(sysvals.mempowerfile):
5517                         if sv.memmode and os. << 
5518                                 mode = 'mem'     4600                                 mode = 'mem'
5519                                 sv.testVal(sv !! 4601                                 pf = open(sysvals.mempowerfile, 'w')
5520                         if sv.diskmode and os !! 4602                                 pf.write(sysvals.memmode)
5521                                 mode = 'disk' !! 4603                                 pf.close()
5522                                 sv.testVal(sv !! 4604                         pf = open(sysvals.powerfile, 'w')
5523                         if sv.acpidebug:      !! 4605                         pf.write(mode)
5524                                 sv.testVal(sv !! 4606                         # execution will pause here
5525                         if ((mode == 'freeze' !! 4607                         try:
5526                                 and sv.haveTu !! 4608                                 pf.close()
5527                                 # execution w !! 4609                         except:
5528                                 retval, turbo !! 4610                                 pass
5529                                 if retval !=  !! 4611                 if(sysvals.rtcwake):
5530                                         tdata !! 4612                         sysvals.rtcWakeAlarmOff()
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                4613                 # postdelay delay
5550                 if(count == sv.execcount and  !! 4614                 if(count == sysvals.execcount and sysvals.postdelay > 0):
5551                         sv.fsetVal('WAIT %d'  !! 4615                         sysvals.fsetVal('WAIT %d' % sysvals.postdelay, 'trace_marker')
5552                         time.sleep(sv.postdel !! 4616                         time.sleep(sysvals.postdelay/1000.0)
5553                         sv.fsetVal('WAIT END' !! 4617                         sysvals.fsetVal('WAIT END', 'trace_marker')
5554                 # return from suspend            4618                 # return from suspend
5555                 pprint('RESUME COMPLETE')     !! 4619                 print('RESUME COMPLETE')
5556                 if(count < sv.execcount):     !! 4620                 if(sysvals.usecallgraph or sysvals.usetraceevents):
5557                         sv.fsetVal(datetime.n !! 4621                         sysvals.fsetVal('RESUME COMPLETE', 'trace_marker')
5558                 elif(not sv.wifitrace):       !! 4622                 if(sysvals.suspendmode == 'mem' or sysvals.suspendmode == 'command'):
5559                         sv.fsetVal(datetime.n !! 4623                         fwdata.append(getFPDT(False))
5560                         sv.stop(pm)           !! 4624         # stop ftrace
5561                 if sv.wifi and wifi:          !! 4625         if(sysvals.usecallgraph or sysvals.usetraceevents):
5562                         tdata['wifi'] = sv.po !! 4626                 if sysvals.useprocmon:
5563                         sv.dlog('wifi check,  !! 4627                         pm.stop()
5564                 if(count == sv.execcount and  !! 4628                 sysvals.fsetVal('0', 'tracing_on')
5565                         sv.fsetVal(datetime.n !! 4629                 print('CAPTURING TRACE')
5566                         sv.stop(pm)           !! 4630                 op = sysvals.writeDatafileHeader(sysvals.ftracefile, fwdata)
5567                 if sv.netfix:                 !! 4631                 fp = open(tp+'trace', 'r')
5568                         tdata['netfix'] = sv. !! 4632                 for line in fp:
5569                         sv.dlog('netfix, %s'  !! 4633                         op.write(line)
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()                       4634                 op.close()
5588                 sv.fsetVal('', 'trace')       !! 4635                 sysvals.fsetVal('', 'trace')
5589                 sv.platforminfo(cmdafter)     !! 4636                 devProps()
                                                   >> 4637         # grab a copy of the dmesg output
                                                   >> 4638         print('CAPTURING DMESG')
                                                   >> 4639         sysvals.getdmesg(fwdata)
5590                                                  4640 
5591 def readFile(file):                              4641 def readFile(file):
5592         if os.path.islink(file):                 4642         if os.path.islink(file):
5593                 return os.readlink(file).spli    4643                 return os.readlink(file).split('/')[-1]
5594         else:                                    4644         else:
5595                 return sysvals.getVal(file).s    4645                 return sysvals.getVal(file).strip()
5596                                                  4646 
5597 # Function: ms2nice                              4647 # Function: ms2nice
5598 # Description:                                   4648 # Description:
5599 #        Print out a very concise time string    4649 #        Print out a very concise time string in minutes and seconds
5600 # Output:                                        4650 # Output:
5601 #        The time string, e.g. "1901m16s"        4651 #        The time string, e.g. "1901m16s"
5602 def ms2nice(val):                                4652 def ms2nice(val):
5603         val = int(val)                           4653         val = int(val)
5604         h = val // 3600000                    !! 4654         h = val / 3600000
5605         m = (val // 60000) % 60               !! 4655         m = (val / 60000) % 60
5606         s = (val // 1000) % 60                !! 4656         s = (val / 1000) % 60
5607         if h > 0:                                4657         if h > 0:
5608                 return '%d:%02d:%02d' % (h, m    4658                 return '%d:%02d:%02d' % (h, m, s)
5609         if m > 0:                                4659         if m > 0:
5610                 return '%02d:%02d' % (m, s)      4660                 return '%02d:%02d' % (m, s)
5611         return '%ds' % s                         4661         return '%ds' % s
5612                                                  4662 
5613 def yesno(val):                                  4663 def yesno(val):
5614         list = {'enabled':'A', 'disabled':'S'    4664         list = {'enabled':'A', 'disabled':'S', 'auto':'E', 'on':'D',
5615                 'active':'A', 'suspended':'S'    4665                 'active':'A', 'suspended':'S', 'suspending':'S'}
5616         if val not in list:                      4666         if val not in list:
5617                 return ' '                       4667                 return ' '
5618         return list[val]                         4668         return list[val]
5619                                                  4669 
5620 # Function: deviceInfo                           4670 # Function: deviceInfo
5621 # Description:                                   4671 # Description:
5622 #        Detect all the USB hosts and devices    4672 #        Detect all the USB hosts and devices currently connected and add
5623 #        a list of USB device names to sysval    4673 #        a list of USB device names to sysvals for better timeline readability
5624 def deviceInfo(output=''):                       4674 def deviceInfo(output=''):
5625         if not output:                           4675         if not output:
5626                 pprint('LEGEND\n'\            !! 4676                 print('LEGEND')
5627                 '---------------------------- !! 4677                 print('---------------------------------------------------------------------------------------------')
5628                 '  A = async/sync PM queue (A !! 4678                 print('  A = async/sync PM queue (A/S)               C = runtime active children')
5629                 '  R = runtime suspend enable !! 4679                 print('  R = runtime suspend enabled/disabled (E/D)  rACTIVE = runtime active (min/sec)')
5630                 '  S = runtime status active/ !! 4680                 print('  S = runtime status active/suspended (A/S)   rSUSPEND = runtime suspend (min/sec)')
5631                 '  U = runtime usage count\n' !! 4681                 print('  U = runtime usage count')
5632                 '---------------------------- !! 4682                 print('---------------------------------------------------------------------------------------------')
5633                 'DEVICE                     N !! 4683                 print('DEVICE                     NAME                       A R S U C    rACTIVE   rSUSPEND')
5634                 '---------------------------- !! 4684                 print('---------------------------------------------------------------------------------------------')
5635                                                  4685 
5636         res = []                                 4686         res = []
5637         tgtval = 'runtime_status'                4687         tgtval = 'runtime_status'
5638         lines = dict()                           4688         lines = dict()
5639         for dirname, dirnames, filenames in o    4689         for dirname, dirnames, filenames in os.walk('/sys/devices'):
5640                 if(not re.match(r'.*/power',  !! 4690                 if(not re.match('.*/power', dirname) or
5641                         'control' not in file    4691                         'control' not in filenames or
5642                         tgtval not in filenam    4692                         tgtval not in filenames):
5643                         continue                 4693                         continue
5644                 name = ''                        4694                 name = ''
5645                 dirname = dirname[:-6]           4695                 dirname = dirname[:-6]
5646                 device = dirname.split('/')[-    4696                 device = dirname.split('/')[-1]
5647                 power = dict()                   4697                 power = dict()
5648                 power[tgtval] = readFile('%s/    4698                 power[tgtval] = readFile('%s/power/%s' % (dirname, tgtval))
5649                 # only list devices which sup    4699                 # only list devices which support runtime suspend
5650                 if power[tgtval] not in ['act    4700                 if power[tgtval] not in ['active', 'suspended', 'suspending']:
5651                         continue                 4701                         continue
5652                 for i in ['product', 'driver'    4702                 for i in ['product', 'driver', 'subsystem']:
5653                         file = '%s/%s' % (dir    4703                         file = '%s/%s' % (dirname, i)
5654                         if os.path.exists(fil    4704                         if os.path.exists(file):
5655                                 name = readFi    4705                                 name = readFile(file)
5656                                 break            4706                                 break
5657                 for i in ['async', 'control',    4707                 for i in ['async', 'control', 'runtime_status', 'runtime_usage',
5658                         'runtime_active_kids'    4708                         'runtime_active_kids', 'runtime_active_time',
5659                         'runtime_suspended_ti    4709                         'runtime_suspended_time']:
5660                         if i in filenames:       4710                         if i in filenames:
5661                                 power[i] = re    4711                                 power[i] = readFile('%s/power/%s' % (dirname, i))
5662                 if output:                       4712                 if output:
5663                         if power['control'] =    4713                         if power['control'] == output:
5664                                 res.append('%    4714                                 res.append('%s/power/control' % dirname)
5665                         continue                 4715                         continue
5666                 lines[dirname] = '%-26s %-26s    4716                 lines[dirname] = '%-26s %-26s %1s %1s %1s %1s %1s %10s %10s' % \
5667                         (device[:26], name[:2    4717                         (device[:26], name[:26],
5668                         yesno(power['async'])    4718                         yesno(power['async']), \
5669                         yesno(power['control'    4719                         yesno(power['control']), \
5670                         yesno(power['runtime_    4720                         yesno(power['runtime_status']), \
5671                         power['runtime_usage'    4721                         power['runtime_usage'], \
5672                         power['runtime_active    4722                         power['runtime_active_kids'], \
5673                         ms2nice(power['runtim    4723                         ms2nice(power['runtime_active_time']), \
5674                         ms2nice(power['runtim    4724                         ms2nice(power['runtime_suspended_time']))
5675         for i in sorted(lines):                  4725         for i in sorted(lines):
5676                 print(lines[i])               !! 4726                 print lines[i]
5677         return res                               4727         return res
5678                                                  4728 
                                                   >> 4729 # Function: devProps
                                                   >> 4730 # Description:
                                                   >> 4731 #        Retrieve a list of properties for all devices in the trace log
                                                   >> 4732 def devProps(data=0):
                                                   >> 4733         props = dict()
                                                   >> 4734 
                                                   >> 4735         if data:
                                                   >> 4736                 idx = data.index(': ') + 2
                                                   >> 4737                 if idx >= len(data):
                                                   >> 4738                         return
                                                   >> 4739                 devlist = data[idx:].split(';')
                                                   >> 4740                 for dev in devlist:
                                                   >> 4741                         f = dev.split(',')
                                                   >> 4742                         if len(f) < 3:
                                                   >> 4743                                 continue
                                                   >> 4744                         dev = f[0]
                                                   >> 4745                         props[dev] = DevProps()
                                                   >> 4746                         props[dev].altname = f[1]
                                                   >> 4747                         if int(f[2]):
                                                   >> 4748                                 props[dev].async = True
                                                   >> 4749                         else:
                                                   >> 4750                                 props[dev].async = False
                                                   >> 4751                         sysvals.devprops = props
                                                   >> 4752                 if sysvals.suspendmode == 'command' and 'testcommandstring' in props:
                                                   >> 4753                         sysvals.testcommand = props['testcommandstring'].altname
                                                   >> 4754                 return
                                                   >> 4755 
                                                   >> 4756         if(os.path.exists(sysvals.ftracefile) == False):
                                                   >> 4757                 doError('%s does not exist' % sysvals.ftracefile)
                                                   >> 4758 
                                                   >> 4759         # first get the list of devices we need properties for
                                                   >> 4760         msghead = 'Additional data added by AnalyzeSuspend'
                                                   >> 4761         alreadystamped = False
                                                   >> 4762         tp = TestProps()
                                                   >> 4763         tf = sysvals.openlog(sysvals.ftracefile, 'r')
                                                   >> 4764         for line in tf:
                                                   >> 4765                 if msghead in line:
                                                   >> 4766                         alreadystamped = True
                                                   >> 4767                         continue
                                                   >> 4768                 # determine the trace data type (required for further parsing)
                                                   >> 4769                 m = re.match(sysvals.tracertypefmt, line)
                                                   >> 4770                 if(m):
                                                   >> 4771                         tp.setTracerType(m.group('t'))
                                                   >> 4772                         continue
                                                   >> 4773                 # parse only valid lines, if this is not one move on
                                                   >> 4774                 m = re.match(tp.ftrace_line_fmt, line)
                                                   >> 4775                 if(not m or 'device_pm_callback_start' not in line):
                                                   >> 4776                         continue
                                                   >> 4777                 m = re.match('.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg'));
                                                   >> 4778                 if(not m):
                                                   >> 4779                         continue
                                                   >> 4780                 dev = m.group('d')
                                                   >> 4781                 if dev not in props:
                                                   >> 4782                         props[dev] = DevProps()
                                                   >> 4783         tf.close()
                                                   >> 4784 
                                                   >> 4785         if not alreadystamped and sysvals.suspendmode == 'command':
                                                   >> 4786                 out = '#\n# '+msghead+'\n# Device Properties: '
                                                   >> 4787                 out += 'testcommandstring,%s,0;' % (sysvals.testcommand)
                                                   >> 4788                 with sysvals.openlog(sysvals.ftracefile, 'a') as fp:
                                                   >> 4789                         fp.write(out+'\n')
                                                   >> 4790                 sysvals.devprops = props
                                                   >> 4791                 return
                                                   >> 4792 
                                                   >> 4793         # now get the syspath for each of our target devices
                                                   >> 4794         for dirname, dirnames, filenames in os.walk('/sys/devices'):
                                                   >> 4795                 if(re.match('.*/power', dirname) and 'async' in filenames):
                                                   >> 4796                         dev = dirname.split('/')[-2]
                                                   >> 4797                         if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)):
                                                   >> 4798                                 props[dev].syspath = dirname[:-6]
                                                   >> 4799 
                                                   >> 4800         # now fill in the properties for our target devices
                                                   >> 4801         for dev in props:
                                                   >> 4802                 dirname = props[dev].syspath
                                                   >> 4803                 if not dirname or not os.path.exists(dirname):
                                                   >> 4804                         continue
                                                   >> 4805                 with open(dirname+'/power/async') as fp:
                                                   >> 4806                         text = fp.read()
                                                   >> 4807                         props[dev].async = False
                                                   >> 4808                         if 'enabled' in text:
                                                   >> 4809                                 props[dev].async = True
                                                   >> 4810                 fields = os.listdir(dirname)
                                                   >> 4811                 if 'product' in fields:
                                                   >> 4812                         with open(dirname+'/product') as fp:
                                                   >> 4813                                 props[dev].altname = fp.read()
                                                   >> 4814                 elif 'name' in fields:
                                                   >> 4815                         with open(dirname+'/name') as fp:
                                                   >> 4816                                 props[dev].altname = fp.read()
                                                   >> 4817                 elif 'model' in fields:
                                                   >> 4818                         with open(dirname+'/model') as fp:
                                                   >> 4819                                 props[dev].altname = fp.read()
                                                   >> 4820                 elif 'description' in fields:
                                                   >> 4821                         with open(dirname+'/description') as fp:
                                                   >> 4822                                 props[dev].altname = fp.read()
                                                   >> 4823                 elif 'id' in fields:
                                                   >> 4824                         with open(dirname+'/id') as fp:
                                                   >> 4825                                 props[dev].altname = fp.read()
                                                   >> 4826                 elif 'idVendor' in fields and 'idProduct' in fields:
                                                   >> 4827                         idv, idp = '', ''
                                                   >> 4828                         with open(dirname+'/idVendor') as fp:
                                                   >> 4829                                 idv = fp.read().strip()
                                                   >> 4830                         with open(dirname+'/idProduct') as fp:
                                                   >> 4831                                 idp = fp.read().strip()
                                                   >> 4832                         props[dev].altname = '%s:%s' % (idv, idp)
                                                   >> 4833 
                                                   >> 4834                 if props[dev].altname:
                                                   >> 4835                         out = props[dev].altname.strip().replace('\n', ' ')
                                                   >> 4836                         out = out.replace(',', ' ')
                                                   >> 4837                         out = out.replace(';', ' ')
                                                   >> 4838                         props[dev].altname = out
                                                   >> 4839 
                                                   >> 4840         # and now write the data to the ftrace file
                                                   >> 4841         if not alreadystamped:
                                                   >> 4842                 out = '#\n# '+msghead+'\n# Device Properties: '
                                                   >> 4843                 for dev in sorted(props):
                                                   >> 4844                         out += props[dev].out(dev)
                                                   >> 4845                 with sysvals.openlog(sysvals.ftracefile, 'a') as fp:
                                                   >> 4846                         fp.write(out+'\n')
                                                   >> 4847 
                                                   >> 4848         sysvals.devprops = props
                                                   >> 4849 
5679 # Function: getModes                             4850 # Function: getModes
5680 # Description:                                   4851 # Description:
5681 #        Determine the supported power modes     4852 #        Determine the supported power modes on this system
5682 # Output:                                        4853 # Output:
5683 #        A string list of the available modes    4854 #        A string list of the available modes
5684 def getModes():                                  4855 def getModes():
5685         modes = []                               4856         modes = []
5686         if(os.path.exists(sysvals.powerfile))    4857         if(os.path.exists(sysvals.powerfile)):
5687                 fp = open(sysvals.powerfile,     4858                 fp = open(sysvals.powerfile, 'r')
5688                 modes = fp.read().split()     !! 4859                 modes = string.split(fp.read())
5689                 fp.close()                       4860                 fp.close()
5690         if(os.path.exists(sysvals.mempowerfil    4861         if(os.path.exists(sysvals.mempowerfile)):
5691                 deep = False                     4862                 deep = False
5692                 fp = open(sysvals.mempowerfil    4863                 fp = open(sysvals.mempowerfile, 'r')
5693                 for m in fp.read().split():   !! 4864                 for m in string.split(fp.read()):
5694                         memmode = m.strip('[]    4865                         memmode = m.strip('[]')
5695                         if memmode == 'deep':    4866                         if memmode == 'deep':
5696                                 deep = True      4867                                 deep = True
5697                         else:                    4868                         else:
5698                                 modes.append(    4869                                 modes.append('mem-%s' % memmode)
5699                 fp.close()                       4870                 fp.close()
5700                 if 'mem' in modes and not dee    4871                 if 'mem' in modes and not deep:
5701                         modes.remove('mem')      4872                         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                             4873         return modes
5708                                                  4874 
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                            4875 # Function: dmidecode
5744 # Description:                                   4876 # Description:
5745 #        Read the bios tables and pull out sy    4877 #        Read the bios tables and pull out system info
5746 # Arguments:                                     4878 # Arguments:
5747 #        mempath: /dev/mem or custom mem path    4879 #        mempath: /dev/mem or custom mem path
5748 #        fatal: True to exit on error, False     4880 #        fatal: True to exit on error, False to return empty dict
5749 # Output:                                        4881 # Output:
5750 #        A dict object with all available key    4882 #        A dict object with all available key/values
5751 def dmidecode(mempath, fatal=False):             4883 def dmidecode(mempath, fatal=False):
5752         out = dict()                             4884         out = dict()
5753         if(not (os.path.exists(mempath) and o << 
5754                 return dmidecode_backup(out,  << 
5755                                                  4885 
5756         # the list of values to retrieve, wit    4886         # the list of values to retrieve, with hardcoded (type, idx)
5757         info = {                                 4887         info = {
5758                 'bios-vendor': (0, 4),           4888                 'bios-vendor': (0, 4),
5759                 'bios-version': (0, 5),          4889                 'bios-version': (0, 5),
5760                 'bios-release-date': (0, 8),     4890                 'bios-release-date': (0, 8),
5761                 'system-manufacturer': (1, 4)    4891                 'system-manufacturer': (1, 4),
5762                 'system-product-name': (1, 5)    4892                 'system-product-name': (1, 5),
5763                 'system-version': (1, 6),        4893                 'system-version': (1, 6),
5764                 'system-serial-number': (1, 7    4894                 'system-serial-number': (1, 7),
5765                 'baseboard-manufacturer': (2,    4895                 'baseboard-manufacturer': (2, 4),
5766                 'baseboard-product-name': (2,    4896                 'baseboard-product-name': (2, 5),
5767                 'baseboard-version': (2, 6),     4897                 'baseboard-version': (2, 6),
5768                 'baseboard-serial-number': (2    4898                 'baseboard-serial-number': (2, 7),
5769                 'chassis-manufacturer': (3, 4    4899                 'chassis-manufacturer': (3, 4),
                                                   >> 4900                 'chassis-type': (3, 5),
5770                 'chassis-version': (3, 6),       4901                 'chassis-version': (3, 6),
5771                 'chassis-serial-number': (3,     4902                 'chassis-serial-number': (3, 7),
5772                 'processor-manufacturer': (4,    4903                 'processor-manufacturer': (4, 7),
5773                 'processor-version': (4, 16),    4904                 'processor-version': (4, 16),
5774         }                                        4905         }
                                                   >> 4906         if(not os.path.exists(mempath)):
                                                   >> 4907                 if(fatal):
                                                   >> 4908                         doError('file does not exist: %s' % mempath)
                                                   >> 4909                 return out
                                                   >> 4910         if(not os.access(mempath, os.R_OK)):
                                                   >> 4911                 if(fatal):
                                                   >> 4912                         doError('file is not readable: %s' % mempath)
                                                   >> 4913                 return out
5775                                                  4914 
5776         # by default use legacy scan, but try    4915         # by default use legacy scan, but try to use EFI first
5777         memaddr, memsize = 0xf0000, 0x10000   !! 4916         memaddr = 0xf0000
                                                   >> 4917         memsize = 0x10000
5778         for ep in ['/sys/firmware/efi/systab'    4918         for ep in ['/sys/firmware/efi/systab', '/proc/efi/systab']:
5779                 if not os.path.exists(ep) or     4919                 if not os.path.exists(ep) or not os.access(ep, os.R_OK):
5780                         continue                 4920                         continue
5781                 fp = open(ep, 'r')               4921                 fp = open(ep, 'r')
5782                 buf = fp.read()                  4922                 buf = fp.read()
5783                 fp.close()                       4923                 fp.close()
5784                 i = buf.find('SMBIOS=')          4924                 i = buf.find('SMBIOS=')
5785                 if i >= 0:                       4925                 if i >= 0:
5786                         try:                     4926                         try:
5787                                 memaddr = int    4927                                 memaddr = int(buf[i+7:], 16)
5788                                 memsize = 0x2    4928                                 memsize = 0x20
5789                         except:                  4929                         except:
5790                                 continue         4930                                 continue
5791                                                  4931 
5792         # read in the memory for scanning        4932         # read in the memory for scanning
                                                   >> 4933         fp = open(mempath, 'rb')
5793         try:                                     4934         try:
5794                 fp = open(mempath, 'rb')      << 
5795                 fp.seek(memaddr)                 4935                 fp.seek(memaddr)
5796                 buf = fp.read(memsize)           4936                 buf = fp.read(memsize)
5797         except:                                  4937         except:
5798                 return dmidecode_backup(out,  !! 4938                 if(fatal):
                                                   >> 4939                         doError('DMI table is unreachable, sorry')
                                                   >> 4940                 else:
                                                   >> 4941                         return out
5799         fp.close()                               4942         fp.close()
5800                                                  4943 
5801         # search for either an SM table or DM    4944         # search for either an SM table or DMI table
5802         i = base = length = num = 0              4945         i = base = length = num = 0
5803         while(i < memsize):                      4946         while(i < memsize):
5804                 if buf[i:i+4] == b'_SM_' and  !! 4947                 if buf[i:i+4] == '_SM_' and i < memsize - 16:
5805                         length = struct.unpac    4948                         length = struct.unpack('H', buf[i+22:i+24])[0]
5806                         base, num = struct.un    4949                         base, num = struct.unpack('IH', buf[i+24:i+30])
5807                         break                    4950                         break
5808                 elif buf[i:i+5] == b'_DMI_':  !! 4951                 elif buf[i:i+5] == '_DMI_':
5809                         length = struct.unpac    4952                         length = struct.unpack('H', buf[i+6:i+8])[0]
5810                         base, num = struct.un    4953                         base, num = struct.unpack('IH', buf[i+8:i+14])
5811                         break                    4954                         break
5812                 i += 16                          4955                 i += 16
5813         if base == 0 and length == 0 and num     4956         if base == 0 and length == 0 and num == 0:
5814                 return dmidecode_backup(out,  !! 4957                 if(fatal):
                                                   >> 4958                         doError('Neither SMBIOS nor DMI were found')
                                                   >> 4959                 else:
                                                   >> 4960                         return out
5815                                                  4961 
5816         # read in the SM or DMI table            4962         # read in the SM or DMI table
                                                   >> 4963         fp = open(mempath, 'rb')
5817         try:                                     4964         try:
5818                 fp = open(mempath, 'rb')      << 
5819                 fp.seek(base)                    4965                 fp.seek(base)
5820                 buf = fp.read(length)            4966                 buf = fp.read(length)
5821         except:                                  4967         except:
5822                 return dmidecode_backup(out,  !! 4968                 if(fatal):
                                                   >> 4969                         doError('DMI table is unreachable, sorry')
                                                   >> 4970                 else:
                                                   >> 4971                         return out
5823         fp.close()                               4972         fp.close()
5824                                                  4973 
5825         # scan the table for the values we wa    4974         # scan the table for the values we want
5826         count = i = 0                            4975         count = i = 0
5827         while(count < num and i <= len(buf) -    4976         while(count < num and i <= len(buf) - 4):
5828                 type, size, handle = struct.u    4977                 type, size, handle = struct.unpack('BBH', buf[i:i+4])
5829                 n = i + size                     4978                 n = i + size
5830                 while n < len(buf) - 1:          4979                 while n < len(buf) - 1:
5831                         if 0 == struct.unpack    4980                         if 0 == struct.unpack('H', buf[n:n+2])[0]:
5832                                 break            4981                                 break
5833                         n += 1                   4982                         n += 1
5834                 data = buf[i+size:n+2].split( !! 4983                 data = buf[i+size:n+2].split('\0')
5835                 for name in info:                4984                 for name in info:
5836                         itype, idxadr = info[    4985                         itype, idxadr = info[name]
5837                         if itype == type:        4986                         if itype == type:
5838                                 idx = struct. !! 4987                                 idx = struct.unpack('B', buf[i+idxadr])[0]
5839                                 if idx > 0 an    4988                                 if idx > 0 and idx < len(data) - 1:
5840                                         s = d !! 4989                                         s = data[idx-1].strip()
5841                                         if s. !! 4990                                         if s and s.lower() != 'to be filled by o.e.m.':
5842                                               !! 4991                                                 out[name] = data[idx-1]
5843                 i = n + 2                        4992                 i = n + 2
5844                 count += 1                       4993                 count += 1
5845         return out                               4994         return out
5846                                                  4995 
                                                   >> 4996 def getBattery():
                                                   >> 4997         p = '/sys/class/power_supply'
                                                   >> 4998         bat = dict()
                                                   >> 4999         for d in os.listdir(p):
                                                   >> 5000                 type = sysvals.getVal(os.path.join(p, d, 'type')).strip().lower()
                                                   >> 5001                 if type != 'battery':
                                                   >> 5002                         continue
                                                   >> 5003                 for v in ['status', 'energy_now', 'capacity_now']:
                                                   >> 5004                         bat[v] = sysvals.getVal(os.path.join(p, d, v)).strip().lower()
                                                   >> 5005                 break
                                                   >> 5006         ac = True
                                                   >> 5007         if 'status' in bat and 'discharging' in bat['status']:
                                                   >> 5008                 ac = False
                                                   >> 5009         charge = 0
                                                   >> 5010         for v in ['energy_now', 'capacity_now']:
                                                   >> 5011                 if v in bat and bat[v]:
                                                   >> 5012                         charge = int(bat[v])
                                                   >> 5013         return (ac, charge)
                                                   >> 5014 
5847 # Function: getFPDT                              5015 # Function: getFPDT
5848 # Description:                                   5016 # Description:
5849 #        Read the acpi bios tables and pull o    5017 #        Read the acpi bios tables and pull out FPDT, the firmware data
5850 # Arguments:                                     5018 # Arguments:
5851 #        output: True to output the info to s    5019 #        output: True to output the info to stdout, False otherwise
5852 def getFPDT(output):                             5020 def getFPDT(output):
5853         rectype = {}                             5021         rectype = {}
5854         rectype[0] = 'Firmware Basic Boot Per    5022         rectype[0] = 'Firmware Basic Boot Performance Record'
5855         rectype[1] = 'S3 Performance Table Re    5023         rectype[1] = 'S3 Performance Table Record'
5856         prectype = {}                            5024         prectype = {}
5857         prectype[0] = 'Basic S3 Resume Perfor    5025         prectype[0] = 'Basic S3 Resume Performance Record'
5858         prectype[1] = 'Basic S3 Suspend Perfo    5026         prectype[1] = 'Basic S3 Suspend Performance Record'
5859                                                  5027 
5860         sysvals.rootCheck(True)                  5028         sysvals.rootCheck(True)
5861         if(not os.path.exists(sysvals.fpdtpat    5029         if(not os.path.exists(sysvals.fpdtpath)):
5862                 if(output):                      5030                 if(output):
5863                         doError('file does no    5031                         doError('file does not exist: %s' % sysvals.fpdtpath)
5864                 return False                     5032                 return False
5865         if(not os.access(sysvals.fpdtpath, os    5033         if(not os.access(sysvals.fpdtpath, os.R_OK)):
5866                 if(output):                      5034                 if(output):
5867                         doError('file is not     5035                         doError('file is not readable: %s' % sysvals.fpdtpath)
5868                 return False                     5036                 return False
5869         if(not os.path.exists(sysvals.mempath    5037         if(not os.path.exists(sysvals.mempath)):
5870                 if(output):                      5038                 if(output):
5871                         doError('file does no    5039                         doError('file does not exist: %s' % sysvals.mempath)
5872                 return False                     5040                 return False
5873         if(not os.access(sysvals.mempath, os.    5041         if(not os.access(sysvals.mempath, os.R_OK)):
5874                 if(output):                      5042                 if(output):
5875                         doError('file is not     5043                         doError('file is not readable: %s' % sysvals.mempath)
5876                 return False                     5044                 return False
5877                                                  5045 
5878         fp = open(sysvals.fpdtpath, 'rb')        5046         fp = open(sysvals.fpdtpath, 'rb')
5879         buf = fp.read()                          5047         buf = fp.read()
5880         fp.close()                               5048         fp.close()
5881                                                  5049 
5882         if(len(buf) < 36):                       5050         if(len(buf) < 36):
5883                 if(output):                      5051                 if(output):
5884                         doError('Invalid FPDT    5052                         doError('Invalid FPDT table data, should '+\
5885                                 'be at least     5053                                 'be at least 36 bytes')
5886                 return False                     5054                 return False
5887                                                  5055 
5888         table = struct.unpack('4sIBB6s8sI4sI'    5056         table = struct.unpack('4sIBB6s8sI4sI', buf[0:36])
5889         if(output):                              5057         if(output):
5890                 pprint('\n'\                  !! 5058                 print('')
5891                 'Firmware Performance Data Ta !! 5059                 print('Firmware Performance Data Table (%s)' % table[0])
5892                 '                  Signature  !! 5060                 print('                  Signature : %s' % table[0])
5893                 '               Table Length  !! 5061                 print('               Table Length : %u' % table[1])
5894                 '                   Revision  !! 5062                 print('                   Revision : %u' % table[2])
5895                 '                   Checksum  !! 5063                 print('                   Checksum : 0x%x' % table[3])
5896                 '                     OEM ID  !! 5064                 print('                     OEM ID : %s' % table[4])
5897                 '               OEM Table ID  !! 5065                 print('               OEM Table ID : %s' % table[5])
5898                 '               OEM Revision  !! 5066                 print('               OEM Revision : %u' % table[6])
5899                 '                 Creator ID  !! 5067                 print('                 Creator ID : %s' % table[7])
5900                 '           Creator Revision  !! 5068                 print('           Creator Revision : 0x%x' % table[8])
5901                 '' % (ascii(table[0]), ascii( !! 5069                 print('')
5902                         table[3], ascii(table << 
5903                         ascii(table[7]), tabl << 
5904                                                  5070 
5905         if(table[0] != b'FPDT'):              !! 5071         if(table[0] != 'FPDT'):
5906                 if(output):                      5072                 if(output):
5907                         doError('Invalid FPDT    5073                         doError('Invalid FPDT table')
5908                 return False                     5074                 return False
5909         if(len(buf) <= 36):                      5075         if(len(buf) <= 36):
5910                 return False                     5076                 return False
5911         i = 0                                    5077         i = 0
5912         fwData = [0, 0]                          5078         fwData = [0, 0]
5913         records = buf[36:]                       5079         records = buf[36:]
5914         try:                                  !! 5080         fp = open(sysvals.mempath, 'rb')
5915                 fp = open(sysvals.mempath, 'r << 
5916         except:                               << 
5917                 pprint('WARNING: /dev/mem is  << 
5918                 return False                  << 
5919         while(i < len(records)):                 5081         while(i < len(records)):
5920                 header = struct.unpack('HBB',    5082                 header = struct.unpack('HBB', records[i:i+4])
5921                 if(header[0] not in rectype):    5083                 if(header[0] not in rectype):
5922                         i += header[1]           5084                         i += header[1]
5923                         continue                 5085                         continue
5924                 if(header[1] != 16):             5086                 if(header[1] != 16):
5925                         i += header[1]           5087                         i += header[1]
5926                         continue                 5088                         continue
5927                 addr = struct.unpack('Q', rec    5089                 addr = struct.unpack('Q', records[i+8:i+16])[0]
5928                 try:                             5090                 try:
5929                         fp.seek(addr)            5091                         fp.seek(addr)
5930                         first = fp.read(8)       5092                         first = fp.read(8)
5931                 except:                          5093                 except:
5932                         if(output):              5094                         if(output):
5933                                 pprint('Bad a !! 5095                                 print('Bad address 0x%x in %s' % (addr, sysvals.mempath))
5934                         return [0, 0]            5096                         return [0, 0]
5935                 rechead = struct.unpack('4sI'    5097                 rechead = struct.unpack('4sI', first)
5936                 recdata = fp.read(rechead[1]-    5098                 recdata = fp.read(rechead[1]-8)
5937                 if(rechead[0] == b'FBPT'):    !! 5099                 if(rechead[0] == 'FBPT'):
5938                         record = struct.unpac !! 5100                         record = struct.unpack('HBBIQQQQQ', recdata)
5939                         if(output):              5101                         if(output):
5940                                 pprint('%s (% !! 5102                                 print('%s (%s)' % (rectype[header[0]], rechead[0]))
5941                                 '             !! 5103                                 print('                  Reset END : %u ns' % record[4])
5942                                 '  OS Loader  !! 5104                                 print('  OS Loader LoadImage Start : %u ns' % record[5])
5943                                 ' OS Loader S !! 5105                                 print(' OS Loader StartImage Start : %u ns' % record[6])
5944                                 '     ExitBoo !! 5106                                 print('     ExitBootServices Entry : %u ns' % record[7])
5945                                 '      ExitBo !! 5107                                 print('      ExitBootServices Exit : %u ns' % record[8])
5946                                 '' % (rectype !! 5108                 elif(rechead[0] == 'S3PT'):
5947                                         recor << 
5948                 elif(rechead[0] == b'S3PT'):  << 
5949                         if(output):              5109                         if(output):
5950                                 pprint('%s (% !! 5110                                 print('%s (%s)' % (rectype[header[0]], rechead[0]))
5951                         j = 0                    5111                         j = 0
5952                         while(j < len(recdata    5112                         while(j < len(recdata)):
5953                                 prechead = st    5113                                 prechead = struct.unpack('HBB', recdata[j:j+4])
5954                                 if(prechead[0    5114                                 if(prechead[0] not in prectype):
5955                                         conti    5115                                         continue
5956                                 if(prechead[0    5116                                 if(prechead[0] == 0):
5957                                         recor    5117                                         record = struct.unpack('IIQQ', recdata[j:j+prechead[1]])
5958                                         fwDat    5118                                         fwData[1] = record[2]
5959                                         if(ou    5119                                         if(output):
5960                                               !! 5120                                                 print('    %s' % prectype[prechead[0]])
5961                                               !! 5121                                                 print('               Resume Count : %u' % \
5962                                               !! 5122                                                         record[1])
5963                                               !! 5123                                                 print('                 FullResume : %u ns' % \
5964                                               !! 5124                                                         record[2])
5965                                               !! 5125                                                 print('              AverageResume : %u ns' % \
                                                   >> 5126                                                         record[3])
5966                                 elif(prechead    5127                                 elif(prechead[0] == 1):
5967                                         recor    5128                                         record = struct.unpack('QQ', recdata[j+4:j+prechead[1]])
5968                                         fwDat    5129                                         fwData[0] = record[1] - record[0]
5969                                         if(ou    5130                                         if(output):
5970                                               !! 5131                                                 print('    %s' % prectype[prechead[0]])
5971                                               !! 5132                                                 print('               SuspendStart : %u ns' % \
5972                                               !! 5133                                                         record[0])
5973                                               !! 5134                                                 print('                 SuspendEnd : %u ns' % \
5974                                               !! 5135                                                         record[1])
5975                                               !! 5136                                                 print('                SuspendTime : %u ns' % \
5976                                               !! 5137                                                         fwData[0])
5977                                 j += prechead    5138                                 j += prechead[1]
5978                 if(output):                      5139                 if(output):
5979                         pprint('')            !! 5140                         print('')
5980                 i += header[1]                   5141                 i += header[1]
5981         fp.close()                               5142         fp.close()
5982         return fwData                            5143         return fwData
5983                                                  5144 
5984 # Function: statusCheck                          5145 # Function: statusCheck
5985 # Description:                                   5146 # Description:
5986 #        Verify that the requested command an    5147 #        Verify that the requested command and options will work, and
5987 #        print the results to the terminal       5148 #        print the results to the terminal
5988 # Output:                                        5149 # Output:
5989 #        True if the test will work, False if    5150 #        True if the test will work, False if not
5990 def statusCheck(probecheck=False):               5151 def statusCheck(probecheck=False):
5991         status = ''                           !! 5152         status = True
5992                                                  5153 
5993         pprint('Checking this system (%s)...' !! 5154         print('Checking this system (%s)...' % platform.node())
5994                                                  5155 
5995         # check we have root access              5156         # check we have root access
5996         res = sysvals.colorText('NO (No featu    5157         res = sysvals.colorText('NO (No features of this tool will work!)')
5997         if(sysvals.rootCheck(False)):            5158         if(sysvals.rootCheck(False)):
5998                 res = 'YES'                      5159                 res = 'YES'
5999         pprint('    have root access: %s' % r !! 5160         print('    have root access: %s' % res)
6000         if(res != 'YES'):                        5161         if(res != 'YES'):
6001                 pprint('    Try running this  !! 5162                 print('    Try running this script with sudo')
6002                 return 'missing root access'  !! 5163                 return False
6003                                                  5164 
6004         # check sysfs is mounted                 5165         # check sysfs is mounted
6005         res = sysvals.colorText('NO (No featu    5166         res = sysvals.colorText('NO (No features of this tool will work!)')
6006         if(os.path.exists(sysvals.powerfile))    5167         if(os.path.exists(sysvals.powerfile)):
6007                 res = 'YES'                      5168                 res = 'YES'
6008         pprint('    is sysfs mounted: %s' % r !! 5169         print('    is sysfs mounted: %s' % res)
6009         if(res != 'YES'):                        5170         if(res != 'YES'):
6010                 return 'sysfs is missing'     !! 5171                 return False
6011                                                  5172 
6012         # check target mode is a valid mode      5173         # check target mode is a valid mode
6013         if sysvals.suspendmode != 'command':     5174         if sysvals.suspendmode != 'command':
6014                 res = sysvals.colorText('NO')    5175                 res = sysvals.colorText('NO')
6015                 modes = getModes()               5176                 modes = getModes()
6016                 if(sysvals.suspendmode in mod    5177                 if(sysvals.suspendmode in modes):
6017                         res = 'YES'              5178                         res = 'YES'
6018                 else:                            5179                 else:
6019                         status = '%s mode is  !! 5180                         status = False
6020                 pprint('    is "%s" a valid p !! 5181                 print('    is "%s" a valid power mode: %s' % (sysvals.suspendmode, res))
6021                 if(res == 'NO'):                 5182                 if(res == 'NO'):
6022                         pprint('      valid p !! 5183                         print('      valid power modes are: %s' % modes)
6023                         pprint('      please  !! 5184                         print('      please choose one with -m')
6024                                                  5185 
6025         # check if ftrace is available           5186         # check if ftrace is available
6026         if sysvals.useftrace:                 !! 5187         res = sysvals.colorText('NO')
6027                 res = sysvals.colorText('NO') !! 5188         ftgood = sysvals.verifyFtrace()
6028                 sysvals.useftrace = sysvals.v !! 5189         if(ftgood):
6029                 efmt = '"{0}" uses ftrace, an !! 5190                 res = 'YES'
6030                 if sysvals.useftrace:         !! 5191         elif(sysvals.usecallgraph):
6031                         res = 'YES'           !! 5192                 status = False
6032                 elif sysvals.usecallgraph:    !! 5193         print('    is ftrace supported: %s' % res)
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                                                  5194 
6040         # check if kprobes are available         5195         # check if kprobes are available
6041         if sysvals.usekprobes:                !! 5196         res = sysvals.colorText('NO')
6042                 res = sysvals.colorText('NO') !! 5197         sysvals.usekprobes = sysvals.verifyKprobes()
6043                 sysvals.usekprobes = sysvals. !! 5198         if(sysvals.usekprobes):
6044                 if(sysvals.usekprobes):       !! 5199                 res = 'YES'
6045                         res = 'YES'           !! 5200         else:
6046                 else:                         !! 5201                 sysvals.usedevsrc = False
6047                         sysvals.usedevsrc = F !! 5202         print('    are kprobes supported: %s' % res)
6048                 pprint('    are kprobes suppo << 
6049                                                  5203 
6050         # what data source are we using          5204         # what data source are we using
6051         res = 'DMESG (very limited, ftrace is !! 5205         res = 'DMESG'
6052         if sysvals.useftrace:                 !! 5206         if(ftgood):
6053                 sysvals.usetraceevents = True    5207                 sysvals.usetraceevents = True
6054                 for e in sysvals.traceevents:    5208                 for e in sysvals.traceevents:
6055                         if not os.path.exists    5209                         if not os.path.exists(sysvals.epath+e):
6056                                 sysvals.usetr    5210                                 sysvals.usetraceevents = False
6057                 if(sysvals.usetraceevents):      5211                 if(sysvals.usetraceevents):
6058                         res = 'FTRACE (all tr    5212                         res = 'FTRACE (all trace events found)'
6059         pprint('    timeline data source: %s' !! 5213         print('    timeline data source: %s' % res)
6060                                                  5214 
6061         # check if rtcwake                       5215         # check if rtcwake
6062         res = sysvals.colorText('NO')            5216         res = sysvals.colorText('NO')
6063         if(sysvals.rtcpath != ''):               5217         if(sysvals.rtcpath != ''):
6064                 res = 'YES'                      5218                 res = 'YES'
6065         elif(sysvals.rtcwake):                   5219         elif(sysvals.rtcwake):
6066                 status = 'rtcwake is not prop !! 5220                 status = False
6067         pprint('    is rtcwake supported: %s' !! 5221         print('    is rtcwake supported: %s' % res)
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                                                  5222 
6080         if not probecheck:                       5223         if not probecheck:
6081                 return status                    5224                 return status
6082                                                  5225 
6083         # verify kprobes                         5226         # verify kprobes
6084         if sysvals.usekprobes:                   5227         if sysvals.usekprobes:
6085                 for name in sysvals.tracefunc    5228                 for name in sysvals.tracefuncs:
6086                         sysvals.defaultKprobe    5229                         sysvals.defaultKprobe(name, sysvals.tracefuncs[name])
6087                 if sysvals.usedevsrc:            5230                 if sysvals.usedevsrc:
6088                         for name in sysvals.d    5231                         for name in sysvals.dev_tracefuncs:
6089                                 sysvals.defau    5232                                 sysvals.defaultKprobe(name, sysvals.dev_tracefuncs[name])
6090                 sysvals.addKprobes(True)         5233                 sysvals.addKprobes(True)
6091                                                  5234 
6092         return status                            5235         return status
6093                                                  5236 
6094 # Function: doError                              5237 # Function: doError
6095 # Description:                                   5238 # Description:
6096 #        generic error function for catastrph    5239 #        generic error function for catastrphic failures
6097 # Arguments:                                     5240 # Arguments:
6098 #        msg: the error message to print         5241 #        msg: the error message to print
6099 #        help: True if printHelp should be ca    5242 #        help: True if printHelp should be called after, False otherwise
6100 def doError(msg, help=False):                    5243 def doError(msg, help=False):
6101         if(help == True):                        5244         if(help == True):
6102                 printHelp()                      5245                 printHelp()
6103         pprint('ERROR: %s\n' % msg)           !! 5246         print('ERROR: %s\n') % msg
6104         sysvals.outputResult({'error':msg})      5247         sysvals.outputResult({'error':msg})
6105         sys.exit(1)                           !! 5248         sys.exit()
6106                                                  5249 
6107 # Function: getArgInt                            5250 # Function: getArgInt
6108 # Description:                                   5251 # Description:
6109 #        pull out an integer argument from th    5252 #        pull out an integer argument from the command line with checks
6110 def getArgInt(name, args, min, max, main=True    5253 def getArgInt(name, args, min, max, main=True):
6111         if main:                                 5254         if main:
6112                 try:                             5255                 try:
6113                         arg = next(args)      !! 5256                         arg = args.next()
6114                 except:                          5257                 except:
6115                         doError(name+': no ar    5258                         doError(name+': no argument supplied', True)
6116         else:                                    5259         else:
6117                 arg = args                       5260                 arg = args
6118         try:                                     5261         try:
6119                 val = int(arg)                   5262                 val = int(arg)
6120         except:                                  5263         except:
6121                 doError(name+': non-integer v    5264                 doError(name+': non-integer value given', True)
6122         if(val < min or val > max):              5265         if(val < min or val > max):
6123                 doError(name+': value should     5266                 doError(name+': value should be between %d and %d' % (min, max), True)
6124         return val                               5267         return val
6125                                                  5268 
6126 # Function: getArgFloat                          5269 # Function: getArgFloat
6127 # Description:                                   5270 # Description:
6128 #        pull out a float argument from the c    5271 #        pull out a float argument from the command line with checks
6129 def getArgFloat(name, args, min, max, main=Tr    5272 def getArgFloat(name, args, min, max, main=True):
6130         if main:                                 5273         if main:
6131                 try:                             5274                 try:
6132                         arg = next(args)      !! 5275                         arg = args.next()
6133                 except:                          5276                 except:
6134                         doError(name+': no ar    5277                         doError(name+': no argument supplied', True)
6135         else:                                    5278         else:
6136                 arg = args                       5279                 arg = args
6137         try:                                     5280         try:
6138                 val = float(arg)                 5281                 val = float(arg)
6139         except:                                  5282         except:
6140                 doError(name+': non-numerical    5283                 doError(name+': non-numerical value given', True)
6141         if(val < min or val > max):              5284         if(val < min or val > max):
6142                 doError(name+': value should     5285                 doError(name+': value should be between %f and %f' % (min, max), True)
6143         return val                               5286         return val
6144                                                  5287 
6145 def processData(live=False, quiet=False):     !! 5288 def processData(live=False):
6146         if not quiet:                         !! 5289         print('PROCESSING DATA')
6147                 pprint('PROCESSING: %s' % sys << 
6148         sysvals.vprint('usetraceevents=%s, us << 
6149                 (sysvals.usetraceevents, sysv << 
6150         error = ''                               5290         error = ''
6151         if(sysvals.usetraceevents):              5291         if(sysvals.usetraceevents):
6152                 testruns, error = parseTraceL    5292                 testruns, error = parseTraceLog(live)
6153                 if sysvals.dmesgfile:            5293                 if sysvals.dmesgfile:
6154                         for data in testruns:    5294                         for data in testruns:
6155                                 data.extractE    5295                                 data.extractErrorInfo()
6156         else:                                    5296         else:
6157                 testruns = loadKernelLog()       5297                 testruns = loadKernelLog()
6158                 for data in testruns:            5298                 for data in testruns:
6159                         parseKernelLog(data)     5299                         parseKernelLog(data)
6160                 if(sysvals.ftracefile and (sy    5300                 if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)):
6161                         appendIncompleteTrace    5301                         appendIncompleteTraceLog(testruns)
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    5302         sysvals.vprint('Command:\n    %s' % sysvals.cmdline)
6172         for data in testruns:                    5303         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()              5304                 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:                       5305         if sysvals.cgdump:
6190                 for data in testruns:            5306                 for data in testruns:
6191                         data.debugPrint()        5307                         data.debugPrint()
6192                 sys.exit(0)                   !! 5308                 sys.exit()
6193         if len(testruns) < 1:                    5309         if len(testruns) < 1:
6194                 pprint('ERROR: Not enough tes << 
6195                 return (testruns, {'error': '    5310                 return (testruns, {'error': 'timeline generation failed'})
6196         sysvals.vprint('Creating the html tim    5311         sysvals.vprint('Creating the html timeline (%s)...' % sysvals.htmlfile)
6197         createHTML(testruns, error)              5312         createHTML(testruns, error)
6198         if not quiet:                         !! 5313         print('DONE')
6199                 pprint('DONE:       %s' % sys << 
6200         data = testruns[0]                       5314         data = testruns[0]
6201         stamp = data.stamp                       5315         stamp = data.stamp
6202         stamp['suspend'], stamp['resume'] = d    5316         stamp['suspend'], stamp['resume'] = data.getTimeValues()
6203         if data.fwValid:                         5317         if data.fwValid:
6204                 stamp['fwsuspend'], stamp['fw    5318                 stamp['fwsuspend'], stamp['fwresume'] = data.fwSuspend, data.fwResume
6205         if error:                                5319         if error:
6206                 stamp['error'] = error           5320                 stamp['error'] = error
6207         return (testruns, stamp)                 5321         return (testruns, stamp)
6208                                                  5322 
6209 # Function: rerunTest                            5323 # Function: rerunTest
6210 # Description:                                   5324 # Description:
6211 #        generate an output from an existing     5325 #        generate an output from an existing set of ftrace/dmesg logs
6212 def rerunTest(htmlfile=''):                   !! 5326 def rerunTest():
6213         if sysvals.ftracefile:                   5327         if sysvals.ftracefile:
6214                 doesTraceLogHaveTraceEvents()    5328                 doesTraceLogHaveTraceEvents()
6215         if not sysvals.dmesgfile and not sysv    5329         if not sysvals.dmesgfile and not sysvals.usetraceevents:
6216                 doError('recreating this html    5330                 doError('recreating this html output requires a dmesg file')
6217         if htmlfile:                          !! 5331         sysvals.setOutputFile()
6218                 sysvals.htmlfile = htmlfile   << 
6219         else:                                 << 
6220                 sysvals.setOutputFile()       << 
6221         if os.path.exists(sysvals.htmlfile):     5332         if os.path.exists(sysvals.htmlfile):
6222                 if not os.path.isfile(sysvals    5333                 if not os.path.isfile(sysvals.htmlfile):
6223                         doError('a directory     5334                         doError('a directory already exists with this name: %s' % sysvals.htmlfile)
6224                 elif not os.access(sysvals.ht    5335                 elif not os.access(sysvals.htmlfile, os.W_OK):
6225                         doError('missing perm    5336                         doError('missing permission to write to %s' % sysvals.htmlfile)
6226         testruns, stamp = processData()       !! 5337         testruns, stamp = processData(False)
6227         sysvals.resetlog()                    << 
6228         return stamp                             5338         return stamp
6229                                                  5339 
6230 # Function: runTest                              5340 # Function: runTest
6231 # Description:                                   5341 # Description:
6232 #        execute a suspend/resume, gather the    5342 #        execute a suspend/resume, gather the logs, and generate the output
6233 def runTest(n=0, quiet=False):                !! 5343 def runTest(n=0):
6234         # prepare for the test                   5344         # prepare for the test
                                                   >> 5345         sysvals.initFtrace()
6235         sysvals.initTestOutput('suspend')        5346         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                                                  5347 
6251         # execute the test                       5348         # execute the test
6252         executeSuspend(quiet)                 !! 5349         executeSuspend()
6253         sysvals.cleanupFtrace()                  5350         sysvals.cleanupFtrace()
6254         if sysvals.skiphtml:                     5351         if sysvals.skiphtml:
6255                 sysvals.outputResult({}, n)   !! 5352                 sysvals.sudouser(sysvals.testdir)
6256                 sysvals.sudoUserchown(sysvals << 
6257                 return                           5353                 return
6258         testruns, stamp = processData(True, q !! 5354         testruns, stamp = processData(True)
6259         for data in testruns:                    5355         for data in testruns:
6260                 del data                         5356                 del data
6261         sysvals.sudoUserchown(sysvals.testdir !! 5357         sysvals.sudouser(sysvals.testdir)
6262         sysvals.outputResult(stamp, n)           5358         sysvals.outputResult(stamp, n)
6263         if 'error' in stamp:                  << 
6264                 return 2                      << 
6265         return 0                              << 
6266                                                  5359 
6267 def find_in_html(html, start, end, firstonly=    5360 def find_in_html(html, start, end, firstonly=True):
6268         cnt, out, list = len(html), [], []    !! 5361         n, out = 0, []
6269         if firstonly:                         !! 5362         while n < len(html):
6270                 m = re.search(start, html)    !! 5363                 m = re.search(start, html[n:])
6271                 if m:                         !! 5364                 if not m:
6272                         list.append(m)        !! 5365                         break
6273         else:                                 !! 5366                 i = m.end()
6274                 list = re.finditer(start, htm !! 5367                 m = re.search(end, html[n+i:])
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:                        5368                 if not m:
6280                         break                    5369                         break
6281                 e = s + m.start()             !! 5370                 j = m.start()
6282                 str = html[s:e]               !! 5371                 str = html[n+i:n+i+j]
6283                 if end == 'ms':                  5372                 if end == 'ms':
6284                         num = re.search(r'[-+    5373                         num = re.search(r'[-+]?\d*\.\d+|\d+', str)
6285                         str = num.group() if     5374                         str = num.group() if num else 'NaN'
6286                 if firstonly:                    5375                 if firstonly:
6287                         return str               5376                         return str
6288                 out.append(str)                  5377                 out.append(str)
                                                   >> 5378                 n += i+j
6289         if firstonly:                            5379         if firstonly:
6290                 return ''                        5380                 return ''
6291         return out                               5381         return out
6292                                                  5382 
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                           5383 # Function: runSummary
6460 # Description:                                   5384 # Description:
6461 #        create a summary of tests in a sub-d    5385 #        create a summary of tests in a sub-directory
6462 def runSummary(subdir, local=True, genhtml=Fa    5386 def runSummary(subdir, local=True, genhtml=False):
6463         inpath = os.path.abspath(subdir)         5387         inpath = os.path.abspath(subdir)
6464         outpath = os.path.abspath('.') if loc !! 5388         outpath = inpath
6465         pprint('Generating a summary of folde !! 5389         if local:
                                                   >> 5390                 outpath = os.path.abspath('.')
                                                   >> 5391         print('Generating a summary of folder "%s"' % inpath)
6466         if genhtml:                              5392         if genhtml:
6467                 genHtml(subdir)               !! 5393                 for dirname, dirnames, filenames in os.walk(subdir):
6468         target, issues, testruns = '', [], [] !! 5394                         sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = ''
6469         desc = {'host':[],'mode':[],'kernel': !! 5395                         for filename in filenames:
                                                   >> 5396                                 if(re.match('.*_dmesg.txt', filename)):
                                                   >> 5397                                         sysvals.dmesgfile = os.path.join(dirname, filename)
                                                   >> 5398                                 elif(re.match('.*_ftrace.txt', filename)):
                                                   >> 5399                                         sysvals.ftracefile = os.path.join(dirname, filename)
                                                   >> 5400                         sysvals.setOutputFile()
                                                   >> 5401                         if sysvals.ftracefile and sysvals.htmlfile and \
                                                   >> 5402                                 not os.path.exists(sysvals.htmlfile):
                                                   >> 5403                                 print('FTRACE: %s' % sysvals.ftracefile)
                                                   >> 5404                                 if sysvals.dmesgfile:
                                                   >> 5405                                         print('DMESG : %s' % sysvals.dmesgfile)
                                                   >> 5406                                 rerunTest()
                                                   >> 5407         testruns = []
6470         for dirname, dirnames, filenames in o    5408         for dirname, dirnames, filenames in os.walk(subdir):
6471                 for filename in filenames:       5409                 for filename in filenames:
6472                         if(not re.match(r'.*. !! 5410                         if(not re.match('.*.html', filename)):
6473                                 continue         5411                                 continue
6474                         data = data_from_html !! 5412                         file = os.path.join(dirname, filename)
6475                         if(not data):         !! 5413                         html = open(file, 'r').read()
                                                   >> 5414                         suspend = find_in_html(html, 'Kernel Suspend', 'ms')
                                                   >> 5415                         resume = find_in_html(html, 'Kernel Resume', 'ms')
                                                   >> 5416                         line = find_in_html(html, '<div class="stamp">', '</div>')
                                                   >> 5417                         stmp = line.split()
                                                   >> 5418                         if not suspend or not resume or len(stmp) != 8:
                                                   >> 5419                                 continue
                                                   >> 5420                         try:
                                                   >> 5421                                 dt = datetime.strptime(' '.join(stmp[3:]), '%B %d %Y, %I:%M:%S %p')
                                                   >> 5422                         except:
6476                                 continue         5423                                 continue
6477                         if 'target' in data:  !! 5424                         tstr = dt.strftime('%Y/%m/%d %H:%M:%S')
6478                                 target = data !! 5425                         error = find_in_html(html, '<table class="testfail"><tr><td>', '</td>')
                                                   >> 5426                         result = 'fail' if error else 'pass'
                                                   >> 5427                         ilist = []
                                                   >> 5428                         e = find_in_html(html, 'class="err"[\w=":;\.%\- ]*>', '&rarr;</div>', False)
                                                   >> 5429                         for i in list(set(e)):
                                                   >> 5430                                 ilist.append('%sx%d' % (i, e.count(i)) if e.count(i) > 1 else i)
                                                   >> 5431                         data = {
                                                   >> 5432                                 'mode': stmp[2],
                                                   >> 5433                                 'host': stmp[0],
                                                   >> 5434                                 'kernel': stmp[1],
                                                   >> 5435                                 'time': tstr,
                                                   >> 5436                                 'result': result,
                                                   >> 5437                                 'issues': ','.join(ilist),
                                                   >> 5438                                 'suspend': suspend,
                                                   >> 5439                                 'resume': resume,
                                                   >> 5440                                 'url': os.path.relpath(file, outpath),
                                                   >> 5441                         }
6479                         testruns.append(data)    5442                         testruns.append(data)
6480                         for key in desc:      !! 5443         outfile = os.path.join(outpath, 'summary.html')
6481                                 if data[key]  !! 5444         print('Summary file: %s' % outfile)
6482                                         desc[ !! 5445         createHTMLSummarySimple(testruns, outfile, inpath)
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                                                  5446 
6497 # Function: checkArgBool                         5447 # Function: checkArgBool
6498 # Description:                                   5448 # Description:
6499 #        check if a boolean string value is t    5449 #        check if a boolean string value is true or false
6500 def checkArgBool(name, value):                   5450 def checkArgBool(name, value):
6501         if value in switchvalues:                5451         if value in switchvalues:
6502                 if value in switchoff:           5452                 if value in switchoff:
6503                         return False             5453                         return False
6504                 return True                      5454                 return True
6505         doError('invalid boolean --> (%s: %s)    5455         doError('invalid boolean --> (%s: %s), use "true/false" or "1/0"' % (name, value), True)
6506         return False                             5456         return False
6507                                                  5457 
6508 # Function: configFromFile                       5458 # Function: configFromFile
6509 # Description:                                   5459 # Description:
6510 #        Configure the script via the info in    5460 #        Configure the script via the info in a config file
6511 def configFromFile(file):                        5461 def configFromFile(file):
6512         Config = configparser.ConfigParser()  !! 5462         Config = ConfigParser.ConfigParser()
6513                                                  5463 
6514         Config.read(file)                        5464         Config.read(file)
6515         sections = Config.sections()             5465         sections = Config.sections()
6516         overridekprobes = False                  5466         overridekprobes = False
6517         overridedevkprobes = False               5467         overridedevkprobes = False
6518         if 'Settings' in sections:               5468         if 'Settings' in sections:
6519                 for opt in Config.options('Se    5469                 for opt in Config.options('Settings'):
6520                         value = Config.get('S    5470                         value = Config.get('Settings', opt).lower()
6521                         option = opt.lower()     5471                         option = opt.lower()
6522                         if(option == 'verbose    5472                         if(option == 'verbose'):
6523                                 sysvals.verbo    5473                                 sysvals.verbose = checkArgBool(option, value)
6524                         elif(option == 'addlo    5474                         elif(option == 'addlogs'):
6525                                 sysvals.dmesg    5475                                 sysvals.dmesglog = sysvals.ftracelog = checkArgBool(option, value)
6526                         elif(option == 'dev')    5476                         elif(option == 'dev'):
6527                                 sysvals.usede    5477                                 sysvals.usedevsrc = checkArgBool(option, value)
6528                         elif(option == 'proc'    5478                         elif(option == 'proc'):
6529                                 sysvals.usepr    5479                                 sysvals.useprocmon = checkArgBool(option, value)
6530                         elif(option == 'x2'):    5480                         elif(option == 'x2'):
6531                                 if checkArgBo    5481                                 if checkArgBool(option, value):
6532                                         sysva    5482                                         sysvals.execcount = 2
6533                         elif(option == 'callg    5483                         elif(option == 'callgraph'):
6534                                 sysvals.useca    5484                                 sysvals.usecallgraph = checkArgBool(option, value)
6535                         elif(option == 'overr    5485                         elif(option == 'override-timeline-functions'):
6536                                 overridekprob    5486                                 overridekprobes = checkArgBool(option, value)
6537                         elif(option == 'overr    5487                         elif(option == 'override-dev-timeline-functions'):
6538                                 overridedevkp    5488                                 overridedevkprobes = checkArgBool(option, value)
6539                         elif(option == 'skiph    5489                         elif(option == 'skiphtml'):
6540                                 sysvals.skiph    5490                                 sysvals.skiphtml = checkArgBool(option, value)
6541                         elif(option == 'sync'    5491                         elif(option == 'sync'):
6542                                 sysvals.sync     5492                                 sysvals.sync = checkArgBool(option, value)
6543                         elif(option == 'rs' o    5493                         elif(option == 'rs' or option == 'runtimesuspend'):
6544                                 if value in s    5494                                 if value in switchvalues:
6545                                         if va    5495                                         if value in switchoff:
6546                                                  5496                                                 sysvals.rs = -1
6547                                         else:    5497                                         else:
6548                                                  5498                                                 sysvals.rs = 1
6549                                 else:            5499                                 else:
6550                                         doErr    5500                                         doError('invalid value --> (%s: %s), use "enable/disable"' % (option, value), True)
6551                         elif(option == 'displ    5501                         elif(option == 'display'):
6552                                 disopt = ['on !! 5502                                 if value in switchvalues:
6553                                 if value not  !! 5503                                         if value in switchoff:
6554                                         doErr !! 5504                                                 sysvals.display = -1
6555                                 sysvals.displ !! 5505                                         else:
                                                   >> 5506                                                 sysvals.display = 1
                                                   >> 5507                                 else:
                                                   >> 5508                                         doError('invalid value --> (%s: %s), use "on/off"' % (option, value), True)
6556                         elif(option == 'gzip'    5509                         elif(option == 'gzip'):
6557                                 sysvals.gzip     5510                                 sysvals.gzip = checkArgBool(option, value)
6558                         elif(option == 'cgfil    5511                         elif(option == 'cgfilter'):
6559                                 sysvals.setCa    5512                                 sysvals.setCallgraphFilter(value)
6560                         elif(option == 'cgski    5513                         elif(option == 'cgskip'):
6561                                 if value in s    5514                                 if value in switchoff:
6562                                         sysva    5515                                         sysvals.cgskip = ''
6563                                 else:            5516                                 else:
6564                                         sysva    5517                                         sysvals.cgskip = sysvals.configFile(val)
6565                                         if(no    5518                                         if(not sysvals.cgskip):
6566                                                  5519                                                 doError('%s does not exist' % sysvals.cgskip)
6567                         elif(option == 'cgtes    5520                         elif(option == 'cgtest'):
6568                                 sysvals.cgtes    5521                                 sysvals.cgtest = getArgInt('cgtest', value, 0, 1, False)
6569                         elif(option == 'cgpha    5522                         elif(option == 'cgphase'):
6570                                 d = Data(0)      5523                                 d = Data(0)
6571                                 if value not  !! 5524                                 if value not in d.phases:
6572                                         doErr    5525                                         doError('invalid phase --> (%s: %s), valid phases are %s'\
6573                                               !! 5526                                                 % (option, value, d.phases), True)
6574                                 sysvals.cgpha    5527                                 sysvals.cgphase = value
6575                         elif(option == 'fadd'    5528                         elif(option == 'fadd'):
6576                                 file = sysval    5529                                 file = sysvals.configFile(value)
6577                                 if(not file):    5530                                 if(not file):
6578                                         doErr    5531                                         doError('%s does not exist' % value)
6579                                 sysvals.addFt    5532                                 sysvals.addFtraceFilterFunctions(file)
6580                         elif(option == 'resul    5533                         elif(option == 'result'):
6581                                 sysvals.resul    5534                                 sysvals.result = value
6582                         elif(option == 'multi    5535                         elif(option == 'multi'):
6583                                 nums = value.    5536                                 nums = value.split()
6584                                 if len(nums)     5537                                 if len(nums) != 2:
6585                                         doErr    5538                                         doError('multi requires 2 integers (exec_count and delay)', True)
6586                                 sysvals.multi !! 5539                                 sysvals.multitest['run'] = True
                                                   >> 5540                                 sysvals.multitest['count'] = getArgInt('multi: n d (exec count)', nums[0], 2, 1000000, False)
                                                   >> 5541                                 sysvals.multitest['delay'] = getArgInt('multi: n d (delay between tests)', nums[1], 0, 3600, False)
6587                         elif(option == 'devic    5542                         elif(option == 'devicefilter'):
6588                                 sysvals.setDe    5543                                 sysvals.setDeviceFilter(value)
6589                         elif(option == 'expan    5544                         elif(option == 'expandcg'):
6590                                 sysvals.cgexp    5545                                 sysvals.cgexp = checkArgBool(option, value)
6591                         elif(option == 'srgap    5546                         elif(option == 'srgap'):
6592                                 if checkArgBo    5547                                 if checkArgBool(option, value):
6593                                         sysva    5548                                         sysvals.srgap = 5
6594                         elif(option == 'mode'    5549                         elif(option == 'mode'):
6595                                 sysvals.suspe    5550                                 sysvals.suspendmode = value
6596                         elif(option == 'comma    5551                         elif(option == 'command' or option == 'cmd'):
6597                                 sysvals.testc    5552                                 sysvals.testcommand = value
6598                         elif(option == 'x2del    5553                         elif(option == 'x2delay'):
6599                                 sysvals.x2del    5554                                 sysvals.x2delay = getArgInt('x2delay', value, 0, 60000, False)
6600                         elif(option == 'prede    5555                         elif(option == 'predelay'):
6601                                 sysvals.prede    5556                                 sysvals.predelay = getArgInt('predelay', value, 0, 60000, False)
6602                         elif(option == 'postd    5557                         elif(option == 'postdelay'):
6603                                 sysvals.postd    5558                                 sysvals.postdelay = getArgInt('postdelay', value, 0, 60000, False)
6604                         elif(option == 'maxde    5559                         elif(option == 'maxdepth'):
6605                                 sysvals.max_g    5560                                 sysvals.max_graph_depth = getArgInt('maxdepth', value, 0, 1000, False)
6606                         elif(option == 'rtcwa    5561                         elif(option == 'rtcwake'):
6607                                 if value in s    5562                                 if value in switchoff:
6608                                         sysva    5563                                         sysvals.rtcwake = False
6609                                 else:            5564                                 else:
6610                                         sysva    5565                                         sysvals.rtcwake = True
6611                                         sysva    5566                                         sysvals.rtcwaketime = getArgInt('rtcwake', value, 0, 3600, False)
6612                         elif(option == 'timep    5567                         elif(option == 'timeprec'):
6613                                 sysvals.setPr    5568                                 sysvals.setPrecision(getArgInt('timeprec', value, 0, 6, False))
6614                         elif(option == 'minde    5569                         elif(option == 'mindev'):
6615                                 sysvals.minde    5570                                 sysvals.mindevlen = getArgFloat('mindev', value, 0.0, 10000.0, False)
6616                         elif(option == 'calll    5571                         elif(option == 'callloop-maxgap'):
6617                                 sysvals.calll    5572                                 sysvals.callloopmaxgap = getArgFloat('callloop-maxgap', value, 0.0, 1.0, False)
6618                         elif(option == 'calll    5573                         elif(option == 'callloop-maxlen'):
6619                                 sysvals.calll    5574                                 sysvals.callloopmaxgap = getArgFloat('callloop-maxlen', value, 0.0, 1.0, False)
6620                         elif(option == 'mincg    5575                         elif(option == 'mincg'):
6621                                 sysvals.mincg    5576                                 sysvals.mincglen = getArgFloat('mincg', value, 0.0, 10000.0, False)
6622                         elif(option == 'bufsi    5577                         elif(option == 'bufsize'):
6623                                 sysvals.bufsi    5578                                 sysvals.bufsize = getArgInt('bufsize', value, 1, 1024*1024*8, False)
6624                         elif(option == 'outpu    5579                         elif(option == 'output-dir'):
6625                                 sysvals.outdi    5580                                 sysvals.outdir = sysvals.setOutputFolder(value)
6626                                                  5581 
6627         if sysvals.suspendmode == 'command' a    5582         if sysvals.suspendmode == 'command' and not sysvals.testcommand:
6628                 doError('No command supplied     5583                 doError('No command supplied for mode "command"')
6629                                                  5584 
6630         # compatibility errors                   5585         # compatibility errors
6631         if sysvals.usedevsrc and sysvals.usec    5586         if sysvals.usedevsrc and sysvals.usecallgraph:
6632                 doError('-dev is not compatib    5587                 doError('-dev is not compatible with -f')
6633         if sysvals.usecallgraph and sysvals.u    5588         if sysvals.usecallgraph and sysvals.useprocmon:
6634                 doError('-proc is not compati    5589                 doError('-proc is not compatible with -f')
6635                                                  5590 
6636         if overridekprobes:                      5591         if overridekprobes:
6637                 sysvals.tracefuncs = dict()      5592                 sysvals.tracefuncs = dict()
6638         if overridedevkprobes:                   5593         if overridedevkprobes:
6639                 sysvals.dev_tracefuncs = dict    5594                 sysvals.dev_tracefuncs = dict()
6640                                                  5595 
6641         kprobes = dict()                         5596         kprobes = dict()
6642         kprobesec = 'dev_timeline_functions_'    5597         kprobesec = 'dev_timeline_functions_'+platform.machine()
6643         if kprobesec in sections:                5598         if kprobesec in sections:
6644                 for name in Config.options(kp    5599                 for name in Config.options(kprobesec):
6645                         text = Config.get(kpr    5600                         text = Config.get(kprobesec, name)
6646                         kprobes[name] = (text    5601                         kprobes[name] = (text, True)
6647         kprobesec = 'timeline_functions_'+pla    5602         kprobesec = 'timeline_functions_'+platform.machine()
6648         if kprobesec in sections:                5603         if kprobesec in sections:
6649                 for name in Config.options(kp    5604                 for name in Config.options(kprobesec):
6650                         if name in kprobes:      5605                         if name in kprobes:
6651                                 doError('Dupl    5606                                 doError('Duplicate timeline function found "%s"' % (name))
6652                         text = Config.get(kpr    5607                         text = Config.get(kprobesec, name)
6653                         kprobes[name] = (text    5608                         kprobes[name] = (text, False)
6654                                                  5609 
6655         for name in kprobes:                     5610         for name in kprobes:
6656                 function = name                  5611                 function = name
6657                 format = name                    5612                 format = name
6658                 color = ''                       5613                 color = ''
6659                 args = dict()                    5614                 args = dict()
6660                 text, dev = kprobes[name]        5615                 text, dev = kprobes[name]
6661                 data = text.split()              5616                 data = text.split()
6662                 i = 0                            5617                 i = 0
6663                 for val in data:                 5618                 for val in data:
6664                         # bracketted strings     5619                         # bracketted strings are special formatting, read them separately
6665                         if val[0] == '[' and     5620                         if val[0] == '[' and val[-1] == ']':
6666                                 for prop in v    5621                                 for prop in val[1:-1].split(','):
6667                                         p = p    5622                                         p = prop.split('=')
6668                                         if p[    5623                                         if p[0] == 'color':
6669                                                  5624                                                 try:
6670                                                  5625                                                         color = int(p[1], 16)
6671                                                  5626                                                         color = '#'+p[1]
6672                                                  5627                                                 except:
6673                                                  5628                                                         color = p[1]
6674                                 continue         5629                                 continue
6675                         # first real arg shou    5630                         # first real arg should be the format string
6676                         if i == 0:               5631                         if i == 0:
6677                                 format = val     5632                                 format = val
6678                         # all other args are     5633                         # all other args are actual function args
6679                         else:                    5634                         else:
6680                                 d = val.split    5635                                 d = val.split('=')
6681                                 args[d[0]] =     5636                                 args[d[0]] = d[1]
6682                         i += 1                   5637                         i += 1
6683                 if not function or not format    5638                 if not function or not format:
6684                         doError('Invalid kpro    5639                         doError('Invalid kprobe: %s' % name)
6685                 for arg in re.findall('{(?P<n    5640                 for arg in re.findall('{(?P<n>[a-z,A-Z,0-9]*)}', format):
6686                         if arg not in args:      5641                         if arg not in args:
6687                                 doError('Kpro    5642                                 doError('Kprobe "%s" is missing argument "%s"' % (name, arg))
6688                 if (dev and name in sysvals.d    5643                 if (dev and name in sysvals.dev_tracefuncs) or (not dev and name in sysvals.tracefuncs):
6689                         doError('Duplicate ti    5644                         doError('Duplicate timeline function found "%s"' % (name))
6690                                                  5645 
6691                 kp = {                           5646                 kp = {
6692                         'name': name,            5647                         'name': name,
6693                         'func': function,        5648                         'func': function,
6694                         'format': format,        5649                         'format': format,
6695                         sysvals.archargs: arg    5650                         sysvals.archargs: args
6696                 }                                5651                 }
6697                 if color:                        5652                 if color:
6698                         kp['color'] = color      5653                         kp['color'] = color
6699                 if dev:                          5654                 if dev:
6700                         sysvals.dev_tracefunc    5655                         sysvals.dev_tracefuncs[name] = kp
6701                 else:                            5656                 else:
6702                         sysvals.tracefuncs[na    5657                         sysvals.tracefuncs[name] = kp
6703                                                  5658 
6704 # Function: printHelp                            5659 # Function: printHelp
6705 # Description:                                   5660 # Description:
6706 #        print out the help text                 5661 #        print out the help text
6707 def printHelp():                                 5662 def printHelp():
6708         pprint('\n%s v%s\n'\                  !! 5663         print('')
6709         'Usage: sudo sleepgraph <options> <co !! 5664         print('%s v%s' % (sysvals.title, sysvals.version))
6710         '\n'\                                 !! 5665         print('Usage: sudo sleepgraph <options> <commands>')
6711         'Description:\n'\                     !! 5666         print('')
6712         '  This tool is designed to assist ke !! 5667         print('Description:')
6713         '  their linux stack\'s suspend/resum !! 5668         print('  This tool is designed to assist kernel and OS developers in optimizing')
6714         '  with a few extra options enabled,  !! 5669         print('  their linux stack\'s suspend/resume time. Using a kernel image built')
6715         '  capture dmesg and ftrace data unti !! 5670         print('  with a few extra options enabled, the tool will execute a suspend and')
6716         '  transformed into a device timeline !! 5671         print('  capture dmesg and ftrace data until resume is complete. This data is')
6717         '  a detailed view of which devices/s !! 5672         print('  transformed into a device timeline and an optional callgraph to give')
6718         '  time in suspend/resume.\n'\        !! 5673         print('  a detailed view of which devices/subsystems are taking the most')
6719         '\n'\                                 !! 5674         print('  time in suspend/resume.')
6720         '  If no specific command is given, t !! 5675         print('')
6721         '  a suspend/resume and capture the d !! 5676         print('  If no specific command is given, the default behavior is to initiate')
6722         '\n'\                                 !! 5677         print('  a suspend/resume and capture the dmesg/ftrace output as an html timeline.')
6723         '  Generates output files in subdirec !! 5678         print('')
6724         '   HTML output:                    < !! 5679         print('  Generates output files in subdirectory: suspend-yymmdd-HHMMSS')
6725         '   raw dmesg output:               < !! 5680         print('   HTML output:                    <hostname>_<mode>.html')
6726         '   raw ftrace output:              < !! 5681         print('   raw dmesg output:               <hostname>_<mode>_dmesg.txt')
6727         '\n'\                                 !! 5682         print('   raw ftrace output:              <hostname>_<mode>_ftrace.txt')
6728         'Options:\n'\                         !! 5683         print('')
6729         '   -h           Print this help text !! 5684         print('Options:')
6730         '   -v           Print the current to !! 5685         print('   -h           Print this help text')
6731         '   -config fn   Pull arguments and c !! 5686         print('   -v           Print the current tool version')
6732         '   -verbose     Print extra informat !! 5687         print('   -config fn   Pull arguments and config options from file fn')
6733         '   -m mode      Mode to initiate for !! 5688         print('   -verbose     Print extra information during execution and analysis')
6734         '   -o name      Overrides the output !! 5689         print('   -m mode      Mode to initiate for suspend (default: %s)') % (sysvals.suspendmode)
6735         '                default: suspend-{da !! 5690         print('   -o name      Overrides the output subdirectory name when running a new test')
6736         '   -rtcwake t   Wakeup t seconds aft !! 5691         print('                default: suspend-{date}-{time}')
6737         '   -addlogs     Add the dmesg and ft !! 5692         print('   -rtcwake t   Wakeup t seconds after suspend, set t to "off" to disable (default: 15)')
6738         '   -noturbostat Dont use turbostat i !! 5693         print('   -addlogs     Add the dmesg and ftrace logs to the html output')
6739         '   -srgap       Add a visible gap in !! 5694         print('   -srgap       Add a visible gap in the timeline between sus/res (default: disabled)')
6740         '   -skiphtml    Run the test and cap !! 5695         print('   -skiphtml    Run the test and capture the trace logs, but skip the timeline (default: disabled)')
6741         '   -result fn   Export a results tab !! 5696         print('   -result fn   Export a results table to a text file for parsing.')
6742         '   -wifi        If a wifi connection !! 5697         print('  [testprep]')
6743         '   -wifitrace   Trace kernel executi !! 5698         print('   -sync        Sync the filesystems before starting the test')
6744         '   -netfix      Use netfix to reset  !! 5699         print('   -rs on/off   Enable/disable runtime suspend for all devices, restore all after test')
6745         '  [testprep]\n'\                     !! 5700         print('   -display on/off  Turn the display on or off for the test')
6746         '   -sync        Sync the filesystems !! 5701         print('  [advanced]')
6747         '   -rs on/off   Enable/disable runti !! 5702         print('   -gzip        Gzip the trace and dmesg logs to save space')
6748         '   -display m   Change the display m !! 5703         print('   -cmd {s}     Run the timeline over a custom command, e.g. "sync -d"')
6749         '  [advanced]\n'\                     !! 5704         print('   -proc        Add usermode process info into the timeline (default: disabled)')
6750         '   -gzip        Gzip the trace and d !! 5705         print('   -dev         Add kernel function calls and threads to the timeline (default: disabled)')
6751         '   -cmd {s}     Run the timeline ove !! 5706         print('   -x2          Run two suspend/resumes back to back (default: disabled)')
6752         '   -proc        Add usermode process !! 5707         print('   -x2delay t   Include t ms delay between multiple test runs (default: 0 ms)')
6753         '   -dev         Add kernel function  !! 5708         print('   -predelay t  Include t ms delay before 1st suspend (default: 0 ms)')
6754         '   -x2          Run two suspend/resu !! 5709         print('   -postdelay t Include t ms delay after last resume (default: 0 ms)')
6755         '   -x2delay t   Include t ms delay b !! 5710         print('   -mindev ms   Discard all device blocks shorter than ms milliseconds (e.g. 0.001 for us)')
6756         '   -predelay t  Include t ms delay b !! 5711         print('   -multi n d   Execute <n> consecutive tests at <d> seconds intervals. The outputs will')
6757         '   -postdelay t Include t ms delay a !! 5712         print('                be created in a new subdirectory with a summary page.')
6758         '   -mindev ms   Discard all device b !! 5713         print('  [debug]')
6759         '   -multi n d   Execute <n> consecut !! 5714         print('   -f           Use ftrace to create device callgraphs (default: disabled)')
6760         '                by a "d", "h", or "m !! 5715         print('   -maxdepth N  limit the callgraph data to N call levels (default: 0=all)')
6761         '                The outputs will be  !! 5716         print('   -expandcg    pre-expand the callgraph data in the html output (default: disabled)')
6762         '   -maxfail n   Abort a -multi run a !! 5717         print('   -fadd file   Add functions to be graphed in the timeline from a list in a text file')
6763         '  [debug]\n'\                        !! 5718         print('   -filter "d1,d2,..." Filter out all but this comma-delimited list of device names')
6764         '   -f           Use ftrace to create !! 5719         print('   -mincg  ms   Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)')
6765         '   -ftop        Use ftrace on the to !! 5720         print('   -cgphase P   Only show callgraph data for phase P (e.g. suspend_late)')
6766         '   -maxdepth N  limit the callgraph  !! 5721         print('   -cgtest N    Only show callgraph data for test N (e.g. 0 or 1 in an x2 run)')
6767         '   -expandcg    pre-expand the callg !! 5722         print('   -timeprec N  Number of significant digits in timestamps (0:S, [3:ms], 6:us)')
6768         '   -fadd file   Add functions to be  !! 5723         print('   -cgfilter S  Filter the callgraph output in the timeline')
6769         '   -filter "d1,d2,..." Filter out al !! 5724         print('   -cgskip file Callgraph functions to skip, off to disable (default: cgskip.txt)')
6770         '   -mincg  ms   Discard all callgrap !! 5725         print('   -bufsize N   Set trace buffer size to N kilo-bytes (default: all of free memory)')
6771         '   -cgphase P   Only show callgraph  !! 5726         print('')
6772         '   -cgtest N    Only show callgraph  !! 5727         print('Other commands:')
6773         '   -timeprec N  Number of significan !! 5728         print('   -modes       List available suspend modes')
6774         '   -cgfilter S  Filter the callgraph !! 5729         print('   -status      Test to see if the system is enabled to run this tool')
6775         '   -cgskip file Callgraph functions  !! 5730         print('   -fpdt        Print out the contents of the ACPI Firmware Performance Data Table')
6776         '   -bufsize N   Set trace buffer siz !! 5731         print('   -battery     Print out battery info (if available)')
6777         '   -devdump     Print out all the ra !! 5732         print('   -sysinfo     Print out system info extracted from BIOS')
6778         '   -cgdump      Print out all the ra !! 5733         print('   -devinfo     Print out the pm settings of all devices which support runtime suspend')
6779         '\n'\                                 !! 5734         print('   -flist       Print the list of functions currently being captured in ftrace')
6780         'Other commands:\n'\                  !! 5735         print('   -flistall    Print all functions capable of being captured in ftrace')
6781         '   -modes       List available suspe !! 5736         print('   -summary dir Create a summary of tests in this dir [-genhtml builds missing html]')
6782         '   -status      Test to see if the s !! 5737         print('  [redo]')
6783         '   -fpdt        Print out the conten !! 5738         print('   -ftrace ftracefile  Create HTML output using ftrace input (used with -dmesg)')
6784         '   -wificheck   Print out wifi conne !! 5739         print('   -dmesg dmesgfile    Create HTML output using dmesg (used with -ftrace)')
6785         '   -x<mode>     Test xset by togglin !! 5740         print('')
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                              5741         return True
6797                                                  5742 
6798 # ----------------- MAIN --------------------    5743 # ----------------- MAIN --------------------
6799 # exec start (skipped if script is loaded as     5744 # exec start (skipped if script is loaded as library)
6800 if __name__ == '__main__':                       5745 if __name__ == '__main__':
6801         genhtml = False                          5746         genhtml = False
6802         cmd = ''                                 5747         cmd = ''
6803         simplecmds = ['-sysinfo', '-modes', ' !! 5748         simplecmds = ['-sysinfo', '-modes', '-fpdt', '-flist', '-flistall', '-devinfo', '-status', '-battery']
6804                 '-devinfo', '-status', '-xon' << 
6805                 '-xinit', '-xreset', '-xstat' << 
6806         if '-f' in sys.argv:                     5749         if '-f' in sys.argv:
6807                 sysvals.cgskip = sysvals.conf    5750                 sysvals.cgskip = sysvals.configFile('cgskip.txt')
6808         # loop through the command line argum    5751         # loop through the command line arguments
6809         args = iter(sys.argv[1:])                5752         args = iter(sys.argv[1:])
6810         for arg in args:                         5753         for arg in args:
6811                 if(arg == '-m'):                 5754                 if(arg == '-m'):
6812                         try:                     5755                         try:
6813                                 val = next(ar !! 5756                                 val = args.next()
6814                         except:                  5757                         except:
6815                                 doError('No m    5758                                 doError('No mode supplied', True)
6816                         if val == 'command' a    5759                         if val == 'command' and not sysvals.testcommand:
6817                                 doError('No c    5760                                 doError('No command supplied for mode "command"', True)
6818                         sysvals.suspendmode =    5761                         sysvals.suspendmode = val
6819                 elif(arg in simplecmds):         5762                 elif(arg in simplecmds):
6820                         cmd = arg[1:]            5763                         cmd = arg[1:]
6821                 elif(arg == '-h'):               5764                 elif(arg == '-h'):
6822                         printHelp()              5765                         printHelp()
6823                         sys.exit(0)           !! 5766                         sys.exit()
6824                 elif(arg == '-v'):               5767                 elif(arg == '-v'):
6825                         pprint("Version %s" % !! 5768                         print("Version %s" % sysvals.version)
6826                         sys.exit(0)           !! 5769                         sys.exit()
6827                 elif(arg == '-debugtiming'):  << 
6828                         debugtiming = True    << 
6829                 elif(arg == '-x2'):              5770                 elif(arg == '-x2'):
6830                         sysvals.execcount = 2    5771                         sysvals.execcount = 2
6831                 elif(arg == '-x2delay'):         5772                 elif(arg == '-x2delay'):
6832                         sysvals.x2delay = get    5773                         sysvals.x2delay = getArgInt('-x2delay', args, 0, 60000)
6833                 elif(arg == '-predelay'):        5774                 elif(arg == '-predelay'):
6834                         sysvals.predelay = ge    5775                         sysvals.predelay = getArgInt('-predelay', args, 0, 60000)
6835                 elif(arg == '-postdelay'):       5776                 elif(arg == '-postdelay'):
6836                         sysvals.postdelay = g    5777                         sysvals.postdelay = getArgInt('-postdelay', args, 0, 60000)
6837                 elif(arg == '-f'):               5778                 elif(arg == '-f'):
6838                         sysvals.usecallgraph     5779                         sysvals.usecallgraph = True
6839                 elif(arg == '-ftop'):         << 
6840                         sysvals.usecallgraph  << 
6841                         sysvals.ftop = True   << 
6842                         sysvals.usekprobes =  << 
6843                 elif(arg == '-skiphtml'):        5780                 elif(arg == '-skiphtml'):
6844                         sysvals.skiphtml = Tr    5781                         sysvals.skiphtml = True
6845                 elif(arg == '-cgdump'):          5782                 elif(arg == '-cgdump'):
6846                         sysvals.cgdump = True    5783                         sysvals.cgdump = True
6847                 elif(arg == '-devdump'):      << 
6848                         sysvals.devdump = Tru << 
6849                 elif(arg == '-genhtml'):         5784                 elif(arg == '-genhtml'):
6850                         genhtml = True           5785                         genhtml = True
6851                 elif(arg == '-addlogs'):         5786                 elif(arg == '-addlogs'):
6852                         sysvals.dmesglog = sy    5787                         sysvals.dmesglog = sysvals.ftracelog = True
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'):         5788                 elif(arg == '-verbose'):
6862                         sysvals.verbose = Tru    5789                         sysvals.verbose = True
6863                 elif(arg == '-proc'):            5790                 elif(arg == '-proc'):
6864                         sysvals.useprocmon =     5791                         sysvals.useprocmon = True
6865                 elif(arg == '-dev'):             5792                 elif(arg == '-dev'):
6866                         sysvals.usedevsrc = T    5793                         sysvals.usedevsrc = True
6867                 elif(arg == '-sync'):            5794                 elif(arg == '-sync'):
6868                         sysvals.sync = True      5795                         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'):            5796                 elif(arg == '-gzip'):
6876                         sysvals.gzip = True      5797                         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'):              5798                 elif(arg == '-rs'):
6888                         try:                     5799                         try:
6889                                 val = next(ar !! 5800                                 val = args.next()
6890                         except:                  5801                         except:
6891                                 doError('-rs     5802                                 doError('-rs requires "enable" or "disable"', True)
6892                         if val.lower() in swi    5803                         if val.lower() in switchvalues:
6893                                 if val.lower(    5804                                 if val.lower() in switchoff:
6894                                         sysva    5805                                         sysvals.rs = -1
6895                                 else:            5806                                 else:
6896                                         sysva    5807                                         sysvals.rs = 1
6897                         else:                    5808                         else:
6898                                 doError('inva    5809                                 doError('invalid option: %s, use "enable/disable" or "on/off"' % val, True)
6899                 elif(arg == '-display'):         5810                 elif(arg == '-display'):
6900                         try:                     5811                         try:
6901                                 val = next(ar !! 5812                                 val = args.next()
6902                         except:                  5813                         except:
6903                                 doError('-dis !! 5814                                 doError('-display requires "on" or "off"', True)
6904                         disopt = ['on', 'off' !! 5815                         if val.lower() in switchvalues:
6905                         if val.lower() not in !! 5816                                 if val.lower() in switchoff:
6906                                 doError('vali !! 5817                                         sysvals.display = -1
6907                         sysvals.display = val !! 5818                                 else:
                                                   >> 5819                                         sysvals.display = 1
                                                   >> 5820                         else:
                                                   >> 5821                                 doError('invalid option: %s, use "on/off"' % val, True)
6908                 elif(arg == '-maxdepth'):        5822                 elif(arg == '-maxdepth'):
6909                         sysvals.max_graph_dep    5823                         sysvals.max_graph_depth = getArgInt('-maxdepth', args, 0, 1000)
6910                 elif(arg == '-rtcwake'):         5824                 elif(arg == '-rtcwake'):
6911                         try:                     5825                         try:
6912                                 val = next(ar !! 5826                                 val = args.next()
6913                         except:                  5827                         except:
6914                                 doError('No r    5828                                 doError('No rtcwake time supplied', True)
6915                         if val.lower() in swi    5829                         if val.lower() in switchoff:
6916                                 sysvals.rtcwa    5830                                 sysvals.rtcwake = False
6917                         else:                    5831                         else:
6918                                 sysvals.rtcwa    5832                                 sysvals.rtcwake = True
6919                                 sysvals.rtcwa    5833                                 sysvals.rtcwaketime = getArgInt('-rtcwake', val, 0, 3600, False)
6920                 elif(arg == '-timeprec'):        5834                 elif(arg == '-timeprec'):
6921                         sysvals.setPrecision(    5835                         sysvals.setPrecision(getArgInt('-timeprec', args, 0, 6))
6922                 elif(arg == '-mindev'):          5836                 elif(arg == '-mindev'):
6923                         sysvals.mindevlen = g    5837                         sysvals.mindevlen = getArgFloat('-mindev', args, 0.0, 10000.0)
6924                 elif(arg == '-mincg'):           5838                 elif(arg == '-mincg'):
6925                         sysvals.mincglen = ge    5839                         sysvals.mincglen = getArgFloat('-mincg', args, 0.0, 10000.0)
6926                 elif(arg == '-bufsize'):         5840                 elif(arg == '-bufsize'):
6927                         sysvals.bufsize = get    5841                         sysvals.bufsize = getArgInt('-bufsize', args, 1, 1024*1024*8)
6928                 elif(arg == '-cgtest'):          5842                 elif(arg == '-cgtest'):
6929                         sysvals.cgtest = getA    5843                         sysvals.cgtest = getArgInt('-cgtest', args, 0, 1)
6930                 elif(arg == '-cgphase'):         5844                 elif(arg == '-cgphase'):
6931                         try:                     5845                         try:
6932                                 val = next(ar !! 5846                                 val = args.next()
6933                         except:                  5847                         except:
6934                                 doError('No p    5848                                 doError('No phase name supplied', True)
6935                         d = Data(0)              5849                         d = Data(0)
6936                         if val not in d.phase !! 5850                         if val not in d.phases:
6937                                 doError('inva    5851                                 doError('invalid phase --> (%s: %s), valid phases are %s'\
6938                                         % (ar !! 5852                                         % (arg, val, d.phases), True)
6939                         sysvals.cgphase = val    5853                         sysvals.cgphase = val
6940                 elif(arg == '-cgfilter'):        5854                 elif(arg == '-cgfilter'):
6941                         try:                     5855                         try:
6942                                 val = next(ar !! 5856                                 val = args.next()
6943                         except:                  5857                         except:
6944                                 doError('No c    5858                                 doError('No callgraph functions supplied', True)
6945                         sysvals.setCallgraphF    5859                         sysvals.setCallgraphFilter(val)
6946                 elif(arg == '-skipkprobe'):   << 
6947                         try:                  << 
6948                                 val = next(ar << 
6949                         except:               << 
6950                                 doError('No k << 
6951                         sysvals.skipKprobes(v << 
6952                 elif(arg == '-cgskip'):          5860                 elif(arg == '-cgskip'):
6953                         try:                     5861                         try:
6954                                 val = next(ar !! 5862                                 val = args.next()
6955                         except:                  5863                         except:
6956                                 doError('No f    5864                                 doError('No file supplied', True)
6957                         if val.lower() in swi    5865                         if val.lower() in switchoff:
6958                                 sysvals.cgski    5866                                 sysvals.cgskip = ''
6959                         else:                    5867                         else:
6960                                 sysvals.cgski    5868                                 sysvals.cgskip = sysvals.configFile(val)
6961                                 if(not sysval    5869                                 if(not sysvals.cgskip):
6962                                         doErr    5870                                         doError('%s does not exist' % sysvals.cgskip)
6963                 elif(arg == '-callloop-maxgap    5871                 elif(arg == '-callloop-maxgap'):
6964                         sysvals.callloopmaxga    5872                         sysvals.callloopmaxgap = getArgFloat('-callloop-maxgap', args, 0.0, 1.0)
6965                 elif(arg == '-callloop-maxlen    5873                 elif(arg == '-callloop-maxlen'):
6966                         sysvals.callloopmaxle    5874                         sysvals.callloopmaxlen = getArgFloat('-callloop-maxlen', args, 0.0, 1.0)
6967                 elif(arg == '-cmd'):             5875                 elif(arg == '-cmd'):
6968                         try:                     5876                         try:
6969                                 val = next(ar !! 5877                                 val = args.next()
6970                         except:                  5878                         except:
6971                                 doError('No c    5879                                 doError('No command string supplied', True)
6972                         sysvals.testcommand =    5880                         sysvals.testcommand = val
6973                         sysvals.suspendmode =    5881                         sysvals.suspendmode = 'command'
6974                 elif(arg == '-expandcg'):        5882                 elif(arg == '-expandcg'):
6975                         sysvals.cgexp = True     5883                         sysvals.cgexp = True
6976                 elif(arg == '-srgap'):           5884                 elif(arg == '-srgap'):
6977                         sysvals.srgap = 5        5885                         sysvals.srgap = 5
6978                 elif(arg == '-maxfail'):      << 
6979                         sysvals.maxfail = get << 
6980                 elif(arg == '-multi'):           5886                 elif(arg == '-multi'):
6981                         try:                  !! 5887                         sysvals.multitest['run'] = True
6982                                 c, d = next(a !! 5888                         sysvals.multitest['count'] = getArgInt('-multi n d (exec count)', args, 2, 1000000)
6983                         except:               !! 5889                         sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600)
6984                                 doError('-mul << 
6985                         sysvals.multiinit(c,  << 
6986                 elif(arg == '-o'):               5890                 elif(arg == '-o'):
6987                         try:                     5891                         try:
6988                                 val = next(ar !! 5892                                 val = args.next()
6989                         except:                  5893                         except:
6990                                 doError('No s    5894                                 doError('No subdirectory name supplied', True)
6991                         sysvals.outdir = sysv    5895                         sysvals.outdir = sysvals.setOutputFolder(val)
6992                 elif(arg == '-config'):          5896                 elif(arg == '-config'):
6993                         try:                     5897                         try:
6994                                 val = next(ar !! 5898                                 val = args.next()
6995                         except:                  5899                         except:
6996                                 doError('No t    5900                                 doError('No text file supplied', True)
6997                         file = sysvals.config    5901                         file = sysvals.configFile(val)
6998                         if(not file):            5902                         if(not file):
6999                                 doError('%s d    5903                                 doError('%s does not exist' % val)
7000                         configFromFile(file)     5904                         configFromFile(file)
7001                 elif(arg == '-fadd'):            5905                 elif(arg == '-fadd'):
7002                         try:                     5906                         try:
7003                                 val = next(ar !! 5907                                 val = args.next()
7004                         except:                  5908                         except:
7005                                 doError('No t    5909                                 doError('No text file supplied', True)
7006                         file = sysvals.config    5910                         file = sysvals.configFile(val)
7007                         if(not file):            5911                         if(not file):
7008                                 doError('%s d    5912                                 doError('%s does not exist' % val)
7009                         sysvals.addFtraceFilt    5913                         sysvals.addFtraceFilterFunctions(file)
7010                 elif(arg == '-dmesg'):           5914                 elif(arg == '-dmesg'):
7011                         try:                     5915                         try:
7012                                 val = next(ar !! 5916                                 val = args.next()
7013                         except:                  5917                         except:
7014                                 doError('No d    5918                                 doError('No dmesg file supplied', True)
7015                         sysvals.notestrun = T    5919                         sysvals.notestrun = True
7016                         sysvals.dmesgfile = v    5920                         sysvals.dmesgfile = val
7017                         if(os.path.exists(sys    5921                         if(os.path.exists(sysvals.dmesgfile) == False):
7018                                 doError('%s d    5922                                 doError('%s does not exist' % sysvals.dmesgfile)
7019                 elif(arg == '-ftrace'):          5923                 elif(arg == '-ftrace'):
7020                         try:                     5924                         try:
7021                                 val = next(ar !! 5925                                 val = args.next()
7022                         except:                  5926                         except:
7023                                 doError('No f    5927                                 doError('No ftrace file supplied', True)
7024                         sysvals.notestrun = T    5928                         sysvals.notestrun = True
7025                         sysvals.ftracefile =     5929                         sysvals.ftracefile = val
7026                         if(os.path.exists(sys    5930                         if(os.path.exists(sysvals.ftracefile) == False):
7027                                 doError('%s d    5931                                 doError('%s does not exist' % sysvals.ftracefile)
7028                 elif(arg == '-summary'):         5932                 elif(arg == '-summary'):
7029                         try:                     5933                         try:
7030                                 val = next(ar !! 5934                                 val = args.next()
7031                         except:                  5935                         except:
7032                                 doError('No d    5936                                 doError('No directory supplied', True)
7033                         cmd = 'summary'          5937                         cmd = 'summary'
7034                         sysvals.outdir = val     5938                         sysvals.outdir = val
7035                         sysvals.notestrun = T    5939                         sysvals.notestrun = True
7036                         if(os.path.isdir(val)    5940                         if(os.path.isdir(val) == False):
7037                                 doError('%s i    5941                                 doError('%s is not accesible' % val)
7038                 elif(arg == '-filter'):          5942                 elif(arg == '-filter'):
7039                         try:                     5943                         try:
7040                                 val = next(ar !! 5944                                 val = args.next()
7041                         except:                  5945                         except:
7042                                 doError('No d    5946                                 doError('No devnames supplied', True)
7043                         sysvals.setDeviceFilt    5947                         sysvals.setDeviceFilter(val)
7044                 elif(arg == '-result'):          5948                 elif(arg == '-result'):
7045                         try:                     5949                         try:
7046                                 val = next(ar !! 5950                                 val = args.next()
7047                         except:                  5951                         except:
7048                                 doError('No r    5952                                 doError('No result file supplied', True)
7049                         sysvals.result = val     5953                         sysvals.result = val
7050                         sysvals.signalHandler << 
7051                 else:                            5954                 else:
7052                         doError('Invalid argu    5955                         doError('Invalid argument: '+arg, True)
7053                                                  5956 
7054         # compatibility errors                   5957         # compatibility errors
7055         if(sysvals.usecallgraph and sysvals.u    5958         if(sysvals.usecallgraph and sysvals.usedevsrc):
7056                 doError('-dev is not compatib    5959                 doError('-dev is not compatible with -f')
7057         if(sysvals.usecallgraph and sysvals.u    5960         if(sysvals.usecallgraph and sysvals.useprocmon):
7058                 doError('-proc is not compati    5961                 doError('-proc is not compatible with -f')
7059                                                  5962 
7060         if sysvals.usecallgraph and sysvals.c    5963         if sysvals.usecallgraph and sysvals.cgskip:
7061                 sysvals.vprint('Using cgskip     5964                 sysvals.vprint('Using cgskip file: %s' % sysvals.cgskip)
7062                 sysvals.setCallgraphBlacklist    5965                 sysvals.setCallgraphBlacklist(sysvals.cgskip)
7063                                                  5966 
7064         # callgraph size cannot exceed device    5967         # callgraph size cannot exceed device size
7065         if sysvals.mincglen < sysvals.mindevl    5968         if sysvals.mincglen < sysvals.mindevlen:
7066                 sysvals.mincglen = sysvals.mi    5969                 sysvals.mincglen = sysvals.mindevlen
7067                                                  5970 
7068         # remove existing buffers before calc    5971         # remove existing buffers before calculating memory
7069         if(sysvals.usecallgraph or sysvals.us    5972         if(sysvals.usecallgraph or sysvals.usedevsrc):
7070                 sysvals.fsetVal('16', 'buffer    5973                 sysvals.fsetVal('16', 'buffer_size_kb')
7071         sysvals.cpuInfo()                        5974         sysvals.cpuInfo()
7072                                                  5975 
7073         # just run a utility command and exit    5976         # just run a utility command and exit
7074         if(cmd != ''):                           5977         if(cmd != ''):
7075                 ret = 0                       << 
7076                 if(cmd == 'status'):             5978                 if(cmd == 'status'):
7077                         if not statusCheck(Tr !! 5979                         statusCheck(True)
7078                                 ret = 1       << 
7079                 elif(cmd == 'fpdt'):             5980                 elif(cmd == 'fpdt'):
7080                         if not getFPDT(True): !! 5981                         getFPDT(True)
7081                                 ret = 1       !! 5982                 elif(cmd == 'battery'):
                                                   >> 5983                         print 'AC Connect: %s\nCharge: %d' % getBattery()
7082                 elif(cmd == 'sysinfo'):          5984                 elif(cmd == 'sysinfo'):
7083                         sysvals.printSystemIn    5985                         sysvals.printSystemInfo(True)
7084                 elif(cmd == 'devinfo'):          5986                 elif(cmd == 'devinfo'):
7085                         deviceInfo()             5987                         deviceInfo()
7086                 elif(cmd == 'modes'):            5988                 elif(cmd == 'modes'):
7087                         pprint(getModes())    !! 5989                         print getModes()
7088                 elif(cmd == 'flist'):            5990                 elif(cmd == 'flist'):
7089                         sysvals.getFtraceFilt    5991                         sysvals.getFtraceFilterFunctions(True)
7090                 elif(cmd == 'flistall'):         5992                 elif(cmd == 'flistall'):
7091                         sysvals.getFtraceFilt    5993                         sysvals.getFtraceFilterFunctions(False)
7092                 elif(cmd == 'summary'):          5994                 elif(cmd == 'summary'):
7093                         runSummary(sysvals.ou    5995                         runSummary(sysvals.outdir, True, genhtml)
7094                 elif(cmd in ['xon', 'xoff', ' !! 5996                 sys.exit()
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                                                  5997 
7110         # if instructed, re-analyze existing     5998         # if instructed, re-analyze existing data files
7111         if(sysvals.notestrun):                   5999         if(sysvals.notestrun):
7112                 stamp = rerunTest(sysvals.out !! 6000                 stamp = rerunTest()
7113                 sysvals.outputResult(stamp)      6001                 sysvals.outputResult(stamp)
7114                 sys.exit(0)                   !! 6002                 sys.exit()
7115                                                  6003 
7116         # verify that we can run a test          6004         # verify that we can run a test
7117         error = statusCheck()                 !! 6005         if(not statusCheck()):
7118         if(error):                            !! 6006                 doError('Check FAILED, aborting the test run!')
7119                 doError(error)                << 
7120                                                  6007 
7121         # extract mem/disk extra modes and co !! 6008         # extract mem modes and convert
7122         mode = sysvals.suspendmode               6009         mode = sysvals.suspendmode
7123         if mode.startswith('mem'):            !! 6010         if 'mem' == mode[:3]:
7124                 memmode = mode.split('-', 1)[ !! 6011                 if '-' in mode:
                                                   >> 6012                         memmode = mode.split('-')[-1]
                                                   >> 6013                 else:
                                                   >> 6014                         memmode = 'deep'
7125                 if memmode == 'shallow':         6015                 if memmode == 'shallow':
7126                         mode = 'standby'         6016                         mode = 'standby'
7127                 elif memmode ==  's2idle':       6017                 elif memmode ==  's2idle':
7128                         mode = 'freeze'          6018                         mode = 'freeze'
7129                 else:                            6019                 else:
7130                         mode = 'mem'             6020                         mode = 'mem'
7131                 sysvals.memmode = memmode        6021                 sysvals.memmode = memmode
7132                 sysvals.suspendmode = mode       6022                 sysvals.suspendmode = mode
7133         if mode.startswith('disk-'):          !! 6023 
7134                 sysvals.diskmode = mode.split << 
7135                 sysvals.suspendmode = 'disk'  << 
7136         sysvals.systemInfo(dmidecode(sysvals.    6024         sysvals.systemInfo(dmidecode(sysvals.mempath))
7137                                                  6025 
7138         failcnt, ret = 0, 0                   !! 6026         setRuntimeSuspend(True)
                                                   >> 6027         if sysvals.display:
                                                   >> 6028                 call('xset -d :0.0 dpms 0 0 0', shell=True)
                                                   >> 6029                 call('xset -d :0.0 s off', shell=True)
7139         if sysvals.multitest['run']:             6030         if sysvals.multitest['run']:
7140                 # run multiple tests in a sep    6031                 # run multiple tests in a separate subdirectory
7141                 if not sysvals.outdir:           6032                 if not sysvals.outdir:
7142                         if 'time' in sysvals. !! 6033                         s = 'suspend-x%d' % sysvals.multitest['count']
7143                                 s = '-%dm' %  !! 6034                         sysvals.outdir = datetime.now().strftime(s+'-%y%m%d-%H%M%S')
7144                         else:                 << 
7145                                 s = '-x%d' %  << 
7146                         sysvals.outdir = date << 
7147                 if not os.path.isdir(sysvals.    6035                 if not os.path.isdir(sysvals.outdir):
7148                         os.makedirs(sysvals.o !! 6036                         os.mkdir(sysvals.outdir)
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    6037                 for i in range(sysvals.multitest['count']):
7154                         sysvals.multistat(Tru !! 6038                         if(i != 0):
7155                         if i != 0 and sysvals !! 6039                                 print('Waiting %d seconds...' % (sysvals.multitest['delay']))
7156                                 pprint('Waiti << 
7157                                 time.sleep(sy    6040                                 time.sleep(sysvals.multitest['delay'])
                                                   >> 6041                         print('TEST (%d/%d) START' % (i+1, sysvals.multitest['count']))
7158                         fmt = 'suspend-%y%m%d    6042                         fmt = 'suspend-%y%m%d-%H%M%S'
7159                         sysvals.testdir = os.    6043                         sysvals.testdir = os.path.join(sysvals.outdir, datetime.now().strftime(fmt))
7160                         ret = runTest(i+1, no !! 6044                         runTest(i+1)
7161                         failcnt = 0 if not re !! 6045                         print('TEST (%d/%d) COMPLETE' % (i+1, sysvals.multitest['count']))
7162                         if sysvals.maxfail >  !! 6046                         sysvals.logmsg = ''
7163                                 pprint('Maxim << 
7164                                 break         << 
7165                         sysvals.resetlog()    << 
7166                         sysvals.multistat(Fal << 
7167                         if 'time' in sysvals. << 
7168                                 break         << 
7169                 if not sysvals.skiphtml:         6047                 if not sysvals.skiphtml:
7170                         runSummary(sysvals.ou    6048                         runSummary(sysvals.outdir, False, False)
7171                 sysvals.sudoUserchown(sysvals !! 6049                 sysvals.sudouser(sysvals.outdir)
7172         else:                                    6050         else:
7173                 if sysvals.outdir:               6051                 if sysvals.outdir:
7174                         sysvals.testdir = sys    6052                         sysvals.testdir = sysvals.outdir
7175                 # run the test in the current    6053                 # run the test in the current directory
7176                 ret = runTest()               !! 6054                 runTest()
7177                                               << 
7178         # reset to default values after testi << 
7179         if sysvals.display:                      6055         if sysvals.display:
7180                 sysvals.displayControl('reset !! 6056                 call('xset -d :0.0 s reset', shell=True)
7181         if sysvals.rs != 0:                   !! 6057         setRuntimeSuspend(False)
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