aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-11-07 00:21:46 -0500
committerIngo Molnar <mingo@kernel.org>2014-11-07 00:21:46 -0500
commit322cd21fc196575d922e5e8bd8d5730a91c2b73d (patch)
tree9bfe532ec54a13c0f2290b0e5c0fedf1246038c0 /tools/perf/util/scripting-engines/trace-event-python.c
parent05b2537e8dc778bb00284f8fc86b83797b8f1d37 (diff)
parentdaa01794a4a36a1da1b09a529adec0c8c0b94ab2 (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: Infrastructure changes: - Add gzip decompression support for kernel modules (Namhyung Kim) - More prep patches for Intel PT, including a a thread stack and more stuff made available via the database export mechanism (Adrian Hunter) - Optimize checking that tracepoint events are defined in perf script perl/python (Jiri Olsa) - Do not free pevent when deleting tracepoint evsel (Jiri Olsa) - Fix build-id matching for vmlinux (Namhyung Kim) 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.c152
1 files changed, 121 insertions, 31 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 2fd7ee8f18c7..d808a328f4dc 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -26,6 +26,7 @@
26#include <string.h> 26#include <string.h>
27#include <stdbool.h> 27#include <stdbool.h>
28#include <errno.h> 28#include <errno.h>
29#include <linux/bitmap.h>
29 30
30#include "../../perf.h" 31#include "../../perf.h"
31#include "../debug.h" 32#include "../debug.h"
@@ -37,6 +38,7 @@
37#include "../comm.h" 38#include "../comm.h"
38#include "../machine.h" 39#include "../machine.h"
39#include "../db-export.h" 40#include "../db-export.h"
41#include "../thread-stack.h"
40#include "../trace-event.h" 42#include "../trace-event.h"
41#include "../machine.h" 43#include "../machine.h"
42 44
@@ -45,7 +47,7 @@ PyMODINIT_FUNC initperf_trace_context(void);
45#define FTRACE_MAX_EVENT \ 47#define FTRACE_MAX_EVENT \
46 ((1 << (sizeof(unsigned short) * 8)) - 1) 48 ((1 << (sizeof(unsigned short) * 8)) - 1)
47 49
48struct event_format *events[FTRACE_MAX_EVENT]; 50static DECLARE_BITMAP(events_defined, FTRACE_MAX_EVENT);
49 51
50#define MAX_FIELDS 64 52#define MAX_FIELDS 64
51#define N_COMMON_FIELDS 7 53#define N_COMMON_FIELDS 7
@@ -66,7 +68,10 @@ struct tables {
66 PyObject *comm_thread_handler; 68 PyObject *comm_thread_handler;
67 PyObject *dso_handler; 69 PyObject *dso_handler;
68 PyObject *symbol_handler; 70 PyObject *symbol_handler;
71 PyObject *branch_type_handler;
69 PyObject *sample_handler; 72 PyObject *sample_handler;
73 PyObject *call_path_handler;
74 PyObject *call_return_handler;
70 bool db_export_mode; 75 bool db_export_mode;
71}; 76};
72 77
@@ -251,31 +256,6 @@ static void define_event_symbols(struct event_format *event,
251 define_event_symbols(event, ev_name, args->next); 256 define_event_symbols(event, ev_name, args->next);
252} 257}
253 258
254static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
255{
256 static char ev_name[256];
257 struct event_format *event;
258 int type = evsel->attr.config;
259
260 /*
261 * XXX: Do we really need to cache this since now we have evsel->tp_format
262 * cached already? Need to re-read this "cache" routine that as well calls
263 * define_event_symbols() :-\
264 */
265 if (events[type])
266 return events[type];
267
268 events[type] = event = evsel->tp_format;
269 if (!event)
270 return NULL;
271
272 sprintf(ev_name, "%s__%s", event->system, event->name);
273
274 define_event_symbols(event, ev_name, event->print_fmt.args);
275
276 return event;
277}
278
279static PyObject *get_field_numeric_entry(struct event_format *event, 259static PyObject *get_field_numeric_entry(struct event_format *event,
280 struct format_field *field, void *data) 260 struct format_field *field, void *data)
281{ 261{
@@ -399,12 +379,12 @@ static void python_process_tracepoint(struct perf_sample *sample,
399 struct thread *thread, 379 struct thread *thread,
400 struct addr_location *al) 380 struct addr_location *al)
401{ 381{
382 struct event_format *event = evsel->tp_format;
402 PyObject *handler, *context, *t, *obj, *callchain; 383 PyObject *handler, *context, *t, *obj, *callchain;
403 PyObject *dict = NULL; 384 PyObject *dict = NULL;
404 static char handler_name[256]; 385 static char handler_name[256];
405 struct format_field *field; 386 struct format_field *field;
406 unsigned long s, ns; 387 unsigned long s, ns;
407 struct event_format *event;
408 unsigned n = 0; 388 unsigned n = 0;
409 int pid; 389 int pid;
410 int cpu = sample->cpu; 390 int cpu = sample->cpu;
@@ -416,7 +396,6 @@ static void python_process_tracepoint(struct perf_sample *sample,
416 if (!t) 396 if (!t)
417 Py_FatalError("couldn't create Python tuple"); 397 Py_FatalError("couldn't create Python tuple");
418 398
419 event = find_cache_event(evsel);
420 if (!event) 399 if (!event)
421 die("ug! no event found for type %d", (int)evsel->attr.config); 400 die("ug! no event found for type %d", (int)evsel->attr.config);
422 401
@@ -424,6 +403,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
424 403
425 sprintf(handler_name, "%s__%s", event->system, event->name); 404 sprintf(handler_name, "%s__%s", event->system, event->name);
426 405
406 if (!test_and_set_bit(event->id, events_defined))
407 define_event_symbols(event, handler_name, event->print_fmt.args);
408
427 handler = get_handler(handler_name); 409 handler = get_handler(handler_name);
428 if (!handler) { 410 if (!handler) {
429 dict = PyDict_New(); 411 dict = PyDict_New();
@@ -664,13 +646,31 @@ static int python_export_symbol(struct db_export *dbe, struct symbol *sym,
664 return 0; 646 return 0;
665} 647}
666 648
649static int python_export_branch_type(struct db_export *dbe, u32 branch_type,
650 const char *name)
651{
652 struct tables *tables = container_of(dbe, struct tables, dbe);
653 PyObject *t;
654
655 t = tuple_new(2);
656
657 tuple_set_s32(t, 0, branch_type);
658 tuple_set_string(t, 1, name);
659
660 call_object(tables->branch_type_handler, t, "branch_type_table");
661
662 Py_DECREF(t);
663
664 return 0;
665}
666
667static int python_export_sample(struct db_export *dbe, 667static int python_export_sample(struct db_export *dbe,
668 struct export_sample *es) 668 struct export_sample *es)
669{ 669{
670 struct tables *tables = container_of(dbe, struct tables, dbe); 670 struct tables *tables = container_of(dbe, struct tables, dbe);
671 PyObject *t; 671 PyObject *t;
672 672
673 t = tuple_new(19); 673 t = tuple_new(21);
674 674
675 tuple_set_u64(t, 0, es->db_id); 675 tuple_set_u64(t, 0, es->db_id);
676 tuple_set_u64(t, 1, es->evsel->db_id); 676 tuple_set_u64(t, 1, es->evsel->db_id);
@@ -691,6 +691,8 @@ static int python_export_sample(struct db_export *dbe,
691 tuple_set_u64(t, 16, es->sample->weight); 691 tuple_set_u64(t, 16, es->sample->weight);
692 tuple_set_u64(t, 17, es->sample->transaction); 692 tuple_set_u64(t, 17, es->sample->transaction);
693 tuple_set_u64(t, 18, es->sample->data_src); 693 tuple_set_u64(t, 18, es->sample->data_src);
694 tuple_set_s32(t, 19, es->sample->flags & PERF_BRANCH_MASK);
695 tuple_set_s32(t, 20, !!(es->sample->flags & PERF_IP_FLAG_IN_TX));
694 696
695 call_object(tables->sample_handler, t, "sample_table"); 697 call_object(tables->sample_handler, t, "sample_table");
696 698
@@ -699,6 +701,64 @@ static int python_export_sample(struct db_export *dbe,
699 return 0; 701 return 0;
700} 702}
701 703
704static int python_export_call_path(struct db_export *dbe, struct call_path *cp)
705{
706 struct tables *tables = container_of(dbe, struct tables, dbe);
707 PyObject *t;
708 u64 parent_db_id, sym_db_id;
709
710 parent_db_id = cp->parent ? cp->parent->db_id : 0;
711 sym_db_id = cp->sym ? *(u64 *)symbol__priv(cp->sym) : 0;
712
713 t = tuple_new(4);
714
715 tuple_set_u64(t, 0, cp->db_id);
716 tuple_set_u64(t, 1, parent_db_id);
717 tuple_set_u64(t, 2, sym_db_id);
718 tuple_set_u64(t, 3, cp->ip);
719
720 call_object(tables->call_path_handler, t, "call_path_table");
721
722 Py_DECREF(t);
723
724 return 0;
725}
726
727static int python_export_call_return(struct db_export *dbe,
728 struct call_return *cr)
729{
730 struct tables *tables = container_of(dbe, struct tables, dbe);
731 u64 comm_db_id = cr->comm ? cr->comm->db_id : 0;
732 PyObject *t;
733
734 t = tuple_new(11);
735
736 tuple_set_u64(t, 0, cr->db_id);
737 tuple_set_u64(t, 1, cr->thread->db_id);
738 tuple_set_u64(t, 2, comm_db_id);
739 tuple_set_u64(t, 3, cr->cp->db_id);
740 tuple_set_u64(t, 4, cr->call_time);
741 tuple_set_u64(t, 5, cr->return_time);
742 tuple_set_u64(t, 6, cr->branch_count);
743 tuple_set_u64(t, 7, cr->call_ref);
744 tuple_set_u64(t, 8, cr->return_ref);
745 tuple_set_u64(t, 9, cr->cp->parent->db_id);
746 tuple_set_s32(t, 10, cr->flags);
747
748 call_object(tables->call_return_handler, t, "call_return_table");
749
750 Py_DECREF(t);
751
752 return 0;
753}
754
755static int python_process_call_return(struct call_return *cr, void *data)
756{
757 struct db_export *dbe = data;
758
759 return db_export__call_return(dbe, cr);
760}
761
702static void python_process_general_event(struct perf_sample *sample, 762static void python_process_general_event(struct perf_sample *sample,
703 struct perf_evsel *evsel, 763 struct perf_evsel *evsel,
704 struct thread *thread, 764 struct thread *thread,
@@ -831,7 +891,9 @@ error:
831static void set_table_handlers(struct tables *tables) 891static void set_table_handlers(struct tables *tables)
832{ 892{
833 const char *perf_db_export_mode = "perf_db_export_mode"; 893 const char *perf_db_export_mode = "perf_db_export_mode";
834 PyObject *db_export_mode; 894 const char *perf_db_export_calls = "perf_db_export_calls";
895 PyObject *db_export_mode, *db_export_calls;
896 bool export_calls = false;
835 int ret; 897 int ret;
836 898
837 memset(tables, 0, sizeof(struct tables)); 899 memset(tables, 0, sizeof(struct tables));
@@ -848,6 +910,23 @@ static void set_table_handlers(struct tables *tables)
848 if (!ret) 910 if (!ret)
849 return; 911 return;
850 912
913 tables->dbe.crp = NULL;
914 db_export_calls = PyDict_GetItemString(main_dict, perf_db_export_calls);
915 if (db_export_calls) {
916 ret = PyObject_IsTrue(db_export_calls);
917 if (ret == -1)
918 handler_call_die(perf_db_export_calls);
919 export_calls = !!ret;
920 }
921
922 if (export_calls) {
923 tables->dbe.crp =
924 call_return_processor__new(python_process_call_return,
925 &tables->dbe);
926 if (!tables->dbe.crp)
927 Py_FatalError("failed to create calls processor");
928 }
929
851 tables->db_export_mode = true; 930 tables->db_export_mode = true;
852 /* 931 /*
853 * Reserve per symbol space for symbol->db_id via symbol__priv() 932 * Reserve per symbol space for symbol->db_id via symbol__priv()
@@ -861,7 +940,10 @@ static void set_table_handlers(struct tables *tables)
861 SET_TABLE_HANDLER(comm_thread); 940 SET_TABLE_HANDLER(comm_thread);
862 SET_TABLE_HANDLER(dso); 941 SET_TABLE_HANDLER(dso);
863 SET_TABLE_HANDLER(symbol); 942 SET_TABLE_HANDLER(symbol);
943 SET_TABLE_HANDLER(branch_type);
864 SET_TABLE_HANDLER(sample); 944 SET_TABLE_HANDLER(sample);
945 SET_TABLE_HANDLER(call_path);
946 SET_TABLE_HANDLER(call_return);
865} 947}
866 948
867/* 949/*
@@ -910,6 +992,12 @@ static int python_start_script(const char *script, int argc, const char **argv)
910 992
911 set_table_handlers(tables); 993 set_table_handlers(tables);
912 994
995 if (tables->db_export_mode) {
996 err = db_export__branch_types(&tables->dbe);
997 if (err)
998 goto error;
999 }
1000
913 return err; 1001 return err;
914error: 1002error:
915 Py_Finalize(); 1003 Py_Finalize();
@@ -920,7 +1008,9 @@ error:
920 1008
921static int python_flush_script(void) 1009static int python_flush_script(void)
922{ 1010{
923 return 0; 1011 struct tables *tables = &tables_global;
1012
1013 return db_export__flush(&tables->dbe);
924} 1014}
925 1015
926/* 1016/*