aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-10-30 02:34:32 -0400
committerIngo Molnar <mingo@kernel.org>2014-10-30 02:34:32 -0400
commit05b2537e8dc778bb00284f8fc86b83797b8f1d37 (patch)
treeb66c9d4d7c82152a034e8ab10f809d91790f4362 /tools/perf/util/scripting-engines/trace-event-python.c
parentd785452c9972fac2808479eb561d5c426b6e7d3b (diff)
parenta293829df788ae96a174b315010d4b56a10e5114 (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 from Arnaldo Carvalho de Melo: User visible changes: - Don't open the DWARF info multiple times, keeping instead a dwfl handle in struct dso, greatly speeding up 'perf report' on powerpc. (Sukadev Bhattiprolu) - Introduce PARSE_OPT_DISABLED option flag and use it to avoid showing undersired options in tools that provides frontends to 'perf record', like sched, kvm, etc (Namhyung Kim) Infrastructure changes: - More Intel PT work, including a facility to export sample data (comms, threads, symbol names, etc) in a database friendly way, with an script to use this to create a postgresql database. (Adrian Hunter) - Use make sure that thread->mg->machine points to the machine where the thread exists (it was being set only for the kmaps kernel modules case, do it as well for the mmaps) and use it to shorten function signatures (Arnaldo Carvalho de Melo) 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.c292
1 files changed, 287 insertions, 5 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..2fd7ee8f18c7 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -24,6 +24,7 @@
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>
28 29
29#include "../../perf.h" 30#include "../../perf.h"
@@ -33,6 +34,9 @@
33#include "../util.h" 34#include "../util.h"
34#include "../event.h" 35#include "../event.h"
35#include "../thread.h" 36#include "../thread.h"
37#include "../comm.h"
38#include "../machine.h"
39#include "../db-export.h"
36#include "../trace-event.h" 40#include "../trace-event.h"
37#include "../machine.h" 41#include "../machine.h"
38 42
@@ -53,6 +57,21 @@ static int zero_flag_atom;
53 57
54static PyObject *main_module, *main_dict; 58static PyObject *main_module, *main_dict;
55 59
60struct tables {
61 struct db_export dbe;
62 PyObject *evsel_handler;
63 PyObject *machine_handler;
64 PyObject *thread_handler;
65 PyObject *comm_handler;
66 PyObject *comm_thread_handler;
67 PyObject *dso_handler;
68 PyObject *symbol_handler;
69 PyObject *sample_handler;
70 bool db_export_mode;
71};
72
73static struct tables tables_global;
74
56static void handler_call_die(const char *handler_name) NORETURN; 75static void handler_call_die(const char *handler_name) NORETURN;
57static void handler_call_die(const char *handler_name) 76static void handler_call_die(const char *handler_name)
58{ 77{
@@ -312,9 +331,9 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
312 if (!symbol_conf.use_callchain || !sample->callchain) 331 if (!symbol_conf.use_callchain || !sample->callchain)
313 goto exit; 332 goto exit;
314 333
315 if (machine__resolve_callchain(al->machine, evsel, al->thread, 334 if (thread__resolve_callchain(al->thread, evsel,
316 sample, NULL, NULL, 335 sample, NULL, NULL,
317 PERF_MAX_STACK_DEPTH) != 0) { 336 PERF_MAX_STACK_DEPTH) != 0) {
318 pr_err("Failed to resolve callchain. Skipping\n"); 337 pr_err("Failed to resolve callchain. Skipping\n");
319 goto exit; 338 goto exit;
320 } 339 }
@@ -475,6 +494,211 @@ static void python_process_tracepoint(struct perf_sample *sample,
475 Py_DECREF(t); 494 Py_DECREF(t);
476} 495}
477 496
497static PyObject *tuple_new(unsigned int sz)
498{
499 PyObject *t;
500
501 t = PyTuple_New(sz);
502 if (!t)
503 Py_FatalError("couldn't create Python tuple");
504 return t;
505}
506
507static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
508{
509#if BITS_PER_LONG == 64
510 return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
511#endif
512#if BITS_PER_LONG == 32
513 return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val));
514#endif
515}
516
517static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val)
518{
519 return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
520}
521
522static int tuple_set_string(PyObject *t, unsigned int pos, const char *s)
523{
524 return PyTuple_SetItem(t, pos, PyString_FromString(s));
525}
526
527static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel)
528{
529 struct tables *tables = container_of(dbe, struct tables, dbe);
530 PyObject *t;
531
532 t = tuple_new(2);
533
534 tuple_set_u64(t, 0, evsel->db_id);
535 tuple_set_string(t, 1, perf_evsel__name(evsel));
536
537 call_object(tables->evsel_handler, t, "evsel_table");
538
539 Py_DECREF(t);
540
541 return 0;
542}
543
544static int python_export_machine(struct db_export *dbe,
545 struct machine *machine)
546{
547 struct tables *tables = container_of(dbe, struct tables, dbe);
548 PyObject *t;
549
550 t = tuple_new(3);
551
552 tuple_set_u64(t, 0, machine->db_id);
553 tuple_set_s32(t, 1, machine->pid);
554 tuple_set_string(t, 2, machine->root_dir ? machine->root_dir : "");
555
556 call_object(tables->machine_handler, t, "machine_table");
557
558 Py_DECREF(t);
559
560 return 0;
561}
562
563static int python_export_thread(struct db_export *dbe, struct thread *thread,
564 u64 main_thread_db_id, struct machine *machine)
565{
566 struct tables *tables = container_of(dbe, struct tables, dbe);
567 PyObject *t;
568
569 t = tuple_new(5);
570
571 tuple_set_u64(t, 0, thread->db_id);
572 tuple_set_u64(t, 1, machine->db_id);
573 tuple_set_u64(t, 2, main_thread_db_id);
574 tuple_set_s32(t, 3, thread->pid_);
575 tuple_set_s32(t, 4, thread->tid);
576
577 call_object(tables->thread_handler, t, "thread_table");
578
579 Py_DECREF(t);
580
581 return 0;
582}
583
584static int python_export_comm(struct db_export *dbe, struct comm *comm)
585{
586 struct tables *tables = container_of(dbe, struct tables, dbe);
587 PyObject *t;
588
589 t = tuple_new(2);
590
591 tuple_set_u64(t, 0, comm->db_id);
592 tuple_set_string(t, 1, comm__str(comm));
593
594 call_object(tables->comm_handler, t, "comm_table");
595
596 Py_DECREF(t);
597
598 return 0;
599}
600
601static int python_export_comm_thread(struct db_export *dbe, u64 db_id,
602 struct comm *comm, struct thread *thread)
603{
604 struct tables *tables = container_of(dbe, struct tables, dbe);
605 PyObject *t;
606
607 t = tuple_new(3);
608
609 tuple_set_u64(t, 0, db_id);
610 tuple_set_u64(t, 1, comm->db_id);
611 tuple_set_u64(t, 2, thread->db_id);
612
613 call_object(tables->comm_thread_handler, t, "comm_thread_table");
614
615 Py_DECREF(t);
616
617 return 0;
618}
619
620static int python_export_dso(struct db_export *dbe, struct dso *dso,
621 struct machine *machine)
622{
623 struct tables *tables = container_of(dbe, struct tables, dbe);
624 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
625 PyObject *t;
626
627 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
628
629 t = tuple_new(5);
630
631 tuple_set_u64(t, 0, dso->db_id);
632 tuple_set_u64(t, 1, machine->db_id);
633 tuple_set_string(t, 2, dso->short_name);
634 tuple_set_string(t, 3, dso->long_name);
635 tuple_set_string(t, 4, sbuild_id);
636
637 call_object(tables->dso_handler, t, "dso_table");
638
639 Py_DECREF(t);
640
641 return 0;
642}
643
644static int python_export_symbol(struct db_export *dbe, struct symbol *sym,
645 struct dso *dso)
646{
647 struct tables *tables = container_of(dbe, struct tables, dbe);
648 u64 *sym_db_id = symbol__priv(sym);
649 PyObject *t;
650
651 t = tuple_new(6);
652
653 tuple_set_u64(t, 0, *sym_db_id);
654 tuple_set_u64(t, 1, dso->db_id);
655 tuple_set_u64(t, 2, sym->start);
656 tuple_set_u64(t, 3, sym->end);
657 tuple_set_s32(t, 4, sym->binding);
658 tuple_set_string(t, 5, sym->name);
659
660 call_object(tables->symbol_handler, t, "symbol_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(19);
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
695 call_object(tables->sample_handler, t, "sample_table");
696
697 Py_DECREF(t);
698
699 return 0;
700}
701
478static void python_process_general_event(struct perf_sample *sample, 702static void python_process_general_event(struct perf_sample *sample,
479 struct perf_evsel *evsel, 703 struct perf_evsel *evsel,
480 struct thread *thread, 704 struct thread *thread,
@@ -551,19 +775,25 @@ exit:
551 Py_DECREF(t); 775 Py_DECREF(t);
552} 776}
553 777
554static void python_process_event(union perf_event *event __maybe_unused, 778static void python_process_event(union perf_event *event,
555 struct perf_sample *sample, 779 struct perf_sample *sample,
556 struct perf_evsel *evsel, 780 struct perf_evsel *evsel,
557 struct thread *thread, 781 struct thread *thread,
558 struct addr_location *al) 782 struct addr_location *al)
559{ 783{
784 struct tables *tables = &tables_global;
785
560 switch (evsel->attr.type) { 786 switch (evsel->attr.type) {
561 case PERF_TYPE_TRACEPOINT: 787 case PERF_TYPE_TRACEPOINT:
562 python_process_tracepoint(sample, evsel, thread, al); 788 python_process_tracepoint(sample, evsel, thread, al);
563 break; 789 break;
564 /* Reserve for future process_hw/sw/raw APIs */ 790 /* Reserve for future process_hw/sw/raw APIs */
565 default: 791 default:
566 python_process_general_event(sample, evsel, thread, al); 792 if (tables->db_export_mode)
793 db_export__sample(&tables->dbe, event, sample, evsel,
794 thread, al);
795 else
796 python_process_general_event(sample, evsel, thread, al);
567 } 797 }
568} 798}
569 799
@@ -589,11 +819,57 @@ error:
589 return -1; 819 return -1;
590} 820}
591 821
822#define SET_TABLE_HANDLER_(name, handler_name, table_name) do { \
823 tables->handler_name = get_handler(#table_name); \
824 if (tables->handler_name) \
825 tables->dbe.export_ ## name = python_export_ ## name; \
826} while (0)
827
828#define SET_TABLE_HANDLER(name) \
829 SET_TABLE_HANDLER_(name, name ## _handler, name ## _table)
830
831static void set_table_handlers(struct tables *tables)
832{
833 const char *perf_db_export_mode = "perf_db_export_mode";
834 PyObject *db_export_mode;
835 int ret;
836
837 memset(tables, 0, sizeof(struct tables));
838 if (db_export__init(&tables->dbe))
839 Py_FatalError("failed to initialize export");
840
841 db_export_mode = PyDict_GetItemString(main_dict, perf_db_export_mode);
842 if (!db_export_mode)
843 return;
844
845 ret = PyObject_IsTrue(db_export_mode);
846 if (ret == -1)
847 handler_call_die(perf_db_export_mode);
848 if (!ret)
849 return;
850
851 tables->db_export_mode = true;
852 /*
853 * Reserve per symbol space for symbol->db_id via symbol__priv()
854 */
855 symbol_conf.priv_size = sizeof(u64);
856
857 SET_TABLE_HANDLER(evsel);
858 SET_TABLE_HANDLER(machine);
859 SET_TABLE_HANDLER(thread);
860 SET_TABLE_HANDLER(comm);
861 SET_TABLE_HANDLER(comm_thread);
862 SET_TABLE_HANDLER(dso);
863 SET_TABLE_HANDLER(symbol);
864 SET_TABLE_HANDLER(sample);
865}
866
592/* 867/*
593 * Start trace script 868 * Start trace script
594 */ 869 */
595static int python_start_script(const char *script, int argc, const char **argv) 870static int python_start_script(const char *script, int argc, const char **argv)
596{ 871{
872 struct tables *tables = &tables_global;
597 const char **command_line; 873 const char **command_line;
598 char buf[PATH_MAX]; 874 char buf[PATH_MAX];
599 int i, err = 0; 875 int i, err = 0;
@@ -632,6 +908,8 @@ static int python_start_script(const char *script, int argc, const char **argv)
632 908
633 free(command_line); 909 free(command_line);
634 910
911 set_table_handlers(tables);
912
635 return err; 913 return err;
636error: 914error:
637 Py_Finalize(); 915 Py_Finalize();
@@ -650,8 +928,12 @@ static int python_flush_script(void)
650 */ 928 */
651static int python_stop_script(void) 929static int python_stop_script(void)
652{ 930{
931 struct tables *tables = &tables_global;
932
653 try_call_object("trace_end", NULL); 933 try_call_object("trace_end", NULL);
654 934
935 db_export__exit(&tables->dbe);
936
655 Py_XDECREF(main_dict); 937 Py_XDECREF(main_dict);
656 Py_XDECREF(main_module); 938 Py_XDECREF(main_module);
657 Py_Finalize(); 939 Py_Finalize();