The format of synthesized events is determined by the attribute config. For the formats for Intel PT power and ptwrite events, create tables and populate them when the synth_data handler is called. If the tables remain empty, drop them at the end. The tables and views, including a combined power_events_view, will display automatically from the tables menu of the exported exported-sql-viewer.py script. Note, currently only Atoms since Gemini Lake have support for ptwrite and mwait, pwre, exstop and pwrx, but all Intel PT implementations support cbr.
Showing the changes to tools/perf/scripts/python (1 of 1 file). Show all
Unified · Split
| @@ -271,6 +271,38 @@ if perf_db_export_calls: · 270 unmodified lines | ||
| 271 | 271 | 'insn_count bigint,' |
| 272 | 272 | 'cyc_count bigint)') |
| 273 | 273 | |
| 274 | +do_query(query, 'CREATE TABLE ptwrite (' | |
| 275 | + 'id integer NOT NULL PRIMARY KEY,' | |
| 276 | + 'payload bigint,' | |
| 277 | + 'exact_ip integer)') | |
| 278 | + | |
| 279 | +do_query(query, 'CREATE TABLE cbr (' | |
| 280 | + 'id integer NOT NULL PRIMARY KEY,' | |
| 281 | + 'cbr integer,' | |
| 282 | + 'mhz integer,' | |
| 283 | + 'percent integer)') | |
| 284 | + | |
| 285 | +do_query(query, 'CREATE TABLE mwait (' | |
| 286 | + 'id integer NOT NULL PRIMARY KEY,' | |
| 287 | + 'hints integer,' | |
| 288 | + 'extensions integer)') | |
| 289 | + | |
| 290 | +do_query(query, 'CREATE TABLE pwre (' | |
| 291 | + 'id integer NOT NULL PRIMARY KEY,' | |
| 292 | + 'cstate integer,' | |
| 293 | + 'subcstate integer,' | |
| 294 | + 'hw integer)') | |
| 295 | + | |
| 296 | +do_query(query, 'CREATE TABLE exstop (' | |
| 297 | + 'id integer NOT NULL PRIMARY KEY,' | |
| 298 | + 'exact_ip integer)') | |
| 299 | + | |
| 300 | +do_query(query, 'CREATE TABLE pwrx (' | |
| 301 | + 'id integer NOT NULL PRIMARY KEY,' | |
| 302 | + 'deepest_cstate integer,' | |
| 303 | + 'last_cstate integer,' | |
| 304 | + 'wake_reason integer)') | |
| 305 | + | |
| 274 | 306 | # printf was added to sqlite in version 3.8.3 |
| 275 | 307 | sqlite_has_printf = False |
| 276 | 308 | try: |
| @@ -399,6 +431,102 @@ do_query(query, 'CREATE VIEW samples_view AS ' · 122 unmodified lines | ||
| 399 | 431 | 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC' |
| 400 | 432 | ' FROM samples') |
| 401 | 433 | |
| 434 | +do_query(query, 'CREATE VIEW ptwrite_view AS ' | |
| 435 | + 'SELECT ' | |
| 436 | + 'ptwrite.id,' | |
| 437 | + 'time,' | |
| 438 | + 'cpu,' | |
| 439 | + + emit_to_hex('payload') + ' AS payload_hex,' | |
| 440 | + 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip' | |
| 441 | + ' FROM ptwrite' | |
| 442 | + ' INNER JOIN samples ON samples.id = ptwrite.id') | |
| 443 | + | |
| 444 | +do_query(query, 'CREATE VIEW cbr_view AS ' | |
| 445 | + 'SELECT ' | |
| 446 | + 'cbr.id,' | |
| 447 | + 'time,' | |
| 448 | + 'cpu,' | |
| 449 | + 'cbr,' | |
| 450 | + 'mhz,' | |
| 451 | + 'percent' | |
| 452 | + ' FROM cbr' | |
| 453 | + ' INNER JOIN samples ON samples.id = cbr.id') | |
| 454 | + | |
| 455 | +do_query(query, 'CREATE VIEW mwait_view AS ' | |
| 456 | + 'SELECT ' | |
| 457 | + 'mwait.id,' | |
| 458 | + 'time,' | |
| 459 | + 'cpu,' | |
| 460 | + + emit_to_hex('hints') + ' AS hints_hex,' | |
| 461 | + + emit_to_hex('extensions') + ' AS extensions_hex' | |
| 462 | + ' FROM mwait' | |
| 463 | + ' INNER JOIN samples ON samples.id = mwait.id') | |
| 464 | + | |
| 465 | +do_query(query, 'CREATE VIEW pwre_view AS ' | |
| 466 | + 'SELECT ' | |
| 467 | + 'pwre.id,' | |
| 468 | + 'time,' | |
| 469 | + 'cpu,' | |
| 470 | + 'cstate,' | |
| 471 | + 'subcstate,' | |
| 472 | + 'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw' | |
| 473 | + ' FROM pwre' | |
| 474 | + ' INNER JOIN samples ON samples.id = pwre.id') | |
| 475 | + | |
| 476 | +do_query(query, 'CREATE VIEW exstop_view AS ' | |
| 477 | + 'SELECT ' | |
| 478 | + 'exstop.id,' | |
| 479 | + 'time,' | |
| 480 | + 'cpu,' | |
| 481 | + 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip' | |
| 482 | + ' FROM exstop' | |
| 483 | + ' INNER JOIN samples ON samples.id = exstop.id') | |
| 484 | + | |
| 485 | +do_query(query, 'CREATE VIEW pwrx_view AS ' | |
| 486 | + 'SELECT ' | |
| 487 | + 'pwrx.id,' | |
| 488 | + 'time,' | |
| 489 | + 'cpu,' | |
| 490 | + 'deepest_cstate,' | |
| 491 | + 'last_cstate,' | |
| 492 | + 'CASE WHEN wake_reason=1 THEN \'Interrupt\'' | |
| 493 | + ' WHEN wake_reason=2 THEN \'Timer Deadline\'' | |
| 494 | + ' WHEN wake_reason=4 THEN \'Monitored Address\'' | |
| 495 | + ' WHEN wake_reason=8 THEN \'HW\'' | |
| 496 | + ' ELSE wake_reason ' | |
| 497 | + 'END AS wake_reason' | |
| 498 | + ' FROM pwrx' | |
| 499 | + ' INNER JOIN samples ON samples.id = pwrx.id') | |
| 500 | + | |
| 501 | +do_query(query, 'CREATE VIEW power_events_view AS ' | |
| 502 | + 'SELECT ' | |
| 503 | + 'samples.id,' | |
| 504 | + 'time,' | |
| 505 | + 'cpu,' | |
| 506 | + 'selected_events.name AS event,' | |
| 507 | + 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,' | |
| 508 | + 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,' | |
| 509 | + 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,' | |
| 510 | + 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,' | |
| 511 | + 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,' | |
| 512 | + 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,' | |
| 513 | + 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,' | |
| 514 | + 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,' | |
| 515 | + 'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,' | |
| 516 | + 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,' | |
| 517 | + 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,' | |
| 518 | + 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT ' | |
| 519 | + 'CASE WHEN wake_reason=1 THEN \'Interrupt\'' | |
| 520 | + ' WHEN wake_reason=2 THEN \'Timer Deadline\'' | |
| 521 | + ' WHEN wake_reason=4 THEN \'Monitored Address\'' | |
| 522 | + ' WHEN wake_reason=8 THEN \'HW\'' | |
| 523 | + ' ELSE wake_reason ' | |
| 524 | + 'END' | |
| 525 | + ' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason' | |
| 526 | + ' FROM samples' | |
| 527 | + ' INNER JOIN selected_events ON selected_events.id = evsel_id' | |
| 528 | + ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')') | |
| 529 | + | |
| 402 | 530 | do_query(query, 'END TRANSACTION') |
| 403 | 531 | |
| 404 | 532 | evsel_query = QSqlQuery(db) |
| @@ -428,6 +556,18 @@ if perf_db_export_calls or perf_db_export_callchains: · 23 unmodified lines | ||
| 428 | 556 | if perf_db_export_calls: |
| 429 | 557 | call_query = QSqlQuery(db) |
| 430 | 558 | call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") |
| 559 | +ptwrite_query = QSqlQuery(db) | |
| 560 | +ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)") | |
| 561 | +cbr_query = QSqlQuery(db) | |
| 562 | +cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)") | |
| 563 | +mwait_query = QSqlQuery(db) | |
| 564 | +mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)") | |
| 565 | +pwre_query = QSqlQuery(db) | |
| 566 | +pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)") | |
| 567 | +exstop_query = QSqlQuery(db) | |
| 568 | +exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)") | |
| 569 | +pwrx_query = QSqlQuery(db) | |
| 570 | +pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)") | |
| 431 | 571 | |
| 432 | 572 | def trace_begin(): |
| 433 | 573 | printdate("Writing records...") |
| @@ -446,6 +586,16 @@ def trace_begin(): · 12 unmodified lines | ||
| 446 | 586 | |
| 447 | 587 | unhandled_count = 0 |
| 448 | 588 | |
| 589 | +def is_table_empty(table_name): | |
| 590 | + do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1'); | |
| 591 | + if query.next(): | |
| 592 | + return False | |
| 593 | + return True | |
| 594 | + | |
| 595 | +def drop(table_name): | |
| 596 | + do_query(query, 'DROP VIEW ' + table_name + '_view'); | |
| 597 | + do_query(query, 'DROP TABLE ' + table_name); | |
| 598 | + | |
| 449 | 599 | def trace_end(): |
| 450 | 600 | do_query(query, 'END TRANSACTION') |
| 451 | 601 | |
| @@ -454,6 +604,18 @@ def trace_end(): · 2 unmodified lines | ||
| 454 | 604 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') |
| 455 | 605 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') |
| 456 | 606 | |
| 607 | + printdate("Dropping unused tables") | |
| 608 | + if is_table_empty("ptwrite"): | |
| 609 | + drop("ptwrite") | |
| 610 | + if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): | |
| 611 | + drop("mwait") | |
| 612 | + drop("pwre") | |
| 613 | + drop("exstop") | |
| 614 | + drop("pwrx") | |
| 615 | + do_query(query, 'DROP VIEW power_events_view'); | |
| 616 | + if is_table_empty("cbr"): | |
| 617 | + drop("cbr") | |
| 618 | + | |
| 457 | 619 | if (unhandled_count): |
| 458 | 620 | printdate("Warning: ", unhandled_count, " unhandled events") |
| 459 | 621 | printdate("Done") |
| @@ -509,3 +671,80 @@ def call_path_table(*x): · 49 unmodified lines | ||
| 509 | 671 | |
| 510 | 672 | def call_return_table(*x): |
| 511 | 673 | bind_exec(call_query, 14, x) |
| 674 | + | |
| 675 | +def ptwrite(id, raw_buf): | |
| 676 | + data = struct.unpack_from("<IQ", raw_buf) | |
| 677 | + flags = data[0] | |
| 678 | + payload = data[1] | |
| 679 | + exact_ip = flags & 1 | |
| 680 | + ptwrite_query.addBindValue(str(id)) | |
| 681 | + ptwrite_query.addBindValue(str(payload)) | |
| 682 | + ptwrite_query.addBindValue(str(exact_ip)) | |
| 683 | + do_query_(ptwrite_query) | |
| 684 | + | |
| 685 | +def cbr(id, raw_buf): | |
| 686 | + data = struct.unpack_from("<BBBBII", raw_buf) | |
| 687 | + cbr = data[0] | |
| 688 | + MHz = (data[4] + 500) / 1000 | |
| 689 | + percent = ((cbr * 1000 / data[2]) + 5) / 10 | |
| 690 | + cbr_query.addBindValue(str(id)) | |
| 691 | + cbr_query.addBindValue(str(cbr)) | |
| 692 | + cbr_query.addBindValue(str(MHz)) | |
| 693 | + cbr_query.addBindValue(str(percent)) | |
| 694 | + do_query_(cbr_query) | |
| 695 | + | |
| 696 | +def mwait(id, raw_buf): | |
| 697 | + data = struct.unpack_from("<IQ", raw_buf) | |
| 698 | + payload = data[1] | |
| 699 | + hints = payload & 0xff | |
| 700 | + extensions = (payload >> 32) & 0x3 | |
| 701 | + mwait_query.addBindValue(str(id)) | |
| 702 | + mwait_query.addBindValue(str(hints)) | |
| 703 | + mwait_query.addBindValue(str(extensions)) | |
| 704 | + do_query_(mwait_query) | |
| 705 | + | |
| 706 | +def pwre(id, raw_buf): | |
| 707 | + data = struct.unpack_from("<IQ", raw_buf) | |
| 708 | + payload = data[1] | |
| 709 | + hw = (payload >> 7) & 1 | |
| 710 | + cstate = (payload >> 12) & 0xf | |
| 711 | + subcstate = (payload >> 8) & 0xf | |
| 712 | + pwre_query.addBindValue(str(id)) | |
| 713 | + pwre_query.addBindValue(str(cstate)) | |
| 714 | + pwre_query.addBindValue(str(subcstate)) | |
| 715 | + pwre_query.addBindValue(str(hw)) | |
| 716 | + do_query_(pwre_query) | |
| 717 | + | |
| 718 | +def exstop(id, raw_buf): | |
| 719 | + data = struct.unpack_from("<I", raw_buf) | |
| 720 | + flags = data[0] | |
| 721 | + exact_ip = flags & 1 | |
| 722 | + exstop_query.addBindValue(str(id)) | |
| 723 | + exstop_query.addBindValue(str(exact_ip)) | |
| 724 | + do_query_(exstop_query) | |
| 725 | + | |
| 726 | +def pwrx(id, raw_buf): | |
| 727 | + data = struct.unpack_from("<IQ", raw_buf) | |
| 728 | + payload = data[1] | |
| 729 | + deepest_cstate = payload & 0xf | |
| 730 | + last_cstate = (payload >> 4) & 0xf | |
| 731 | + wake_reason = (payload >> 8) & 0xf | |
| 732 | + pwrx_query.addBindValue(str(id)) | |
| 733 | + pwrx_query.addBindValue(str(deepest_cstate)) | |
| 734 | + pwrx_query.addBindValue(str(last_cstate)) | |
| 735 | + pwrx_query.addBindValue(str(wake_reason)) | |
| 736 | + do_query_(pwrx_query) | |
| 737 | + | |
| 738 | +def synth_data(id, config, raw_buf, *x): | |
| 739 | + if config == 0: | |
| 740 | + ptwrite(id, raw_buf) | |
| 741 | + elif config == 1: | |
| 742 | + mwait(id, raw_buf) | |
| 743 | + elif config == 2: | |
| 744 | + pwre(id, raw_buf) | |
| 745 | + elif config == 3: | |
| 746 | + exstop(id, raw_buf) | |
| 747 | + elif config == 4: | |
| 748 | + pwrx(id, raw_buf) | |
| 749 | + elif config == 5: | |
| 750 | + cbr(id, raw_buf) | |