aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python/export-to-sqlite.py
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2019-05-20 07:37:22 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-06-05 08:47:57 -0400
commit64adadb3f9dbaaae3d14ea75fa71a3b877cbe82e (patch)
treec9865af4fdd1e6f756acfa2238e6abab1e744f5b /tools/perf/scripts/python/export-to-sqlite.py
parent52a2ab6fa99df9288f2c8c7f461b815550b9b366 (diff)
perf scripts python: export-to-sqlite.py: Export IPC information
Export cycle and instruction counts on samples and calls tables. Committer testing: First runs some workload collecting intel_pt with the 'cyc' ter just for userspace: [root@quaco adrian.hunter]# perf record -o simple-retpoline.perf.data -e intel_pt/cyc/u ./simple-retpoline [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.035 MB simple-retpoline.perf.data ] [root@quaco adrian.hunter]# Then use the export-to-sqlite.py script to see if the changes in this cset don't make it to break and if the changes in the db schema are the ones expected: [root@quaco adrian.hunter]# perf script -i simple-retpoline.perf.data --itrace=be -s ~acme/libexec/perf-core/scripts/python/export-to-sqlite.py simple-retpoline.db branches calls 2019-05-31 11:50:46.942710 Creating database ... 2019-05-31 11:50:46.949663 Writing records... 2019-05-31 11:50:47.224033 Adding indexes 2019-05-31 11:50:47.231599 Done [root@quaco adrian.hunter]# Now lets use the db: [root@quaco adrian.hunter]# sqlite3 simple-retpoline.db SQLite version 3.26.0 2018-12-01 12:34:55 Enter ".help" for usage hints. sqlite> .schema samples CREATE TABLE samples (id integer NOT NULL PRIMARY KEY,evsel_id bigint,machine_id bigint,thread_id bigint,comm_id bigint,dso_id bigint,symbol_id bigint,sym_offset bigint,ip bigint,time bigint,cpuinteger,to_dso_id bigint,to_symbol_id bigint,to_sym_offset bigint,to_ip bigint,branch_type integer,in_tx boolean,call_path_id bigint,insn_count bigint,cyc_count bigint); sqlite> Cool, the 'insn_count' and 'cyc_count' are there, now lets see if we can use them in a query: sqlite> select insn_count,cyc_count from samples where cyc_count > 1500 and insn_count < 10; 6|1507 sqlite> select insn_count,cyc_count from samples where cyc_count > 1500; 118|2210 140|1516 3783|1861 132|1521 6|1507 sqlite> Seems to work :-) Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/r/20190520113728.14389-17-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/scripts/python/export-to-sqlite.py')
-rw-r--r--tools/perf/scripts/python/export-to-sqlite.py36
1 files changed, 24 insertions, 12 deletions
diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py
index f617e518332f..4542ce89034b 100644
--- a/tools/perf/scripts/python/export-to-sqlite.py
+++ b/tools/perf/scripts/python/export-to-sqlite.py
@@ -218,7 +218,9 @@ if branches:
218 'to_ip bigint,' 218 'to_ip bigint,'
219 'branch_type integer,' 219 'branch_type integer,'
220 'in_tx boolean,' 220 'in_tx boolean,'
221 'call_path_id bigint)') 221 'call_path_id bigint,'
222 'insn_count bigint,'
223 'cyc_count bigint)')
222else: 224else:
223 do_query(query, 'CREATE TABLE samples (' 225 do_query(query, 'CREATE TABLE samples ('
224 'id integer NOT NULL PRIMARY KEY,' 226 'id integer NOT NULL PRIMARY KEY,'
@@ -242,7 +244,9 @@ else:
242 'data_src bigint,' 244 'data_src bigint,'
243 'branch_type integer,' 245 'branch_type integer,'
244 'in_tx boolean,' 246 'in_tx boolean,'
245 'call_path_id bigint)') 247 'call_path_id bigint,'
248 'insn_count bigint,'
249 'cyc_count bigint)')
246 250
247if perf_db_export_calls or perf_db_export_callchains: 251if perf_db_export_calls or perf_db_export_callchains:
248 do_query(query, 'CREATE TABLE call_paths (' 252 do_query(query, 'CREATE TABLE call_paths ('
@@ -263,7 +267,9 @@ if perf_db_export_calls:
263 'return_id bigint,' 267 'return_id bigint,'
264 'parent_call_path_id bigint,' 268 'parent_call_path_id bigint,'
265 'flags integer,' 269 'flags integer,'
266 'parent_id bigint)') 270 'parent_id bigint,'
271 'insn_count bigint,'
272 'cyc_count bigint)')
267 273
268# printf was added to sqlite in version 3.8.3 274# printf was added to sqlite in version 3.8.3
269sqlite_has_printf = False 275sqlite_has_printf = False
@@ -359,6 +365,9 @@ if perf_db_export_calls:
359 'return_time,' 365 'return_time,'
360 'return_time - call_time AS elapsed_time,' 366 'return_time - call_time AS elapsed_time,'
361 'branch_count,' 367 'branch_count,'
368 'insn_count,'
369 'cyc_count,'
370 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
362 'call_id,' 371 'call_id,'
363 'return_id,' 372 'return_id,'
364 '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,' 373 '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,'
@@ -384,7 +393,10 @@ do_query(query, 'CREATE VIEW samples_view AS '
384 'to_sym_offset,' 393 'to_sym_offset,'
385 '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,' 394 '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'
386 '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,' 395 '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'
387 'in_tx' 396 'in_tx,'
397 'insn_count,'
398 'cyc_count,'
399 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC'
388 ' FROM samples') 400 ' FROM samples')
389 401
390do_query(query, 'END TRANSACTION') 402do_query(query, 'END TRANSACTION')
@@ -407,15 +419,15 @@ branch_type_query = QSqlQuery(db)
407branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)") 419branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")
408sample_query = QSqlQuery(db) 420sample_query = QSqlQuery(db)
409if branches: 421if branches:
410 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 422 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
411else: 423else:
412 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 424 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
413if perf_db_export_calls or perf_db_export_callchains: 425if perf_db_export_calls or perf_db_export_callchains:
414 call_path_query = QSqlQuery(db) 426 call_path_query = QSqlQuery(db)
415 call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)") 427 call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")
416if perf_db_export_calls: 428if perf_db_export_calls:
417 call_query = QSqlQuery(db) 429 call_query = QSqlQuery(db)
418 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 430 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
419 431
420def trace_begin(): 432def trace_begin():
421 printdate("Writing records...") 433 printdate("Writing records...")
@@ -427,10 +439,10 @@ def trace_begin():
427 comm_table(0, "unknown") 439 comm_table(0, "unknown")
428 dso_table(0, 0, "unknown", "unknown", "") 440 dso_table(0, 0, "unknown", "unknown", "")
429 symbol_table(0, 0, 0, 0, 0, "unknown") 441 symbol_table(0, 0, 0, 0, 0, "unknown")
430 sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 442 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)
431 if perf_db_export_calls or perf_db_export_callchains: 443 if perf_db_export_calls or perf_db_export_callchains:
432 call_path_table(0, 0, 0, 0) 444 call_path_table(0, 0, 0, 0)
433 call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 445 call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
434 446
435unhandled_count = 0 447unhandled_count = 0
436 448
@@ -486,14 +498,14 @@ def sample_table(*x):
486 if branches: 498 if branches:
487 for xx in x[0:15]: 499 for xx in x[0:15]:
488 sample_query.addBindValue(str(xx)) 500 sample_query.addBindValue(str(xx))
489 for xx in x[19:22]: 501 for xx in x[19:24]:
490 sample_query.addBindValue(str(xx)) 502 sample_query.addBindValue(str(xx))
491 do_query_(sample_query) 503 do_query_(sample_query)
492 else: 504 else:
493 bind_exec(sample_query, 22, x) 505 bind_exec(sample_query, 24, x)
494 506
495def call_path_table(*x): 507def call_path_table(*x):
496 bind_exec(call_path_query, 4, x) 508 bind_exec(call_path_query, 4, x)
497 509
498def call_return_table(*x): 510def call_return_table(*x):
499 bind_exec(call_query, 12, x) 511 bind_exec(call_query, 14, x)