aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c440
1 files changed, 406 insertions, 34 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 496f21cadd97..d808a328f4dc 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -24,7 +24,9 @@
24#include <stdio.h> 24#include <stdio.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h> 26#include <string.h>
27#include <stdbool.h>
27#include <errno.h> 28#include <errno.h>
29#include <linux/bitmap.h>
28 30
29#include "../../perf.h" 31#include "../../perf.h"
30#include "../debug.h" 32#include "../debug.h"
@@ -33,6 +35,10 @@
33#include "../util.h" 35#include "../util.h"
34#include "../event.h" 36#include "../event.h"
35#include "../thread.h" 37#include "../thread.h"
38#include "../comm.h"
39#include "../machine.h"
40#include "../db-export.h"
41#include "../thread-stack.h"
36#include "../trace-event.h" 42#include "../trace-event.h"
37#include "../machine.h" 43#include "../machine.h"
38 44
@@ -41,7 +47,7 @@ PyMODINIT_FUNC initperf_trace_context(void);
41#define FTRACE_MAX_EVENT \ 47#define FTRACE_MAX_EVENT \
42 ((1 << (sizeof(unsigned short) * 8)) - 1) 48 ((1 << (sizeof(unsigned short) * 8)) - 1)
43 49
44struct event_format *events[FTRACE_MAX_EVENT]; 50static DECLARE_BITMAP(events_defined, FTRACE_MAX_EVENT);
45 51
46#define MAX_FIELDS 64 52#define MAX_FIELDS 64
47#define N_COMMON_FIELDS 7 53#define N_COMMON_FIELDS 7
@@ -53,6 +59,24 @@ static int zero_flag_atom;
53 59
54static PyObject *main_module, *main_dict; 60static PyObject *main_module, *main_dict;
55 61
62struct tables {
63 struct db_export dbe;
64 PyObject *evsel_handler;
65 PyObject *machine_handler;
66 PyObject *thread_handler;
67 PyObject *comm_handler;
68 PyObject *comm_thread_handler;
69 PyObject *dso_handler;
70 PyObject *symbol_handler;
71 PyObject *branch_type_handler;
72 PyObject *sample_handler;
73 PyObject *call_path_handler;
74 PyObject *call_return_handler;
75 bool db_export_mode;
76};
77
78static struct tables tables_global;
79
56static void handler_call_die(const char *handler_name) NORETURN; 80static void handler_call_die(const char *handler_name) NORETURN;
57static void handler_call_die(const char *handler_name) 81static void handler_call_die(const char *handler_name)
58{ 82{
@@ -232,31 +256,6 @@ static void define_event_symbols(struct event_format *event,
232 define_event_symbols(event, ev_name, args->next); 256 define_event_symbols(event, ev_name, args->next);
233} 257}
234 258
235static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
236{
237 static char ev_name[256];
238 struct event_format *event;
239 int type = evsel->attr.config;
240
241 /*
242 * XXX: Do we really need to cache this since now we have evsel->tp_format
243 * cached already? Need to re-read this "cache" routine that as well calls
244 * define_event_symbols() :-\
245 */
246 if (events[type])
247 return events[type];
248
249 events[type] = event = evsel->tp_format;
250 if (!event)
251 return NULL;
252
253 sprintf(ev_name, "%s__%s", event->system, event->name);
254
255 define_event_symbols(event, ev_name, event->print_fmt.args);
256
257 return event;
258}
259
260static PyObject *get_field_numeric_entry(struct event_format *event, 259static PyObject *get_field_numeric_entry(struct event_format *event,
261 struct format_field *field, void *data) 260 struct format_field *field, void *data)
262{ 261{
@@ -312,9 +311,9 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
312 if (!symbol_conf.use_callchain || !sample->callchain) 311 if (!symbol_conf.use_callchain || !sample->callchain)
313 goto exit; 312 goto exit;
314 313
315 if (machine__resolve_callchain(al->machine, evsel, al->thread, 314 if (thread__resolve_callchain(al->thread, evsel,
316 sample, NULL, NULL, 315 sample, NULL, NULL,
317 PERF_MAX_STACK_DEPTH) != 0) { 316 PERF_MAX_STACK_DEPTH) != 0) {
318 pr_err("Failed to resolve callchain. Skipping\n"); 317 pr_err("Failed to resolve callchain. Skipping\n");
319 goto exit; 318 goto exit;
320 } 319 }
@@ -380,12 +379,12 @@ static void python_process_tracepoint(struct perf_sample *sample,
380 struct thread *thread, 379 struct thread *thread,
381 struct addr_location *al) 380 struct addr_location *al)
382{ 381{
382 struct event_format *event = evsel->tp_format;
383 PyObject *handler, *context, *t, *obj, *callchain; 383 PyObject *handler, *context, *t, *obj, *callchain;
384 PyObject *dict = NULL; 384 PyObject *dict = NULL;
385 static char handler_name[256]; 385 static char handler_name[256];
386 struct format_field *field; 386 struct format_field *field;
387 unsigned long s, ns; 387 unsigned long s, ns;
388 struct event_format *event;
389 unsigned n = 0; 388 unsigned n = 0;
390 int pid; 389 int pid;
391 int cpu = sample->cpu; 390 int cpu = sample->cpu;
@@ -397,7 +396,6 @@ static void python_process_tracepoint(struct perf_sample *sample,
397 if (!t) 396 if (!t)
398 Py_FatalError("couldn't create Python tuple"); 397 Py_FatalError("couldn't create Python tuple");
399 398
400 event = find_cache_event(evsel);
401 if (!event) 399 if (!event)
402 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);
403 401
@@ -405,6 +403,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
405 403
406 sprintf(handler_name, "%s__%s", event->system, event->name); 404 sprintf(handler_name, "%s__%s", event->system, event->name);
407 405
406 if (!test_and_set_bit(event->id, events_defined))
407 define_event_symbols(event, handler_name, event->print_fmt.args);
408
408 handler = get_handler(handler_name); 409 handler = get_handler(handler_name);
409 if (!handler) { 410 if (!handler) {
410 dict = PyDict_New(); 411 dict = PyDict_New();
@@ -475,6 +476,289 @@ static void python_process_tracepoint(struct perf_sample *sample,
475 Py_DECREF(t); 476 Py_DECREF(t);
476} 477}
477 478
479static PyObject *tuple_new(unsigned int sz)
480{
481 PyObject *t;
482
483 t = PyTuple_New(sz);
484 if (!t)
485 Py_FatalError("couldn't create Python tuple");
486 return t;
487}
488
489static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
490{
491#if BITS_PER_LONG == 64
492 return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
493#endif
494#if BITS_PER_LONG == 32
495 return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val));
496#endif
497}
498
499static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val)
500{
501 return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
502}
503
504static int tuple_set_string(PyObject *t, unsigned int pos, const char *s)
505{
506 return PyTuple_SetItem(t, pos, PyString_FromString(s));
507}
508
509static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel)
510{
511 struct tables *tables = container_of(dbe, struct tables, dbe);
512 PyObject *t;
513
514 t = tuple_new(2);
515
516 tuple_set_u64(t, 0, evsel->db_id);
517 tuple_set_string(t, 1, perf_evsel__name(evsel));
518
519 call_object(tables->evsel_handler, t, "evsel_table");
520
521 Py_DECREF(t);
522
523 return 0;
524}
525
526static int python_export_machine(struct db_export *dbe,
527 struct machine *machine)
528{
529 struct tables *tables = container_of(dbe, struct tables, dbe);
530 PyObject *t;
531
532 t = tuple_new(3);
533
534 tuple_set_u64(t, 0, machine->db_id);
535 tuple_set_s32(t, 1, machine->pid);
536 tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : "");
537
538 call_object(tables->machine_handler, t, "machine_table");
539
540 Py_DECREF(t);
541
542 return 0;
543}
544
545static int python_export_thread(struct db_export *dbe, struct thread *thread,
546 u64 main_thread_db_id, struct machine *machine)
547{
548 struct tables *tables = container_of(dbe, struct tables, dbe);
549 PyObject *t;
550
551 t = tuple_new(5);
552
553 tuple_set_u64(t, 0, thread->db_id);
554 tuple_set_u64(t, 1, machine->db_id);
555 tuple_set_u64(t, 2, main_thread_db_id);
556 tuple_set_s32(t, 3, thread->pid_);
557 tuple_set_s32(t, 4, thread->tid);
558
559 call_object(tables->thread_handler, t, "thread_table");
560
561 Py_DECREF(t);
562
563 return 0;
564}
565
566static int python_export_comm(struct db_export *dbe, struct comm *comm)
567{
568 struct tables *tables = container_of(dbe, struct tables, dbe);
569 PyObject *t;
570
571 t = tuple_new(2);
572
573 tuple_set_u64(t, 0, comm->db_id);
574 tuple_set_string(t, 1, comm__str(comm));
575
576 call_object(tables->comm_handler, t, "comm_table");
577
578 Py_DECREF(t);
579
580 return 0;
581}
582
583static int python_export_comm_thread(struct db_export *dbe, u64 db_id,
584 struct comm *comm, struct thread *thread)
585{
586 struct tables *tables = container_of(dbe, struct tables, dbe);
587 PyObject *t;
588
589 t = tuple_new(3);
590
591 tuple_set_u64(t, 0, db_id);
592 tuple_set_u64(t, 1, comm->db_id);
593 tuple_set_u64(t, 2, thread->db_id);
594
595 call_object(tables->comm_thread_handler, t, "comm_thread_table");
596
597 Py_DECREF(t);
598
599 return 0;
600}
601
602static int python_export_dso(struct db_export *dbe, struct dso *dso,
603 struct machine *machine)
604{
605 struct tables *tables = container_of(dbe, struct tables, dbe);
606 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
607 PyObject *t;
608
609 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
610
611 t = tuple_new(5);
612
613 tuple_set_u64(t, 0, dso->db_id);
614 tuple_set_u64(t, 1, machine->db_id);
615 tuple_set_string(t, 2, dso->short_name);
616 tuple_set_string(t, 3, dso->long_name);
617 tuple_set_string(t, 4, sbuild_id);
618
619 call_object(tables->dso_handler, t, "dso_table");
620
621 Py_DECREF(t);
622
623 return 0;
624}
625
626static int python_export_symbol(struct db_export *dbe, struct symbol *sym,
627 struct dso *dso)
628{
629 struct tables *tables = container_of(dbe, struct tables, dbe);
630 u64 *sym_db_id = symbol__priv(sym);
631 PyObject *t;
632
633 t = tuple_new(6);
634
635 tuple_set_u64(t, 0, *sym_db_id);
636 tuple_set_u64(t, 1, dso->db_id);
637 tuple_set_u64(t, 2, sym->start);
638 tuple_set_u64(t, 3, sym->end);
639 tuple_set_s32(t, 4, sym->binding);
640 tuple_set_string(t, 5, sym->name);
641
642 call_object(tables->symbol_handler, t, "symbol_table");
643
644 Py_DECREF(t);
645
646 return 0;
647}
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,
668 struct export_sample *es)
669{
670 struct tables *tables = container_of(dbe, struct tables, dbe);
671 PyObject *t;
672
673 t = tuple_new(21);
674
675 tuple_set_u64(t, 0, es->db_id);
676 tuple_set_u64(t, 1, es->evsel->db_id);
677 tuple_set_u64(t, 2, es->al->machine->db_id);
678 tuple_set_u64(t, 3, es->thread->db_id);
679 tuple_set_u64(t, 4, es->comm_db_id);
680 tuple_set_u64(t, 5, es->dso_db_id);
681 tuple_set_u64(t, 6, es->sym_db_id);
682 tuple_set_u64(t, 7, es->offset);
683 tuple_set_u64(t, 8, es->sample->ip);
684 tuple_set_u64(t, 9, es->sample->time);
685 tuple_set_s32(t, 10, es->sample->cpu);
686 tuple_set_u64(t, 11, es->addr_dso_db_id);
687 tuple_set_u64(t, 12, es->addr_sym_db_id);
688 tuple_set_u64(t, 13, es->addr_offset);
689 tuple_set_u64(t, 14, es->sample->addr);
690 tuple_set_u64(t, 15, es->sample->period);
691 tuple_set_u64(t, 16, es->sample->weight);
692 tuple_set_u64(t, 17, es->sample->transaction);
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));
696
697 call_object(tables->sample_handler, t, "sample_table");
698
699 Py_DECREF(t);
700
701 return 0;
702}
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
478static void python_process_general_event(struct perf_sample *sample, 762static void python_process_general_event(struct perf_sample *sample,
479 struct perf_evsel *evsel, 763 struct perf_evsel *evsel,
480 struct thread *thread, 764 struct thread *thread,
@@ -551,19 +835,25 @@ exit:
551 Py_DECREF(t); 835 Py_DECREF(t);
552} 836}
553 837
554static void python_process_event(union perf_event *event __maybe_unused, 838static void python_process_event(union perf_event *event,
555 struct perf_sample *sample, 839 struct perf_sample *sample,
556 struct perf_evsel *evsel, 840 struct perf_evsel *evsel,
557 struct thread *thread, 841 struct thread *thread,
558 struct addr_location *al) 842 struct addr_location *al)
559{ 843{
844 struct tables *tables = &tables_global;
845
560 switch (evsel->attr.type) { 846 switch (evsel->attr.type) {
561 case PERF_TYPE_TRACEPOINT: 847 case PERF_TYPE_TRACEPOINT:
562 python_process_tracepoint(sample, evsel, thread, al); 848 python_process_tracepoint(sample, evsel, thread, al);
563 break; 849 break;
564 /* Reserve for future process_hw/sw/raw APIs */ 850 /* Reserve for future process_hw/sw/raw APIs */
565 default: 851 default:
566 python_process_general_event(sample, evsel, thread, al); 852 if (tables->db_export_mode)
853 db_export__sample(&tables->dbe, event, sample, evsel,
854 thread, al);
855 else
856 python_process_general_event(sample, evsel, thread, al);
567 } 857 }
568} 858}
569 859
@@ -589,11 +879,79 @@ error:
589 return -1; 879 return -1;
590} 880}
591 881
882#define SET_TABLE_HANDLER_(name, handler_name, table_name) do { \
883 tables->handler_name = get_handler(#table_name); \
884 if (tables->handler_name) \
885 tables->dbe.export_ ## name = python_export_ ## name; \
886} while (0)
887
888#define SET_TABLE_HANDLER(name) \
889 SET_TABLE_HANDLER_(name, name ## _handler, name ## _table)
890
891static void set_table_handlers(struct tables *tables)
892{
893 const char *perf_db_export_mode = "perf_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;
897 int ret;
898
899 memset(tables, 0, sizeof(struct tables));
900 if (db_export__init(&tables->dbe))
901 Py_FatalError("failed to initialize export");
902
903 db_export_mode = PyDict_GetItemString(main_dict, perf_db_export_mode);
904 if (!db_export_mode)
905 return;
906
907 ret = PyObject_IsTrue(db_export_mode);
908 if (ret == -1)
909 handler_call_die(perf_db_export_mode);
910 if (!ret)
911 return;
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
930 tables->db_export_mode = true;
931 /*
932 * Reserve per symbol space for symbol->db_id via symbol__priv()
933 */
934 symbol_conf.priv_size = sizeof(u64);
935
936 SET_TABLE_HANDLER(evsel);
937 SET_TABLE_HANDLER(machine);
938 SET_TABLE_HANDLER(thread);
939 SET_TABLE_HANDLER(comm);
940 SET_TABLE_HANDLER(comm_thread);
941 SET_TABLE_HANDLER(dso);
942 SET_TABLE_HANDLER(symbol);
943 SET_TABLE_HANDLER(branch_type);
944 SET_TABLE_HANDLER(sample);
945 SET_TABLE_HANDLER(call_path);
946 SET_TABLE_HANDLER(call_return);
947}
948
592/* 949/*
593 * Start trace script 950 * Start trace script
594 */ 951 */
595static int python_start_script(const char *script, int argc, const char **argv) 952static int python_start_script(const char *script, int argc, const char **argv)
596{ 953{
954 struct tables *tables = &tables_global;
597 const char **command_line; 955 const char **command_line;
598 char buf[PATH_MAX]; 956 char buf[PATH_MAX];
599 int i, err = 0; 957 int i, err = 0;
@@ -632,6 +990,14 @@ static int python_start_script(const char *script, int argc, const char **argv)
632 990
633 free(command_line); 991 free(command_line);
634 992
993 set_table_handlers(tables);
994
995 if (tables->db_export_mode) {
996 err = db_export__branch_types(&tables->dbe);
997 if (err)
998 goto error;
999 }
1000
635 return err; 1001 return err;
636error: 1002error:
637 Py_Finalize(); 1003 Py_Finalize();
@@ -642,7 +1008,9 @@ error:
642 1008
643static int python_flush_script(void) 1009static int python_flush_script(void)
644{ 1010{
645 return 0; 1011 struct tables *tables = &tables_global;
1012
1013 return db_export__flush(&tables->dbe);
646} 1014}
647 1015
648/* 1016/*
@@ -650,8 +1018,12 @@ static int python_flush_script(void)
650 */ 1018 */
651static int python_stop_script(void) 1019static int python_stop_script(void)
652{ 1020{
1021 struct tables *tables = &tables_global;
1022
653 try_call_object("trace_end", NULL); 1023 try_call_object("trace_end", NULL);
654 1024
1025 db_export__exit(&tables->dbe);
1026
655 Py_XDECREF(main_dict); 1027 Py_XDECREF(main_dict);
656 Py_XDECREF(main_module); 1028 Py_XDECREF(main_module);
657 Py_Finalize(); 1029 Py_Finalize();