aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines/trace-event-python.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 09:58:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 09:58:15 -0400
commit9d9420f1209a1facea7110d549ac695f5aeeb503 (patch)
tree7956d1c40420644830decbbc90b8bbdfeb194364 /tools/perf/util/scripting-engines/trace-event-python.c
parent6d5f0ebfc0be9cbfeaafdd9258d5fa24b7975a36 (diff)
parentcc6cd47e7395bc05c5077009808b820633eb3f18 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "Kernel side updates: - Fix and enhance poll support (Jiri Olsa) - Re-enable inheritance optimization (Jiri Olsa) - Enhance Intel memory events support (Stephane Eranian) - Refactor the Intel uncore driver to be more maintainable (Zheng Yan) - Enhance and fix Intel CPU and uncore PMU drivers (Peter Zijlstra, Andi Kleen) - [ plus various smaller fixes/cleanups ] User visible tooling updates: - Add +field argument support for --field option, so that one can add fields to the default list of fields to show, ie now one can just do: perf report --fields +pid And the pid will appear in addition to the default fields (Jiri Olsa) - Add +field argument support for --sort option (Jiri Olsa) - Honour -w in the report tools (report, top), allowing to specify the widths for the histogram entries columns (Namhyung Kim) - Properly show submicrosecond times in 'perf kvm stat' (Christian Borntraeger) - Add beautifier for mremap flags param in 'trace' (Alex Snast) - perf script: Allow callchains if any event samples them - Don't truncate Intel style addresses in 'annotate' (Alex Converse) - Allow profiling when kptr_restrict == 1 for non root users, kernel samples will just remain unresolved (Andi Kleen) - Allow configuring default options for callchains in config file (Namhyung Kim) - Support operations for shared futexes. (Davidlohr Bueso) - "perf kvm stat report" improvements by Alexander Yarygin: - Save pid string in opts.target.pid - Enable the target.system_wide flag - Unify the title bar output - [ plus lots of other fixes and small improvements. ] Tooling infrastructure changes: - Refactor unit and scale function parameters for PMU parsing routines (Matt Fleming) - Improve DSO long names lookup with rbtree, resulting in great speedup for workloads with lots of DSOs (Waiman Long) - We were not handling POLLHUP notifications for event file descriptors Fix it by filtering entries in the events file descriptor array after poll() returns, refcounting mmaps so that when the last fd pointing to a perf mmap goes away we do the unmap (Arnaldo Carvalho de Melo) - Intel PT prep work, from Adrian Hunter, including: - Let a user specify a PMU event without any config terms - Add perf-with-kcore script - Let default config be defined for a PMU - Add perf_pmu__scan_file() - Add a 'perf test' for tracking with sched_switch - Add 'flush' callback to scripting API - Use ring buffer consume method to look like other tools (Arnaldo Carvalho de Melo) - hists browser (used in top and report) refactorings, getting rid of unused variables and reducing source code size by handling similar cases in a fewer functions (Namhyung Kim). - Replace thread unsafe strerror() with strerror_r() accross the whole tools/perf/ tree (Masami Hiramatsu) - Rename ordered_samples to ordered_events and allow setting a queue size for ordering events (Jiri Olsa) - [ plus lots of fixes, cleanups and other improvements ]" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (198 commits) perf/x86: Tone down kernel messages when the PMU check fails in a virtual environment perf/x86/intel/uncore: Fix minor race in box set up perf record: Fix error message for --filter option not coming after tracepoint perf tools: Fix build breakage on arm64 targets perf symbols: Improve DSO long names lookup speed with rbtree perf symbols: Encapsulate dsos list head into struct dsos perf bench futex: Sanitize -q option in requeue perf bench futex: Support operations for shared futexes perf trace: Fix mmap return address truncation to 32-bit perf tools: Refactor unit and scale function parameters perf tools: Fix line number in the config file error message perf tools: Convert {record,top}.call-graph option to call-graph.record-mode perf tools: Introduce perf_callchain_config() perf callchain: Move some parser functions to callchain.c perf tools: Move callchain config from record_opts to callchain_param perf hists browser: Fix callchain print bug on TUI perf tools: Use ACCESS_ONCE() instead of volatile cast perf tools: Modify error code for when perf_session__new() fails perf tools: Fix perf record as non root with kptr_restrict == 1 perf stat: Fix --per-core on multi socket systems ...
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c120
1 files changed, 53 insertions, 67 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index cbce2545da45..56ba07cce549 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -73,6 +73,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObj
73 Py_DECREF(val); 73 Py_DECREF(val);
74} 74}
75 75
76static PyObject *get_handler(const char *handler_name)
77{
78 PyObject *handler;
79
80 handler = PyDict_GetItemString(main_dict, handler_name);
81 if (handler && !PyCallable_Check(handler))
82 return NULL;
83 return handler;
84}
85
86static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
87{
88 PyObject *retval;
89
90 retval = PyObject_CallObject(handler, args);
91 if (retval == NULL)
92 handler_call_die(die_msg);
93 Py_DECREF(retval);
94}
95
96static void try_call_object(const char *handler_name, PyObject *args)
97{
98 PyObject *handler;
99
100 handler = get_handler(handler_name);
101 if (handler)
102 call_object(handler, args, handler_name);
103}
104
76static void define_value(enum print_arg_type field_type, 105static void define_value(enum print_arg_type field_type,
77 const char *ev_name, 106 const char *ev_name,
78 const char *field_name, 107 const char *field_name,
@@ -80,7 +109,7 @@ static void define_value(enum print_arg_type field_type,
80 const char *field_str) 109 const char *field_str)
81{ 110{
82 const char *handler_name = "define_flag_value"; 111 const char *handler_name = "define_flag_value";
83 PyObject *handler, *t, *retval; 112 PyObject *t;
84 unsigned long long value; 113 unsigned long long value;
85 unsigned n = 0; 114 unsigned n = 0;
86 115
@@ -98,13 +127,7 @@ static void define_value(enum print_arg_type field_type,
98 PyTuple_SetItem(t, n++, PyInt_FromLong(value)); 127 PyTuple_SetItem(t, n++, PyInt_FromLong(value));
99 PyTuple_SetItem(t, n++, PyString_FromString(field_str)); 128 PyTuple_SetItem(t, n++, PyString_FromString(field_str));
100 129
101 handler = PyDict_GetItemString(main_dict, handler_name); 130 try_call_object(handler_name, t);
102 if (handler && PyCallable_Check(handler)) {
103 retval = PyObject_CallObject(handler, t);
104 if (retval == NULL)
105 handler_call_die(handler_name);
106 Py_DECREF(retval);
107 }
108 131
109 Py_DECREF(t); 132 Py_DECREF(t);
110} 133}
@@ -127,7 +150,7 @@ static void define_field(enum print_arg_type field_type,
127 const char *delim) 150 const char *delim)
128{ 151{
129 const char *handler_name = "define_flag_field"; 152 const char *handler_name = "define_flag_field";
130 PyObject *handler, *t, *retval; 153 PyObject *t;
131 unsigned n = 0; 154 unsigned n = 0;
132 155
133 if (field_type == PRINT_SYMBOL) 156 if (field_type == PRINT_SYMBOL)
@@ -145,13 +168,7 @@ static void define_field(enum print_arg_type field_type,
145 if (field_type == PRINT_FLAGS) 168 if (field_type == PRINT_FLAGS)
146 PyTuple_SetItem(t, n++, PyString_FromString(delim)); 169 PyTuple_SetItem(t, n++, PyString_FromString(delim));
147 170
148 handler = PyDict_GetItemString(main_dict, handler_name); 171 try_call_object(handler_name, t);
149 if (handler && PyCallable_Check(handler)) {
150 retval = PyObject_CallObject(handler, t);
151 if (retval == NULL)
152 handler_call_die(handler_name);
153 Py_DECREF(retval);
154 }
155 172
156 Py_DECREF(t); 173 Py_DECREF(t);
157} 174}
@@ -362,7 +379,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
362 struct thread *thread, 379 struct thread *thread,
363 struct addr_location *al) 380 struct addr_location *al)
364{ 381{
365 PyObject *handler, *retval, *context, *t, *obj, *callchain; 382 PyObject *handler, *context, *t, *obj, *callchain;
366 PyObject *dict = NULL; 383 PyObject *dict = NULL;
367 static char handler_name[256]; 384 static char handler_name[256];
368 struct format_field *field; 385 struct format_field *field;
@@ -387,9 +404,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
387 404
388 sprintf(handler_name, "%s__%s", event->system, event->name); 405 sprintf(handler_name, "%s__%s", event->system, event->name);
389 406
390 handler = PyDict_GetItemString(main_dict, handler_name); 407 handler = get_handler(handler_name);
391 if (handler && !PyCallable_Check(handler))
392 handler = NULL;
393 if (!handler) { 408 if (!handler) {
394 dict = PyDict_New(); 409 dict = PyDict_New();
395 if (!dict) 410 if (!dict)
@@ -450,19 +465,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
450 Py_FatalError("error resizing Python tuple"); 465 Py_FatalError("error resizing Python tuple");
451 466
452 if (handler) { 467 if (handler) {
453 retval = PyObject_CallObject(handler, t); 468 call_object(handler, t, handler_name);
454 if (retval == NULL)
455 handler_call_die(handler_name);
456 Py_DECREF(retval);
457 } else { 469 } else {
458 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 470 try_call_object("trace_unhandled", t);
459 if (handler && PyCallable_Check(handler)) {
460
461 retval = PyObject_CallObject(handler, t);
462 if (retval == NULL)
463 handler_call_die("trace_unhandled");
464 Py_DECREF(retval);
465 }
466 Py_DECREF(dict); 471 Py_DECREF(dict);
467 } 472 }
468 473
@@ -474,7 +479,7 @@ static void python_process_general_event(struct perf_sample *sample,
474 struct thread *thread, 479 struct thread *thread,
475 struct addr_location *al) 480 struct addr_location *al)
476{ 481{
477 PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample; 482 PyObject *handler, *t, *dict, *callchain, *dict_sample;
478 static char handler_name[64]; 483 static char handler_name[64];
479 unsigned n = 0; 484 unsigned n = 0;
480 485
@@ -496,8 +501,8 @@ static void python_process_general_event(struct perf_sample *sample,
496 501
497 snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 502 snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
498 503
499 handler = PyDict_GetItemString(main_dict, handler_name); 504 handler = get_handler(handler_name);
500 if (!handler || !PyCallable_Check(handler)) 505 if (!handler)
501 goto exit; 506 goto exit;
502 507
503 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); 508 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
@@ -539,10 +544,7 @@ static void python_process_general_event(struct perf_sample *sample,
539 if (_PyTuple_Resize(&t, n) == -1) 544 if (_PyTuple_Resize(&t, n) == -1)
540 Py_FatalError("error resizing Python tuple"); 545 Py_FatalError("error resizing Python tuple");
541 546
542 retval = PyObject_CallObject(handler, t); 547 call_object(handler, t, handler_name);
543 if (retval == NULL)
544 handler_call_die(handler_name);
545 Py_DECREF(retval);
546exit: 548exit:
547 Py_DECREF(dict); 549 Py_DECREF(dict);
548 Py_DECREF(t); 550 Py_DECREF(t);
@@ -566,36 +568,24 @@ static void python_process_event(union perf_event *event __maybe_unused,
566 568
567static int run_start_sub(void) 569static int run_start_sub(void)
568{ 570{
569 PyObject *handler, *retval;
570 int err = 0;
571
572 main_module = PyImport_AddModule("__main__"); 571 main_module = PyImport_AddModule("__main__");
573 if (main_module == NULL) 572 if (main_module == NULL)
574 return -1; 573 return -1;
575 Py_INCREF(main_module); 574 Py_INCREF(main_module);
576 575
577 main_dict = PyModule_GetDict(main_module); 576 main_dict = PyModule_GetDict(main_module);
578 if (main_dict == NULL) { 577 if (main_dict == NULL)
579 err = -1;
580 goto error; 578 goto error;
581 }
582 Py_INCREF(main_dict); 579 Py_INCREF(main_dict);
583 580
584 handler = PyDict_GetItemString(main_dict, "trace_begin"); 581 try_call_object("trace_begin", NULL);
585 if (handler == NULL || !PyCallable_Check(handler))
586 goto out;
587 582
588 retval = PyObject_CallObject(handler, NULL); 583 return 0;
589 if (retval == NULL)
590 handler_call_die("trace_begin");
591 584
592 Py_DECREF(retval);
593 return err;
594error: 585error:
595 Py_XDECREF(main_dict); 586 Py_XDECREF(main_dict);
596 Py_XDECREF(main_module); 587 Py_XDECREF(main_module);
597out: 588 return -1;
598 return err;
599} 589}
600 590
601/* 591/*
@@ -649,28 +639,23 @@ error:
649 return err; 639 return err;
650} 640}
651 641
642static int python_flush_script(void)
643{
644 return 0;
645}
646
652/* 647/*
653 * Stop trace script 648 * Stop trace script
654 */ 649 */
655static int python_stop_script(void) 650static int python_stop_script(void)
656{ 651{
657 PyObject *handler, *retval; 652 try_call_object("trace_end", NULL);
658 int err = 0;
659 653
660 handler = PyDict_GetItemString(main_dict, "trace_end");
661 if (handler == NULL || !PyCallable_Check(handler))
662 goto out;
663
664 retval = PyObject_CallObject(handler, NULL);
665 if (retval == NULL)
666 handler_call_die("trace_end");
667 Py_DECREF(retval);
668out:
669 Py_XDECREF(main_dict); 654 Py_XDECREF(main_dict);
670 Py_XDECREF(main_module); 655 Py_XDECREF(main_module);
671 Py_Finalize(); 656 Py_Finalize();
672 657
673 return err; 658 return 0;
674} 659}
675 660
676static int python_generate_script(struct pevent *pevent, const char *outfile) 661static int python_generate_script(struct pevent *pevent, const char *outfile)
@@ -843,6 +828,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
843struct scripting_ops python_scripting_ops = { 828struct scripting_ops python_scripting_ops = {
844 .name = "Python", 829 .name = "Python",
845 .start_script = python_start_script, 830 .start_script = python_start_script,
831 .flush_script = python_flush_script,
846 .stop_script = python_stop_script, 832 .stop_script = python_stop_script,
847 .process_event = python_process_event, 833 .process_event = python_process_event,
848 .generate_script = python_generate_script, 834 .generate_script = python_generate_script,