aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-01-09 11:17:33 -0500
committerIngo Molnar <mingo@kernel.org>2016-01-09 11:17:33 -0500
commit3eb9ede23bdd96e9ba60e2b4d4d17a7c35d58448 (patch)
tree2bed2ab8e7fa6e6202154992433bb24ecdb9a24d /tools/perf/util/scripting-engines/trace-event-python.c
parent9cc2617de5b9222abb39cd02e90d57dfea99c6d7 (diff)
parent775d8a1b0d75211cc6123915c6b5b688f2002478 (diff)
Merge tag 'perf-core-for-mingo' 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: New features: - Allow using trace events fields as sort order keys, making 'perf evlist --trace_fields' show those, and then the user can select a subset and use like: perf top -e sched:sched_switch -s prev_comm,next_comm That works as well in 'perf report' when handling files containing tracepoints. The default when just tracepoint events are found in a perf.data file is to format it like ftrace, using the libtraceevent formatters, plugins, etc (Namhyung Kim) - Add support in 'perf script' to process 'perf stat record' generated files, culminating in a python perf script that calculates CPI (Cycles per Instruction) (Jiri Olsa) - Show random perf tool tips in the 'perf report' bottom line (Namhyung Kim) - perf report now defaults to --group if the perf.data file has grouped events, try it with: # perf record -e '{cycles,instructions}' -a sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 1.093 MB perf.data (1247 samples) ] # perf report # Samples: 1K of event 'anon group { cycles, instructions }' # Event count (approx.): 1955219195 # # Overhead Command Shared Object Symbol 2.86% 0.22% swapper [kernel.kallsyms] [k] intel_idle 1.05% 0.33% firefox libxul.so [.] js::SetObjectElement 1.05% 0.00% kworker/0:3 [kernel.kallsyms] [k] gen6_ring_get_seqno 0.88% 0.17% chrome chrome [.] 0x0000000000ee27ab 0.65% 0.86% firefox libxul.so [.] js::ValueToId<(js::AllowGC)1> 0.64% 0.23% JS Helper libxul.so [.] js::SplayTree<js::jit::LiveRange*, js::jit::LiveRange>::splay 0.62% 1.27% firefox libxul.so [.] js::GetIterator 0.61% 1.74% firefox libxul.so [.] js::NativeSetProperty 0.61% 0.31% firefox libxul.so [.] js::SetPropertyByDefining User visible fixes: - Coect data mmaps so that the DWARF unwinder can handle usecases needing them, like softice (Jiri Olsa) - Decay callchains in fractal mode, fixing up cases where 'perf top -g' would show entries with more than 100% (Namhyung Kim) Infrastructure changes: - Sync tools/lib with the lib/ in the kernel sources for find_bit.c and move bitmap.[ch] from tools/perf/util/ to tools/lib/ (Arnaldo Carvalho de Melo) - No need to set attr.sample_freq in some 'perf test' entries that only want to deal with PERF_RECORD_ meta-events, improve a bit error output for CQM test (Arnaldo Carvalho de Melo) - Fix python binding build, adding some missing object files now required due to cpumap using find_bit stuff (Arnaldo Carvalho de Melo) - tools/build improvemnts (Jiri Olsa) - Add more files to cscope/ctags databases (Jiri Olsa) - Do not show 'trace' in 'perf help' if it is not compiled in (Jiri Olsa) - Make perf_evlist__open() open evsels with their cpus and threads, like perf record does, making them consistent (Adrian Hunter) - Fix pmu snapshot initialization bug (Stephane Eranian) - Add missing headers in perf's MANIFEST (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c115
1 files changed, 109 insertions, 6 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index a8e825fca42a..d72fafc1c800 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -41,6 +41,9 @@
41#include "../thread-stack.h" 41#include "../thread-stack.h"
42#include "../trace-event.h" 42#include "../trace-event.h"
43#include "../machine.h" 43#include "../machine.h"
44#include "thread_map.h"
45#include "cpumap.h"
46#include "stat.h"
44 47
45PyMODINIT_FUNC initperf_trace_context(void); 48PyMODINIT_FUNC initperf_trace_context(void);
46 49
@@ -859,6 +862,104 @@ static void python_process_event(union perf_event *event,
859 } 862 }
860} 863}
861 864
865static void get_handler_name(char *str, size_t size,
866 struct perf_evsel *evsel)
867{
868 char *p = str;
869
870 scnprintf(str, size, "stat__%s", perf_evsel__name(evsel));
871
872 while ((p = strchr(p, ':'))) {
873 *p = '_';
874 p++;
875 }
876}
877
878static void
879process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp,
880 struct perf_counts_values *count)
881{
882 PyObject *handler, *t;
883 static char handler_name[256];
884 int n = 0;
885
886 t = PyTuple_New(MAX_FIELDS);
887 if (!t)
888 Py_FatalError("couldn't create Python tuple");
889
890 get_handler_name(handler_name, sizeof(handler_name),
891 counter);
892
893 handler = get_handler(handler_name);
894 if (!handler) {
895 pr_debug("can't find python handler %s\n", handler_name);
896 return;
897 }
898
899 PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
900 PyTuple_SetItem(t, n++, PyInt_FromLong(thread));
901
902 tuple_set_u64(t, n++, tstamp);
903 tuple_set_u64(t, n++, count->val);
904 tuple_set_u64(t, n++, count->ena);
905 tuple_set_u64(t, n++, count->run);
906
907 if (_PyTuple_Resize(&t, n) == -1)
908 Py_FatalError("error resizing Python tuple");
909
910 call_object(handler, t, handler_name);
911
912 Py_DECREF(t);
913}
914
915static void python_process_stat(struct perf_stat_config *config,
916 struct perf_evsel *counter, u64 tstamp)
917{
918 struct thread_map *threads = counter->threads;
919 struct cpu_map *cpus = counter->cpus;
920 int cpu, thread;
921
922 if (config->aggr_mode == AGGR_GLOBAL) {
923 process_stat(counter, -1, -1, tstamp,
924 &counter->counts->aggr);
925 return;
926 }
927
928 for (thread = 0; thread < threads->nr; thread++) {
929 for (cpu = 0; cpu < cpus->nr; cpu++) {
930 process_stat(counter, cpus->map[cpu],
931 thread_map__pid(threads, thread), tstamp,
932 perf_counts(counter->counts, cpu, thread));
933 }
934 }
935}
936
937static void python_process_stat_interval(u64 tstamp)
938{
939 PyObject *handler, *t;
940 static const char handler_name[] = "stat__interval";
941 int n = 0;
942
943 t = PyTuple_New(MAX_FIELDS);
944 if (!t)
945 Py_FatalError("couldn't create Python tuple");
946
947 handler = get_handler(handler_name);
948 if (!handler) {
949 pr_debug("can't find python handler %s\n", handler_name);
950 return;
951 }
952
953 tuple_set_u64(t, n++, tstamp);
954
955 if (_PyTuple_Resize(&t, n) == -1)
956 Py_FatalError("error resizing Python tuple");
957
958 call_object(handler, t, handler_name);
959
960 Py_DECREF(t);
961}
962
862static int run_start_sub(void) 963static int run_start_sub(void)
863{ 964{
864 main_module = PyImport_AddModule("__main__"); 965 main_module = PyImport_AddModule("__main__");
@@ -1201,10 +1302,12 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
1201} 1302}
1202 1303
1203struct scripting_ops python_scripting_ops = { 1304struct scripting_ops python_scripting_ops = {
1204 .name = "Python", 1305 .name = "Python",
1205 .start_script = python_start_script, 1306 .start_script = python_start_script,
1206 .flush_script = python_flush_script, 1307 .flush_script = python_flush_script,
1207 .stop_script = python_stop_script, 1308 .stop_script = python_stop_script,
1208 .process_event = python_process_event, 1309 .process_event = python_process_event,
1209 .generate_script = python_generate_script, 1310 .process_stat = python_process_stat,
1311 .process_stat_interval = python_process_stat_interval,
1312 .generate_script = python_generate_script,
1210}; 1313};