aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /tools/perf/util/scripting-engines
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'tools/perf/util/scripting-engines')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c119
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c138
2 files changed, 46 insertions, 211 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index f80605eb185..74350ffb57f 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -25,16 +25,13 @@
25#include <ctype.h> 25#include <ctype.h>
26#include <errno.h> 26#include <errno.h>
27 27
28#include "../../perf.h"
28#include "../util.h" 29#include "../util.h"
30#include "../trace-event.h"
31
29#include <EXTERN.h> 32#include <EXTERN.h>
30#include <perl.h> 33#include <perl.h>
31 34
32#include "../../perf.h"
33#include "../thread.h"
34#include "../event.h"
35#include "../trace-event.h"
36#include "../evsel.h"
37
38void boot_Perf__Trace__Context(pTHX_ CV *cv); 35void boot_Perf__Trace__Context(pTHX_ CV *cv);
39void boot_DynaLoader(pTHX_ CV *cv); 36void boot_DynaLoader(pTHX_ CV *cv);
40typedef PerlInterpreter * INTERP; 37typedef PerlInterpreter * INTERP;
@@ -56,7 +53,7 @@ INTERP my_perl;
56#define FTRACE_MAX_EVENT \ 53#define FTRACE_MAX_EVENT \
57 ((1 << (sizeof(unsigned short) * 8)) - 1) 54 ((1 << (sizeof(unsigned short) * 8)) - 1)
58 55
59struct event_format *events[FTRACE_MAX_EVENT]; 56struct event *events[FTRACE_MAX_EVENT];
60 57
61extern struct scripting_context *scripting_context; 58extern struct scripting_context *scripting_context;
62 59
@@ -181,7 +178,7 @@ static void define_flag_field(const char *ev_name,
181 LEAVE; 178 LEAVE;
182} 179}
183 180
184static void define_event_symbols(struct event_format *event, 181static void define_event_symbols(struct event *event,
185 const char *ev_name, 182 const char *ev_name,
186 struct print_arg *args) 183 struct print_arg *args)
187{ 184{
@@ -209,12 +206,6 @@ static void define_event_symbols(struct event_format *event,
209 define_symbolic_values(args->symbol.symbols, ev_name, 206 define_symbolic_values(args->symbol.symbols, ev_name,
210 cur_field_name); 207 cur_field_name);
211 break; 208 break;
212 case PRINT_HEX:
213 define_event_symbols(event, ev_name, args->hex.field);
214 define_event_symbols(event, ev_name, args->hex.size);
215 break;
216 case PRINT_BSTRING:
217 case PRINT_DYNAMIC_ARRAY:
218 case PRINT_STRING: 209 case PRINT_STRING:
219 break; 210 break;
220 case PRINT_TYPE: 211 case PRINT_TYPE:
@@ -226,9 +217,7 @@ static void define_event_symbols(struct event_format *event,
226 define_event_symbols(event, ev_name, args->op.left); 217 define_event_symbols(event, ev_name, args->op.left);
227 define_event_symbols(event, ev_name, args->op.right); 218 define_event_symbols(event, ev_name, args->op.right);
228 break; 219 break;
229 case PRINT_FUNC:
230 default: 220 default:
231 pr_err("Unsupported print arg type\n");
232 /* we should warn... */ 221 /* we should warn... */
233 return; 222 return;
234 } 223 }
@@ -237,16 +226,15 @@ static void define_event_symbols(struct event_format *event,
237 define_event_symbols(event, ev_name, args->next); 226 define_event_symbols(event, ev_name, args->next);
238} 227}
239 228
240static inline struct event_format *find_cache_event(struct perf_evsel *evsel) 229static inline struct event *find_cache_event(int type)
241{ 230{
242 static char ev_name[256]; 231 static char ev_name[256];
243 struct event_format *event; 232 struct event *event;
244 int type = evsel->attr.config;
245 233
246 if (events[type]) 234 if (events[type])
247 return events[type]; 235 return events[type];
248 236
249 events[type] = event = evsel->tp_format; 237 events[type] = event = trace_find_event(type);
250 if (!event) 238 if (!event)
251 return NULL; 239 return NULL;
252 240
@@ -257,34 +245,33 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
257 return event; 245 return event;
258} 246}
259 247
260static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused, 248static void perl_process_event(union perf_event *pevent __unused,
261 struct perf_sample *sample, 249 struct perf_sample *sample,
262 struct perf_evsel *evsel, 250 struct perf_evsel *evsel,
263 struct machine *machine __maybe_unused, 251 struct perf_session *session __unused,
264 struct addr_location *al) 252 struct thread *thread)
265{ 253{
266 struct format_field *field; 254 struct format_field *field;
267 static char handler[256]; 255 static char handler[256];
268 unsigned long long val; 256 unsigned long long val;
269 unsigned long s, ns; 257 unsigned long s, ns;
270 struct event_format *event; 258 struct event *event;
259 int type;
271 int pid; 260 int pid;
272 int cpu = sample->cpu; 261 int cpu = sample->cpu;
273 void *data = sample->raw_data; 262 void *data = sample->raw_data;
274 unsigned long long nsecs = sample->time; 263 unsigned long long nsecs = sample->time;
275 struct thread *thread = al->thread;
276 char *comm = thread->comm; 264 char *comm = thread->comm;
277 265
278 dSP; 266 dSP;
279 267
280 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 268 type = trace_parse_common_type(data);
281 return;
282 269
283 event = find_cache_event(evsel); 270 event = find_cache_event(type);
284 if (!event) 271 if (!event)
285 die("ug! no event found for type %" PRIu64, evsel->attr.config); 272 die("ug! no event found for type %d", type);
286 273
287 pid = raw_field_value(event, "common_pid", data); 274 pid = trace_parse_common_pid(data);
288 275
289 sprintf(handler, "%s::%s", event->system, event->name); 276 sprintf(handler, "%s::%s", event->system, event->name);
290 277
@@ -317,8 +304,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
317 offset = field->offset; 304 offset = field->offset;
318 XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); 305 XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
319 } else { /* FIELD_IS_NUMERIC */ 306 } else { /* FIELD_IS_NUMERIC */
320 val = read_size(event, data + field->offset, 307 val = read_size(data + field->offset, field->size);
321 field->size);
322 if (field->flags & FIELD_IS_SIGNED) { 308 if (field->flags & FIELD_IS_SIGNED) {
323 XPUSHs(sv_2mortal(newSViv(val))); 309 XPUSHs(sv_2mortal(newSViv(val)));
324 } else { 310 } else {
@@ -346,42 +332,6 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
346 LEAVE; 332 LEAVE;
347} 333}
348 334
349static void perl_process_event_generic(union perf_event *event,
350 struct perf_sample *sample,
351 struct perf_evsel *evsel,
352 struct machine *machine __maybe_unused,
353 struct addr_location *al __maybe_unused)
354{
355 dSP;
356
357 if (!get_cv("process_event", 0))
358 return;
359
360 ENTER;
361 SAVETMPS;
362 PUSHMARK(SP);
363 XPUSHs(sv_2mortal(newSVpvn((const char *)event, event->header.size)));
364 XPUSHs(sv_2mortal(newSVpvn((const char *)&evsel->attr, sizeof(evsel->attr))));
365 XPUSHs(sv_2mortal(newSVpvn((const char *)sample, sizeof(*sample))));
366 XPUSHs(sv_2mortal(newSVpvn((const char *)sample->raw_data, sample->raw_size)));
367 PUTBACK;
368 call_pv("process_event", G_SCALAR);
369 SPAGAIN;
370 PUTBACK;
371 FREETMPS;
372 LEAVE;
373}
374
375static void perl_process_event(union perf_event *event,
376 struct perf_sample *sample,
377 struct perf_evsel *evsel,
378 struct machine *machine,
379 struct addr_location *al)
380{
381 perl_process_tracepoint(event, sample, evsel, machine, al);
382 perl_process_event_generic(event, sample, evsel, machine, al);
383}
384
385static void run_start_sub(void) 335static void run_start_sub(void)
386{ 336{
387 dSP; /* access to Perl stack */ 337 dSP; /* access to Perl stack */
@@ -452,9 +402,9 @@ static int perl_stop_script(void)
452 return 0; 402 return 0;
453} 403}
454 404
455static int perl_generate_script(struct pevent *pevent, const char *outfile) 405static int perl_generate_script(const char *outfile)
456{ 406{
457 struct event_format *event = NULL; 407 struct event *event = NULL;
458 struct format_field *f; 408 struct format_field *f;
459 char fname[PATH_MAX]; 409 char fname[PATH_MAX];
460 int not_first, count; 410 int not_first, count;
@@ -499,7 +449,7 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile)
499 fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); 449 fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
500 fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); 450 fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
501 451
502 while ((event = trace_find_next_event(pevent, event))) { 452 while ((event = trace_find_next_event(event))) {
503 fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); 453 fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
504 fprintf(ofp, "\tmy ("); 454 fprintf(ofp, "\tmy (");
505 455
@@ -603,28 +553,7 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile)
603 fprintf(ofp, "sub print_header\n{\n" 553 fprintf(ofp, "sub print_header\n{\n"
604 "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n" 554 "\tmy ($event_name, $cpu, $secs, $nsecs, $pid, $comm) = @_;\n\n"
605 "\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t " 555 "\tprintf(\"%%-20s %%5u %%05u.%%09u %%8u %%-20s \",\n\t "
606 "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}\n"); 556 "$event_name, $cpu, $secs, $nsecs, $pid, $comm);\n}");
607
608 fprintf(ofp,
609 "\n# Packed byte string args of process_event():\n"
610 "#\n"
611 "# $event:\tunion perf_event\tutil/event.h\n"
612 "# $attr:\tstruct perf_event_attr\tlinux/perf_event.h\n"
613 "# $sample:\tstruct perf_sample\tutil/event.h\n"
614 "# $raw_data:\tperf_sample->raw_data\tutil/event.h\n"
615 "\n"
616 "sub process_event\n"
617 "{\n"
618 "\tmy ($event, $attr, $sample, $raw_data) = @_;\n"
619 "\n"
620 "\tmy @event\t= unpack(\"LSS\", $event);\n"
621 "\tmy @attr\t= unpack(\"LLQQQQQLLQQ\", $attr);\n"
622 "\tmy @sample\t= unpack(\"QLLQQQQQLL\", $sample);\n"
623 "\tmy @raw_data\t= unpack(\"C*\", $raw_data);\n"
624 "\n"
625 "\tuse Data::Dumper;\n"
626 "\tprint Dumper \\@event, \\@attr, \\@sample, \\@raw_data;\n"
627 "}\n");
628 557
629 fclose(ofp); 558 fclose(ofp);
630 559
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 14683dfca2e..6ccf70e8d8f 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -24,13 +24,11 @@
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 <ctype.h>
27#include <errno.h> 28#include <errno.h>
28 29
29#include "../../perf.h" 30#include "../../perf.h"
30#include "../evsel.h"
31#include "../util.h" 31#include "../util.h"
32#include "../event.h"
33#include "../thread.h"
34#include "../trace-event.h" 32#include "../trace-event.h"
35 33
36PyMODINIT_FUNC initperf_trace_context(void); 34PyMODINIT_FUNC initperf_trace_context(void);
@@ -38,7 +36,7 @@ PyMODINIT_FUNC initperf_trace_context(void);
38#define FTRACE_MAX_EVENT \ 36#define FTRACE_MAX_EVENT \
39 ((1 << (sizeof(unsigned short) * 8)) - 1) 37 ((1 << (sizeof(unsigned short) * 8)) - 1)
40 38
41struct event_format *events[FTRACE_MAX_EVENT]; 39struct event *events[FTRACE_MAX_EVENT];
42 40
43#define MAX_FIELDS 64 41#define MAX_FIELDS 64
44#define N_COMMON_FIELDS 7 42#define N_COMMON_FIELDS 7
@@ -137,7 +135,7 @@ static void define_field(enum print_arg_type field_type,
137 Py_DECREF(t); 135 Py_DECREF(t);
138} 136}
139 137
140static void define_event_symbols(struct event_format *event, 138static void define_event_symbols(struct event *event,
141 const char *ev_name, 139 const char *ev_name,
142 struct print_arg *args) 140 struct print_arg *args)
143{ 141{
@@ -167,10 +165,6 @@ static void define_event_symbols(struct event_format *event,
167 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, 165 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name,
168 cur_field_name); 166 cur_field_name);
169 break; 167 break;
170 case PRINT_HEX:
171 define_event_symbols(event, ev_name, args->hex.field);
172 define_event_symbols(event, ev_name, args->hex.size);
173 break;
174 case PRINT_STRING: 168 case PRINT_STRING:
175 break; 169 break;
176 case PRINT_TYPE: 170 case PRINT_TYPE:
@@ -183,10 +177,6 @@ static void define_event_symbols(struct event_format *event,
183 define_event_symbols(event, ev_name, args->op.right); 177 define_event_symbols(event, ev_name, args->op.right);
184 break; 178 break;
185 default: 179 default:
186 /* gcc warns for these? */
187 case PRINT_BSTRING:
188 case PRINT_DYNAMIC_ARRAY:
189 case PRINT_FUNC:
190 /* we should warn... */ 180 /* we should warn... */
191 return; 181 return;
192 } 182 }
@@ -195,21 +185,15 @@ static void define_event_symbols(struct event_format *event,
195 define_event_symbols(event, ev_name, args->next); 185 define_event_symbols(event, ev_name, args->next);
196} 186}
197 187
198static inline struct event_format *find_cache_event(struct perf_evsel *evsel) 188static inline struct event *find_cache_event(int type)
199{ 189{
200 static char ev_name[256]; 190 static char ev_name[256];
201 struct event_format *event; 191 struct event *event;
202 int type = evsel->attr.config; 192
203
204 /*
205 * XXX: Do we really need to cache this since now we have evsel->tp_format
206 * cached already? Need to re-read this "cache" routine that as well calls
207 * define_event_symbols() :-\
208 */
209 if (events[type]) 193 if (events[type])
210 return events[type]; 194 return events[type];
211 195
212 events[type] = event = evsel->tp_format; 196 events[type] = event = trace_find_event(type);
213 if (!event) 197 if (!event)
214 return NULL; 198 return NULL;
215 199
@@ -220,36 +204,37 @@ static inline struct event_format *find_cache_event(struct perf_evsel *evsel)
220 return event; 204 return event;
221} 205}
222 206
223static void python_process_tracepoint(union perf_event *perf_event 207static void python_process_event(union perf_event *pevent __unused,
224 __maybe_unused,
225 struct perf_sample *sample, 208 struct perf_sample *sample,
226 struct perf_evsel *evsel, 209 struct perf_evsel *evsel __unused,
227 struct machine *machine __maybe_unused, 210 struct perf_session *session __unused,
228 struct addr_location *al) 211 struct thread *thread)
229{ 212{
230 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 213 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
231 static char handler_name[256]; 214 static char handler_name[256];
232 struct format_field *field; 215 struct format_field *field;
233 unsigned long long val; 216 unsigned long long val;
234 unsigned long s, ns; 217 unsigned long s, ns;
235 struct event_format *event; 218 struct event *event;
236 unsigned n = 0; 219 unsigned n = 0;
220 int type;
237 int pid; 221 int pid;
238 int cpu = sample->cpu; 222 int cpu = sample->cpu;
239 void *data = sample->raw_data; 223 void *data = sample->raw_data;
240 unsigned long long nsecs = sample->time; 224 unsigned long long nsecs = sample->time;
241 struct thread *thread = al->thread;
242 char *comm = thread->comm; 225 char *comm = thread->comm;
243 226
244 t = PyTuple_New(MAX_FIELDS); 227 t = PyTuple_New(MAX_FIELDS);
245 if (!t) 228 if (!t)
246 Py_FatalError("couldn't create Python tuple"); 229 Py_FatalError("couldn't create Python tuple");
247 230
248 event = find_cache_event(evsel); 231 type = trace_parse_common_type(data);
232
233 event = find_cache_event(type);
249 if (!event) 234 if (!event)
250 die("ug! no event found for type %d", (int)evsel->attr.config); 235 die("ug! no event found for type %d", type);
251 236
252 pid = raw_field_value(event, "common_pid", data); 237 pid = trace_parse_common_pid(data);
253 238
254 sprintf(handler_name, "%s__%s", event->system, event->name); 239 sprintf(handler_name, "%s__%s", event->system, event->name);
255 240
@@ -294,8 +279,7 @@ static void python_process_tracepoint(union perf_event *perf_event
294 offset = field->offset; 279 offset = field->offset;
295 obj = PyString_FromString((char *)data + offset); 280 obj = PyString_FromString((char *)data + offset);
296 } else { /* FIELD_IS_NUMERIC */ 281 } else { /* FIELD_IS_NUMERIC */
297 val = read_size(event, data + field->offset, 282 val = read_size(data + field->offset, field->size);
298 field->size);
299 if (field->flags & FIELD_IS_SIGNED) { 283 if (field->flags & FIELD_IS_SIGNED) {
300 if ((long long)val >= LONG_MIN && 284 if ((long long)val >= LONG_MIN &&
301 (long long)val <= LONG_MAX) 285 (long long)val <= LONG_MAX)
@@ -339,84 +323,6 @@ static void python_process_tracepoint(union perf_event *perf_event
339 Py_DECREF(t); 323 Py_DECREF(t);
340} 324}
341 325
342static void python_process_general_event(union perf_event *perf_event
343 __maybe_unused,
344 struct perf_sample *sample,
345 struct perf_evsel *evsel,
346 struct machine *machine __maybe_unused,
347 struct addr_location *al)
348{
349 PyObject *handler, *retval, *t, *dict;
350 static char handler_name[64];
351 unsigned n = 0;
352 struct thread *thread = al->thread;
353
354 /*
355 * Use the MAX_FIELDS to make the function expandable, though
356 * currently there is only one item for the tuple.
357 */
358 t = PyTuple_New(MAX_FIELDS);
359 if (!t)
360 Py_FatalError("couldn't create Python tuple");
361
362 dict = PyDict_New();
363 if (!dict)
364 Py_FatalError("couldn't create Python dictionary");
365
366 snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
367
368 handler = PyDict_GetItemString(main_dict, handler_name);
369 if (!handler || !PyCallable_Check(handler))
370 goto exit;
371
372 PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
373 PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize(
374 (const char *)&evsel->attr, sizeof(evsel->attr)));
375 PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize(
376 (const char *)sample, sizeof(*sample)));
377 PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize(
378 (const char *)sample->raw_data, sample->raw_size));
379 PyDict_SetItemString(dict, "comm",
380 PyString_FromString(thread->comm));
381 if (al->map) {
382 PyDict_SetItemString(dict, "dso",
383 PyString_FromString(al->map->dso->name));
384 }
385 if (al->sym) {
386 PyDict_SetItemString(dict, "symbol",
387 PyString_FromString(al->sym->name));
388 }
389
390 PyTuple_SetItem(t, n++, dict);
391 if (_PyTuple_Resize(&t, n) == -1)
392 Py_FatalError("error resizing Python tuple");
393
394 retval = PyObject_CallObject(handler, t);
395 if (retval == NULL)
396 handler_call_die(handler_name);
397exit:
398 Py_DECREF(dict);
399 Py_DECREF(t);
400}
401
402static void python_process_event(union perf_event *perf_event,
403 struct perf_sample *sample,
404 struct perf_evsel *evsel,
405 struct machine *machine,
406 struct addr_location *al)
407{
408 switch (evsel->attr.type) {
409 case PERF_TYPE_TRACEPOINT:
410 python_process_tracepoint(perf_event, sample, evsel,
411 machine, al);
412 break;
413 /* Reserve for future process_hw/sw/raw APIs */
414 default:
415 python_process_general_event(perf_event, sample, evsel,
416 machine, al);
417 }
418}
419
420static int run_start_sub(void) 326static int run_start_sub(void)
421{ 327{
422 PyObject *handler, *retval; 328 PyObject *handler, *retval;
@@ -527,9 +433,9 @@ out:
527 return err; 433 return err;
528} 434}
529 435
530static int python_generate_script(struct pevent *pevent, const char *outfile) 436static int python_generate_script(const char *outfile)
531{ 437{
532 struct event_format *event = NULL; 438 struct event *event = NULL;
533 struct format_field *f; 439 struct format_field *f;
534 char fname[PATH_MAX]; 440 char fname[PATH_MAX];
535 int not_first, count; 441 int not_first, count;
@@ -576,7 +482,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)
576 fprintf(ofp, "def trace_end():\n"); 482 fprintf(ofp, "def trace_end():\n");
577 fprintf(ofp, "\tprint \"in trace_end\"\n\n"); 483 fprintf(ofp, "\tprint \"in trace_end\"\n\n");
578 484
579 while ((event = trace_find_next_event(pevent, event))) { 485 while ((event = trace_find_next_event(event))) {
580 fprintf(ofp, "def %s__%s(", event->system, event->name); 486 fprintf(ofp, "def %s__%s(", event->system, event->name);
581 fprintf(ofp, "event_name, "); 487 fprintf(ofp, "event_name, ");
582 fprintf(ofp, "context, "); 488 fprintf(ofp, "context, ");