.. | .. |
---|
10 | 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
11 | 11 | # more details. |
---|
12 | 12 | |
---|
| 13 | +from __future__ import print_function |
---|
| 14 | + |
---|
13 | 15 | import os |
---|
14 | 16 | import sys |
---|
15 | 17 | import struct |
---|
.. | .. |
---|
18 | 20 | # To use this script you will need to have installed package python-pyside which |
---|
19 | 21 | # provides LGPL-licensed Python bindings for Qt. You will also need the package |
---|
20 | 22 | # libqt4-sql-sqlite for Qt sqlite3 support. |
---|
| 23 | +# |
---|
| 24 | +# Examples of installing pyside: |
---|
| 25 | +# |
---|
| 26 | +# ubuntu: |
---|
| 27 | +# |
---|
| 28 | +# $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql |
---|
| 29 | +# |
---|
| 30 | +# Alternately, to use Python3 and/or pyside 2, one of the following: |
---|
| 31 | +# |
---|
| 32 | +# $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql |
---|
| 33 | +# $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql |
---|
| 34 | +# $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql |
---|
| 35 | +# fedora: |
---|
| 36 | +# |
---|
| 37 | +# $ sudo yum install python-pyside |
---|
| 38 | +# |
---|
| 39 | +# Alternately, to use Python3 and/or pyside 2, one of the following: |
---|
| 40 | +# $ sudo yum install python3-pyside |
---|
| 41 | +# $ pip install --user PySide2 |
---|
| 42 | +# $ pip3 install --user PySide2 |
---|
21 | 43 | # |
---|
22 | 44 | # An example of using this script with Intel PT: |
---|
23 | 45 | # |
---|
.. | .. |
---|
40 | 62 | # sqlite> .quit |
---|
41 | 63 | # |
---|
42 | 64 | # An example of using the database is provided by the script |
---|
43 | | -# call-graph-from-sql.py. Refer to that script for details. |
---|
| 65 | +# exported-sql-viewer.py. Refer to that script for details. |
---|
44 | 66 | # |
---|
45 | 67 | # The database structure is practically the same as created by the script |
---|
46 | 68 | # export-to-postgresql.py. Refer to that script for details. A notable |
---|
47 | 69 | # difference is the 'transaction' column of the 'samples' table which is |
---|
48 | 70 | # renamed 'transaction_' in sqlite because 'transaction' is a reserved word. |
---|
49 | 71 | |
---|
50 | | -from PySide.QtSql import * |
---|
| 72 | +pyside_version_1 = True |
---|
| 73 | +if not "pyside-version-1" in sys.argv: |
---|
| 74 | + try: |
---|
| 75 | + from PySide2.QtSql import * |
---|
| 76 | + pyside_version_1 = False |
---|
| 77 | + except: |
---|
| 78 | + pass |
---|
| 79 | + |
---|
| 80 | +if pyside_version_1: |
---|
| 81 | + from PySide.QtSql import * |
---|
51 | 82 | |
---|
52 | 83 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ |
---|
53 | 84 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') |
---|
.. | .. |
---|
60 | 91 | perf_db_export_calls = False |
---|
61 | 92 | perf_db_export_callchains = False |
---|
62 | 93 | |
---|
| 94 | +def printerr(*args, **keyword_args): |
---|
| 95 | + print(*args, file=sys.stderr, **keyword_args) |
---|
| 96 | + |
---|
| 97 | +def printdate(*args, **kw_args): |
---|
| 98 | + print(datetime.datetime.today(), *args, sep=' ', **kw_args) |
---|
| 99 | + |
---|
63 | 100 | def usage(): |
---|
64 | | - print >> sys.stderr, "Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]" |
---|
65 | | - print >> sys.stderr, "where: columns 'all' or 'branches'" |
---|
66 | | - print >> sys.stderr, " calls 'calls' => create calls and call_paths table" |
---|
67 | | - print >> sys.stderr, " callchains 'callchains' => create call_paths table" |
---|
68 | | - raise Exception("Too few arguments") |
---|
| 101 | + printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]"); |
---|
| 102 | + printerr("where: columns 'all' or 'branches'"); |
---|
| 103 | + printerr(" calls 'calls' => create calls and call_paths table"); |
---|
| 104 | + printerr(" callchains 'callchains' => create call_paths table"); |
---|
| 105 | + printerr(" pyside-version-1 'pyside-version-1' => use pyside version 1"); |
---|
| 106 | + raise Exception("Too few or bad arguments") |
---|
69 | 107 | |
---|
70 | 108 | if (len(sys.argv) < 2): |
---|
71 | 109 | usage() |
---|
.. | .. |
---|
87 | 125 | perf_db_export_calls = True |
---|
88 | 126 | elif (sys.argv[i] == "callchains"): |
---|
89 | 127 | perf_db_export_callchains = True |
---|
| 128 | + elif (sys.argv[i] == "pyside-version-1"): |
---|
| 129 | + pass |
---|
90 | 130 | else: |
---|
91 | 131 | usage() |
---|
92 | 132 | |
---|
.. | .. |
---|
100 | 140 | return |
---|
101 | 141 | raise Exception("Query failed: " + q.lastError().text()) |
---|
102 | 142 | |
---|
103 | | -print datetime.datetime.today(), "Creating database..." |
---|
| 143 | +printdate("Creating database ...") |
---|
104 | 144 | |
---|
105 | 145 | db_exists = False |
---|
106 | 146 | try: |
---|
.. | .. |
---|
137 | 177 | 'tid integer)') |
---|
138 | 178 | do_query(query, 'CREATE TABLE comms (' |
---|
139 | 179 | 'id integer NOT NULL PRIMARY KEY,' |
---|
140 | | - 'comm varchar(16))') |
---|
| 180 | + 'comm varchar(16),' |
---|
| 181 | + 'c_thread_id bigint,' |
---|
| 182 | + 'c_time bigint,' |
---|
| 183 | + 'exec_flag boolean)') |
---|
141 | 184 | do_query(query, 'CREATE TABLE comm_threads (' |
---|
142 | 185 | 'id integer NOT NULL PRIMARY KEY,' |
---|
143 | 186 | 'comm_id bigint,' |
---|
.. | .. |
---|
178 | 221 | 'to_ip bigint,' |
---|
179 | 222 | 'branch_type integer,' |
---|
180 | 223 | 'in_tx boolean,' |
---|
181 | | - 'call_path_id bigint)') |
---|
| 224 | + 'call_path_id bigint,' |
---|
| 225 | + 'insn_count bigint,' |
---|
| 226 | + 'cyc_count bigint)') |
---|
182 | 227 | else: |
---|
183 | 228 | do_query(query, 'CREATE TABLE samples (' |
---|
184 | 229 | 'id integer NOT NULL PRIMARY KEY,' |
---|
.. | .. |
---|
202 | 247 | 'data_src bigint,' |
---|
203 | 248 | 'branch_type integer,' |
---|
204 | 249 | 'in_tx boolean,' |
---|
205 | | - 'call_path_id bigint)') |
---|
| 250 | + 'call_path_id bigint,' |
---|
| 251 | + 'insn_count bigint,' |
---|
| 252 | + 'cyc_count bigint)') |
---|
206 | 253 | |
---|
207 | 254 | if perf_db_export_calls or perf_db_export_callchains: |
---|
208 | 255 | do_query(query, 'CREATE TABLE call_paths (' |
---|
.. | .. |
---|
222 | 269 | 'call_id bigint,' |
---|
223 | 270 | 'return_id bigint,' |
---|
224 | 271 | 'parent_call_path_id bigint,' |
---|
| 272 | + 'flags integer,' |
---|
| 273 | + 'parent_id bigint,' |
---|
| 274 | + 'insn_count bigint,' |
---|
| 275 | + 'cyc_count bigint)') |
---|
| 276 | + |
---|
| 277 | +do_query(query, 'CREATE TABLE ptwrite (' |
---|
| 278 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 279 | + 'payload bigint,' |
---|
| 280 | + 'exact_ip integer)') |
---|
| 281 | + |
---|
| 282 | +do_query(query, 'CREATE TABLE cbr (' |
---|
| 283 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 284 | + 'cbr integer,' |
---|
| 285 | + 'mhz integer,' |
---|
| 286 | + 'percent integer)') |
---|
| 287 | + |
---|
| 288 | +do_query(query, 'CREATE TABLE mwait (' |
---|
| 289 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 290 | + 'hints integer,' |
---|
| 291 | + 'extensions integer)') |
---|
| 292 | + |
---|
| 293 | +do_query(query, 'CREATE TABLE pwre (' |
---|
| 294 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 295 | + 'cstate integer,' |
---|
| 296 | + 'subcstate integer,' |
---|
| 297 | + 'hw integer)') |
---|
| 298 | + |
---|
| 299 | +do_query(query, 'CREATE TABLE exstop (' |
---|
| 300 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 301 | + 'exact_ip integer)') |
---|
| 302 | + |
---|
| 303 | +do_query(query, 'CREATE TABLE pwrx (' |
---|
| 304 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 305 | + 'deepest_cstate integer,' |
---|
| 306 | + 'last_cstate integer,' |
---|
| 307 | + 'wake_reason integer)') |
---|
| 308 | + |
---|
| 309 | +do_query(query, 'CREATE TABLE context_switches (' |
---|
| 310 | + 'id integer NOT NULL PRIMARY KEY,' |
---|
| 311 | + 'machine_id bigint,' |
---|
| 312 | + 'time bigint,' |
---|
| 313 | + 'cpu integer,' |
---|
| 314 | + 'thread_out_id bigint,' |
---|
| 315 | + 'comm_out_id bigint,' |
---|
| 316 | + 'thread_in_id bigint,' |
---|
| 317 | + 'comm_in_id bigint,' |
---|
225 | 318 | 'flags integer)') |
---|
226 | 319 | |
---|
227 | 320 | # printf was added to sqlite in version 3.8.3 |
---|
.. | .. |
---|
318 | 411 | 'return_time,' |
---|
319 | 412 | 'return_time - call_time AS elapsed_time,' |
---|
320 | 413 | 'branch_count,' |
---|
| 414 | + 'insn_count,' |
---|
| 415 | + 'cyc_count,' |
---|
| 416 | + 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,' |
---|
321 | 417 | 'call_id,' |
---|
322 | 418 | 'return_id,' |
---|
323 | | - 'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,' |
---|
324 | | - 'parent_call_path_id' |
---|
| 419 | + 'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,' |
---|
| 420 | + 'parent_call_path_id,' |
---|
| 421 | + 'calls.parent_id' |
---|
325 | 422 | ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id') |
---|
326 | 423 | |
---|
327 | 424 | do_query(query, 'CREATE VIEW samples_view AS ' |
---|
.. | .. |
---|
342 | 439 | 'to_sym_offset,' |
---|
343 | 440 | '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,' |
---|
344 | 441 | '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,' |
---|
345 | | - 'in_tx' |
---|
| 442 | + 'in_tx,' |
---|
| 443 | + 'insn_count,' |
---|
| 444 | + 'cyc_count,' |
---|
| 445 | + 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC' |
---|
346 | 446 | ' FROM samples') |
---|
| 447 | + |
---|
| 448 | +do_query(query, 'CREATE VIEW ptwrite_view AS ' |
---|
| 449 | + 'SELECT ' |
---|
| 450 | + 'ptwrite.id,' |
---|
| 451 | + 'time,' |
---|
| 452 | + 'cpu,' |
---|
| 453 | + + emit_to_hex('payload') + ' AS payload_hex,' |
---|
| 454 | + 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip' |
---|
| 455 | + ' FROM ptwrite' |
---|
| 456 | + ' INNER JOIN samples ON samples.id = ptwrite.id') |
---|
| 457 | + |
---|
| 458 | +do_query(query, 'CREATE VIEW cbr_view AS ' |
---|
| 459 | + 'SELECT ' |
---|
| 460 | + 'cbr.id,' |
---|
| 461 | + 'time,' |
---|
| 462 | + 'cpu,' |
---|
| 463 | + 'cbr,' |
---|
| 464 | + 'mhz,' |
---|
| 465 | + 'percent' |
---|
| 466 | + ' FROM cbr' |
---|
| 467 | + ' INNER JOIN samples ON samples.id = cbr.id') |
---|
| 468 | + |
---|
| 469 | +do_query(query, 'CREATE VIEW mwait_view AS ' |
---|
| 470 | + 'SELECT ' |
---|
| 471 | + 'mwait.id,' |
---|
| 472 | + 'time,' |
---|
| 473 | + 'cpu,' |
---|
| 474 | + + emit_to_hex('hints') + ' AS hints_hex,' |
---|
| 475 | + + emit_to_hex('extensions') + ' AS extensions_hex' |
---|
| 476 | + ' FROM mwait' |
---|
| 477 | + ' INNER JOIN samples ON samples.id = mwait.id') |
---|
| 478 | + |
---|
| 479 | +do_query(query, 'CREATE VIEW pwre_view AS ' |
---|
| 480 | + 'SELECT ' |
---|
| 481 | + 'pwre.id,' |
---|
| 482 | + 'time,' |
---|
| 483 | + 'cpu,' |
---|
| 484 | + 'cstate,' |
---|
| 485 | + 'subcstate,' |
---|
| 486 | + 'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw' |
---|
| 487 | + ' FROM pwre' |
---|
| 488 | + ' INNER JOIN samples ON samples.id = pwre.id') |
---|
| 489 | + |
---|
| 490 | +do_query(query, 'CREATE VIEW exstop_view AS ' |
---|
| 491 | + 'SELECT ' |
---|
| 492 | + 'exstop.id,' |
---|
| 493 | + 'time,' |
---|
| 494 | + 'cpu,' |
---|
| 495 | + 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip' |
---|
| 496 | + ' FROM exstop' |
---|
| 497 | + ' INNER JOIN samples ON samples.id = exstop.id') |
---|
| 498 | + |
---|
| 499 | +do_query(query, 'CREATE VIEW pwrx_view AS ' |
---|
| 500 | + 'SELECT ' |
---|
| 501 | + 'pwrx.id,' |
---|
| 502 | + 'time,' |
---|
| 503 | + 'cpu,' |
---|
| 504 | + 'deepest_cstate,' |
---|
| 505 | + 'last_cstate,' |
---|
| 506 | + 'CASE WHEN wake_reason=1 THEN \'Interrupt\'' |
---|
| 507 | + ' WHEN wake_reason=2 THEN \'Timer Deadline\'' |
---|
| 508 | + ' WHEN wake_reason=4 THEN \'Monitored Address\'' |
---|
| 509 | + ' WHEN wake_reason=8 THEN \'HW\'' |
---|
| 510 | + ' ELSE wake_reason ' |
---|
| 511 | + 'END AS wake_reason' |
---|
| 512 | + ' FROM pwrx' |
---|
| 513 | + ' INNER JOIN samples ON samples.id = pwrx.id') |
---|
| 514 | + |
---|
| 515 | +do_query(query, 'CREATE VIEW power_events_view AS ' |
---|
| 516 | + 'SELECT ' |
---|
| 517 | + 'samples.id,' |
---|
| 518 | + 'time,' |
---|
| 519 | + 'cpu,' |
---|
| 520 | + 'selected_events.name AS event,' |
---|
| 521 | + 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,' |
---|
| 522 | + 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,' |
---|
| 523 | + 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,' |
---|
| 524 | + 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,' |
---|
| 525 | + 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,' |
---|
| 526 | + 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,' |
---|
| 527 | + 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,' |
---|
| 528 | + 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,' |
---|
| 529 | + 'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,' |
---|
| 530 | + 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,' |
---|
| 531 | + 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,' |
---|
| 532 | + 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT ' |
---|
| 533 | + 'CASE WHEN wake_reason=1 THEN \'Interrupt\'' |
---|
| 534 | + ' WHEN wake_reason=2 THEN \'Timer Deadline\'' |
---|
| 535 | + ' WHEN wake_reason=4 THEN \'Monitored Address\'' |
---|
| 536 | + ' WHEN wake_reason=8 THEN \'HW\'' |
---|
| 537 | + ' ELSE wake_reason ' |
---|
| 538 | + 'END' |
---|
| 539 | + ' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason' |
---|
| 540 | + ' FROM samples' |
---|
| 541 | + ' INNER JOIN selected_events ON selected_events.id = evsel_id' |
---|
| 542 | + ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')') |
---|
| 543 | + |
---|
| 544 | +do_query(query, 'CREATE VIEW context_switches_view AS ' |
---|
| 545 | + 'SELECT ' |
---|
| 546 | + 'context_switches.id,' |
---|
| 547 | + 'context_switches.machine_id,' |
---|
| 548 | + 'context_switches.time,' |
---|
| 549 | + 'context_switches.cpu,' |
---|
| 550 | + 'th_out.pid AS pid_out,' |
---|
| 551 | + 'th_out.tid AS tid_out,' |
---|
| 552 | + 'comm_out.comm AS comm_out,' |
---|
| 553 | + 'th_in.pid AS pid_in,' |
---|
| 554 | + 'th_in.tid AS tid_in,' |
---|
| 555 | + 'comm_in.comm AS comm_in,' |
---|
| 556 | + 'CASE WHEN context_switches.flags = 0 THEN \'in\'' |
---|
| 557 | + ' WHEN context_switches.flags = 1 THEN \'out\'' |
---|
| 558 | + ' WHEN context_switches.flags = 3 THEN \'out preempt\'' |
---|
| 559 | + ' ELSE context_switches.flags ' |
---|
| 560 | + 'END AS flags' |
---|
| 561 | + ' FROM context_switches' |
---|
| 562 | + ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id' |
---|
| 563 | + ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id' |
---|
| 564 | + ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id' |
---|
| 565 | + ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id') |
---|
347 | 566 | |
---|
348 | 567 | do_query(query, 'END TRANSACTION') |
---|
349 | 568 | |
---|
.. | .. |
---|
354 | 573 | thread_query = QSqlQuery(db) |
---|
355 | 574 | thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") |
---|
356 | 575 | comm_query = QSqlQuery(db) |
---|
357 | | -comm_query.prepare("INSERT INTO comms VALUES (?, ?)") |
---|
| 576 | +comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)") |
---|
358 | 577 | comm_thread_query = QSqlQuery(db) |
---|
359 | 578 | comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") |
---|
360 | 579 | dso_query = QSqlQuery(db) |
---|
.. | .. |
---|
365 | 584 | branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)") |
---|
366 | 585 | sample_query = QSqlQuery(db) |
---|
367 | 586 | if branches: |
---|
368 | | - sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
| 587 | + sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
369 | 588 | else: |
---|
370 | | - sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
| 589 | + sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
371 | 590 | if perf_db_export_calls or perf_db_export_callchains: |
---|
372 | 591 | call_path_query = QSqlQuery(db) |
---|
373 | 592 | call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)") |
---|
374 | 593 | if perf_db_export_calls: |
---|
375 | 594 | call_query = QSqlQuery(db) |
---|
376 | | - call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
| 595 | + call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
| 596 | +ptwrite_query = QSqlQuery(db) |
---|
| 597 | +ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)") |
---|
| 598 | +cbr_query = QSqlQuery(db) |
---|
| 599 | +cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)") |
---|
| 600 | +mwait_query = QSqlQuery(db) |
---|
| 601 | +mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)") |
---|
| 602 | +pwre_query = QSqlQuery(db) |
---|
| 603 | +pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)") |
---|
| 604 | +exstop_query = QSqlQuery(db) |
---|
| 605 | +exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)") |
---|
| 606 | +pwrx_query = QSqlQuery(db) |
---|
| 607 | +pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)") |
---|
| 608 | +context_switch_query = QSqlQuery(db) |
---|
| 609 | +context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)") |
---|
377 | 610 | |
---|
378 | 611 | def trace_begin(): |
---|
379 | | - print datetime.datetime.today(), "Writing records..." |
---|
| 612 | + printdate("Writing records...") |
---|
380 | 613 | do_query(query, 'BEGIN TRANSACTION') |
---|
381 | 614 | # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs |
---|
382 | 615 | evsel_table(0, "unknown") |
---|
383 | 616 | machine_table(0, 0, "unknown") |
---|
384 | 617 | thread_table(0, 0, 0, -1, -1) |
---|
385 | | - comm_table(0, "unknown") |
---|
| 618 | + comm_table(0, "unknown", 0, 0, 0) |
---|
386 | 619 | dso_table(0, 0, "unknown", "unknown", "") |
---|
387 | 620 | symbol_table(0, 0, 0, 0, 0, "unknown") |
---|
388 | | - sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
---|
| 621 | + sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
---|
389 | 622 | if perf_db_export_calls or perf_db_export_callchains: |
---|
390 | 623 | call_path_table(0, 0, 0, 0) |
---|
| 624 | + call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
---|
391 | 625 | |
---|
392 | 626 | unhandled_count = 0 |
---|
| 627 | + |
---|
| 628 | +def is_table_empty(table_name): |
---|
| 629 | + do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1'); |
---|
| 630 | + if query.next(): |
---|
| 631 | + return False |
---|
| 632 | + return True |
---|
| 633 | + |
---|
| 634 | +def drop(table_name): |
---|
| 635 | + do_query(query, 'DROP VIEW ' + table_name + '_view'); |
---|
| 636 | + do_query(query, 'DROP TABLE ' + table_name); |
---|
393 | 637 | |
---|
394 | 638 | def trace_end(): |
---|
395 | 639 | do_query(query, 'END TRANSACTION') |
---|
396 | 640 | |
---|
397 | | - print datetime.datetime.today(), "Adding indexes" |
---|
| 641 | + printdate("Adding indexes") |
---|
398 | 642 | if perf_db_export_calls: |
---|
399 | 643 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') |
---|
| 644 | + do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') |
---|
| 645 | + do_query(query, 'ALTER TABLE comms ADD has_calls boolean') |
---|
| 646 | + do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)') |
---|
| 647 | + |
---|
| 648 | + printdate("Dropping unused tables") |
---|
| 649 | + if is_table_empty("ptwrite"): |
---|
| 650 | + drop("ptwrite") |
---|
| 651 | + if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): |
---|
| 652 | + do_query(query, 'DROP VIEW power_events_view'); |
---|
| 653 | + drop("mwait") |
---|
| 654 | + drop("pwre") |
---|
| 655 | + drop("exstop") |
---|
| 656 | + drop("pwrx") |
---|
| 657 | + if is_table_empty("cbr"): |
---|
| 658 | + drop("cbr") |
---|
| 659 | + if is_table_empty("context_switches"): |
---|
| 660 | + drop("context_switches") |
---|
400 | 661 | |
---|
401 | 662 | if (unhandled_count): |
---|
402 | | - print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" |
---|
403 | | - print datetime.datetime.today(), "Done" |
---|
| 663 | + printdate("Warning: ", unhandled_count, " unhandled events") |
---|
| 664 | + printdate("Done") |
---|
404 | 665 | |
---|
405 | 666 | def trace_unhandled(event_name, context, event_fields_dict): |
---|
406 | 667 | global unhandled_count |
---|
.. | .. |
---|
424 | 685 | bind_exec(thread_query, 5, x) |
---|
425 | 686 | |
---|
426 | 687 | def comm_table(*x): |
---|
427 | | - bind_exec(comm_query, 2, x) |
---|
| 688 | + bind_exec(comm_query, 5, x) |
---|
428 | 689 | |
---|
429 | 690 | def comm_thread_table(*x): |
---|
430 | 691 | bind_exec(comm_thread_query, 3, x) |
---|
.. | .. |
---|
442 | 703 | if branches: |
---|
443 | 704 | for xx in x[0:15]: |
---|
444 | 705 | sample_query.addBindValue(str(xx)) |
---|
445 | | - for xx in x[19:22]: |
---|
| 706 | + for xx in x[19:24]: |
---|
446 | 707 | sample_query.addBindValue(str(xx)) |
---|
447 | 708 | do_query_(sample_query) |
---|
448 | 709 | else: |
---|
449 | | - bind_exec(sample_query, 22, x) |
---|
| 710 | + bind_exec(sample_query, 24, x) |
---|
450 | 711 | |
---|
451 | 712 | def call_path_table(*x): |
---|
452 | 713 | bind_exec(call_path_query, 4, x) |
---|
453 | 714 | |
---|
454 | 715 | def call_return_table(*x): |
---|
455 | | - bind_exec(call_query, 11, x) |
---|
| 716 | + bind_exec(call_query, 14, x) |
---|
| 717 | + |
---|
| 718 | +def ptwrite(id, raw_buf): |
---|
| 719 | + data = struct.unpack_from("<IQ", raw_buf) |
---|
| 720 | + flags = data[0] |
---|
| 721 | + payload = data[1] |
---|
| 722 | + exact_ip = flags & 1 |
---|
| 723 | + ptwrite_query.addBindValue(str(id)) |
---|
| 724 | + ptwrite_query.addBindValue(str(payload)) |
---|
| 725 | + ptwrite_query.addBindValue(str(exact_ip)) |
---|
| 726 | + do_query_(ptwrite_query) |
---|
| 727 | + |
---|
| 728 | +def cbr(id, raw_buf): |
---|
| 729 | + data = struct.unpack_from("<BBBBII", raw_buf) |
---|
| 730 | + cbr = data[0] |
---|
| 731 | + MHz = (data[4] + 500) / 1000 |
---|
| 732 | + percent = ((cbr * 1000 / data[2]) + 5) / 10 |
---|
| 733 | + cbr_query.addBindValue(str(id)) |
---|
| 734 | + cbr_query.addBindValue(str(cbr)) |
---|
| 735 | + cbr_query.addBindValue(str(MHz)) |
---|
| 736 | + cbr_query.addBindValue(str(percent)) |
---|
| 737 | + do_query_(cbr_query) |
---|
| 738 | + |
---|
| 739 | +def mwait(id, raw_buf): |
---|
| 740 | + data = struct.unpack_from("<IQ", raw_buf) |
---|
| 741 | + payload = data[1] |
---|
| 742 | + hints = payload & 0xff |
---|
| 743 | + extensions = (payload >> 32) & 0x3 |
---|
| 744 | + mwait_query.addBindValue(str(id)) |
---|
| 745 | + mwait_query.addBindValue(str(hints)) |
---|
| 746 | + mwait_query.addBindValue(str(extensions)) |
---|
| 747 | + do_query_(mwait_query) |
---|
| 748 | + |
---|
| 749 | +def pwre(id, raw_buf): |
---|
| 750 | + data = struct.unpack_from("<IQ", raw_buf) |
---|
| 751 | + payload = data[1] |
---|
| 752 | + hw = (payload >> 7) & 1 |
---|
| 753 | + cstate = (payload >> 12) & 0xf |
---|
| 754 | + subcstate = (payload >> 8) & 0xf |
---|
| 755 | + pwre_query.addBindValue(str(id)) |
---|
| 756 | + pwre_query.addBindValue(str(cstate)) |
---|
| 757 | + pwre_query.addBindValue(str(subcstate)) |
---|
| 758 | + pwre_query.addBindValue(str(hw)) |
---|
| 759 | + do_query_(pwre_query) |
---|
| 760 | + |
---|
| 761 | +def exstop(id, raw_buf): |
---|
| 762 | + data = struct.unpack_from("<I", raw_buf) |
---|
| 763 | + flags = data[0] |
---|
| 764 | + exact_ip = flags & 1 |
---|
| 765 | + exstop_query.addBindValue(str(id)) |
---|
| 766 | + exstop_query.addBindValue(str(exact_ip)) |
---|
| 767 | + do_query_(exstop_query) |
---|
| 768 | + |
---|
| 769 | +def pwrx(id, raw_buf): |
---|
| 770 | + data = struct.unpack_from("<IQ", raw_buf) |
---|
| 771 | + payload = data[1] |
---|
| 772 | + deepest_cstate = payload & 0xf |
---|
| 773 | + last_cstate = (payload >> 4) & 0xf |
---|
| 774 | + wake_reason = (payload >> 8) & 0xf |
---|
| 775 | + pwrx_query.addBindValue(str(id)) |
---|
| 776 | + pwrx_query.addBindValue(str(deepest_cstate)) |
---|
| 777 | + pwrx_query.addBindValue(str(last_cstate)) |
---|
| 778 | + pwrx_query.addBindValue(str(wake_reason)) |
---|
| 779 | + do_query_(pwrx_query) |
---|
| 780 | + |
---|
| 781 | +def synth_data(id, config, raw_buf, *x): |
---|
| 782 | + if config == 0: |
---|
| 783 | + ptwrite(id, raw_buf) |
---|
| 784 | + elif config == 1: |
---|
| 785 | + mwait(id, raw_buf) |
---|
| 786 | + elif config == 2: |
---|
| 787 | + pwre(id, raw_buf) |
---|
| 788 | + elif config == 3: |
---|
| 789 | + exstop(id, raw_buf) |
---|
| 790 | + elif config == 4: |
---|
| 791 | + pwrx(id, raw_buf) |
---|
| 792 | + elif config == 5: |
---|
| 793 | + cbr(id, raw_buf) |
---|
| 794 | + |
---|
| 795 | +def context_switch_table(*x): |
---|
| 796 | + bind_exec(context_switch_query, 9, x) |
---|