summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/export-to-sqlite.py
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2019-07-03 16:54:24 +0300
committerIngo Molnar <mingo@kernel.org>2019-07-03 16:54:24 +0300
commita041ede090119510bb56396dd0df0ee0b3173b47 (patch)
tree9892f0784574adbd397d68df6a7326d25bea162a /tools/perf/scripts/python/export-to-sqlite.py
parentfd7d55172d1e2e501e6da0a5c1de25f06612dc2e (diff)
parent06c642c0e9fceafd16b1a4c80d44b1c09e282215 (diff)
downloadlinux-a041ede090119510bb56396dd0df0ee0b3173b47.tar.xz
Merge tag 'perf-core-for-mingo-5.3-20190701' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: perf annotate: Mao Han: - Add support for the csky processor architecture. perf stat: Andi Kleen: - Fix metrics with --no-merge. - Don't merge events in the same PMU. - Fix group lookup for metric group. Intel PT: Adrian Hunter: - Improve CBR (Core to Bus Ratio) packets support. - Fix thread stack return from kernel for kernel only case. - Export power and ptwrite events to sqlite and postgresql. core libraries: Arnaldo Carvalho de Melo: - Find routines in tools/perf/util/ that have implementations in the kernel libraries (lib/*.c), such as strreplace(), strim(), skip_spaces() and reuse them after making a copy into tools/lib and tools/include/. This continues the effort of having tools/ code looking as much as possible like kernel source code, to help encourage people to work on both the kernel and in tools hosted in the kernel sources. That in turn will help moving stuff that uses those routines to tools/lib/perf/ where they will be made available for use in other tools. In the process ditch old cruft, remove unused variables and add missing include directives for headers providing things used in places that were building by sheer luck. Kyle Meyer: - Bump MAX_NR_CPUS and MAX_CACHES to get these tools to work on more machines. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/scripts/python/export-to-sqlite.py')
-rw-r--r--tools/perf/scripts/python/export-to-sqlite.py239
1 files changed, 239 insertions, 0 deletions
diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py
index 4542ce89034b..3222a83f4184 100644
--- a/tools/perf/scripts/python/export-to-sqlite.py
+++ b/tools/perf/scripts/python/export-to-sqlite.py
@@ -271,6 +271,38 @@ if perf_db_export_calls:
'insn_count bigint,'
'cyc_count bigint)')
+do_query(query, 'CREATE TABLE ptwrite ('
+ 'id integer NOT NULL PRIMARY KEY,'
+ 'payload bigint,'
+ 'exact_ip integer)')
+
+do_query(query, 'CREATE TABLE cbr ('
+ 'id integer NOT NULL PRIMARY KEY,'
+ 'cbr integer,'
+ 'mhz integer,'
+ 'percent integer)')
+
+do_query(query, 'CREATE TABLE mwait ('
+ 'id integer NOT NULL PRIMARY KEY,'
+ 'hints integer,'
+ 'extensions integer)')
+
+do_query(query, 'CREATE TABLE pwre ('
+ 'id integer NOT NULL PRIMARY KEY,'
+ 'cstate integer,'
+ 'subcstate integer,'
+ 'hw integer)')
+
+do_query(query, 'CREATE TABLE exstop ('
+ 'id integer NOT NULL PRIMARY KEY,'
+ 'exact_ip integer)')
+
+do_query(query, 'CREATE TABLE pwrx ('
+ 'id integer NOT NULL PRIMARY KEY,'
+ 'deepest_cstate integer,'
+ 'last_cstate integer,'
+ 'wake_reason integer)')
+
# printf was added to sqlite in version 3.8.3
sqlite_has_printf = False
try:
@@ -399,6 +431,102 @@ do_query(query, 'CREATE VIEW samples_view AS '
'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC'
' FROM samples')
+do_query(query, 'CREATE VIEW ptwrite_view AS '
+ 'SELECT '
+ 'ptwrite.id,'
+ 'time,'
+ 'cpu,'
+ + emit_to_hex('payload') + ' AS payload_hex,'
+ 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
+ ' FROM ptwrite'
+ ' INNER JOIN samples ON samples.id = ptwrite.id')
+
+do_query(query, 'CREATE VIEW cbr_view AS '
+ 'SELECT '
+ 'cbr.id,'
+ 'time,'
+ 'cpu,'
+ 'cbr,'
+ 'mhz,'
+ 'percent'
+ ' FROM cbr'
+ ' INNER JOIN samples ON samples.id = cbr.id')
+
+do_query(query, 'CREATE VIEW mwait_view AS '
+ 'SELECT '
+ 'mwait.id,'
+ 'time,'
+ 'cpu,'
+ + emit_to_hex('hints') + ' AS hints_hex,'
+ + emit_to_hex('extensions') + ' AS extensions_hex'
+ ' FROM mwait'
+ ' INNER JOIN samples ON samples.id = mwait.id')
+
+do_query(query, 'CREATE VIEW pwre_view AS '
+ 'SELECT '
+ 'pwre.id,'
+ 'time,'
+ 'cpu,'
+ 'cstate,'
+ 'subcstate,'
+ 'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw'
+ ' FROM pwre'
+ ' INNER JOIN samples ON samples.id = pwre.id')
+
+do_query(query, 'CREATE VIEW exstop_view AS '
+ 'SELECT '
+ 'exstop.id,'
+ 'time,'
+ 'cpu,'
+ 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
+ ' FROM exstop'
+ ' INNER JOIN samples ON samples.id = exstop.id')
+
+do_query(query, 'CREATE VIEW pwrx_view AS '
+ 'SELECT '
+ 'pwrx.id,'
+ 'time,'
+ 'cpu,'
+ 'deepest_cstate,'
+ 'last_cstate,'
+ 'CASE WHEN wake_reason=1 THEN \'Interrupt\''
+ ' WHEN wake_reason=2 THEN \'Timer Deadline\''
+ ' WHEN wake_reason=4 THEN \'Monitored Address\''
+ ' WHEN wake_reason=8 THEN \'HW\''
+ ' ELSE wake_reason '
+ 'END AS wake_reason'
+ ' FROM pwrx'
+ ' INNER JOIN samples ON samples.id = pwrx.id')
+
+do_query(query, 'CREATE VIEW power_events_view AS '
+ 'SELECT '
+ 'samples.id,'
+ 'time,'
+ 'cpu,'
+ 'selected_events.name AS event,'
+ 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,'
+ 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,'
+ 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,'
+ 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,'
+ 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,'
+ 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,'
+ 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,'
+ 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,'
+ 'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,'
+ 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,'
+ 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,'
+ 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT '
+ 'CASE WHEN wake_reason=1 THEN \'Interrupt\''
+ ' WHEN wake_reason=2 THEN \'Timer Deadline\''
+ ' WHEN wake_reason=4 THEN \'Monitored Address\''
+ ' WHEN wake_reason=8 THEN \'HW\''
+ ' ELSE wake_reason '
+ 'END'
+ ' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason'
+ ' FROM samples'
+ ' INNER JOIN selected_events ON selected_events.id = evsel_id'
+ ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')')
+
do_query(query, 'END TRANSACTION')
evsel_query = QSqlQuery(db)
@@ -428,6 +556,18 @@ if perf_db_export_calls or perf_db_export_callchains:
if perf_db_export_calls:
call_query = QSqlQuery(db)
call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ptwrite_query = QSqlQuery(db)
+ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)")
+cbr_query = QSqlQuery(db)
+cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)")
+mwait_query = QSqlQuery(db)
+mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)")
+pwre_query = QSqlQuery(db)
+pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)")
+exstop_query = QSqlQuery(db)
+exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)")
+pwrx_query = QSqlQuery(db)
+pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)")
def trace_begin():
printdate("Writing records...")
@@ -446,6 +586,16 @@ def trace_begin():
unhandled_count = 0
+def is_table_empty(table_name):
+ do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1');
+ if query.next():
+ return False
+ return True
+
+def drop(table_name):
+ do_query(query, 'DROP VIEW ' + table_name + '_view');
+ do_query(query, 'DROP TABLE ' + table_name);
+
def trace_end():
do_query(query, 'END TRANSACTION')
@@ -454,6 +604,18 @@ def trace_end():
do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
+ printdate("Dropping unused tables")
+ if is_table_empty("ptwrite"):
+ drop("ptwrite")
+ if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):
+ drop("mwait")
+ drop("pwre")
+ drop("exstop")
+ drop("pwrx")
+ do_query(query, 'DROP VIEW power_events_view');
+ if is_table_empty("cbr"):
+ drop("cbr")
+
if (unhandled_count):
printdate("Warning: ", unhandled_count, " unhandled events")
printdate("Done")
@@ -509,3 +671,80 @@ def call_path_table(*x):
def call_return_table(*x):
bind_exec(call_query, 14, x)
+
+def ptwrite(id, raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+ flags = data[0]
+ payload = data[1]
+ exact_ip = flags & 1
+ ptwrite_query.addBindValue(str(id))
+ ptwrite_query.addBindValue(str(payload))
+ ptwrite_query.addBindValue(str(exact_ip))
+ do_query_(ptwrite_query)
+
+def cbr(id, raw_buf):
+ data = struct.unpack_from("<BBBBII", raw_buf)
+ cbr = data[0]
+ MHz = (data[4] + 500) / 1000
+ percent = ((cbr * 1000 / data[2]) + 5) / 10
+ cbr_query.addBindValue(str(id))
+ cbr_query.addBindValue(str(cbr))
+ cbr_query.addBindValue(str(MHz))
+ cbr_query.addBindValue(str(percent))
+ do_query_(cbr_query)
+
+def mwait(id, raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+ payload = data[1]
+ hints = payload & 0xff
+ extensions = (payload >> 32) & 0x3
+ mwait_query.addBindValue(str(id))
+ mwait_query.addBindValue(str(hints))
+ mwait_query.addBindValue(str(extensions))
+ do_query_(mwait_query)
+
+def pwre(id, raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+ payload = data[1]
+ hw = (payload >> 7) & 1
+ cstate = (payload >> 12) & 0xf
+ subcstate = (payload >> 8) & 0xf
+ pwre_query.addBindValue(str(id))
+ pwre_query.addBindValue(str(cstate))
+ pwre_query.addBindValue(str(subcstate))
+ pwre_query.addBindValue(str(hw))
+ do_query_(pwre_query)
+
+def exstop(id, raw_buf):
+ data = struct.unpack_from("<I", raw_buf)
+ flags = data[0]
+ exact_ip = flags & 1
+ exstop_query.addBindValue(str(id))
+ exstop_query.addBindValue(str(exact_ip))
+ do_query_(exstop_query)
+
+def pwrx(id, raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+ payload = data[1]
+ deepest_cstate = payload & 0xf
+ last_cstate = (payload >> 4) & 0xf
+ wake_reason = (payload >> 8) & 0xf
+ pwrx_query.addBindValue(str(id))
+ pwrx_query.addBindValue(str(deepest_cstate))
+ pwrx_query.addBindValue(str(last_cstate))
+ pwrx_query.addBindValue(str(wake_reason))
+ do_query_(pwrx_query)
+
+def synth_data(id, config, raw_buf, *x):
+ if config == 0:
+ ptwrite(id, raw_buf)
+ elif config == 1:
+ mwait(id, raw_buf)
+ elif config == 2:
+ pwre(id, raw_buf)
+ elif config == 3:
+ exstop(id, raw_buf)
+ elif config == 4:
+ pwrx(id, raw_buf)
+ elif config == 5:
+ cbr(id, raw_buf)