| .. | .. |
|---|
| 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) |
|---|