diff options
| author | David S. Miller <davem@davemloft.net> | 2012-10-02 23:02:10 -0400 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-10-02 23:02:10 -0400 | 
| commit | 954f9ac43b87b44152b8c21163cefd466a87145e (patch) | |
| tree | 31c4197f975c66c96976948663e6ce844900b41a /tools/perf/util/scripting-engines/trace-event-python.c | |
| parent | 1b62ca7bf5775bed048032b7e779561e1fe66aa0 (diff) | |
| parent | 7fe0b14b725d6d09a1d9e1409bd465cb88b587f9 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
There's a Niagara 2 memcpy fix in this tree and I have
a Kconfig fix from Dave Jones which requires the sparc-next
changes which went upstream yesterday.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 113 | 
1 files changed, 98 insertions, 15 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index ce4d1b0c3862..730c6630cba5 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -27,10 +27,12 @@  #include <errno.h>  #include "../../perf.h" +#include "../evsel.h"  #include "../util.h"  #include "../event.h"  #include "../thread.h"  #include "../trace-event.h" +#include "../evsel.h"  PyMODINIT_FUNC initperf_trace_context(void); @@ -194,16 +196,21 @@ static void define_event_symbols(struct event_format *event,  		define_event_symbols(event, ev_name, args->next);  } -static inline -struct event_format *find_cache_event(struct pevent *pevent, int type) +static inline struct event_format *find_cache_event(struct perf_evsel *evsel)  {  	static char ev_name[256];  	struct event_format *event; +	int type = evsel->attr.config; +	/* + 	 * XXX: Do we really need to cache this since now we have evsel->tp_format + 	 * cached already? Need to re-read this "cache" routine that as well calls + 	 * define_event_symbols() :-\ + 	 */  	if (events[type])  		return events[type]; -	events[type] = event = pevent_find_event(pevent, type); +	events[type] = event = evsel->tp_format;  	if (!event)  		return NULL; @@ -214,12 +221,12 @@ struct event_format *find_cache_event(struct pevent *pevent, int type)  	return event;  } -static void python_process_event(union perf_event *perf_event __unused, -				 struct pevent *pevent, +static void python_process_tracepoint(union perf_event *perf_event +				      __maybe_unused,  				 struct perf_sample *sample, -				 struct perf_evsel *evsel __unused, -				 struct machine *machine __unused, -				 struct thread *thread) +				 struct perf_evsel *evsel, +				 struct machine *machine __maybe_unused, +				 struct addr_location *al)  {  	PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;  	static char handler_name[256]; @@ -228,24 +235,22 @@ static void python_process_event(union perf_event *perf_event __unused,  	unsigned long s, ns;  	struct event_format *event;  	unsigned n = 0; -	int type;  	int pid;  	int cpu = sample->cpu;  	void *data = sample->raw_data;  	unsigned long long nsecs = sample->time; +	struct thread *thread = al->thread;  	char *comm = thread->comm;  	t = PyTuple_New(MAX_FIELDS);  	if (!t)  		Py_FatalError("couldn't create Python tuple"); -	type = trace_parse_common_type(pevent, data); - -	event = find_cache_event(pevent, type); +	event = find_cache_event(evsel);  	if (!event) -		die("ug! no event found for type %d", type); +		die("ug! no event found for type %d", (int)evsel->attr.config); -	pid = trace_parse_common_pid(pevent, data); +	pid = raw_field_value(event, "common_pid", data);  	sprintf(handler_name, "%s__%s", event->system, event->name); @@ -290,7 +295,7 @@ static void python_process_event(union perf_event *perf_event __unused,  				offset = field->offset;  			obj = PyString_FromString((char *)data + offset);  		} else { /* FIELD_IS_NUMERIC */ -			val = read_size(pevent, data + field->offset, +			val = read_size(event, data + field->offset,  					field->size);  			if (field->flags & FIELD_IS_SIGNED) {  				if ((long long)val >= LONG_MIN && @@ -335,6 +340,84 @@ static void python_process_event(union perf_event *perf_event __unused,  	Py_DECREF(t);  } +static void python_process_general_event(union perf_event *perf_event +					 __maybe_unused, +					 struct perf_sample *sample, +					 struct perf_evsel *evsel, +					 struct machine *machine __maybe_unused, +					 struct addr_location *al) +{ +	PyObject *handler, *retval, *t, *dict; +	static char handler_name[64]; +	unsigned n = 0; +	struct thread *thread = al->thread; + +	/* +	 * Use the MAX_FIELDS to make the function expandable, though +	 * currently there is only one item for the tuple. +	 */ +	t = PyTuple_New(MAX_FIELDS); +	if (!t) +		Py_FatalError("couldn't create Python tuple"); + +	dict = PyDict_New(); +	if (!dict) +		Py_FatalError("couldn't create Python dictionary"); + +	snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); + +	handler = PyDict_GetItemString(main_dict, handler_name); +	if (!handler || !PyCallable_Check(handler)) +		goto exit; + +	PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); +	PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize( +			(const char *)&evsel->attr, sizeof(evsel->attr))); +	PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize( +			(const char *)sample, sizeof(*sample))); +	PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize( +			(const char *)sample->raw_data, sample->raw_size)); +	PyDict_SetItemString(dict, "comm", +			PyString_FromString(thread->comm)); +	if (al->map) { +		PyDict_SetItemString(dict, "dso", +			PyString_FromString(al->map->dso->name)); +	} +	if (al->sym) { +		PyDict_SetItemString(dict, "symbol", +			PyString_FromString(al->sym->name)); +	} + +	PyTuple_SetItem(t, n++, dict); +	if (_PyTuple_Resize(&t, n) == -1) +		Py_FatalError("error resizing Python tuple"); + +	retval = PyObject_CallObject(handler, t); +	if (retval == NULL) +		handler_call_die(handler_name); +exit: +	Py_DECREF(dict); +	Py_DECREF(t); +} + +static void python_process_event(union perf_event *perf_event, +				 struct perf_sample *sample, +				 struct perf_evsel *evsel, +				 struct machine *machine, +				 struct addr_location *al) +{ +	switch (evsel->attr.type) { +	case PERF_TYPE_TRACEPOINT: +		python_process_tracepoint(perf_event, sample, evsel, +					  machine, al); +		break; +	/* Reserve for future process_hw/sw/raw APIs */ +	default: +		python_process_general_event(perf_event, sample, evsel, +					     machine, al); +	} +} +  static int run_start_sub(void)  {  	PyObject *handler, *retval;  | 
