summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/export-to-postgresql.py
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-03 17:38:09 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-03 17:38:09 -0800
commitb02ac6b18cd4e2c76bf0a102c20c429b973f5f76 (patch)
tree87b3648f448627d61cb9ba32511584d6318b7bb6 /tools/perf/scripts/python/export-to-postgresql.py
parent105ff3cbf225036b75a6a46c96d1ddce8e7bdc66 (diff)
parentbebd23a2ed31d47e7dd746d3b125068aa2c42d85 (diff)
downloadlwn-b02ac6b18cd4e2c76bf0a102c20c429b973f5f76.tar.gz
lwn-b02ac6b18cd4e2c76bf0a102c20c429b973f5f76.zip
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "Kernel side changes: - Improve accuracy of perf/sched clock on x86. (Adrian Hunter) - Intel DS and BTS updates. (Alexander Shishkin) - Intel cstate PMU support. (Kan Liang) - Add group read support to perf_event_read(). (Peter Zijlstra) - Branch call hardware sampling support, implemented on x86 and PowerPC. (Stephane Eranian) - Event groups transactional interface enhancements. (Sukadev Bhattiprolu) - Enable proper x86/intel/uncore PMU support on multi-segment PCI systems. (Taku Izumi) - ... misc fixes and cleanups. The perf tooling team was very busy again with 200+ commits, the full diff doesn't fit into lkml size limits. Here's an (incomplete) list of the tooling highlights: New features: - Change the default event used in all tools (record/top): use the most precise "cycles" hw counter available, i.e. when the user doesn't specify any event, it will try using cycles:ppp, cycles:pp, etc and fall back transparently until it finds a working counter. (Arnaldo Carvalho de Melo) - Integration of perf with eBPF that, given an eBPF .c source file (or .o file built for the 'bpf' target with clang), will get it automatically built, validated and loaded into the kernel via the sys_bpf syscall, which can then be used and seen using 'perf trace' and other tools. (Wang Nan) Various user interface improvements: - Automatic pager invocation on long help output. (Namhyung Kim) - Search for more options when passing args to -h, e.g.: (Arnaldo Carvalho de Melo) $ perf report -h interface Usage: perf report [<options>] --gtk Use the GTK2 interface --stdio Use the stdio interface --tui Use the TUI interface - Show ordered command line options when -h is used or when an unknown option is specified. (Arnaldo Carvalho de Melo) - If options are passed after -h, show just its descriptions, not all options. (Arnaldo Carvalho de Melo) - Implement column based horizontal scrolling in the hists browser (top, report), making it possible to use the TUI for things like 'perf mem report' where there are many more columns than can fit in a terminal. (Arnaldo Carvalho de Melo) - Enhance the error reporting of tracepoint event parsing, e.g.: $ oldperf record -e sched:sched_switc usleep 1 event syntax error: 'sched:sched_switc' \___ unknown tracepoint Run 'perf list' for a list of valid events Now we get the much nicer: $ perf record -e sched:sched_switc ls event syntax error: 'sched:sched_switc' \___ can't access trace events Error: No permissions to read /sys/kernel/debug/tracing/events/sched/sched_switc Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug' And after we have those mount point permissions fixed: $ perf record -e sched:sched_switc ls event syntax error: 'sched:sched_switc' \___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sched/sched_switc not found. Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?. I.e. basically now the event parsing routing uses the strerror_open() routines introduced by and used in 'perf trace' work. (Jiri Olsa) - Fail properly when pattern matching fails to find a tracepoint, i.e. '-e non:existent' was being correctly handled, with a proper error message about that not being a valid event, but '-e non:existent*' wasn't, fix it. (Jiri Olsa) - Do event name substring search as last resort in 'perf list'. (Arnaldo Carvalho de Melo) E.g.: # perf list clock List of pre-defined events (to be used in -e): cpu-clock [Software event] task-clock [Software event] uncore_cbox_0/clockticks/ [Kernel PMU event] uncore_cbox_1/clockticks/ [Kernel PMU event] kvm:kvm_pvclock_update [Tracepoint event] kvm:kvm_update_master_clock [Tracepoint event] power:clock_disable [Tracepoint event] power:clock_enable [Tracepoint event] power:clock_set_rate [Tracepoint event] syscalls:sys_enter_clock_adjtime [Tracepoint event] syscalls:sys_enter_clock_getres [Tracepoint event] syscalls:sys_enter_clock_gettime [Tracepoint event] syscalls:sys_enter_clock_nanosleep [Tracepoint event] syscalls:sys_enter_clock_settime [Tracepoint event] syscalls:sys_exit_clock_adjtime [Tracepoint event] syscalls:sys_exit_clock_getres [Tracepoint event] syscalls:sys_exit_clock_gettime [Tracepoint event] syscalls:sys_exit_clock_nanosleep [Tracepoint event] syscalls:sys_exit_clock_settime [Tracepoint event] Intel PT hardware tracing enhancements: - Accept a zero --itrace period, meaning "as often as possible". In the case of Intel PT that is the same as a period of 1 and a unit of 'instructions' (i.e. --itrace=i1i). (Adrian Hunter) - Harmonize itrace's synthesized callchains with the existing --max-stack tool option. (Adrian Hunter) - Allow time to be displayed in nanoseconds in 'perf script'. (Adrian Hunter) - Fix potential infinite loop when handling Intel PT timestamps. (Adrian Hunter) - Slighly improve Intel PT debug logging. (Adrian Hunter) - Warn when AUX data has been lost, just like when processing PERF_RECORD_LOST. (Adrian Hunter) - Further document export-to-postgresql.py script. (Adrian Hunter) - Add option to synthesize branch stack from auxtrace data. (Adrian Hunter) Misc notable changes: - Switch the default callchain output mode to 'graph,0.5,caller', to make it look like the default for other tools, reducing the learning curve for people used to 'caller' based viewing. (Arnaldo Carvalho de Melo) - various call chain usability enhancements. (Namhyung Kim) - Introduce the 'P' event modifier, meaning 'max precision level, please', i.e.: $ perf record -e cycles:P usleep 1 Is now similar to: $ perf record usleep 1 Useful, for instance, when specifying multiple events. (Jiri Olsa) - Add 'socket' sort entry, to sort by the processor socket in 'perf top' and 'perf report'. (Kan Liang) - Introduce --socket-filter to 'perf report', for filtering by processor socket. (Kan Liang) - Add new "Zoom into Processor Socket" operation in the perf hists browser, used in 'perf top' and 'perf report'. (Kan Liang) - Allow probing on kmodules without DWARF. (Masami Hiramatsu) - Fix 'perf probe -l' for probes added to kernel module functions. (Masami Hiramatsu) - Preparatory work for the 'perf stat record' feature that will allow generating perf.data files with counting data in addition to the sampling mode we have now (Jiri Olsa) - Update libtraceevent KVM plugin. (Paolo Bonzini) - ... plus lots of other enhancements that I failed to list properly, by: Adrian Hunter, Alexander Shishkin, Andi Kleen, Andrzej Hajda, Arnaldo Carvalho de Melo, Dima Kogan, Don Zickus, Geliang Tang, He Kuang, Huaitong Han, Ingo Molnar, Jan Stancek, Jiri Olsa, Kan Liang, Kirill Tkhai, Masami Hiramatsu, Matt Fleming, Namhyung Kim, Paolo Bonzini, Peter Zijlstra, Rabin Vincent, Scott Wood, Stephane Eranian, Sukadev Bhattiprolu, Taku Izumi, Vaishali Thakkar, Wang Nan, Yang Shi and Yunlong Song" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (260 commits) perf unwind: Pass symbol source to libunwind tools build: Fix libiberty feature detection perf tools: Compile scriptlets to BPF objects when passing '.c' to --event perf record: Add clang options for compiling BPF scripts perf bpf: Attach eBPF filter to perf event perf tools: Make sure fixdep is built before libbpf perf script: Enable printing of branch stack perf trace: Add cmd string table to decode sys_bpf first arg perf bpf: Collect perf_evsel in BPF object files perf tools: Load eBPF object into kernel perf tools: Create probe points for BPF programs perf tools: Enable passing bpf object file to --event perf ebpf: Add the libbpf glue perf tools: Make perf depend on libbpf perf symbols: Fix endless loop in dso__split_kallsyms_for_kcore perf tools: Enable pre-event inherit setting by config terms perf symbols: we can now read separate debug-info files based on a build ID perf symbols: Fix type error when reading a build-id perf tools: Search for more options when passing args to -h perf stat: Cache aggregated map entries in extra cpumap ...
Diffstat (limited to 'tools/perf/scripts/python/export-to-postgresql.py')
-rw-r--r--tools/perf/scripts/python/export-to-postgresql.py221
1 files changed, 221 insertions, 0 deletions
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py
index 84a32037a80f..1b02cdc0cab6 100644
--- a/tools/perf/scripts/python/export-to-postgresql.py
+++ b/tools/perf/scripts/python/export-to-postgresql.py
@@ -61,6 +61,142 @@ import datetime
#
# An example of using the database is provided by the script
# call-graph-from-postgresql.py. Refer to that script for details.
+#
+# Tables:
+#
+# The tables largely correspond to perf tools' data structures. They are largely self-explanatory.
+#
+# samples
+#
+# 'samples' is the main table. It represents what instruction was executing at a point in time
+# when something (a selected event) happened. The memory address is the instruction pointer or 'ip'.
+#
+# calls
+#
+# 'calls' represents function calls and is related to 'samples' by 'call_id' and 'return_id'.
+# 'calls' is only created when the 'calls' option to this script is specified.
+#
+# call_paths
+#
+# 'call_paths' represents all the call stacks. Each 'call' has an associated record in 'call_paths'.
+# 'calls_paths' is only created when the 'calls' option to this script is specified.
+#
+# branch_types
+#
+# 'branch_types' provides descriptions for each type of branch.
+#
+# comm_threads
+#
+# 'comm_threads' shows how 'comms' relates to 'threads'.
+#
+# comms
+#
+# 'comms' contains a record for each 'comm' - the name given to the executable that is running.
+#
+# dsos
+#
+# 'dsos' contains a record for each executable file or library.
+#
+# machines
+#
+# 'machines' can be used to distinguish virtual machines if virtualization is supported.
+#
+# selected_events
+#
+# 'selected_events' contains a record for each kind of event that has been sampled.
+#
+# symbols
+#
+# 'symbols' contains a record for each symbol. Only symbols that have samples are present.
+#
+# threads
+#
+# 'threads' contains a record for each thread.
+#
+# Views:
+#
+# Most of the tables have views for more friendly display. The views are:
+#
+# calls_view
+# call_paths_view
+# comm_threads_view
+# dsos_view
+# machines_view
+# samples_view
+# symbols_view
+# threads_view
+#
+# More examples of browsing the database with psql:
+# Note that some of the examples are not the most optimal SQL query.
+# Note that call information is only available if the script's 'calls' option has been used.
+#
+# Top 10 function calls (not aggregated by symbol):
+#
+# SELECT * FROM calls_view ORDER BY elapsed_time DESC LIMIT 10;
+#
+# Top 10 function calls (aggregated by symbol):
+#
+# SELECT symbol_id,(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
+# SUM(elapsed_time) AS tot_elapsed_time,SUM(branch_count) AS tot_branch_count
+# FROM calls_view GROUP BY symbol_id ORDER BY tot_elapsed_time DESC LIMIT 10;
+#
+# Note that the branch count gives a rough estimation of cpu usage, so functions
+# that took a long time but have a relatively low branch count must have spent time
+# waiting.
+#
+# Find symbols by pattern matching on part of the name (e.g. names containing 'alloc'):
+#
+# SELECT * FROM symbols_view WHERE name LIKE '%alloc%';
+#
+# Top 10 function calls for a specific symbol (e.g. whose symbol_id is 187):
+#
+# SELECT * FROM calls_view WHERE symbol_id = 187 ORDER BY elapsed_time DESC LIMIT 10;
+#
+# Show function calls made by function in the same context (i.e. same call path) (e.g. one with call_path_id 254):
+#
+# SELECT * FROM calls_view WHERE parent_call_path_id = 254;
+#
+# Show branches made during a function call (e.g. where call_id is 29357 and return_id is 29370 and tid is 29670)
+#
+# SELECT * FROM samples_view WHERE id >= 29357 AND id <= 29370 AND tid = 29670 AND event LIKE 'branches%';
+#
+# Show transactions:
+#
+# SELECT * FROM samples_view WHERE event = 'transactions';
+#
+# Note transaction start has 'in_tx' true whereas, transaction end has 'in_tx' false.
+# Transaction aborts have branch_type_name 'transaction abort'
+#
+# Show transaction aborts:
+#
+# SELECT * FROM samples_view WHERE event = 'transactions' AND branch_type_name = 'transaction abort';
+#
+# To print a call stack requires walking the call_paths table. For example this python script:
+# #!/usr/bin/python2
+#
+# import sys
+# from PySide.QtSql import *
+#
+# if __name__ == '__main__':
+# if (len(sys.argv) < 3):
+# print >> sys.stderr, "Usage is: printcallstack.py <database name> <call_path_id>"
+# raise Exception("Too few arguments")
+# dbname = sys.argv[1]
+# call_path_id = sys.argv[2]
+# db = QSqlDatabase.addDatabase('QPSQL')
+# db.setDatabaseName(dbname)
+# if not db.open():
+# raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())
+# query = QSqlQuery(db)
+# print " id ip symbol_id symbol dso_id dso_short_name"
+# while call_path_id != 0 and call_path_id != 1:
+# ret = query.exec_('SELECT * FROM call_paths_view WHERE id = ' + str(call_path_id))
+# if not ret:
+# raise Exception("Query failed: " + query.lastError().text())
+# if not query.next():
+# raise Exception("Query failed")
+# print "{0:>6} {1:>10} {2:>9} {3:<30} {4:>6} {5:<30}".format(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4), query.value(5))
+# call_path_id = query.value(6)
from PySide.QtSql import *
@@ -244,6 +380,91 @@ if perf_db_export_calls:
'parent_call_path_id bigint,'
'flags integer)')
+do_query(query, 'CREATE VIEW machines_view AS '
+ 'SELECT '
+ 'id,'
+ 'pid,'
+ 'root_dir,'
+ 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'
+ ' FROM machines')
+
+do_query(query, 'CREATE VIEW dsos_view AS '
+ 'SELECT '
+ 'id,'
+ 'machine_id,'
+ '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
+ 'short_name,'
+ 'long_name,'
+ 'build_id'
+ ' FROM dsos')
+
+do_query(query, 'CREATE VIEW symbols_view AS '
+ 'SELECT '
+ 'id,'
+ 'name,'
+ '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'
+ 'dso_id,'
+ 'sym_start,'
+ 'sym_end,'
+ 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'
+ ' FROM symbols')
+
+do_query(query, 'CREATE VIEW threads_view AS '
+ 'SELECT '
+ 'id,'
+ 'machine_id,'
+ '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
+ 'process_id,'
+ 'pid,'
+ 'tid'
+ ' FROM threads')
+
+do_query(query, 'CREATE VIEW comm_threads_view AS '
+ 'SELECT '
+ 'comm_id,'
+ '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
+ 'thread_id,'
+ '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
+ '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
+ ' FROM comm_threads')
+
+if perf_db_export_calls:
+ do_query(query, 'CREATE VIEW call_paths_view AS '
+ 'SELECT '
+ 'c.id,'
+ 'to_hex(c.ip) AS ip,'
+ 'c.symbol_id,'
+ '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'
+ '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'
+ '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,'
+ 'c.parent_id,'
+ 'to_hex(p.ip) AS parent_ip,'
+ 'p.symbol_id AS parent_symbol_id,'
+ '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'
+ '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
+ '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name'
+ ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
+ do_query(query, 'CREATE VIEW calls_view AS '
+ 'SELECT '
+ 'calls.id,'
+ 'thread_id,'
+ '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
+ '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
+ '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
+ 'call_path_id,'
+ 'to_hex(ip) AS ip,'
+ 'symbol_id,'
+ '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
+ 'call_time,'
+ 'return_time,'
+ 'return_time - call_time AS elapsed_time,'
+ 'branch_count,'
+ 'call_id,'
+ 'return_id,'
+ 'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,'
+ 'parent_call_path_id'
+ ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')
+
do_query(query, 'CREATE VIEW samples_view AS '
'SELECT '
'id,'