diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-09-07 17:39:55 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-09-07 17:39:55 -0400 |
commit | e3e2ffdc0c13db8631a7248a3f356bb006ff5068 (patch) | |
tree | 2a4a8bee128c69490836cf907dbecb368afae9a9 /tools/power | |
parent | a41f7f0ae7b340adaaaaad162fd363859e346c75 (diff) | |
parent | 4216148337211be7ad2bfe38a0dffc3ce479c283 (diff) |
Merge back earlier power management tools updates for v5.4.
Diffstat (limited to 'tools/power')
-rw-r--r-- | tools/power/pm-graph/README | 6 | ||||
-rwxr-xr-x | tools/power/pm-graph/bootgraph.py | 59 | ||||
-rw-r--r-- | tools/power/pm-graph/sleepgraph.8 | 8 | ||||
-rwxr-xr-x | tools/power/pm-graph/sleepgraph.py | 618 |
4 files changed, 391 insertions, 300 deletions
diff --git a/tools/power/pm-graph/README b/tools/power/pm-graph/README index 58a5591e3951..96259f6e5715 100644 --- a/tools/power/pm-graph/README +++ b/tools/power/pm-graph/README | |||
@@ -1,7 +1,7 @@ | |||
1 | p m - g r a p h | 1 | p m - g r a p h |
2 | 2 | ||
3 | pm-graph: suspend/resume/boot timing analysis tools | 3 | pm-graph: suspend/resume/boot timing analysis tools |
4 | Version: 5.4 | 4 | Version: 5.5 |
5 | Author: Todd Brandt <todd.e.brandt@intel.com> | 5 | Author: Todd Brandt <todd.e.brandt@intel.com> |
6 | Home Page: https://01.org/pm-graph | 6 | Home Page: https://01.org/pm-graph |
7 | 7 | ||
@@ -18,6 +18,10 @@ | |||
18 | - upstream version in git: | 18 | - upstream version in git: |
19 | https://github.com/intel/pm-graph/ | 19 | https://github.com/intel/pm-graph/ |
20 | 20 | ||
21 | Requirements: | ||
22 | - runs with python2 or python3, choice is made by /usr/bin/python link | ||
23 | - python2 now requires python-configparser be installed | ||
24 | |||
21 | Table of Contents | 25 | Table of Contents |
22 | - Overview | 26 | - Overview |
23 | - Setup | 27 | - Setup |
diff --git a/tools/power/pm-graph/bootgraph.py b/tools/power/pm-graph/bootgraph.py index 666bcbda648d..d3b99a1e92d6 100755 --- a/tools/power/pm-graph/bootgraph.py +++ b/tools/power/pm-graph/bootgraph.py | |||
@@ -1,9 +1,18 @@ | |||
1 | #!/usr/bin/python2 | 1 | #!/usr/bin/python |
2 | # SPDX-License-Identifier: GPL-2.0-only | 2 | # SPDX-License-Identifier: GPL-2.0-only |
3 | # | 3 | # |
4 | # Tool for analyzing boot timing | 4 | # Tool for analyzing boot timing |
5 | # Copyright (c) 2013, Intel Corporation. | 5 | # Copyright (c) 2013, Intel Corporation. |
6 | # | 6 | # |
7 | # This program is free software; you can redistribute it and/or modify it | ||
8 | # under the terms and conditions of the GNU General Public License, | ||
9 | # version 2, as published by the Free Software Foundation. | ||
10 | # | ||
11 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | # more details. | ||
15 | # | ||
7 | # Authors: | 16 | # Authors: |
8 | # Todd Brandt <todd.e.brandt@linux.intel.com> | 17 | # Todd Brandt <todd.e.brandt@linux.intel.com> |
9 | # | 18 | # |
@@ -81,7 +90,7 @@ class SystemValues(aslib.SystemValues): | |||
81 | cmdline = 'initcall_debug log_buf_len=32M' | 90 | cmdline = 'initcall_debug log_buf_len=32M' |
82 | if self.useftrace: | 91 | if self.useftrace: |
83 | if self.cpucount > 0: | 92 | if self.cpucount > 0: |
84 | bs = min(self.memtotal / 2, 2*1024*1024) / self.cpucount | 93 | bs = min(self.memtotal // 2, 2*1024*1024) // self.cpucount |
85 | else: | 94 | else: |
86 | bs = 131072 | 95 | bs = 131072 |
87 | cmdline += ' trace_buf_size=%dK trace_clock=global '\ | 96 | cmdline += ' trace_buf_size=%dK trace_clock=global '\ |
@@ -137,13 +146,13 @@ class SystemValues(aslib.SystemValues): | |||
137 | if arg in ['-h', '-v', '-cronjob', '-reboot', '-verbose']: | 146 | if arg in ['-h', '-v', '-cronjob', '-reboot', '-verbose']: |
138 | continue | 147 | continue |
139 | elif arg in ['-o', '-dmesg', '-ftrace', '-func']: | 148 | elif arg in ['-o', '-dmesg', '-ftrace', '-func']: |
140 | args.next() | 149 | next(args) |
141 | continue | 150 | continue |
142 | elif arg == '-result': | 151 | elif arg == '-result': |
143 | cmdline += ' %s "%s"' % (arg, os.path.abspath(args.next())) | 152 | cmdline += ' %s "%s"' % (arg, os.path.abspath(next(args))) |
144 | continue | 153 | continue |
145 | elif arg == '-cgskip': | 154 | elif arg == '-cgskip': |
146 | file = self.configFile(args.next()) | 155 | file = self.configFile(next(args)) |
147 | cmdline += ' %s "%s"' % (arg, os.path.abspath(file)) | 156 | cmdline += ' %s "%s"' % (arg, os.path.abspath(file)) |
148 | continue | 157 | continue |
149 | cmdline += ' '+arg | 158 | cmdline += ' '+arg |
@@ -292,11 +301,11 @@ def parseKernelLog(): | |||
292 | tp = aslib.TestProps() | 301 | tp = aslib.TestProps() |
293 | devtemp = dict() | 302 | devtemp = dict() |
294 | if(sysvals.dmesgfile): | 303 | if(sysvals.dmesgfile): |
295 | lf = open(sysvals.dmesgfile, 'r') | 304 | lf = open(sysvals.dmesgfile, 'rb') |
296 | else: | 305 | else: |
297 | lf = Popen('dmesg', stdout=PIPE).stdout | 306 | lf = Popen('dmesg', stdout=PIPE).stdout |
298 | for line in lf: | 307 | for line in lf: |
299 | line = line.replace('\r\n', '') | 308 | line = aslib.ascii(line).replace('\r\n', '') |
300 | # grab the stamp and sysinfo | 309 | # grab the stamp and sysinfo |
301 | if re.match(tp.stampfmt, line): | 310 | if re.match(tp.stampfmt, line): |
302 | tp.stamp = line | 311 | tp.stamp = line |
@@ -649,7 +658,7 @@ def createBootGraph(data): | |||
649 | statinfo += '\t"%s": [\n\t\t"%s",\n' % (n, devstats[n]['info']) | 658 | statinfo += '\t"%s": [\n\t\t"%s",\n' % (n, devstats[n]['info']) |
650 | if 'fstat' in devstats[n]: | 659 | if 'fstat' in devstats[n]: |
651 | funcs = devstats[n]['fstat'] | 660 | funcs = devstats[n]['fstat'] |
652 | for f in sorted(funcs, key=funcs.get, reverse=True): | 661 | for f in sorted(funcs, key=lambda k:(funcs[k], k), reverse=True): |
653 | if funcs[f][0] < 0.01 and len(funcs) > 10: | 662 | if funcs[f][0] < 0.01 and len(funcs) > 10: |
654 | break | 663 | break |
655 | statinfo += '\t\t"%f|%s|%d",\n' % (funcs[f][0], f, funcs[f][1]) | 664 | statinfo += '\t\t"%f|%s|%d",\n' % (funcs[f][0], f, funcs[f][1]) |
@@ -729,7 +738,7 @@ def updateCron(restore=False): | |||
729 | op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) | 738 | op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) |
730 | op.close() | 739 | op.close() |
731 | res = call([cmd, cronfile]) | 740 | res = call([cmd, cronfile]) |
732 | except Exception, e: | 741 | except Exception as e: |
733 | pprint('Exception: %s' % str(e)) | 742 | pprint('Exception: %s' % str(e)) |
734 | shutil.move(backfile, cronfile) | 743 | shutil.move(backfile, cronfile) |
735 | res = -1 | 744 | res = -1 |
@@ -745,7 +754,7 @@ def updateGrub(restore=False): | |||
745 | try: | 754 | try: |
746 | call(sysvals.blexec, stderr=PIPE, stdout=PIPE, | 755 | call(sysvals.blexec, stderr=PIPE, stdout=PIPE, |
747 | env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) | 756 | env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) |
748 | except Exception, e: | 757 | except Exception as e: |
749 | pprint('Exception: %s\n' % str(e)) | 758 | pprint('Exception: %s\n' % str(e)) |
750 | return | 759 | return |
751 | # extract the option and create a grub config without it | 760 | # extract the option and create a grub config without it |
@@ -792,7 +801,7 @@ def updateGrub(restore=False): | |||
792 | op.close() | 801 | op.close() |
793 | res = call(sysvals.blexec) | 802 | res = call(sysvals.blexec) |
794 | os.remove(grubfile) | 803 | os.remove(grubfile) |
795 | except Exception, e: | 804 | except Exception as e: |
796 | pprint('Exception: %s' % str(e)) | 805 | pprint('Exception: %s' % str(e)) |
797 | res = -1 | 806 | res = -1 |
798 | # cleanup | 807 | # cleanup |
@@ -866,6 +875,7 @@ def printHelp(): | |||
866 | 'Other commands:\n'\ | 875 | 'Other commands:\n'\ |
867 | ' -flistall Print all functions capable of being captured in ftrace\n'\ | 876 | ' -flistall Print all functions capable of being captured in ftrace\n'\ |
868 | ' -sysinfo Print out system info extracted from BIOS\n'\ | 877 | ' -sysinfo Print out system info extracted from BIOS\n'\ |
878 | ' -which exec Print an executable path, should function even without PATH\n'\ | ||
869 | ' [redo]\n'\ | 879 | ' [redo]\n'\ |
870 | ' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\ | 880 | ' -dmesg file Create HTML output using dmesg input (used with -ftrace)\n'\ |
871 | ' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\ | 881 | ' -ftrace file Create HTML output using ftrace input (used with -dmesg)\n'\ |
@@ -907,13 +917,13 @@ if __name__ == '__main__': | |||
907 | sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) | 917 | sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) |
908 | elif(arg == '-cgfilter'): | 918 | elif(arg == '-cgfilter'): |
909 | try: | 919 | try: |
910 | val = args.next() | 920 | val = next(args) |
911 | except: | 921 | except: |
912 | doError('No callgraph functions supplied', True) | 922 | doError('No callgraph functions supplied', True) |
913 | sysvals.setCallgraphFilter(val) | 923 | sysvals.setCallgraphFilter(val) |
914 | elif(arg == '-cgskip'): | 924 | elif(arg == '-cgskip'): |
915 | try: | 925 | try: |
916 | val = args.next() | 926 | val = next(args) |
917 | except: | 927 | except: |
918 | doError('No file supplied', True) | 928 | doError('No file supplied', True) |
919 | if val.lower() in switchoff: | 929 | if val.lower() in switchoff: |
@@ -924,7 +934,7 @@ if __name__ == '__main__': | |||
924 | doError('%s does not exist' % cgskip) | 934 | doError('%s does not exist' % cgskip) |
925 | elif(arg == '-bl'): | 935 | elif(arg == '-bl'): |
926 | try: | 936 | try: |
927 | val = args.next() | 937 | val = next(args) |
928 | except: | 938 | except: |
929 | doError('No boot loader name supplied', True) | 939 | doError('No boot loader name supplied', True) |
930 | if val.lower() not in ['grub']: | 940 | if val.lower() not in ['grub']: |
@@ -937,7 +947,7 @@ if __name__ == '__main__': | |||
937 | sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) | 947 | sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) |
938 | elif(arg == '-func'): | 948 | elif(arg == '-func'): |
939 | try: | 949 | try: |
940 | val = args.next() | 950 | val = next(args) |
941 | except: | 951 | except: |
942 | doError('No filter functions supplied', True) | 952 | doError('No filter functions supplied', True) |
943 | sysvals.useftrace = True | 953 | sysvals.useftrace = True |
@@ -946,7 +956,7 @@ if __name__ == '__main__': | |||
946 | sysvals.setGraphFilter(val) | 956 | sysvals.setGraphFilter(val) |
947 | elif(arg == '-ftrace'): | 957 | elif(arg == '-ftrace'): |
948 | try: | 958 | try: |
949 | val = args.next() | 959 | val = next(args) |
950 | except: | 960 | except: |
951 | doError('No ftrace file supplied', True) | 961 | doError('No ftrace file supplied', True) |
952 | if(os.path.exists(val) == False): | 962 | if(os.path.exists(val) == False): |
@@ -959,7 +969,7 @@ if __name__ == '__main__': | |||
959 | sysvals.cgexp = True | 969 | sysvals.cgexp = True |
960 | elif(arg == '-dmesg'): | 970 | elif(arg == '-dmesg'): |
961 | try: | 971 | try: |
962 | val = args.next() | 972 | val = next(args) |
963 | except: | 973 | except: |
964 | doError('No dmesg file supplied', True) | 974 | doError('No dmesg file supplied', True) |
965 | if(os.path.exists(val) == False): | 975 | if(os.path.exists(val) == False): |
@@ -968,13 +978,13 @@ if __name__ == '__main__': | |||
968 | sysvals.dmesgfile = val | 978 | sysvals.dmesgfile = val |
969 | elif(arg == '-o'): | 979 | elif(arg == '-o'): |
970 | try: | 980 | try: |
971 | val = args.next() | 981 | val = next(args) |
972 | except: | 982 | except: |
973 | doError('No subdirectory name supplied', True) | 983 | doError('No subdirectory name supplied', True) |
974 | sysvals.testdir = sysvals.setOutputFolder(val) | 984 | sysvals.testdir = sysvals.setOutputFolder(val) |
975 | elif(arg == '-result'): | 985 | elif(arg == '-result'): |
976 | try: | 986 | try: |
977 | val = args.next() | 987 | val = next(args) |
978 | except: | 988 | except: |
979 | doError('No result file supplied', True) | 989 | doError('No result file supplied', True) |
980 | sysvals.result = val | 990 | sysvals.result = val |
@@ -986,6 +996,17 @@ if __name__ == '__main__': | |||
986 | # remaining options are only for cron job use | 996 | # remaining options are only for cron job use |
987 | elif(arg == '-cronjob'): | 997 | elif(arg == '-cronjob'): |
988 | sysvals.iscronjob = True | 998 | sysvals.iscronjob = True |
999 | elif(arg == '-which'): | ||
1000 | try: | ||
1001 | val = next(args) | ||
1002 | except: | ||
1003 | doError('No executable supplied', True) | ||
1004 | out = sysvals.getExec(val) | ||
1005 | if not out: | ||
1006 | print('%s not found' % val) | ||
1007 | sys.exit(1) | ||
1008 | print(out) | ||
1009 | sys.exit(0) | ||
989 | else: | 1010 | else: |
990 | doError('Invalid argument: '+arg, True) | 1011 | doError('Invalid argument: '+arg, True) |
991 | 1012 | ||
diff --git a/tools/power/pm-graph/sleepgraph.8 b/tools/power/pm-graph/sleepgraph.8 index 9648be644d5f..43aee64316df 100644 --- a/tools/power/pm-graph/sleepgraph.8 +++ b/tools/power/pm-graph/sleepgraph.8 | |||
@@ -53,10 +53,10 @@ disable rtcwake and require a user keypress to resume. | |||
53 | Add the dmesg and ftrace logs to the html output. They will be viewable by | 53 | Add the dmesg and ftrace logs to the html output. They will be viewable by |
54 | clicking buttons in the timeline. | 54 | clicking buttons in the timeline. |
55 | .TP | 55 | .TP |
56 | \fB-turbostat\fR | 56 | \fB-noturbostat\fR |
57 | Use turbostat to execute the command in freeze mode (default: disabled). This | 57 | By default, if turbostat is found and the requested mode is freeze, sleepgraph |
58 | will provide turbostat output in the log which will tell you which actual | 58 | will execute the suspend via turbostat and collect data in the timeline log. |
59 | power modes were entered. | 59 | This option disables the use of turbostat. |
60 | .TP | 60 | .TP |
61 | \fB-result \fIfile\fR | 61 | \fB-result \fIfile\fR |
62 | Export a results table to a text file for parsing. | 62 | Export a results table to a text file for parsing. |
diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py index 4f46a7a1feb6..f7d1c1f62f86 100755 --- a/tools/power/pm-graph/sleepgraph.py +++ b/tools/power/pm-graph/sleepgraph.py | |||
@@ -1,9 +1,18 @@ | |||
1 | #!/usr/bin/python2 | 1 | #!/usr/bin/python |
2 | # SPDX-License-Identifier: GPL-2.0-only | 2 | # SPDX-License-Identifier: GPL-2.0-only |
3 | # | 3 | # |
4 | # Tool for analyzing suspend/resume timing | 4 | # Tool for analyzing suspend/resume timing |
5 | # Copyright (c) 2013, Intel Corporation. | 5 | # Copyright (c) 2013, Intel Corporation. |
6 | # | 6 | # |
7 | # This program is free software; you can redistribute it and/or modify it | ||
8 | # under the terms and conditions of the GNU General Public License, | ||
9 | # version 2, as published by the Free Software Foundation. | ||
10 | # | ||
11 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | # more details. | ||
15 | # | ||
7 | # Authors: | 16 | # Authors: |
8 | # Todd Brandt <todd.e.brandt@linux.intel.com> | 17 | # Todd Brandt <todd.e.brandt@linux.intel.com> |
9 | # | 18 | # |
@@ -48,9 +57,10 @@ import string | |||
48 | import re | 57 | import re |
49 | import platform | 58 | import platform |
50 | import signal | 59 | import signal |
60 | import codecs | ||
51 | from datetime import datetime | 61 | from datetime import datetime |
52 | import struct | 62 | import struct |
53 | import ConfigParser | 63 | import configparser |
54 | import gzip | 64 | import gzip |
55 | from threading import Thread | 65 | from threading import Thread |
56 | from subprocess import call, Popen, PIPE | 66 | from subprocess import call, Popen, PIPE |
@@ -60,6 +70,9 @@ def pprint(msg): | |||
60 | print(msg) | 70 | print(msg) |
61 | sys.stdout.flush() | 71 | sys.stdout.flush() |
62 | 72 | ||
73 | def ascii(text): | ||
74 | return text.decode('ascii', 'ignore') | ||
75 | |||
63 | # ----------------- CLASSES -------------------- | 76 | # ----------------- CLASSES -------------------- |
64 | 77 | ||
65 | # Class: SystemValues | 78 | # Class: SystemValues |
@@ -68,7 +81,7 @@ def pprint(msg): | |||
68 | # store system values and test parameters | 81 | # store system values and test parameters |
69 | class SystemValues: | 82 | class SystemValues: |
70 | title = 'SleepGraph' | 83 | title = 'SleepGraph' |
71 | version = '5.4' | 84 | version = '5.5' |
72 | ansi = False | 85 | ansi = False |
73 | rs = 0 | 86 | rs = 0 |
74 | display = '' | 87 | display = '' |
@@ -78,7 +91,7 @@ class SystemValues: | |||
78 | testlog = True | 91 | testlog = True |
79 | dmesglog = True | 92 | dmesglog = True |
80 | ftracelog = False | 93 | ftracelog = False |
81 | tstat = False | 94 | tstat = True |
82 | mindevlen = 0.0 | 95 | mindevlen = 0.0 |
83 | mincglen = 0.0 | 96 | mincglen = 0.0 |
84 | cgphase = '' | 97 | cgphase = '' |
@@ -147,6 +160,7 @@ class SystemValues: | |||
147 | devdump = False | 160 | devdump = False |
148 | mixedphaseheight = True | 161 | mixedphaseheight = True |
149 | devprops = dict() | 162 | devprops = dict() |
163 | platinfo = [] | ||
150 | predelay = 0 | 164 | predelay = 0 |
151 | postdelay = 0 | 165 | postdelay = 0 |
152 | pmdebug = '' | 166 | pmdebug = '' |
@@ -323,13 +337,20 @@ class SystemValues: | |||
323 | sys.exit(1) | 337 | sys.exit(1) |
324 | return False | 338 | return False |
325 | def getExec(self, cmd): | 339 | def getExec(self, cmd): |
326 | dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin', | 340 | try: |
327 | '/usr/local/sbin', '/usr/local/bin'] | 341 | fp = Popen(['which', cmd], stdout=PIPE, stderr=PIPE).stdout |
328 | for path in dirlist: | 342 | out = ascii(fp.read()).strip() |
343 | fp.close() | ||
344 | except: | ||
345 | out = '' | ||
346 | if out: | ||
347 | return out | ||
348 | for path in ['/sbin', '/bin', '/usr/sbin', '/usr/bin', | ||
349 | '/usr/local/sbin', '/usr/local/bin']: | ||
329 | cmdfull = os.path.join(path, cmd) | 350 | cmdfull = os.path.join(path, cmd) |
330 | if os.path.exists(cmdfull): | 351 | if os.path.exists(cmdfull): |
331 | return cmdfull | 352 | return cmdfull |
332 | return '' | 353 | return out |
333 | def setPrecision(self, num): | 354 | def setPrecision(self, num): |
334 | if num < 0 or num > 6: | 355 | if num < 0 or num > 6: |
335 | return | 356 | return |
@@ -455,7 +476,7 @@ class SystemValues: | |||
455 | fp = Popen('dmesg', stdout=PIPE).stdout | 476 | fp = Popen('dmesg', stdout=PIPE).stdout |
456 | ktime = '0' | 477 | ktime = '0' |
457 | for line in fp: | 478 | for line in fp: |
458 | line = line.replace('\r\n', '') | 479 | line = ascii(line).replace('\r\n', '') |
459 | idx = line.find('[') | 480 | idx = line.find('[') |
460 | if idx > 1: | 481 | if idx > 1: |
461 | line = line[idx:] | 482 | line = line[idx:] |
@@ -469,7 +490,7 @@ class SystemValues: | |||
469 | # store all new dmesg lines since initdmesg was called | 490 | # store all new dmesg lines since initdmesg was called |
470 | fp = Popen('dmesg', stdout=PIPE).stdout | 491 | fp = Popen('dmesg', stdout=PIPE).stdout |
471 | for line in fp: | 492 | for line in fp: |
472 | line = line.replace('\r\n', '') | 493 | line = ascii(line).replace('\r\n', '') |
473 | idx = line.find('[') | 494 | idx = line.find('[') |
474 | if idx > 1: | 495 | if idx > 1: |
475 | line = line[idx:] | 496 | line = line[idx:] |
@@ -501,7 +522,7 @@ class SystemValues: | |||
501 | call('cat '+self.tpath+'available_filter_functions', shell=True) | 522 | call('cat '+self.tpath+'available_filter_functions', shell=True) |
502 | return | 523 | return |
503 | master = self.listFromFile(self.tpath+'available_filter_functions') | 524 | master = self.listFromFile(self.tpath+'available_filter_functions') |
504 | for i in self.tracefuncs: | 525 | for i in sorted(self.tracefuncs): |
505 | if 'func' in self.tracefuncs[i]: | 526 | if 'func' in self.tracefuncs[i]: |
506 | i = self.tracefuncs[i]['func'] | 527 | i = self.tracefuncs[i]['func'] |
507 | if i in master: | 528 | if i in master: |
@@ -628,7 +649,7 @@ class SystemValues: | |||
628 | self.fsetVal(kprobeevents, 'kprobe_events') | 649 | self.fsetVal(kprobeevents, 'kprobe_events') |
629 | if output: | 650 | if output: |
630 | check = self.fgetVal('kprobe_events') | 651 | check = self.fgetVal('kprobe_events') |
631 | linesack = (len(check.split('\n')) - 1) / 2 | 652 | linesack = (len(check.split('\n')) - 1) // 2 |
632 | pprint(' kprobe functions enabled: %d/%d' % (linesack, linesout)) | 653 | pprint(' kprobe functions enabled: %d/%d' % (linesack, linesout)) |
633 | self.fsetVal('1', 'events/kprobes/enable') | 654 | self.fsetVal('1', 'events/kprobes/enable') |
634 | def testKprobe(self, kname, kprobe): | 655 | def testKprobe(self, kname, kprobe): |
@@ -646,19 +667,19 @@ class SystemValues: | |||
646 | if linesack < linesout: | 667 | if linesack < linesout: |
647 | return False | 668 | return False |
648 | return True | 669 | return True |
649 | def setVal(self, val, file, mode='w'): | 670 | def setVal(self, val, file): |
650 | if not os.path.exists(file): | 671 | if not os.path.exists(file): |
651 | return False | 672 | return False |
652 | try: | 673 | try: |
653 | fp = open(file, mode, 0) | 674 | fp = open(file, 'wb', 0) |
654 | fp.write(val) | 675 | fp.write(val.encode()) |
655 | fp.flush() | 676 | fp.flush() |
656 | fp.close() | 677 | fp.close() |
657 | except: | 678 | except: |
658 | return False | 679 | return False |
659 | return True | 680 | return True |
660 | def fsetVal(self, val, path, mode='w'): | 681 | def fsetVal(self, val, path): |
661 | return self.setVal(val, self.tpath+path, mode) | 682 | return self.setVal(val, self.tpath+path) |
662 | def getVal(self, file): | 683 | def getVal(self, file): |
663 | res = '' | 684 | res = '' |
664 | if not os.path.exists(file): | 685 | if not os.path.exists(file): |
@@ -719,7 +740,7 @@ class SystemValues: | |||
719 | tgtsize = min(self.memfree, bmax) | 740 | tgtsize = min(self.memfree, bmax) |
720 | else: | 741 | else: |
721 | tgtsize = 65536 | 742 | tgtsize = 65536 |
722 | while not self.fsetVal('%d' % (tgtsize / cpus), 'buffer_size_kb'): | 743 | while not self.fsetVal('%d' % (tgtsize // cpus), 'buffer_size_kb'): |
723 | # if the size failed to set, lower it and keep trying | 744 | # if the size failed to set, lower it and keep trying |
724 | tgtsize -= 65536 | 745 | tgtsize -= 65536 |
725 | if tgtsize < 65536: | 746 | if tgtsize < 65536: |
@@ -863,14 +884,23 @@ class SystemValues: | |||
863 | isgz = self.gzip | 884 | isgz = self.gzip |
864 | if mode == 'r': | 885 | if mode == 'r': |
865 | try: | 886 | try: |
866 | with gzip.open(filename, mode+'b') as fp: | 887 | with gzip.open(filename, mode+'t') as fp: |
867 | test = fp.read(64) | 888 | test = fp.read(64) |
868 | isgz = True | 889 | isgz = True |
869 | except: | 890 | except: |
870 | isgz = False | 891 | isgz = False |
871 | if isgz: | 892 | if isgz: |
872 | return gzip.open(filename, mode+'b') | 893 | return gzip.open(filename, mode+'t') |
873 | return open(filename, mode) | 894 | return open(filename, mode) |
895 | def b64unzip(self, data): | ||
896 | try: | ||
897 | out = codecs.decode(base64.b64decode(data), 'zlib').decode() | ||
898 | except: | ||
899 | out = data | ||
900 | return out | ||
901 | def b64zip(self, data): | ||
902 | out = base64.b64encode(codecs.encode(data.encode(), 'zlib')).decode() | ||
903 | return out | ||
874 | def mcelog(self, clear=False): | 904 | def mcelog(self, clear=False): |
875 | cmd = self.getExec('mcelog') | 905 | cmd = self.getExec('mcelog') |
876 | if not cmd: | 906 | if not cmd: |
@@ -878,12 +908,124 @@ class SystemValues: | |||
878 | if clear: | 908 | if clear: |
879 | call(cmd+' > /dev/null 2>&1', shell=True) | 909 | call(cmd+' > /dev/null 2>&1', shell=True) |
880 | return '' | 910 | return '' |
881 | fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout | 911 | try: |
882 | out = fp.read().strip() | 912 | fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout |
883 | fp.close() | 913 | out = ascii(fp.read()).strip() |
914 | fp.close() | ||
915 | except: | ||
916 | return '' | ||
884 | if not out: | 917 | if not out: |
885 | return '' | 918 | return '' |
886 | return base64.b64encode(out.encode('zlib')) | 919 | return self.b64zip(out) |
920 | def platforminfo(self): | ||
921 | # add platform info on to a completed ftrace file | ||
922 | if not os.path.exists(self.ftracefile): | ||
923 | return False | ||
924 | footer = '#\n' | ||
925 | |||
926 | # add test command string line if need be | ||
927 | if self.suspendmode == 'command' and self.testcommand: | ||
928 | footer += '# platform-testcmd: %s\n' % (self.testcommand) | ||
929 | |||
930 | # get a list of target devices from the ftrace file | ||
931 | props = dict() | ||
932 | tp = TestProps() | ||
933 | tf = self.openlog(self.ftracefile, 'r') | ||
934 | for line in tf: | ||
935 | # determine the trace data type (required for further parsing) | ||
936 | m = re.match(tp.tracertypefmt, line) | ||
937 | if(m): | ||
938 | tp.setTracerType(m.group('t')) | ||
939 | continue | ||
940 | # parse only valid lines, if this is not one move on | ||
941 | m = re.match(tp.ftrace_line_fmt, line) | ||
942 | if(not m or 'device_pm_callback_start' not in line): | ||
943 | continue | ||
944 | m = re.match('.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg')); | ||
945 | if(not m): | ||
946 | continue | ||
947 | dev = m.group('d') | ||
948 | if dev not in props: | ||
949 | props[dev] = DevProps() | ||
950 | tf.close() | ||
951 | |||
952 | # now get the syspath for each target device | ||
953 | for dirname, dirnames, filenames in os.walk('/sys/devices'): | ||
954 | if(re.match('.*/power', dirname) and 'async' in filenames): | ||
955 | dev = dirname.split('/')[-2] | ||
956 | if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)): | ||
957 | props[dev].syspath = dirname[:-6] | ||
958 | |||
959 | # now fill in the properties for our target devices | ||
960 | for dev in sorted(props): | ||
961 | dirname = props[dev].syspath | ||
962 | if not dirname or not os.path.exists(dirname): | ||
963 | continue | ||
964 | with open(dirname+'/power/async') as fp: | ||
965 | text = fp.read() | ||
966 | props[dev].isasync = False | ||
967 | if 'enabled' in text: | ||
968 | props[dev].isasync = True | ||
969 | fields = os.listdir(dirname) | ||
970 | if 'product' in fields: | ||
971 | with open(dirname+'/product', 'rb') as fp: | ||
972 | props[dev].altname = ascii(fp.read()) | ||
973 | elif 'name' in fields: | ||
974 | with open(dirname+'/name', 'rb') as fp: | ||
975 | props[dev].altname = ascii(fp.read()) | ||
976 | elif 'model' in fields: | ||
977 | with open(dirname+'/model', 'rb') as fp: | ||
978 | props[dev].altname = ascii(fp.read()) | ||
979 | elif 'description' in fields: | ||
980 | with open(dirname+'/description', 'rb') as fp: | ||
981 | props[dev].altname = ascii(fp.read()) | ||
982 | elif 'id' in fields: | ||
983 | with open(dirname+'/id', 'rb') as fp: | ||
984 | props[dev].altname = ascii(fp.read()) | ||
985 | elif 'idVendor' in fields and 'idProduct' in fields: | ||
986 | idv, idp = '', '' | ||
987 | with open(dirname+'/idVendor', 'rb') as fp: | ||
988 | idv = ascii(fp.read()).strip() | ||
989 | with open(dirname+'/idProduct', 'rb') as fp: | ||
990 | idp = ascii(fp.read()).strip() | ||
991 | props[dev].altname = '%s:%s' % (idv, idp) | ||
992 | if props[dev].altname: | ||
993 | out = props[dev].altname.strip().replace('\n', ' ')\ | ||
994 | .replace(',', ' ').replace(';', ' ') | ||
995 | props[dev].altname = out | ||
996 | |||
997 | # add a devinfo line to the bottom of ftrace | ||
998 | out = '' | ||
999 | for dev in sorted(props): | ||
1000 | out += props[dev].out(dev) | ||
1001 | footer += '# platform-devinfo: %s\n' % self.b64zip(out) | ||
1002 | |||
1003 | # add a line for each of these commands with their outputs | ||
1004 | cmds = [ | ||
1005 | ['pcidevices', 'lspci', '-tv'], | ||
1006 | ['interrupts', 'cat', '/proc/interrupts'], | ||
1007 | ['gpecounts', 'sh', '-c', 'grep -v invalid /sys/firmware/acpi/interrupts/gpe*'], | ||
1008 | ] | ||
1009 | for cargs in cmds: | ||
1010 | name = cargs[0] | ||
1011 | cmdline = ' '.join(cargs[1:]) | ||
1012 | cmdpath = self.getExec(cargs[1]) | ||
1013 | if not cmdpath: | ||
1014 | continue | ||
1015 | cmd = [cmdpath] + cargs[2:] | ||
1016 | try: | ||
1017 | fp = Popen(cmd, stdout=PIPE, stderr=PIPE).stdout | ||
1018 | info = ascii(fp.read()).strip() | ||
1019 | fp.close() | ||
1020 | except: | ||
1021 | continue | ||
1022 | if not info: | ||
1023 | continue | ||
1024 | footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info)) | ||
1025 | |||
1026 | with self.openlog(self.ftracefile, 'a') as fp: | ||
1027 | fp.write(footer) | ||
1028 | return True | ||
887 | def haveTurbostat(self): | 1029 | def haveTurbostat(self): |
888 | if not self.tstat: | 1030 | if not self.tstat: |
889 | return False | 1031 | return False |
@@ -891,31 +1033,40 @@ class SystemValues: | |||
891 | if not cmd: | 1033 | if not cmd: |
892 | return False | 1034 | return False |
893 | fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr | 1035 | fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr |
894 | out = fp.read().strip() | 1036 | out = ascii(fp.read()).strip() |
895 | fp.close() | 1037 | fp.close() |
896 | return re.match('turbostat version [0-9\.]* .*', out) | 1038 | if re.match('turbostat version [0-9\.]* .*', out): |
1039 | sysvals.vprint(out) | ||
1040 | return True | ||
1041 | return False | ||
897 | def turbostat(self): | 1042 | def turbostat(self): |
898 | cmd = self.getExec('turbostat') | 1043 | cmd = self.getExec('turbostat') |
899 | if not cmd: | 1044 | rawout = keyline = valline = '' |
900 | return 'missing turbostat executable' | ||
901 | text = [] | ||
902 | fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile) | 1045 | fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile) |
903 | fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr | 1046 | fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr |
904 | for line in fp: | 1047 | for line in fp: |
905 | if re.match('[0-9.]* sec', line): | 1048 | line = ascii(line) |
1049 | rawout += line | ||
1050 | if keyline and valline: | ||
906 | continue | 1051 | continue |
907 | text.append(line.split()) | 1052 | if re.match('(?i)Avg_MHz.*', line): |
1053 | keyline = line.strip().split() | ||
1054 | elif keyline: | ||
1055 | valline = line.strip().split() | ||
908 | fp.close() | 1056 | fp.close() |
909 | if len(text) < 2: | 1057 | if not keyline or not valline or len(keyline) != len(valline): |
910 | return 'turbostat output format error' | 1058 | errmsg = 'unrecognized turbostat output:\n'+rawout.strip() |
1059 | sysvals.vprint(errmsg) | ||
1060 | if not sysvals.verbose: | ||
1061 | pprint(errmsg) | ||
1062 | return '' | ||
1063 | if sysvals.verbose: | ||
1064 | pprint(rawout.strip()) | ||
911 | out = [] | 1065 | out = [] |
912 | for key in text[0]: | 1066 | for key in keyline: |
913 | values = [] | 1067 | idx = keyline.index(key) |
914 | idx = text[0].index(key) | 1068 | val = valline[idx] |
915 | for line in text[1:]: | 1069 | out.append('%s=%s' % (key, val)) |
916 | if len(line) > idx: | ||
917 | values.append(line[idx]) | ||
918 | out.append('%s=%s' % (key, ','.join(values))) | ||
919 | return '|'.join(out) | 1070 | return '|'.join(out) |
920 | def checkWifi(self): | 1071 | def checkWifi(self): |
921 | out = dict() | 1072 | out = dict() |
@@ -924,7 +1075,7 @@ class SystemValues: | |||
924 | return out | 1075 | return out |
925 | fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout | 1076 | fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout |
926 | for line in fp: | 1077 | for line in fp: |
927 | m = re.match('(?P<dev>\S*) .* ESSID:(?P<ess>\S*)', line) | 1078 | m = re.match('(?P<dev>\S*) .* ESSID:(?P<ess>\S*)', ascii(line)) |
928 | if not m: | 1079 | if not m: |
929 | continue | 1080 | continue |
930 | out['device'] = m.group('dev') | 1081 | out['device'] = m.group('dev') |
@@ -935,7 +1086,7 @@ class SystemValues: | |||
935 | if 'device' in out: | 1086 | if 'device' in out: |
936 | fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout | 1087 | fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout |
937 | for line in fp: | 1088 | for line in fp: |
938 | m = re.match('.* inet (?P<ip>[0-9\.]*)', line) | 1089 | m = re.match('.* inet (?P<ip>[0-9\.]*)', ascii(line)) |
939 | if m: | 1090 | if m: |
940 | out['ip'] = m.group('ip') | 1091 | out['ip'] = m.group('ip') |
941 | break | 1092 | break |
@@ -990,13 +1141,13 @@ class DevProps: | |||
990 | def __init__(self): | 1141 | def __init__(self): |
991 | self.syspath = '' | 1142 | self.syspath = '' |
992 | self.altname = '' | 1143 | self.altname = '' |
993 | self.async = True | 1144 | self.isasync = True |
994 | self.xtraclass = '' | 1145 | self.xtraclass = '' |
995 | self.xtrainfo = '' | 1146 | self.xtrainfo = '' |
996 | def out(self, dev): | 1147 | def out(self, dev): |
997 | return '%s,%s,%d;' % (dev, self.altname, self.async) | 1148 | return '%s,%s,%d;' % (dev, self.altname, self.isasync) |
998 | def debug(self, dev): | 1149 | def debug(self, dev): |
999 | pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.async)) | 1150 | pprint('%s:\n\taltname = %s\n\t async = %s' % (dev, self.altname, self.isasync)) |
1000 | def altName(self, dev): | 1151 | def altName(self, dev): |
1001 | if not self.altname or self.altname == dev: | 1152 | if not self.altname or self.altname == dev: |
1002 | return dev | 1153 | return dev |
@@ -1004,13 +1155,13 @@ class DevProps: | |||
1004 | def xtraClass(self): | 1155 | def xtraClass(self): |
1005 | if self.xtraclass: | 1156 | if self.xtraclass: |
1006 | return ' '+self.xtraclass | 1157 | return ' '+self.xtraclass |
1007 | if not self.async: | 1158 | if not self.isasync: |
1008 | return ' sync' | 1159 | return ' sync' |
1009 | return '' | 1160 | return '' |
1010 | def xtraInfo(self): | 1161 | def xtraInfo(self): |
1011 | if self.xtraclass: | 1162 | if self.xtraclass: |
1012 | return ' '+self.xtraclass | 1163 | return ' '+self.xtraclass |
1013 | if self.async: | 1164 | if self.isasync: |
1014 | return ' async_device' | 1165 | return ' async_device' |
1015 | return ' sync_device' | 1166 | return ' sync_device' |
1016 | 1167 | ||
@@ -1108,7 +1259,7 @@ class Data: | |||
1108 | return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order']) | 1259 | return sorted(self.dmesg, key=lambda k:self.dmesg[k]['order']) |
1109 | def initDevicegroups(self): | 1260 | def initDevicegroups(self): |
1110 | # called when phases are all finished being added | 1261 | # called when phases are all finished being added |
1111 | for phase in self.dmesg.keys(): | 1262 | for phase in sorted(self.dmesg.keys()): |
1112 | if '*' in phase: | 1263 | if '*' in phase: |
1113 | p = phase.split('*') | 1264 | p = phase.split('*') |
1114 | pnew = '%s%d' % (p[0], len(p)) | 1265 | pnew = '%s%d' % (p[0], len(p)) |
@@ -1430,16 +1581,7 @@ class Data: | |||
1430 | return phase | 1581 | return phase |
1431 | def sortedDevices(self, phase): | 1582 | def sortedDevices(self, phase): |
1432 | list = self.dmesg[phase]['list'] | 1583 | list = self.dmesg[phase]['list'] |
1433 | slist = [] | 1584 | return sorted(list, key=lambda k:list[k]['start']) |
1434 | tmp = dict() | ||
1435 | for devname in list: | ||
1436 | dev = list[devname] | ||
1437 | if dev['length'] == 0: | ||
1438 | continue | ||
1439 | tmp[dev['start']] = devname | ||
1440 | for t in sorted(tmp): | ||
1441 | slist.append(tmp[t]) | ||
1442 | return slist | ||
1443 | def fixupInitcalls(self, phase): | 1585 | def fixupInitcalls(self, phase): |
1444 | # if any calls never returned, clip them at system resume end | 1586 | # if any calls never returned, clip them at system resume end |
1445 | phaselist = self.dmesg[phase]['list'] | 1587 | phaselist = self.dmesg[phase]['list'] |
@@ -1576,7 +1718,7 @@ class Data: | |||
1576 | maxname = '%d' % self.maxDeviceNameSize(phase) | 1718 | maxname = '%d' % self.maxDeviceNameSize(phase) |
1577 | fmt = '%3d) %'+maxname+'s - %f - %f' | 1719 | fmt = '%3d) %'+maxname+'s - %f - %f' |
1578 | c = 1 | 1720 | c = 1 |
1579 | for name in devlist: | 1721 | for name in sorted(devlist): |
1580 | s = devlist[name]['start'] | 1722 | s = devlist[name]['start'] |
1581 | e = devlist[name]['end'] | 1723 | e = devlist[name]['end'] |
1582 | sysvals.vprint(fmt % (c, name, s, e)) | 1724 | sysvals.vprint(fmt % (c, name, s, e)) |
@@ -1588,7 +1730,7 @@ class Data: | |||
1588 | devlist = [] | 1730 | devlist = [] |
1589 | for phase in self.sortedPhases(): | 1731 | for phase in self.sortedPhases(): |
1590 | list = self.deviceChildren(devname, phase) | 1732 | list = self.deviceChildren(devname, phase) |
1591 | for dev in list: | 1733 | for dev in sorted(list): |
1592 | if dev not in devlist: | 1734 | if dev not in devlist: |
1593 | devlist.append(dev) | 1735 | devlist.append(dev) |
1594 | return devlist | 1736 | return devlist |
@@ -1628,16 +1770,16 @@ class Data: | |||
1628 | def rootDeviceList(self): | 1770 | def rootDeviceList(self): |
1629 | # list of devices graphed | 1771 | # list of devices graphed |
1630 | real = [] | 1772 | real = [] |
1631 | for phase in self.dmesg: | 1773 | for phase in self.sortedPhases(): |
1632 | list = self.dmesg[phase]['list'] | 1774 | list = self.dmesg[phase]['list'] |
1633 | for dev in list: | 1775 | for dev in sorted(list): |
1634 | if list[dev]['pid'] >= 0 and dev not in real: | 1776 | if list[dev]['pid'] >= 0 and dev not in real: |
1635 | real.append(dev) | 1777 | real.append(dev) |
1636 | # list of top-most root devices | 1778 | # list of top-most root devices |
1637 | rootlist = [] | 1779 | rootlist = [] |
1638 | for phase in self.dmesg: | 1780 | for phase in self.sortedPhases(): |
1639 | list = self.dmesg[phase]['list'] | 1781 | list = self.dmesg[phase]['list'] |
1640 | for dev in list: | 1782 | for dev in sorted(list): |
1641 | pdev = list[dev]['par'] | 1783 | pdev = list[dev]['par'] |
1642 | pid = list[dev]['pid'] | 1784 | pid = list[dev]['pid'] |
1643 | if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)): | 1785 | if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)): |
@@ -1718,9 +1860,9 @@ class Data: | |||
1718 | def createProcessUsageEvents(self): | 1860 | def createProcessUsageEvents(self): |
1719 | # get an array of process names | 1861 | # get an array of process names |
1720 | proclist = [] | 1862 | proclist = [] |
1721 | for t in self.pstl: | 1863 | for t in sorted(self.pstl): |
1722 | pslist = self.pstl[t] | 1864 | pslist = self.pstl[t] |
1723 | for ps in pslist: | 1865 | for ps in sorted(pslist): |
1724 | if ps not in proclist: | 1866 | if ps not in proclist: |
1725 | proclist.append(ps) | 1867 | proclist.append(ps) |
1726 | # get a list of data points for suspend and resume | 1868 | # get a list of data points for suspend and resume |
@@ -1765,7 +1907,7 @@ class Data: | |||
1765 | def debugPrint(self): | 1907 | def debugPrint(self): |
1766 | for p in self.sortedPhases(): | 1908 | for p in self.sortedPhases(): |
1767 | list = self.dmesg[p]['list'] | 1909 | list = self.dmesg[p]['list'] |
1768 | for devname in list: | 1910 | for devname in sorted(list): |
1769 | dev = list[devname] | 1911 | dev = list[devname] |
1770 | if 'ftrace' in dev: | 1912 | if 'ftrace' in dev: |
1771 | dev['ftrace'].debugPrint(' [%s]' % devname) | 1913 | dev['ftrace'].debugPrint(' [%s]' % devname) |
@@ -2466,7 +2608,7 @@ class Timeline: | |||
2466 | # if there is 1 line per row, draw them the standard way | 2608 | # if there is 1 line per row, draw them the standard way |
2467 | for t, p in standardphases: | 2609 | for t, p in standardphases: |
2468 | for i in sorted(self.rowheight[t][p]): | 2610 | for i in sorted(self.rowheight[t][p]): |
2469 | self.rowheight[t][p][i] = self.bodyH/len(self.rowlines[t][p]) | 2611 | self.rowheight[t][p][i] = float(self.bodyH)/len(self.rowlines[t][p]) |
2470 | def createZoomBox(self, mode='command', testcount=1): | 2612 | def createZoomBox(self, mode='command', testcount=1): |
2471 | # Create bounding box, add buttons | 2613 | # Create bounding box, add buttons |
2472 | html_zoombox = '<center><button id="zoomin">ZOOM IN +</button><button id="zoomout">ZOOM OUT -</button><button id="zoomdef">ZOOM 1:1</button></center>\n' | 2614 | html_zoombox = '<center><button id="zoomin">ZOOM IN +</button><button id="zoomout">ZOOM OUT -</button><button id="zoomdef">ZOOM 1:1</button></center>\n' |
@@ -2537,6 +2679,7 @@ class TestProps: | |||
2537 | cmdlinefmt = '^# command \| (?P<cmd>.*)' | 2679 | cmdlinefmt = '^# command \| (?P<cmd>.*)' |
2538 | kparamsfmt = '^# kparams \| (?P<kp>.*)' | 2680 | kparamsfmt = '^# kparams \| (?P<kp>.*)' |
2539 | devpropfmt = '# Device Properties: .*' | 2681 | devpropfmt = '# Device Properties: .*' |
2682 | pinfofmt = '# platform-(?P<val>[a-z,A-Z,0-9]*): (?P<info>.*)' | ||
2540 | tracertypefmt = '# tracer: (?P<t>.*)' | 2683 | tracertypefmt = '# tracer: (?P<t>.*)' |
2541 | firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$' | 2684 | firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$' |
2542 | procexecfmt = 'ps - (?P<ps>.*)$' | 2685 | procexecfmt = 'ps - (?P<ps>.*)$' |
@@ -2571,12 +2714,6 @@ class TestProps: | |||
2571 | self.ftrace_line_fmt = self.ftrace_line_fmt_nop | 2714 | self.ftrace_line_fmt = self.ftrace_line_fmt_nop |
2572 | else: | 2715 | else: |
2573 | doError('Invalid tracer format: [%s]' % tracer) | 2716 | doError('Invalid tracer format: [%s]' % tracer) |
2574 | def decode(self, data): | ||
2575 | try: | ||
2576 | out = base64.b64decode(data).decode('zlib') | ||
2577 | except: | ||
2578 | out = data | ||
2579 | return out | ||
2580 | def stampInfo(self, line): | 2717 | def stampInfo(self, line): |
2581 | if re.match(self.stampfmt, line): | 2718 | if re.match(self.stampfmt, line): |
2582 | self.stamp = line | 2719 | self.stamp = line |
@@ -2660,7 +2797,7 @@ class TestProps: | |||
2660 | if len(self.mcelog) > data.testnumber: | 2797 | if len(self.mcelog) > data.testnumber: |
2661 | m = re.match(self.mcelogfmt, self.mcelog[data.testnumber]) | 2798 | m = re.match(self.mcelogfmt, self.mcelog[data.testnumber]) |
2662 | if m: | 2799 | if m: |
2663 | data.mcelog = self.decode(m.group('m')) | 2800 | data.mcelog = sv.b64unzip(m.group('m')) |
2664 | # turbostat data | 2801 | # turbostat data |
2665 | if len(self.turbostat) > data.testnumber: | 2802 | if len(self.turbostat) > data.testnumber: |
2666 | m = re.match(self.tstatfmt, self.turbostat[data.testnumber]) | 2803 | m = re.match(self.tstatfmt, self.turbostat[data.testnumber]) |
@@ -2681,6 +2818,46 @@ class TestProps: | |||
2681 | m = re.match(self.testerrfmt, self.testerror[data.testnumber]) | 2818 | m = re.match(self.testerrfmt, self.testerror[data.testnumber]) |
2682 | if m: | 2819 | if m: |
2683 | data.enterfail = m.group('e') | 2820 | data.enterfail = m.group('e') |
2821 | def devprops(self, data): | ||
2822 | props = dict() | ||
2823 | devlist = data.split(';') | ||
2824 | for dev in devlist: | ||
2825 | f = dev.split(',') | ||
2826 | if len(f) < 3: | ||
2827 | continue | ||
2828 | dev = f[0] | ||
2829 | props[dev] = DevProps() | ||
2830 | props[dev].altname = f[1] | ||
2831 | if int(f[2]): | ||
2832 | props[dev].isasync = True | ||
2833 | else: | ||
2834 | props[dev].isasync = False | ||
2835 | return props | ||
2836 | def parseDevprops(self, line, sv): | ||
2837 | idx = line.index(': ') + 2 | ||
2838 | if idx >= len(line): | ||
2839 | return | ||
2840 | props = self.devprops(line[idx:]) | ||
2841 | if sv.suspendmode == 'command' and 'testcommandstring' in props: | ||
2842 | sv.testcommand = props['testcommandstring'].altname | ||
2843 | sv.devprops = props | ||
2844 | def parsePlatformInfo(self, line, sv): | ||
2845 | m = re.match(self.pinfofmt, line) | ||
2846 | if not m: | ||
2847 | return | ||
2848 | name, info = m.group('val'), m.group('info') | ||
2849 | if name == 'devinfo': | ||
2850 | sv.devprops = self.devprops(sv.b64unzip(info)) | ||
2851 | return | ||
2852 | elif name == 'testcmd': | ||
2853 | sv.testcommand = info | ||
2854 | return | ||
2855 | field = info.split('|') | ||
2856 | if len(field) < 2: | ||
2857 | return | ||
2858 | cmdline = field[0].strip() | ||
2859 | output = sv.b64unzip(field[1].strip()) | ||
2860 | sv.platinfo.append([name, cmdline, output]) | ||
2684 | 2861 | ||
2685 | # Class: TestRun | 2862 | # Class: TestRun |
2686 | # Description: | 2863 | # Description: |
@@ -2701,7 +2878,7 @@ class ProcessMonitor: | |||
2701 | process = Popen(c, shell=True, stdout=PIPE) | 2878 | process = Popen(c, shell=True, stdout=PIPE) |
2702 | running = dict() | 2879 | running = dict() |
2703 | for line in process.stdout: | 2880 | for line in process.stdout: |
2704 | data = line.split() | 2881 | data = ascii(line).split() |
2705 | pid = data[0] | 2882 | pid = data[0] |
2706 | name = re.sub('[()]', '', data[1]) | 2883 | name = re.sub('[()]', '', data[1]) |
2707 | user = int(data[13]) | 2884 | user = int(data[13]) |
@@ -2805,7 +2982,11 @@ def appendIncompleteTraceLog(testruns): | |||
2805 | continue | 2982 | continue |
2806 | # device properties line | 2983 | # device properties line |
2807 | if(re.match(tp.devpropfmt, line)): | 2984 | if(re.match(tp.devpropfmt, line)): |
2808 | devProps(line) | 2985 | tp.parseDevprops(line, sysvals) |
2986 | continue | ||
2987 | # platform info line | ||
2988 | if(re.match(tp.pinfofmt, line)): | ||
2989 | tp.parsePlatformInfo(line, sysvals) | ||
2809 | continue | 2990 | continue |
2810 | # parse only valid lines, if this is not one move on | 2991 | # parse only valid lines, if this is not one move on |
2811 | m = re.match(tp.ftrace_line_fmt, line) | 2992 | m = re.match(tp.ftrace_line_fmt, line) |
@@ -2902,7 +3083,7 @@ def parseTraceLog(live=False): | |||
2902 | sysvals.setupAllKprobes() | 3083 | sysvals.setupAllKprobes() |
2903 | ksuscalls = ['pm_prepare_console'] | 3084 | ksuscalls = ['pm_prepare_console'] |
2904 | krescalls = ['pm_restore_console'] | 3085 | krescalls = ['pm_restore_console'] |
2905 | tracewatch = [] | 3086 | tracewatch = ['irq_wakeup'] |
2906 | if sysvals.usekprobes: | 3087 | if sysvals.usekprobes: |
2907 | tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend', | 3088 | tracewatch += ['sync_filesystems', 'freeze_processes', 'syscore_suspend', |
2908 | 'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON', | 3089 | 'syscore_resume', 'resume_console', 'thaw_processes', 'CPU_ON', |
@@ -2928,7 +3109,11 @@ def parseTraceLog(live=False): | |||
2928 | continue | 3109 | continue |
2929 | # device properties line | 3110 | # device properties line |
2930 | if(re.match(tp.devpropfmt, line)): | 3111 | if(re.match(tp.devpropfmt, line)): |
2931 | devProps(line) | 3112 | tp.parseDevprops(line, sysvals) |
3113 | continue | ||
3114 | # platform info line | ||
3115 | if(re.match(tp.pinfofmt, line)): | ||
3116 | tp.parsePlatformInfo(line, sysvals) | ||
2932 | continue | 3117 | continue |
2933 | # ignore all other commented lines | 3118 | # ignore all other commented lines |
2934 | if line[0] == '#': | 3119 | if line[0] == '#': |
@@ -3001,16 +3186,11 @@ def parseTraceLog(live=False): | |||
3001 | isbegin = False | 3186 | isbegin = False |
3002 | else: | 3187 | else: |
3003 | continue | 3188 | continue |
3004 | m = re.match('(?P<name>.*)\[(?P<val>[0-9]*)\] .*', t.name) | 3189 | if '[' in t.name: |
3005 | if(m): | 3190 | m = re.match('(?P<name>.*)\[.*', t.name) |
3006 | val = m.group('val') | ||
3007 | if val == '0': | ||
3008 | name = m.group('name') | ||
3009 | else: | ||
3010 | name = m.group('name')+'['+val+']' | ||
3011 | else: | 3191 | else: |
3012 | m = re.match('(?P<name>.*) .*', t.name) | 3192 | m = re.match('(?P<name>.*) .*', t.name) |
3013 | name = m.group('name') | 3193 | name = m.group('name') |
3014 | # ignore these events | 3194 | # ignore these events |
3015 | if(name.split('[')[0] in tracewatch): | 3195 | if(name.split('[')[0] in tracewatch): |
3016 | continue | 3196 | continue |
@@ -3045,6 +3225,8 @@ def parseTraceLog(live=False): | |||
3045 | elif(re.match('machine_suspend\[.*', t.name)): | 3225 | elif(re.match('machine_suspend\[.*', t.name)): |
3046 | if(isbegin): | 3226 | if(isbegin): |
3047 | lp = data.lastPhase() | 3227 | lp = data.lastPhase() |
3228 | if lp == 'resume_machine': | ||
3229 | data.dmesg[lp]['end'] = t.time | ||
3048 | phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True) | 3230 | phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True) |
3049 | data.setPhase(phase, t.time, False) | 3231 | data.setPhase(phase, t.time, False) |
3050 | if data.tSuspended == 0: | 3232 | if data.tSuspended == 0: |
@@ -3213,11 +3395,11 @@ def parseTraceLog(live=False): | |||
3213 | # add the traceevent data to the device hierarchy | 3395 | # add the traceevent data to the device hierarchy |
3214 | if(sysvals.usetraceevents): | 3396 | if(sysvals.usetraceevents): |
3215 | # add actual trace funcs | 3397 | # add actual trace funcs |
3216 | for name in test.ttemp: | 3398 | for name in sorted(test.ttemp): |
3217 | for event in test.ttemp[name]: | 3399 | for event in test.ttemp[name]: |
3218 | data.newActionGlobal(name, event['begin'], event['end'], event['pid']) | 3400 | data.newActionGlobal(name, event['begin'], event['end'], event['pid']) |
3219 | # add the kprobe based virtual tracefuncs as actual devices | 3401 | # add the kprobe based virtual tracefuncs as actual devices |
3220 | for key in tp.ktemp: | 3402 | for key in sorted(tp.ktemp): |
3221 | name, pid = key | 3403 | name, pid = key |
3222 | if name not in sysvals.tracefuncs: | 3404 | if name not in sysvals.tracefuncs: |
3223 | continue | 3405 | continue |
@@ -3231,7 +3413,7 @@ def parseTraceLog(live=False): | |||
3231 | data.newActionGlobal(e['name'], kb, ke, pid, color) | 3413 | data.newActionGlobal(e['name'], kb, ke, pid, color) |
3232 | # add config base kprobes and dev kprobes | 3414 | # add config base kprobes and dev kprobes |
3233 | if sysvals.usedevsrc: | 3415 | if sysvals.usedevsrc: |
3234 | for key in tp.ktemp: | 3416 | for key in sorted(tp.ktemp): |
3235 | name, pid = key | 3417 | name, pid = key |
3236 | if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs: | 3418 | if name in sysvals.tracefuncs or name not in sysvals.dev_tracefuncs: |
3237 | continue | 3419 | continue |
@@ -3244,7 +3426,7 @@ def parseTraceLog(live=False): | |||
3244 | if sysvals.usecallgraph: | 3426 | if sysvals.usecallgraph: |
3245 | # add the callgraph data to the device hierarchy | 3427 | # add the callgraph data to the device hierarchy |
3246 | sortlist = dict() | 3428 | sortlist = dict() |
3247 | for key in test.ftemp: | 3429 | for key in sorted(test.ftemp): |
3248 | proc, pid = key | 3430 | proc, pid = key |
3249 | for cg in test.ftemp[key]: | 3431 | for cg in test.ftemp[key]: |
3250 | if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0): | 3432 | if len(cg.list) < 1 or cg.invalid or (cg.end - cg.start == 0): |
@@ -3582,7 +3764,7 @@ def parseKernelLog(data): | |||
3582 | # if trace events are not available, these are better than nothing | 3764 | # if trace events are not available, these are better than nothing |
3583 | if(not sysvals.usetraceevents): | 3765 | if(not sysvals.usetraceevents): |
3584 | # look for known actions | 3766 | # look for known actions |
3585 | for a in at: | 3767 | for a in sorted(at): |
3586 | if(re.match(at[a]['smsg'], msg)): | 3768 | if(re.match(at[a]['smsg'], msg)): |
3587 | if(a not in actions): | 3769 | if(a not in actions): |
3588 | actions[a] = [] | 3770 | actions[a] = [] |
@@ -3641,7 +3823,7 @@ def parseKernelLog(data): | |||
3641 | data.tResumed = data.tSuspended | 3823 | data.tResumed = data.tSuspended |
3642 | 3824 | ||
3643 | # fill in any actions we've found | 3825 | # fill in any actions we've found |
3644 | for name in actions: | 3826 | for name in sorted(actions): |
3645 | for event in actions[name]: | 3827 | for event in actions[name]: |
3646 | data.newActionGlobal(name, event['begin'], event['end']) | 3828 | data.newActionGlobal(name, event['begin'], event['end']) |
3647 | 3829 | ||
@@ -3761,7 +3943,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): | |||
3761 | if lastmode and lastmode != mode and num > 0: | 3943 | if lastmode and lastmode != mode and num > 0: |
3762 | for i in range(2): | 3944 | for i in range(2): |
3763 | s = sorted(tMed[i]) | 3945 | s = sorted(tMed[i]) |
3764 | list[lastmode]['med'][i] = s[int(len(s)/2)] | 3946 | list[lastmode]['med'][i] = s[int(len(s)//2)] |
3765 | iMed[i] = tMed[i][list[lastmode]['med'][i]] | 3947 | iMed[i] = tMed[i][list[lastmode]['med'][i]] |
3766 | list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] | 3948 | list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] |
3767 | list[lastmode]['min'] = tMin | 3949 | list[lastmode]['min'] = tMin |
@@ -3803,7 +3985,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): | |||
3803 | if lastmode and num > 0: | 3985 | if lastmode and num > 0: |
3804 | for i in range(2): | 3986 | for i in range(2): |
3805 | s = sorted(tMed[i]) | 3987 | s = sorted(tMed[i]) |
3806 | list[lastmode]['med'][i] = s[int(len(s)/2)] | 3988 | list[lastmode]['med'][i] = s[int(len(s)//2)] |
3807 | iMed[i] = tMed[i][list[lastmode]['med'][i]] | 3989 | iMed[i] = tMed[i][list[lastmode]['med'][i]] |
3808 | list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] | 3990 | list[lastmode]['avg'] = [tAvg[0] / num, tAvg[1] / num] |
3809 | list[lastmode]['min'] = tMin | 3991 | list[lastmode]['min'] = tMin |
@@ -3845,7 +4027,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title): | |||
3845 | '</tr>\n' | 4027 | '</tr>\n' |
3846 | headnone = '<tr class="head"><td>{0}</td><td>{1}</td><td colspan='+\ | 4028 | headnone = '<tr class="head"><td>{0}</td><td>{1}</td><td colspan='+\ |
3847 | colspan+'></td></tr>\n' | 4029 | colspan+'></td></tr>\n' |
3848 | for mode in list: | 4030 | for mode in sorted(list): |
3849 | # header line for each suspend mode | 4031 | # header line for each suspend mode |
3850 | num = 0 | 4032 | num = 0 |
3851 | tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\ | 4033 | tAvg, tMin, tMax, tMed = list[mode]['avg'], list[mode]['min'],\ |
@@ -3944,7 +4126,8 @@ def createHTMLDeviceSummary(testruns, htmlfile, title): | |||
3944 | th.format('Average Time') + th.format('Count') +\ | 4126 | th.format('Average Time') + th.format('Count') +\ |
3945 | th.format('Worst Time') + th.format('Host (worst time)') +\ | 4127 | th.format('Worst Time') + th.format('Host (worst time)') +\ |
3946 | th.format('Link (worst time)') + '</tr>\n' | 4128 | th.format('Link (worst time)') + '</tr>\n' |
3947 | for name in sorted(devlist, key=lambda k:devlist[k]['worst'], reverse=True): | 4129 | for name in sorted(devlist, key=lambda k:(devlist[k]['worst'], \ |
4130 | devlist[k]['total'], devlist[k]['name']), reverse=True): | ||
3948 | data = devall[type][name] | 4131 | data = devall[type][name] |
3949 | data['average'] = data['total'] / data['count'] | 4132 | data['average'] = data['total'] / data['count'] |
3950 | if data['average'] < limit: | 4133 | if data['average'] < limit: |
@@ -4085,7 +4268,7 @@ def createHTML(testruns, testfail): | |||
4085 | if(tTotal == 0): | 4268 | if(tTotal == 0): |
4086 | doError('No timeline data') | 4269 | doError('No timeline data') |
4087 | if(len(data.tLow) > 0): | 4270 | if(len(data.tLow) > 0): |
4088 | low_time = '|'.join(data.tLow) | 4271 | low_time = '+'.join(data.tLow) |
4089 | if sysvals.suspendmode == 'command': | 4272 | if sysvals.suspendmode == 'command': |
4090 | run_time = '%.0f'%((data.end-data.start)*1000) | 4273 | run_time = '%.0f'%((data.end-data.start)*1000) |
4091 | if sysvals.testcommand: | 4274 | if sysvals.testcommand: |
@@ -4151,7 +4334,7 @@ def createHTML(testruns, testfail): | |||
4151 | for group in data.devicegroups: | 4334 | for group in data.devicegroups: |
4152 | devlist = [] | 4335 | devlist = [] |
4153 | for phase in group: | 4336 | for phase in group: |
4154 | for devname in data.tdevlist[phase]: | 4337 | for devname in sorted(data.tdevlist[phase]): |
4155 | d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname]) | 4338 | d = DevItem(data.testnumber, phase, data.dmesg[phase]['list'][devname]) |
4156 | devlist.append(d) | 4339 | devlist.append(d) |
4157 | if d.isa('kth'): | 4340 | if d.isa('kth'): |
@@ -4230,7 +4413,7 @@ def createHTML(testruns, testfail): | |||
4230 | for b in phases[dir]: | 4413 | for b in phases[dir]: |
4231 | # draw the devices for this phase | 4414 | # draw the devices for this phase |
4232 | phaselist = data.dmesg[b]['list'] | 4415 | phaselist = data.dmesg[b]['list'] |
4233 | for d in data.tdevlist[b]: | 4416 | for d in sorted(data.tdevlist[b]): |
4234 | name = d | 4417 | name = d |
4235 | drv = '' | 4418 | drv = '' |
4236 | dev = phaselist[d] | 4419 | dev = phaselist[d] |
@@ -4971,13 +5154,9 @@ def executeSuspend(): | |||
4971 | if mode == 'freeze' and sysvals.haveTurbostat(): | 5154 | if mode == 'freeze' and sysvals.haveTurbostat(): |
4972 | # execution will pause here | 5155 | # execution will pause here |
4973 | turbo = sysvals.turbostat() | 5156 | turbo = sysvals.turbostat() |
4974 | if '|' in turbo: | 5157 | if turbo: |
4975 | tdata['turbo'] = turbo | 5158 | tdata['turbo'] = turbo |
4976 | else: | ||
4977 | tdata['error'] = turbo | ||
4978 | else: | 5159 | else: |
4979 | if sysvals.haveTurbostat(): | ||
4980 | sysvals.vprint('WARNING: ignoring turbostat in mode "%s"' % mode) | ||
4981 | pf = open(sysvals.powerfile, 'w') | 5160 | pf = open(sysvals.powerfile, 'w') |
4982 | pf.write(mode) | 5161 | pf.write(mode) |
4983 | # execution will pause here | 5162 | # execution will pause here |
@@ -5024,7 +5203,7 @@ def executeSuspend(): | |||
5024 | op.write(line) | 5203 | op.write(line) |
5025 | op.close() | 5204 | op.close() |
5026 | sysvals.fsetVal('', 'trace') | 5205 | sysvals.fsetVal('', 'trace') |
5027 | devProps() | 5206 | sysvals.platforminfo() |
5028 | return testdata | 5207 | return testdata |
5029 | 5208 | ||
5030 | def readFile(file): | 5209 | def readFile(file): |
@@ -5040,9 +5219,9 @@ def readFile(file): | |||
5040 | # The time string, e.g. "1901m16s" | 5219 | # The time string, e.g. "1901m16s" |
5041 | def ms2nice(val): | 5220 | def ms2nice(val): |
5042 | val = int(val) | 5221 | val = int(val) |
5043 | h = val / 3600000 | 5222 | h = val // 3600000 |
5044 | m = (val / 60000) % 60 | 5223 | m = (val // 60000) % 60 |
5045 | s = (val / 1000) % 60 | 5224 | s = (val // 1000) % 60 |
5046 | if h > 0: | 5225 | if h > 0: |
5047 | return '%d:%02d:%02d' % (h, m, s) | 5226 | return '%d:%02d:%02d' % (h, m, s) |
5048 | if m > 0: | 5227 | if m > 0: |
@@ -5115,127 +5294,6 @@ def deviceInfo(output=''): | |||
5115 | print(lines[i]) | 5294 | print(lines[i]) |
5116 | return res | 5295 | return res |
5117 | 5296 | ||
5118 | # Function: devProps | ||
5119 | # Description: | ||
5120 | # Retrieve a list of properties for all devices in the trace log | ||
5121 | def devProps(data=0): | ||
5122 | props = dict() | ||
5123 | |||
5124 | if data: | ||
5125 | idx = data.index(': ') + 2 | ||
5126 | if idx >= len(data): | ||
5127 | return | ||
5128 | devlist = data[idx:].split(';') | ||
5129 | for dev in devlist: | ||
5130 | f = dev.split(',') | ||
5131 | if len(f) < 3: | ||
5132 | continue | ||
5133 | dev = f[0] | ||
5134 | props[dev] = DevProps() | ||
5135 | props[dev].altname = f[1] | ||
5136 | if int(f[2]): | ||
5137 | props[dev].async = True | ||
5138 | else: | ||
5139 | props[dev].async = False | ||
5140 | sysvals.devprops = props | ||
5141 | if sysvals.suspendmode == 'command' and 'testcommandstring' in props: | ||
5142 | sysvals.testcommand = props['testcommandstring'].altname | ||
5143 | return | ||
5144 | |||
5145 | if(os.path.exists(sysvals.ftracefile) == False): | ||
5146 | doError('%s does not exist' % sysvals.ftracefile) | ||
5147 | |||
5148 | # first get the list of devices we need properties for | ||
5149 | msghead = 'Additional data added by AnalyzeSuspend' | ||
5150 | alreadystamped = False | ||
5151 | tp = TestProps() | ||
5152 | tf = sysvals.openlog(sysvals.ftracefile, 'r') | ||
5153 | for line in tf: | ||
5154 | if msghead in line: | ||
5155 | alreadystamped = True | ||
5156 | continue | ||
5157 | # determine the trace data type (required for further parsing) | ||
5158 | m = re.match(tp.tracertypefmt, line) | ||
5159 | if(m): | ||
5160 | tp.setTracerType(m.group('t')) | ||
5161 | continue | ||
5162 | # parse only valid lines, if this is not one move on | ||
5163 | m = re.match(tp.ftrace_line_fmt, line) | ||
5164 | if(not m or 'device_pm_callback_start' not in line): | ||
5165 | continue | ||
5166 | m = re.match('.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg')); | ||
5167 | if(not m): | ||
5168 | continue | ||
5169 | dev = m.group('d') | ||
5170 | if dev not in props: | ||
5171 | props[dev] = DevProps() | ||
5172 | tf.close() | ||
5173 | |||
5174 | if not alreadystamped and sysvals.suspendmode == 'command': | ||
5175 | out = '#\n# '+msghead+'\n# Device Properties: ' | ||
5176 | out += 'testcommandstring,%s,0;' % (sysvals.testcommand) | ||
5177 | with sysvals.openlog(sysvals.ftracefile, 'a') as fp: | ||
5178 | fp.write(out+'\n') | ||
5179 | sysvals.devprops = props | ||
5180 | return | ||
5181 | |||
5182 | # now get the syspath for each of our target devices | ||
5183 | for dirname, dirnames, filenames in os.walk('/sys/devices'): | ||
5184 | if(re.match('.*/power', dirname) and 'async' in filenames): | ||
5185 | dev = dirname.split('/')[-2] | ||
5186 | if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)): | ||
5187 | props[dev].syspath = dirname[:-6] | ||
5188 | |||
5189 | # now fill in the properties for our target devices | ||
5190 | for dev in props: | ||
5191 | dirname = props[dev].syspath | ||
5192 | if not dirname or not os.path.exists(dirname): | ||
5193 | continue | ||
5194 | with open(dirname+'/power/async') as fp: | ||
5195 | text = fp.read() | ||
5196 | props[dev].async = False | ||
5197 | if 'enabled' in text: | ||
5198 | props[dev].async = True | ||
5199 | fields = os.listdir(dirname) | ||
5200 | if 'product' in fields: | ||
5201 | with open(dirname+'/product') as fp: | ||
5202 | props[dev].altname = fp.read() | ||
5203 | elif 'name' in fields: | ||
5204 | with open(dirname+'/name') as fp: | ||
5205 | props[dev].altname = fp.read() | ||
5206 | elif 'model' in fields: | ||
5207 | with open(dirname+'/model') as fp: | ||
5208 | props[dev].altname = fp.read() | ||
5209 | elif 'description' in fields: | ||
5210 | with open(dirname+'/description') as fp: | ||
5211 | props[dev].altname = fp.read() | ||
5212 | elif 'id' in fields: | ||
5213 | with open(dirname+'/id') as fp: | ||
5214 | props[dev].altname = fp.read() | ||
5215 | elif 'idVendor' in fields and 'idProduct' in fields: | ||
5216 | idv, idp = '', '' | ||
5217 | with open(dirname+'/idVendor') as fp: | ||
5218 | idv = fp.read().strip() | ||
5219 | with open(dirname+'/idProduct') as fp: | ||
5220 | idp = fp.read().strip() | ||
5221 | props[dev].altname = '%s:%s' % (idv, idp) | ||
5222 | |||
5223 | if props[dev].altname: | ||
5224 | out = props[dev].altname.strip().replace('\n', ' ') | ||
5225 | out = out.replace(',', ' ') | ||
5226 | out = out.replace(';', ' ') | ||
5227 | props[dev].altname = out | ||
5228 | |||
5229 | # and now write the data to the ftrace file | ||
5230 | if not alreadystamped: | ||
5231 | out = '#\n# '+msghead+'\n# Device Properties: ' | ||
5232 | for dev in sorted(props): | ||
5233 | out += props[dev].out(dev) | ||
5234 | with sysvals.openlog(sysvals.ftracefile, 'a') as fp: | ||
5235 | fp.write(out+'\n') | ||
5236 | |||
5237 | sysvals.devprops = props | ||
5238 | |||
5239 | # Function: getModes | 5297 | # Function: getModes |
5240 | # Description: | 5298 | # Description: |
5241 | # Determine the supported power modes on this system | 5299 | # Determine the supported power modes on this system |
@@ -5339,11 +5397,11 @@ def dmidecode(mempath, fatal=False): | |||
5339 | # search for either an SM table or DMI table | 5397 | # search for either an SM table or DMI table |
5340 | i = base = length = num = 0 | 5398 | i = base = length = num = 0 |
5341 | while(i < memsize): | 5399 | while(i < memsize): |
5342 | if buf[i:i+4] == '_SM_' and i < memsize - 16: | 5400 | if buf[i:i+4] == b'_SM_' and i < memsize - 16: |
5343 | length = struct.unpack('H', buf[i+22:i+24])[0] | 5401 | length = struct.unpack('H', buf[i+22:i+24])[0] |
5344 | base, num = struct.unpack('IH', buf[i+24:i+30]) | 5402 | base, num = struct.unpack('IH', buf[i+24:i+30]) |
5345 | break | 5403 | break |
5346 | elif buf[i:i+5] == '_DMI_': | 5404 | elif buf[i:i+5] == b'_DMI_': |
5347 | length = struct.unpack('H', buf[i+6:i+8])[0] | 5405 | length = struct.unpack('H', buf[i+6:i+8])[0] |
5348 | base, num = struct.unpack('IH', buf[i+8:i+14]) | 5406 | base, num = struct.unpack('IH', buf[i+8:i+14]) |
5349 | break | 5407 | break |
@@ -5376,15 +5434,15 @@ def dmidecode(mempath, fatal=False): | |||
5376 | if 0 == struct.unpack('H', buf[n:n+2])[0]: | 5434 | if 0 == struct.unpack('H', buf[n:n+2])[0]: |
5377 | break | 5435 | break |
5378 | n += 1 | 5436 | n += 1 |
5379 | data = buf[i+size:n+2].split('\0') | 5437 | data = buf[i+size:n+2].split(b'\0') |
5380 | for name in info: | 5438 | for name in info: |
5381 | itype, idxadr = info[name] | 5439 | itype, idxadr = info[name] |
5382 | if itype == type: | 5440 | if itype == type: |
5383 | idx = struct.unpack('B', buf[i+idxadr])[0] | 5441 | idx = struct.unpack('B', buf[i+idxadr:i+idxadr+1])[0] |
5384 | if idx > 0 and idx < len(data) - 1: | 5442 | if idx > 0 and idx < len(data) - 1: |
5385 | s = data[idx-1].strip() | 5443 | s = data[idx-1].decode('utf-8') |
5386 | if s and s.lower() != 'to be filled by o.e.m.': | 5444 | if s.strip() and s.strip().lower() != 'to be filled by o.e.m.': |
5387 | out[name] = data[idx-1] | 5445 | out[name] = s |
5388 | i = n + 2 | 5446 | i = n + 2 |
5389 | count += 1 | 5447 | count += 1 |
5390 | return out | 5448 | return out |
@@ -5409,7 +5467,7 @@ def getBattery(): | |||
5409 | return (ac, charge) | 5467 | return (ac, charge) |
5410 | 5468 | ||
5411 | def displayControl(cmd): | 5469 | def displayControl(cmd): |
5412 | xset, ret = 'xset -d :0.0 {0}', 0 | 5470 | xset, ret = 'timeout 10 xset -d :0.0 {0}', 0 |
5413 | if sysvals.sudouser: | 5471 | if sysvals.sudouser: |
5414 | xset = 'sudo -u %s %s' % (sysvals.sudouser, xset) | 5472 | xset = 'sudo -u %s %s' % (sysvals.sudouser, xset) |
5415 | if cmd == 'init': | 5473 | if cmd == 'init': |
@@ -5433,7 +5491,7 @@ def displayControl(cmd): | |||
5433 | fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout | 5491 | fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout |
5434 | ret = 'unknown' | 5492 | ret = 'unknown' |
5435 | for line in fp: | 5493 | for line in fp: |
5436 | m = re.match('[\s]*Monitor is (?P<m>.*)', line) | 5494 | m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line)) |
5437 | if(m and len(m.group('m')) >= 2): | 5495 | if(m and len(m.group('m')) >= 2): |
5438 | out = m.group('m').lower() | 5496 | out = m.group('m').lower() |
5439 | ret = out[3:] if out[0:2] == 'in' else out | 5497 | ret = out[3:] if out[0:2] == 'in' else out |
@@ -5495,10 +5553,11 @@ def getFPDT(output): | |||
5495 | ' OEM Revision : %u\n'\ | 5553 | ' OEM Revision : %u\n'\ |
5496 | ' Creator ID : %s\n'\ | 5554 | ' Creator ID : %s\n'\ |
5497 | ' Creator Revision : 0x%x\n'\ | 5555 | ' Creator Revision : 0x%x\n'\ |
5498 | '' % (table[0], table[0], table[1], table[2], table[3], | 5556 | '' % (ascii(table[0]), ascii(table[0]), table[1], table[2], |
5499 | table[4], table[5], table[6], table[7], table[8])) | 5557 | table[3], ascii(table[4]), ascii(table[5]), table[6], |
5558 | ascii(table[7]), table[8])) | ||
5500 | 5559 | ||
5501 | if(table[0] != 'FPDT'): | 5560 | if(table[0] != b'FPDT'): |
5502 | if(output): | 5561 | if(output): |
5503 | doError('Invalid FPDT table') | 5562 | doError('Invalid FPDT table') |
5504 | return False | 5563 | return False |
@@ -5530,8 +5589,8 @@ def getFPDT(output): | |||
5530 | return [0, 0] | 5589 | return [0, 0] |
5531 | rechead = struct.unpack('4sI', first) | 5590 | rechead = struct.unpack('4sI', first) |
5532 | recdata = fp.read(rechead[1]-8) | 5591 | recdata = fp.read(rechead[1]-8) |
5533 | if(rechead[0] == 'FBPT'): | 5592 | if(rechead[0] == b'FBPT'): |
5534 | record = struct.unpack('HBBIQQQQQ', recdata) | 5593 | record = struct.unpack('HBBIQQQQQ', recdata[:48]) |
5535 | if(output): | 5594 | if(output): |
5536 | pprint('%s (%s)\n'\ | 5595 | pprint('%s (%s)\n'\ |
5537 | ' Reset END : %u ns\n'\ | 5596 | ' Reset END : %u ns\n'\ |
@@ -5539,11 +5598,11 @@ def getFPDT(output): | |||
5539 | ' OS Loader StartImage Start : %u ns\n'\ | 5598 | ' OS Loader StartImage Start : %u ns\n'\ |
5540 | ' ExitBootServices Entry : %u ns\n'\ | 5599 | ' ExitBootServices Entry : %u ns\n'\ |
5541 | ' ExitBootServices Exit : %u ns'\ | 5600 | ' ExitBootServices Exit : %u ns'\ |
5542 | '' % (rectype[header[0]], rechead[0], record[4], record[5], | 5601 | '' % (rectype[header[0]], ascii(rechead[0]), record[4], record[5], |
5543 | record[6], record[7], record[8])) | 5602 | record[6], record[7], record[8])) |
5544 | elif(rechead[0] == 'S3PT'): | 5603 | elif(rechead[0] == b'S3PT'): |
5545 | if(output): | 5604 | if(output): |
5546 | pprint('%s (%s)' % (rectype[header[0]], rechead[0])) | 5605 | pprint('%s (%s)' % (rectype[header[0]], ascii(rechead[0]))) |
5547 | j = 0 | 5606 | j = 0 |
5548 | while(j < len(recdata)): | 5607 | while(j < len(recdata)): |
5549 | prechead = struct.unpack('HBB', recdata[j:j+4]) | 5608 | prechead = struct.unpack('HBB', recdata[j:j+4]) |
@@ -5689,7 +5748,7 @@ def doError(msg, help=False): | |||
5689 | def getArgInt(name, args, min, max, main=True): | 5748 | def getArgInt(name, args, min, max, main=True): |
5690 | if main: | 5749 | if main: |
5691 | try: | 5750 | try: |
5692 | arg = args.next() | 5751 | arg = next(args) |
5693 | except: | 5752 | except: |
5694 | doError(name+': no argument supplied', True) | 5753 | doError(name+': no argument supplied', True) |
5695 | else: | 5754 | else: |
@@ -5708,7 +5767,7 @@ def getArgInt(name, args, min, max, main=True): | |||
5708 | def getArgFloat(name, args, min, max, main=True): | 5767 | def getArgFloat(name, args, min, max, main=True): |
5709 | if main: | 5768 | if main: |
5710 | try: | 5769 | try: |
5711 | arg = args.next() | 5770 | arg = next(args) |
5712 | except: | 5771 | except: |
5713 | doError(name+': no argument supplied', True) | 5772 | doError(name+': no argument supplied', True) |
5714 | else: | 5773 | else: |
@@ -5737,9 +5796,12 @@ def processData(live=False): | |||
5737 | parseKernelLog(data) | 5796 | parseKernelLog(data) |
5738 | if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)): | 5797 | if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)): |
5739 | appendIncompleteTraceLog(testruns) | 5798 | appendIncompleteTraceLog(testruns) |
5799 | shown = ['bios', 'biosdate', 'cpu', 'host', 'kernel', 'man', 'memfr', | ||
5800 | 'memsz', 'mode', 'numcpu', 'plat', 'time'] | ||
5740 | sysvals.vprint('System Info:') | 5801 | sysvals.vprint('System Info:') |
5741 | for key in sorted(sysvals.stamp): | 5802 | for key in sorted(sysvals.stamp): |
5742 | sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) | 5803 | if key in shown: |
5804 | sysvals.vprint(' %-8s : %s' % (key.upper(), sysvals.stamp[key])) | ||
5743 | if sysvals.kparams: | 5805 | if sysvals.kparams: |
5744 | sysvals.vprint('Kparams:\n %s' % sysvals.kparams) | 5806 | sysvals.vprint('Kparams:\n %s' % sysvals.kparams) |
5745 | sysvals.vprint('Command:\n %s' % sysvals.cmdline) | 5807 | sysvals.vprint('Command:\n %s' % sysvals.cmdline) |
@@ -5768,6 +5830,12 @@ def processData(live=False): | |||
5768 | (w[0], w[1]) | 5830 | (w[0], w[1]) |
5769 | sysvals.vprint(s) | 5831 | sysvals.vprint(s) |
5770 | data.printDetails() | 5832 | data.printDetails() |
5833 | if len(sysvals.platinfo) > 0: | ||
5834 | sysvals.vprint('\nPlatform Info:') | ||
5835 | for info in sysvals.platinfo: | ||
5836 | sysvals.vprint(info[0]+' - '+info[1]) | ||
5837 | sysvals.vprint(info[2]) | ||
5838 | sysvals.vprint('') | ||
5771 | if sysvals.cgdump: | 5839 | if sysvals.cgdump: |
5772 | for data in testruns: | 5840 | for data in testruns: |
5773 | data.debugPrint() | 5841 | data.debugPrint() |
@@ -5951,7 +6019,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): | |||
5951 | worst[d] = {'name':'', 'time': 0.0} | 6019 | worst[d] = {'name':'', 'time': 0.0} |
5952 | dev = devices[d] if d in devices else 0 | 6020 | dev = devices[d] if d in devices else 0 |
5953 | if dev and len(dev.keys()) > 0: | 6021 | if dev and len(dev.keys()) > 0: |
5954 | n = sorted(dev, key=dev.get, reverse=True)[0] | 6022 | n = sorted(dev, key=lambda k:(dev[k], k), reverse=True)[0] |
5955 | worst[d]['name'], worst[d]['time'] = n, dev[n] | 6023 | worst[d]['name'], worst[d]['time'] = n, dev[n] |
5956 | data = { | 6024 | data = { |
5957 | 'mode': stmp[2], | 6025 | 'mode': stmp[2], |
@@ -5976,7 +6044,7 @@ def data_from_html(file, outpath, issues, fulldetail=False): | |||
5976 | data['funclist'] = find_in_html(html, '<div title="', '" class="traceevent"', False) | 6044 | data['funclist'] = find_in_html(html, '<div title="', '" class="traceevent"', False) |
5977 | return data | 6045 | return data |
5978 | 6046 | ||
5979 | def genHtml(subdir): | 6047 | def genHtml(subdir, force=False): |
5980 | for dirname, dirnames, filenames in os.walk(subdir): | 6048 | for dirname, dirnames, filenames in os.walk(subdir): |
5981 | sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = '' | 6049 | sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = '' |
5982 | for filename in filenames: | 6050 | for filename in filenames: |
@@ -5986,7 +6054,7 @@ def genHtml(subdir): | |||
5986 | sysvals.ftracefile = os.path.join(dirname, filename) | 6054 | sysvals.ftracefile = os.path.join(dirname, filename) |
5987 | sysvals.setOutputFile() | 6055 | sysvals.setOutputFile() |
5988 | if sysvals.ftracefile and sysvals.htmlfile and \ | 6056 | if sysvals.ftracefile and sysvals.htmlfile and \ |
5989 | not os.path.exists(sysvals.htmlfile): | 6057 | (force or not os.path.exists(sysvals.htmlfile)): |
5990 | pprint('FTRACE: %s' % sysvals.ftracefile) | 6058 | pprint('FTRACE: %s' % sysvals.ftracefile) |
5991 | if sysvals.dmesgfile: | 6059 | if sysvals.dmesgfile: |
5992 | pprint('DMESG : %s' % sysvals.dmesgfile) | 6060 | pprint('DMESG : %s' % sysvals.dmesgfile) |
@@ -6042,7 +6110,7 @@ def checkArgBool(name, value): | |||
6042 | # Description: | 6110 | # Description: |
6043 | # Configure the script via the info in a config file | 6111 | # Configure the script via the info in a config file |
6044 | def configFromFile(file): | 6112 | def configFromFile(file): |
6045 | Config = ConfigParser.ConfigParser() | 6113 | Config = configparser.ConfigParser() |
6046 | 6114 | ||
6047 | Config.read(file) | 6115 | Config.read(file) |
6048 | sections = Config.sections() | 6116 | sections = Config.sections() |
@@ -6270,7 +6338,7 @@ def printHelp(): | |||
6270 | ' default: suspend-{date}-{time}\n'\ | 6338 | ' default: suspend-{date}-{time}\n'\ |
6271 | ' -rtcwake t Wakeup t seconds after suspend, set t to "off" to disable (default: 15)\n'\ | 6339 | ' -rtcwake t Wakeup t seconds after suspend, set t to "off" to disable (default: 15)\n'\ |
6272 | ' -addlogs Add the dmesg and ftrace logs to the html output\n'\ | 6340 | ' -addlogs Add the dmesg and ftrace logs to the html output\n'\ |
6273 | ' -turbostat Use turbostat to execute the command in freeze mode (default: disabled)\n'\ | 6341 | ' -noturbostat Dont use turbostat in freeze mode (default: disabled)\n'\ |
6274 | ' -srgap Add a visible gap in the timeline between sus/res (default: disabled)\n'\ | 6342 | ' -srgap Add a visible gap in the timeline between sus/res (default: disabled)\n'\ |
6275 | ' -skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\ | 6343 | ' -skiphtml Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\ |
6276 | ' -result fn Export a results table to a text file for parsing.\n'\ | 6344 | ' -result fn Export a results table to a text file for parsing.\n'\ |
@@ -6340,7 +6408,7 @@ if __name__ == '__main__': | |||
6340 | for arg in args: | 6408 | for arg in args: |
6341 | if(arg == '-m'): | 6409 | if(arg == '-m'): |
6342 | try: | 6410 | try: |
6343 | val = args.next() | 6411 | val = next(args) |
6344 | except: | 6412 | except: |
6345 | doError('No mode supplied', True) | 6413 | doError('No mode supplied', True) |
6346 | if val == 'command' and not sysvals.testcommand: | 6414 | if val == 'command' and not sysvals.testcommand: |
@@ -6384,10 +6452,8 @@ if __name__ == '__main__': | |||
6384 | sysvals.dmesglog = True | 6452 | sysvals.dmesglog = True |
6385 | elif(arg == '-addlogftrace'): | 6453 | elif(arg == '-addlogftrace'): |
6386 | sysvals.ftracelog = True | 6454 | sysvals.ftracelog = True |
6387 | elif(arg == '-turbostat'): | 6455 | elif(arg == '-noturbostat'): |
6388 | sysvals.tstat = True | 6456 | sysvals.tstat = False |
6389 | if not sysvals.haveTurbostat(): | ||
6390 | doError('Turbostat command not found') | ||
6391 | elif(arg == '-verbose'): | 6457 | elif(arg == '-verbose'): |
6392 | sysvals.verbose = True | 6458 | sysvals.verbose = True |
6393 | elif(arg == '-proc'): | 6459 | elif(arg == '-proc'): |
@@ -6400,7 +6466,7 @@ if __name__ == '__main__': | |||
6400 | sysvals.gzip = True | 6466 | sysvals.gzip = True |
6401 | elif(arg == '-rs'): | 6467 | elif(arg == '-rs'): |
6402 | try: | 6468 | try: |
6403 | val = args.next() | 6469 | val = next(args) |
6404 | except: | 6470 | except: |
6405 | doError('-rs requires "enable" or "disable"', True) | 6471 | doError('-rs requires "enable" or "disable"', True) |
6406 | if val.lower() in switchvalues: | 6472 | if val.lower() in switchvalues: |
@@ -6412,7 +6478,7 @@ if __name__ == '__main__': | |||
6412 | doError('invalid option: %s, use "enable/disable" or "on/off"' % val, True) | 6478 | doError('invalid option: %s, use "enable/disable" or "on/off"' % val, True) |
6413 | elif(arg == '-display'): | 6479 | elif(arg == '-display'): |
6414 | try: | 6480 | try: |
6415 | val = args.next() | 6481 | val = next(args) |
6416 | except: | 6482 | except: |
6417 | doError('-display requires an mode value', True) | 6483 | doError('-display requires an mode value', True) |
6418 | disopt = ['on', 'off', 'standby', 'suspend'] | 6484 | disopt = ['on', 'off', 'standby', 'suspend'] |
@@ -6423,7 +6489,7 @@ if __name__ == '__main__': | |||
6423 | sysvals.max_graph_depth = getArgInt('-maxdepth', args, 0, 1000) | 6489 | sysvals.max_graph_depth = getArgInt('-maxdepth', args, 0, 1000) |
6424 | elif(arg == '-rtcwake'): | 6490 | elif(arg == '-rtcwake'): |
6425 | try: | 6491 | try: |
6426 | val = args.next() | 6492 | val = next(args) |
6427 | except: | 6493 | except: |
6428 | doError('No rtcwake time supplied', True) | 6494 | doError('No rtcwake time supplied', True) |
6429 | if val.lower() in switchoff: | 6495 | if val.lower() in switchoff: |
@@ -6443,7 +6509,7 @@ if __name__ == '__main__': | |||
6443 | sysvals.cgtest = getArgInt('-cgtest', args, 0, 1) | 6509 | sysvals.cgtest = getArgInt('-cgtest', args, 0, 1) |
6444 | elif(arg == '-cgphase'): | 6510 | elif(arg == '-cgphase'): |
6445 | try: | 6511 | try: |
6446 | val = args.next() | 6512 | val = next(args) |
6447 | except: | 6513 | except: |
6448 | doError('No phase name supplied', True) | 6514 | doError('No phase name supplied', True) |
6449 | d = Data(0) | 6515 | d = Data(0) |
@@ -6453,19 +6519,19 @@ if __name__ == '__main__': | |||
6453 | sysvals.cgphase = val | 6519 | sysvals.cgphase = val |
6454 | elif(arg == '-cgfilter'): | 6520 | elif(arg == '-cgfilter'): |
6455 | try: | 6521 | try: |
6456 | val = args.next() | 6522 | val = next(args) |
6457 | except: | 6523 | except: |
6458 | doError('No callgraph functions supplied', True) | 6524 | doError('No callgraph functions supplied', True) |
6459 | sysvals.setCallgraphFilter(val) | 6525 | sysvals.setCallgraphFilter(val) |
6460 | elif(arg == '-skipkprobe'): | 6526 | elif(arg == '-skipkprobe'): |
6461 | try: | 6527 | try: |
6462 | val = args.next() | 6528 | val = next(args) |
6463 | except: | 6529 | except: |
6464 | doError('No kprobe functions supplied', True) | 6530 | doError('No kprobe functions supplied', True) |
6465 | sysvals.skipKprobes(val) | 6531 | sysvals.skipKprobes(val) |
6466 | elif(arg == '-cgskip'): | 6532 | elif(arg == '-cgskip'): |
6467 | try: | 6533 | try: |
6468 | val = args.next() | 6534 | val = next(args) |
6469 | except: | 6535 | except: |
6470 | doError('No file supplied', True) | 6536 | doError('No file supplied', True) |
6471 | if val.lower() in switchoff: | 6537 | if val.lower() in switchoff: |
@@ -6480,7 +6546,7 @@ if __name__ == '__main__': | |||
6480 | sysvals.callloopmaxlen = getArgFloat('-callloop-maxlen', args, 0.0, 1.0) | 6546 | sysvals.callloopmaxlen = getArgFloat('-callloop-maxlen', args, 0.0, 1.0) |
6481 | elif(arg == '-cmd'): | 6547 | elif(arg == '-cmd'): |
6482 | try: | 6548 | try: |
6483 | val = args.next() | 6549 | val = next(args) |
6484 | except: | 6550 | except: |
6485 | doError('No command string supplied', True) | 6551 | doError('No command string supplied', True) |
6486 | sysvals.testcommand = val | 6552 | sysvals.testcommand = val |
@@ -6495,13 +6561,13 @@ if __name__ == '__main__': | |||
6495 | sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600) | 6561 | sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600) |
6496 | elif(arg == '-o'): | 6562 | elif(arg == '-o'): |
6497 | try: | 6563 | try: |
6498 | val = args.next() | 6564 | val = next(args) |
6499 | except: | 6565 | except: |
6500 | doError('No subdirectory name supplied', True) | 6566 | doError('No subdirectory name supplied', True) |
6501 | sysvals.outdir = sysvals.setOutputFolder(val) | 6567 | sysvals.outdir = sysvals.setOutputFolder(val) |
6502 | elif(arg == '-config'): | 6568 | elif(arg == '-config'): |
6503 | try: | 6569 | try: |
6504 | val = args.next() | 6570 | val = next(args) |
6505 | except: | 6571 | except: |
6506 | doError('No text file supplied', True) | 6572 | doError('No text file supplied', True) |
6507 | file = sysvals.configFile(val) | 6573 | file = sysvals.configFile(val) |
@@ -6510,7 +6576,7 @@ if __name__ == '__main__': | |||
6510 | configFromFile(file) | 6576 | configFromFile(file) |
6511 | elif(arg == '-fadd'): | 6577 | elif(arg == '-fadd'): |
6512 | try: | 6578 | try: |
6513 | val = args.next() | 6579 | val = next(args) |
6514 | except: | 6580 | except: |
6515 | doError('No text file supplied', True) | 6581 | doError('No text file supplied', True) |
6516 | file = sysvals.configFile(val) | 6582 | file = sysvals.configFile(val) |
@@ -6519,7 +6585,7 @@ if __name__ == '__main__': | |||
6519 | sysvals.addFtraceFilterFunctions(file) | 6585 | sysvals.addFtraceFilterFunctions(file) |
6520 | elif(arg == '-dmesg'): | 6586 | elif(arg == '-dmesg'): |
6521 | try: | 6587 | try: |
6522 | val = args.next() | 6588 | val = next(args) |
6523 | except: | 6589 | except: |
6524 | doError('No dmesg file supplied', True) | 6590 | doError('No dmesg file supplied', True) |
6525 | sysvals.notestrun = True | 6591 | sysvals.notestrun = True |
@@ -6528,7 +6594,7 @@ if __name__ == '__main__': | |||
6528 | doError('%s does not exist' % sysvals.dmesgfile) | 6594 | doError('%s does not exist' % sysvals.dmesgfile) |
6529 | elif(arg == '-ftrace'): | 6595 | elif(arg == '-ftrace'): |
6530 | try: | 6596 | try: |
6531 | val = args.next() | 6597 | val = next(args) |
6532 | except: | 6598 | except: |
6533 | doError('No ftrace file supplied', True) | 6599 | doError('No ftrace file supplied', True) |
6534 | sysvals.notestrun = True | 6600 | sysvals.notestrun = True |
@@ -6537,7 +6603,7 @@ if __name__ == '__main__': | |||
6537 | doError('%s does not exist' % sysvals.ftracefile) | 6603 | doError('%s does not exist' % sysvals.ftracefile) |
6538 | elif(arg == '-summary'): | 6604 | elif(arg == '-summary'): |
6539 | try: | 6605 | try: |
6540 | val = args.next() | 6606 | val = next(args) |
6541 | except: | 6607 | except: |
6542 | doError('No directory supplied', True) | 6608 | doError('No directory supplied', True) |
6543 | cmd = 'summary' | 6609 | cmd = 'summary' |
@@ -6547,13 +6613,13 @@ if __name__ == '__main__': | |||
6547 | doError('%s is not accesible' % val) | 6613 | doError('%s is not accesible' % val) |
6548 | elif(arg == '-filter'): | 6614 | elif(arg == '-filter'): |
6549 | try: | 6615 | try: |
6550 | val = args.next() | 6616 | val = next(args) |
6551 | except: | 6617 | except: |
6552 | doError('No devnames supplied', True) | 6618 | doError('No devnames supplied', True) |
6553 | sysvals.setDeviceFilter(val) | 6619 | sysvals.setDeviceFilter(val) |
6554 | elif(arg == '-result'): | 6620 | elif(arg == '-result'): |
6555 | try: | 6621 | try: |
6556 | val = args.next() | 6622 | val = next(args) |
6557 | except: | 6623 | except: |
6558 | doError('No result file supplied', True) | 6624 | doError('No result file supplied', True) |
6559 | sysvals.result = val | 6625 | sysvals.result = val |