diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 18:23:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 18:23:47 -0400 |
commit | c5617b200ac52e35f7e8cf05a17b0a2d50f6b3e9 (patch) | |
tree | 40d5e99660c77c5791392d349a93113c044dbf14 /include/trace | |
parent | cad719d86e9dbd06634eaba6401e022c8101d6b2 (diff) | |
parent | 49c177461bfbedeccbab22bf3905db2f9da7f1c3 (diff) |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (61 commits)
tracing: Add __used annotation to event variable
perf, trace: Fix !x86 build bug
perf report: Support multiple events on the TUI
perf annotate: Fix up usage of the build id cache
x86/mmiotrace: Remove redundant instruction prefix checks
perf annotate: Add TUI interface
perf tui: Remove annotate from popup menu after failure
perf report: Don't start the TUI if -D is used
perf: Fix getline undeclared
perf: Optimize perf_tp_event_match()
perf: Remove more code from the fastpath
perf: Optimize the !vmalloc backed buffer
perf: Optimize perf_output_copy()
perf: Fix wakeup storm for RO mmap()s
perf-record: Share per-cpu buffers
perf-record: Remove -M
perf: Ensure that IOC_OUTPUT isn't used to create multi-writer buffers
perf, trace: Optimize tracepoints by using per-tracepoint-per-cpu hlist to track events
perf, trace: Optimize tracepoints by removing IRQ-disable from perf/tracepoint interaction
perf tui: Allow disabling the TUI on a per command basis in ~/.perfconfig
...
Diffstat (limited to 'include/trace')
-rw-r--r-- | include/trace/ftrace.h | 249 | ||||
-rw-r--r-- | include/trace/syscall.h | 10 |
2 files changed, 97 insertions, 162 deletions
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 88c59c13ea7..3d685d1f2a0 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -62,10 +62,13 @@ | |||
62 | struct trace_entry ent; \ | 62 | struct trace_entry ent; \ |
63 | tstruct \ | 63 | tstruct \ |
64 | char __data[0]; \ | 64 | char __data[0]; \ |
65 | }; | 65 | }; \ |
66 | \ | ||
67 | static struct ftrace_event_class event_class_##name; | ||
68 | |||
66 | #undef DEFINE_EVENT | 69 | #undef DEFINE_EVENT |
67 | #define DEFINE_EVENT(template, name, proto, args) \ | 70 | #define DEFINE_EVENT(template, name, proto, args) \ |
68 | static struct ftrace_event_call \ | 71 | static struct ftrace_event_call __used \ |
69 | __attribute__((__aligned__(4))) event_##name | 72 | __attribute__((__aligned__(4))) event_##name |
70 | 73 | ||
71 | #undef DEFINE_EVENT_PRINT | 74 | #undef DEFINE_EVENT_PRINT |
@@ -147,7 +150,7 @@ | |||
147 | * | 150 | * |
148 | * entry = iter->ent; | 151 | * entry = iter->ent; |
149 | * | 152 | * |
150 | * if (entry->type != event_<call>.id) { | 153 | * if (entry->type != event_<call>->event.type) { |
151 | * WARN_ON_ONCE(1); | 154 | * WARN_ON_ONCE(1); |
152 | * return TRACE_TYPE_UNHANDLED; | 155 | * return TRACE_TYPE_UNHANDLED; |
153 | * } | 156 | * } |
@@ -206,18 +209,22 @@ | |||
206 | #undef DECLARE_EVENT_CLASS | 209 | #undef DECLARE_EVENT_CLASS |
207 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 210 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
208 | static notrace enum print_line_t \ | 211 | static notrace enum print_line_t \ |
209 | ftrace_raw_output_id_##call(int event_id, const char *name, \ | 212 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ |
210 | struct trace_iterator *iter, int flags) \ | 213 | struct trace_event *trace_event) \ |
211 | { \ | 214 | { \ |
215 | struct ftrace_event_call *event; \ | ||
212 | struct trace_seq *s = &iter->seq; \ | 216 | struct trace_seq *s = &iter->seq; \ |
213 | struct ftrace_raw_##call *field; \ | 217 | struct ftrace_raw_##call *field; \ |
214 | struct trace_entry *entry; \ | 218 | struct trace_entry *entry; \ |
215 | struct trace_seq *p; \ | 219 | struct trace_seq *p; \ |
216 | int ret; \ | 220 | int ret; \ |
217 | \ | 221 | \ |
222 | event = container_of(trace_event, struct ftrace_event_call, \ | ||
223 | event); \ | ||
224 | \ | ||
218 | entry = iter->ent; \ | 225 | entry = iter->ent; \ |
219 | \ | 226 | \ |
220 | if (entry->type != event_id) { \ | 227 | if (entry->type != event->event.type) { \ |
221 | WARN_ON_ONCE(1); \ | 228 | WARN_ON_ONCE(1); \ |
222 | return TRACE_TYPE_UNHANDLED; \ | 229 | return TRACE_TYPE_UNHANDLED; \ |
223 | } \ | 230 | } \ |
@@ -226,7 +233,7 @@ ftrace_raw_output_id_##call(int event_id, const char *name, \ | |||
226 | \ | 233 | \ |
227 | p = &get_cpu_var(ftrace_event_seq); \ | 234 | p = &get_cpu_var(ftrace_event_seq); \ |
228 | trace_seq_init(p); \ | 235 | trace_seq_init(p); \ |
229 | ret = trace_seq_printf(s, "%s: ", name); \ | 236 | ret = trace_seq_printf(s, "%s: ", event->name); \ |
230 | if (ret) \ | 237 | if (ret) \ |
231 | ret = trace_seq_printf(s, print); \ | 238 | ret = trace_seq_printf(s, print); \ |
232 | put_cpu(); \ | 239 | put_cpu(); \ |
@@ -234,21 +241,16 @@ ftrace_raw_output_id_##call(int event_id, const char *name, \ | |||
234 | return TRACE_TYPE_PARTIAL_LINE; \ | 241 | return TRACE_TYPE_PARTIAL_LINE; \ |
235 | \ | 242 | \ |
236 | return TRACE_TYPE_HANDLED; \ | 243 | return TRACE_TYPE_HANDLED; \ |
237 | } | 244 | } \ |
238 | 245 | static struct trace_event_functions ftrace_event_type_funcs_##call = { \ | |
239 | #undef DEFINE_EVENT | 246 | .trace = ftrace_raw_output_##call, \ |
240 | #define DEFINE_EVENT(template, name, proto, args) \ | 247 | }; |
241 | static notrace enum print_line_t \ | ||
242 | ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \ | ||
243 | { \ | ||
244 | return ftrace_raw_output_id_##template(event_##name.id, \ | ||
245 | #name, iter, flags); \ | ||
246 | } | ||
247 | 248 | ||
248 | #undef DEFINE_EVENT_PRINT | 249 | #undef DEFINE_EVENT_PRINT |
249 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ | 250 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ |
250 | static notrace enum print_line_t \ | 251 | static notrace enum print_line_t \ |
251 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | 252 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ |
253 | struct trace_event *event) \ | ||
252 | { \ | 254 | { \ |
253 | struct trace_seq *s = &iter->seq; \ | 255 | struct trace_seq *s = &iter->seq; \ |
254 | struct ftrace_raw_##template *field; \ | 256 | struct ftrace_raw_##template *field; \ |
@@ -258,7 +260,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
258 | \ | 260 | \ |
259 | entry = iter->ent; \ | 261 | entry = iter->ent; \ |
260 | \ | 262 | \ |
261 | if (entry->type != event_##call.id) { \ | 263 | if (entry->type != event_##call.event.type) { \ |
262 | WARN_ON_ONCE(1); \ | 264 | WARN_ON_ONCE(1); \ |
263 | return TRACE_TYPE_UNHANDLED; \ | 265 | return TRACE_TYPE_UNHANDLED; \ |
264 | } \ | 266 | } \ |
@@ -275,7 +277,10 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
275 | return TRACE_TYPE_PARTIAL_LINE; \ | 277 | return TRACE_TYPE_PARTIAL_LINE; \ |
276 | \ | 278 | \ |
277 | return TRACE_TYPE_HANDLED; \ | 279 | return TRACE_TYPE_HANDLED; \ |
278 | } | 280 | } \ |
281 | static struct trace_event_functions ftrace_event_type_funcs_##call = { \ | ||
282 | .trace = ftrace_raw_output_##call, \ | ||
283 | }; | ||
279 | 284 | ||
280 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 285 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
281 | 286 | ||
@@ -381,80 +386,18 @@ static inline notrace int ftrace_get_offsets_##call( \ | |||
381 | 386 | ||
382 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 387 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
383 | 388 | ||
384 | #ifdef CONFIG_PERF_EVENTS | ||
385 | |||
386 | /* | ||
387 | * Generate the functions needed for tracepoint perf_event support. | ||
388 | * | ||
389 | * NOTE: The insertion profile callback (ftrace_profile_<call>) is defined later | ||
390 | * | ||
391 | * static int ftrace_profile_enable_<call>(void) | ||
392 | * { | ||
393 | * return register_trace_<call>(ftrace_profile_<call>); | ||
394 | * } | ||
395 | * | ||
396 | * static void ftrace_profile_disable_<call>(void) | ||
397 | * { | ||
398 | * unregister_trace_<call>(ftrace_profile_<call>); | ||
399 | * } | ||
400 | * | ||
401 | */ | ||
402 | |||
403 | #undef DECLARE_EVENT_CLASS | ||
404 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) | ||
405 | |||
406 | #undef DEFINE_EVENT | ||
407 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
408 | \ | ||
409 | static void perf_trace_##name(proto); \ | ||
410 | \ | ||
411 | static notrace int \ | ||
412 | perf_trace_enable_##name(struct ftrace_event_call *unused) \ | ||
413 | { \ | ||
414 | return register_trace_##name(perf_trace_##name); \ | ||
415 | } \ | ||
416 | \ | ||
417 | static notrace void \ | ||
418 | perf_trace_disable_##name(struct ftrace_event_call *unused) \ | ||
419 | { \ | ||
420 | unregister_trace_##name(perf_trace_##name); \ | ||
421 | } | ||
422 | |||
423 | #undef DEFINE_EVENT_PRINT | ||
424 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | ||
425 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | ||
426 | |||
427 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | ||
428 | |||
429 | #endif /* CONFIG_PERF_EVENTS */ | ||
430 | |||
431 | /* | 389 | /* |
432 | * Stage 4 of the trace events. | 390 | * Stage 4 of the trace events. |
433 | * | 391 | * |
434 | * Override the macros in <trace/trace_events.h> to include the following: | 392 | * Override the macros in <trace/trace_events.h> to include the following: |
435 | * | 393 | * |
436 | * static void ftrace_event_<call>(proto) | ||
437 | * { | ||
438 | * event_trace_printk(_RET_IP_, "<call>: " <fmt>); | ||
439 | * } | ||
440 | * | ||
441 | * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused) | ||
442 | * { | ||
443 | * return register_trace_<call>(ftrace_event_<call>); | ||
444 | * } | ||
445 | * | ||
446 | * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) | ||
447 | * { | ||
448 | * unregister_trace_<call>(ftrace_event_<call>); | ||
449 | * } | ||
450 | * | ||
451 | * | ||
452 | * For those macros defined with TRACE_EVENT: | 394 | * For those macros defined with TRACE_EVENT: |
453 | * | 395 | * |
454 | * static struct ftrace_event_call event_<call>; | 396 | * static struct ftrace_event_call event_<call>; |
455 | * | 397 | * |
456 | * static void ftrace_raw_event_<call>(proto) | 398 | * static void ftrace_raw_event_<call>(void *__data, proto) |
457 | * { | 399 | * { |
400 | * struct ftrace_event_call *event_call = __data; | ||
458 | * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; | 401 | * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; |
459 | * struct ring_buffer_event *event; | 402 | * struct ring_buffer_event *event; |
460 | * struct ftrace_raw_<call> *entry; <-- defined in stage 1 | 403 | * struct ftrace_raw_<call> *entry; <-- defined in stage 1 |
@@ -469,7 +412,7 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ | |||
469 | * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); | 412 | * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); |
470 | * | 413 | * |
471 | * event = trace_current_buffer_lock_reserve(&buffer, | 414 | * event = trace_current_buffer_lock_reserve(&buffer, |
472 | * event_<call>.id, | 415 | * event_<call>->event.type, |
473 | * sizeof(*entry) + __data_size, | 416 | * sizeof(*entry) + __data_size, |
474 | * irq_flags, pc); | 417 | * irq_flags, pc); |
475 | * if (!event) | 418 | * if (!event) |
@@ -484,43 +427,42 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ | |||
484 | * event, irq_flags, pc); | 427 | * event, irq_flags, pc); |
485 | * } | 428 | * } |
486 | * | 429 | * |
487 | * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused) | ||
488 | * { | ||
489 | * return register_trace_<call>(ftrace_raw_event_<call>); | ||
490 | * } | ||
491 | * | ||
492 | * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) | ||
493 | * { | ||
494 | * unregister_trace_<call>(ftrace_raw_event_<call>); | ||
495 | * } | ||
496 | * | ||
497 | * static struct trace_event ftrace_event_type_<call> = { | 430 | * static struct trace_event ftrace_event_type_<call> = { |
498 | * .trace = ftrace_raw_output_<call>, <-- stage 2 | 431 | * .trace = ftrace_raw_output_<call>, <-- stage 2 |
499 | * }; | 432 | * }; |
500 | * | 433 | * |
501 | * static const char print_fmt_<call>[] = <TP_printk>; | 434 | * static const char print_fmt_<call>[] = <TP_printk>; |
502 | * | 435 | * |
436 | * static struct ftrace_event_class __used event_class_<template> = { | ||
437 | * .system = "<system>", | ||
438 | * .define_fields = ftrace_define_fields_<call>, | ||
439 | * .fields = LIST_HEAD_INIT(event_class_##call.fields), | ||
440 | * .raw_init = trace_event_raw_init, | ||
441 | * .probe = ftrace_raw_event_##call, | ||
442 | * }; | ||
443 | * | ||
503 | * static struct ftrace_event_call __used | 444 | * static struct ftrace_event_call __used |
504 | * __attribute__((__aligned__(4))) | 445 | * __attribute__((__aligned__(4))) |
505 | * __attribute__((section("_ftrace_events"))) event_<call> = { | 446 | * __attribute__((section("_ftrace_events"))) event_<call> = { |
506 | * .name = "<call>", | 447 | * .name = "<call>", |
507 | * .system = "<system>", | 448 | * .class = event_class_<template>, |
508 | * .raw_init = trace_event_raw_init, | 449 | * .event = &ftrace_event_type_<call>, |
509 | * .regfunc = ftrace_reg_event_<call>, | ||
510 | * .unregfunc = ftrace_unreg_event_<call>, | ||
511 | * .print_fmt = print_fmt_<call>, | 450 | * .print_fmt = print_fmt_<call>, |
512 | * .define_fields = ftrace_define_fields_<call>, | 451 | * }; |
513 | * } | ||
514 | * | 452 | * |
515 | */ | 453 | */ |
516 | 454 | ||
517 | #ifdef CONFIG_PERF_EVENTS | 455 | #ifdef CONFIG_PERF_EVENTS |
518 | 456 | ||
457 | #define _TRACE_PERF_PROTO(call, proto) \ | ||
458 | static notrace void \ | ||
459 | perf_trace_##call(void *__data, proto); | ||
460 | |||
519 | #define _TRACE_PERF_INIT(call) \ | 461 | #define _TRACE_PERF_INIT(call) \ |
520 | .perf_event_enable = perf_trace_enable_##call, \ | 462 | .perf_probe = perf_trace_##call, |
521 | .perf_event_disable = perf_trace_disable_##call, | ||
522 | 463 | ||
523 | #else | 464 | #else |
465 | #define _TRACE_PERF_PROTO(call, proto) | ||
524 | #define _TRACE_PERF_INIT(call) | 466 | #define _TRACE_PERF_INIT(call) |
525 | #endif /* CONFIG_PERF_EVENTS */ | 467 | #endif /* CONFIG_PERF_EVENTS */ |
526 | 468 | ||
@@ -554,9 +496,9 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ | |||
554 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 496 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
555 | \ | 497 | \ |
556 | static notrace void \ | 498 | static notrace void \ |
557 | ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ | 499 | ftrace_raw_event_##call(void *__data, proto) \ |
558 | proto) \ | ||
559 | { \ | 500 | { \ |
501 | struct ftrace_event_call *event_call = __data; \ | ||
560 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 502 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
561 | struct ring_buffer_event *event; \ | 503 | struct ring_buffer_event *event; \ |
562 | struct ftrace_raw_##call *entry; \ | 504 | struct ftrace_raw_##call *entry; \ |
@@ -571,7 +513,7 @@ ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ | |||
571 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ | 513 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ |
572 | \ | 514 | \ |
573 | event = trace_current_buffer_lock_reserve(&buffer, \ | 515 | event = trace_current_buffer_lock_reserve(&buffer, \ |
574 | event_call->id, \ | 516 | event_call->event.type, \ |
575 | sizeof(*entry) + __data_size, \ | 517 | sizeof(*entry) + __data_size, \ |
576 | irq_flags, pc); \ | 518 | irq_flags, pc); \ |
577 | if (!event) \ | 519 | if (!event) \ |
@@ -586,34 +528,21 @@ ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ | |||
586 | trace_nowake_buffer_unlock_commit(buffer, \ | 528 | trace_nowake_buffer_unlock_commit(buffer, \ |
587 | event, irq_flags, pc); \ | 529 | event, irq_flags, pc); \ |
588 | } | 530 | } |
531 | /* | ||
532 | * The ftrace_test_probe is compiled out, it is only here as a build time check | ||
533 | * to make sure that if the tracepoint handling changes, the ftrace probe will | ||
534 | * fail to compile unless it too is updated. | ||
535 | */ | ||
589 | 536 | ||
590 | #undef DEFINE_EVENT | 537 | #undef DEFINE_EVENT |
591 | #define DEFINE_EVENT(template, call, proto, args) \ | 538 | #define DEFINE_EVENT(template, call, proto, args) \ |
592 | \ | 539 | static inline void ftrace_test_probe_##call(void) \ |
593 | static notrace void ftrace_raw_event_##call(proto) \ | ||
594 | { \ | ||
595 | ftrace_raw_event_id_##template(&event_##call, args); \ | ||
596 | } \ | ||
597 | \ | ||
598 | static notrace int \ | ||
599 | ftrace_raw_reg_event_##call(struct ftrace_event_call *unused) \ | ||
600 | { \ | 540 | { \ |
601 | return register_trace_##call(ftrace_raw_event_##call); \ | 541 | check_trace_callback_type_##call(ftrace_raw_event_##template); \ |
602 | } \ | 542 | } |
603 | \ | ||
604 | static notrace void \ | ||
605 | ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused) \ | ||
606 | { \ | ||
607 | unregister_trace_##call(ftrace_raw_event_##call); \ | ||
608 | } \ | ||
609 | \ | ||
610 | static struct trace_event ftrace_event_type_##call = { \ | ||
611 | .trace = ftrace_raw_output_##call, \ | ||
612 | }; | ||
613 | 543 | ||
614 | #undef DEFINE_EVENT_PRINT | 544 | #undef DEFINE_EVENT_PRINT |
615 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 545 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) |
616 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | ||
617 | 546 | ||
618 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 547 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
619 | 548 | ||
@@ -630,7 +559,16 @@ static struct trace_event ftrace_event_type_##call = { \ | |||
630 | 559 | ||
631 | #undef DECLARE_EVENT_CLASS | 560 | #undef DECLARE_EVENT_CLASS |
632 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 561 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
633 | static const char print_fmt_##call[] = print; | 562 | _TRACE_PERF_PROTO(call, PARAMS(proto)); \ |
563 | static const char print_fmt_##call[] = print; \ | ||
564 | static struct ftrace_event_class __used event_class_##call = { \ | ||
565 | .system = __stringify(TRACE_SYSTEM), \ | ||
566 | .define_fields = ftrace_define_fields_##call, \ | ||
567 | .fields = LIST_HEAD_INIT(event_class_##call.fields),\ | ||
568 | .raw_init = trace_event_raw_init, \ | ||
569 | .probe = ftrace_raw_event_##call, \ | ||
570 | _TRACE_PERF_INIT(call) \ | ||
571 | }; | ||
634 | 572 | ||
635 | #undef DEFINE_EVENT | 573 | #undef DEFINE_EVENT |
636 | #define DEFINE_EVENT(template, call, proto, args) \ | 574 | #define DEFINE_EVENT(template, call, proto, args) \ |
@@ -639,15 +577,10 @@ static struct ftrace_event_call __used \ | |||
639 | __attribute__((__aligned__(4))) \ | 577 | __attribute__((__aligned__(4))) \ |
640 | __attribute__((section("_ftrace_events"))) event_##call = { \ | 578 | __attribute__((section("_ftrace_events"))) event_##call = { \ |
641 | .name = #call, \ | 579 | .name = #call, \ |
642 | .system = __stringify(TRACE_SYSTEM), \ | 580 | .class = &event_class_##template, \ |
643 | .event = &ftrace_event_type_##call, \ | 581 | .event.funcs = &ftrace_event_type_funcs_##template, \ |
644 | .raw_init = trace_event_raw_init, \ | ||
645 | .regfunc = ftrace_raw_reg_event_##call, \ | ||
646 | .unregfunc = ftrace_raw_unreg_event_##call, \ | ||
647 | .print_fmt = print_fmt_##template, \ | 582 | .print_fmt = print_fmt_##template, \ |
648 | .define_fields = ftrace_define_fields_##template, \ | 583 | }; |
649 | _TRACE_PERF_INIT(call) \ | ||
650 | } | ||
651 | 584 | ||
652 | #undef DEFINE_EVENT_PRINT | 585 | #undef DEFINE_EVENT_PRINT |
653 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ | 586 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ |
@@ -658,14 +591,9 @@ static struct ftrace_event_call __used \ | |||
658 | __attribute__((__aligned__(4))) \ | 591 | __attribute__((__aligned__(4))) \ |
659 | __attribute__((section("_ftrace_events"))) event_##call = { \ | 592 | __attribute__((section("_ftrace_events"))) event_##call = { \ |
660 | .name = #call, \ | 593 | .name = #call, \ |
661 | .system = __stringify(TRACE_SYSTEM), \ | 594 | .class = &event_class_##template, \ |
662 | .event = &ftrace_event_type_##call, \ | 595 | .event.funcs = &ftrace_event_type_funcs_##call, \ |
663 | .raw_init = trace_event_raw_init, \ | ||
664 | .regfunc = ftrace_raw_reg_event_##call, \ | ||
665 | .unregfunc = ftrace_raw_unreg_event_##call, \ | ||
666 | .print_fmt = print_fmt_##call, \ | 596 | .print_fmt = print_fmt_##call, \ |
667 | .define_fields = ftrace_define_fields_##template, \ | ||
668 | _TRACE_PERF_INIT(call) \ | ||
669 | } | 597 | } |
670 | 598 | ||
671 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 599 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
@@ -765,17 +693,20 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
765 | #undef DECLARE_EVENT_CLASS | 693 | #undef DECLARE_EVENT_CLASS |
766 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 694 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
767 | static notrace void \ | 695 | static notrace void \ |
768 | perf_trace_templ_##call(struct ftrace_event_call *event_call, \ | 696 | perf_trace_##call(void *__data, proto) \ |
769 | struct pt_regs *__regs, proto) \ | ||
770 | { \ | 697 | { \ |
698 | struct ftrace_event_call *event_call = __data; \ | ||
771 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 699 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
772 | struct ftrace_raw_##call *entry; \ | 700 | struct ftrace_raw_##call *entry; \ |
701 | struct pt_regs __regs; \ | ||
773 | u64 __addr = 0, __count = 1; \ | 702 | u64 __addr = 0, __count = 1; \ |
774 | unsigned long irq_flags; \ | 703 | struct hlist_head *head; \ |
775 | int __entry_size; \ | 704 | int __entry_size; \ |
776 | int __data_size; \ | 705 | int __data_size; \ |
777 | int rctx; \ | 706 | int rctx; \ |
778 | \ | 707 | \ |
708 | perf_fetch_caller_regs(&__regs, 1); \ | ||
709 | \ | ||
779 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ | 710 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ |
780 | __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ | 711 | __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ |
781 | sizeof(u64)); \ | 712 | sizeof(u64)); \ |
@@ -784,32 +715,34 @@ perf_trace_templ_##call(struct ftrace_event_call *event_call, \ | |||
784 | if (WARN_ONCE(__entry_size > PERF_MAX_TRACE_SIZE, \ | 715 | if (WARN_ONCE(__entry_size > PERF_MAX_TRACE_SIZE, \ |
785 | "profile buffer not large enough")) \ | 716 | "profile buffer not large enough")) \ |
786 | return; \ | 717 | return; \ |
718 | \ | ||
787 | entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare( \ | 719 | entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare( \ |
788 | __entry_size, event_call->id, &rctx, &irq_flags); \ | 720 | __entry_size, event_call->event.type, &__regs, &rctx); \ |
789 | if (!entry) \ | 721 | if (!entry) \ |
790 | return; \ | 722 | return; \ |
723 | \ | ||
791 | tstruct \ | 724 | tstruct \ |
792 | \ | 725 | \ |
793 | { assign; } \ | 726 | { assign; } \ |
794 | \ | 727 | \ |
728 | head = per_cpu_ptr(event_call->perf_events, smp_processor_id());\ | ||
795 | perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ | 729 | perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ |
796 | __count, irq_flags, __regs); \ | 730 | __count, &__regs, head); \ |
797 | } | 731 | } |
798 | 732 | ||
733 | /* | ||
734 | * This part is compiled out, it is only here as a build time check | ||
735 | * to make sure that if the tracepoint handling changes, the | ||
736 | * perf probe will fail to compile unless it too is updated. | ||
737 | */ | ||
799 | #undef DEFINE_EVENT | 738 | #undef DEFINE_EVENT |
800 | #define DEFINE_EVENT(template, call, proto, args) \ | 739 | #define DEFINE_EVENT(template, call, proto, args) \ |
801 | static notrace void perf_trace_##call(proto) \ | 740 | static inline void perf_test_probe_##call(void) \ |
802 | { \ | 741 | { \ |
803 | struct ftrace_event_call *event_call = &event_##call; \ | 742 | check_trace_callback_type_##call(perf_trace_##template); \ |
804 | struct pt_regs *__regs = &get_cpu_var(perf_trace_regs); \ | ||
805 | \ | ||
806 | perf_fetch_caller_regs(__regs, 1); \ | ||
807 | \ | ||
808 | perf_trace_templ_##template(event_call, __regs, args); \ | ||
809 | \ | ||
810 | put_cpu_var(perf_trace_regs); \ | ||
811 | } | 743 | } |
812 | 744 | ||
745 | |||
813 | #undef DEFINE_EVENT_PRINT | 746 | #undef DEFINE_EVENT_PRINT |
814 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 747 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
815 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | 748 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) |
diff --git a/include/trace/syscall.h b/include/trace/syscall.h index e5e5f48dbfb..257e08960d7 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h | |||
@@ -25,6 +25,8 @@ struct syscall_metadata { | |||
25 | int nb_args; | 25 | int nb_args; |
26 | const char **types; | 26 | const char **types; |
27 | const char **args; | 27 | const char **args; |
28 | struct list_head enter_fields; | ||
29 | struct list_head exit_fields; | ||
28 | 30 | ||
29 | struct ftrace_event_call *enter_event; | 31 | struct ftrace_event_call *enter_event; |
30 | struct ftrace_event_call *exit_event; | 32 | struct ftrace_event_call *exit_event; |
@@ -34,16 +36,16 @@ struct syscall_metadata { | |||
34 | extern unsigned long arch_syscall_addr(int nr); | 36 | extern unsigned long arch_syscall_addr(int nr); |
35 | extern int init_syscall_trace(struct ftrace_event_call *call); | 37 | extern int init_syscall_trace(struct ftrace_event_call *call); |
36 | 38 | ||
37 | extern int syscall_enter_define_fields(struct ftrace_event_call *call); | ||
38 | extern int syscall_exit_define_fields(struct ftrace_event_call *call); | ||
39 | extern int reg_event_syscall_enter(struct ftrace_event_call *call); | 39 | extern int reg_event_syscall_enter(struct ftrace_event_call *call); |
40 | extern void unreg_event_syscall_enter(struct ftrace_event_call *call); | 40 | extern void unreg_event_syscall_enter(struct ftrace_event_call *call); |
41 | extern int reg_event_syscall_exit(struct ftrace_event_call *call); | 41 | extern int reg_event_syscall_exit(struct ftrace_event_call *call); |
42 | extern void unreg_event_syscall_exit(struct ftrace_event_call *call); | 42 | extern void unreg_event_syscall_exit(struct ftrace_event_call *call); |
43 | extern int | 43 | extern int |
44 | ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s); | 44 | ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s); |
45 | enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags); | 45 | enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags, |
46 | enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags); | 46 | struct trace_event *event); |
47 | enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags, | ||
48 | struct trace_event *event); | ||
47 | #endif | 49 | #endif |
48 | 50 | ||
49 | #ifdef CONFIG_PERF_EVENTS | 51 | #ifdef CONFIG_PERF_EVENTS |