aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2014-10-23 06:45:14 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-10-29 08:32:49 -0400
commitdf919b400ad3f9e6aac392ce421d710207abf9be (patch)
tree0e49286a4bfa90bbe221c787702e4759f3005a90 /tools/perf
parent0db15b1e84a59e6e1da5fe6e74c35fe52fa29d92 (diff)
perf scripting python: Extend interface to export data in a database-friendly way
Use the new db_export facility to export data in a database-friendly way. A Python script selects the db_export mode by setting a global variable 'perf_db_export_mode' to True. The script then optionally implements functions to receive table rows. The functions are: evsel_table machine_table thread_table comm_table dso_table symbol_table sample_table An example script is provided in a subsequent patch. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1414061124-26830-7-git-send-email-adrian.hunter@intel.com [ Reserve space for per symbol db_id space when perf_db_export_mode is on ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c286
1 files changed, 284 insertions, 2 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 25e5a238f1cb..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{
@@ -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();