diff options
Diffstat (limited to 'kernel/trace/trace.h')
| -rw-r--r-- | kernel/trace/trace.h | 82 |
1 files changed, 64 insertions, 18 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 405cb850b75d..7fa33cab6962 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/ftrace.h> | 11 | #include <linux/ftrace.h> |
| 12 | #include <trace/boot.h> | 12 | #include <trace/boot.h> |
| 13 | #include <linux/kmemtrace.h> | 13 | #include <linux/kmemtrace.h> |
| 14 | #include <linux/hw_breakpoint.h> | ||
| 14 | 15 | ||
| 15 | #include <linux/trace_seq.h> | 16 | #include <linux/trace_seq.h> |
| 16 | #include <linux/ftrace_event.h> | 17 | #include <linux/ftrace_event.h> |
| @@ -37,6 +38,7 @@ enum trace_type { | |||
| 37 | TRACE_KMEM_ALLOC, | 38 | TRACE_KMEM_ALLOC, |
| 38 | TRACE_KMEM_FREE, | 39 | TRACE_KMEM_FREE, |
| 39 | TRACE_BLK, | 40 | TRACE_BLK, |
| 41 | TRACE_KSYM, | ||
| 40 | 42 | ||
| 41 | __TRACE_LAST_TYPE, | 43 | __TRACE_LAST_TYPE, |
| 42 | }; | 44 | }; |
| @@ -98,9 +100,32 @@ struct syscall_trace_enter { | |||
| 98 | struct syscall_trace_exit { | 100 | struct syscall_trace_exit { |
| 99 | struct trace_entry ent; | 101 | struct trace_entry ent; |
| 100 | int nr; | 102 | int nr; |
| 101 | unsigned long ret; | 103 | long ret; |
| 102 | }; | 104 | }; |
| 103 | 105 | ||
| 106 | struct kprobe_trace_entry { | ||
| 107 | struct trace_entry ent; | ||
| 108 | unsigned long ip; | ||
| 109 | int nargs; | ||
| 110 | unsigned long args[]; | ||
| 111 | }; | ||
| 112 | |||
| 113 | #define SIZEOF_KPROBE_TRACE_ENTRY(n) \ | ||
| 114 | (offsetof(struct kprobe_trace_entry, args) + \ | ||
| 115 | (sizeof(unsigned long) * (n))) | ||
| 116 | |||
| 117 | struct kretprobe_trace_entry { | ||
| 118 | struct trace_entry ent; | ||
| 119 | unsigned long func; | ||
| 120 | unsigned long ret_ip; | ||
| 121 | int nargs; | ||
| 122 | unsigned long args[]; | ||
| 123 | }; | ||
| 124 | |||
| 125 | #define SIZEOF_KRETPROBE_TRACE_ENTRY(n) \ | ||
| 126 | (offsetof(struct kretprobe_trace_entry, args) + \ | ||
| 127 | (sizeof(unsigned long) * (n))) | ||
| 128 | |||
| 104 | /* | 129 | /* |
| 105 | * trace_flag_type is an enumeration that holds different | 130 | * trace_flag_type is an enumeration that holds different |
| 106 | * states when a trace occurs. These are: | 131 | * states when a trace occurs. These are: |
| @@ -209,6 +234,7 @@ extern void __ftrace_bad_type(void); | |||
| 209 | TRACE_KMEM_ALLOC); \ | 234 | TRACE_KMEM_ALLOC); \ |
| 210 | IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \ | 235 | IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \ |
| 211 | TRACE_KMEM_FREE); \ | 236 | TRACE_KMEM_FREE); \ |
| 237 | IF_ASSIGN(var, ent, struct ksym_trace_entry, TRACE_KSYM);\ | ||
| 212 | __ftrace_bad_type(); \ | 238 | __ftrace_bad_type(); \ |
| 213 | } while (0) | 239 | } while (0) |
| 214 | 240 | ||
| @@ -246,6 +272,7 @@ struct tracer_flags { | |||
| 246 | * @pipe_open: called when the trace_pipe file is opened | 272 | * @pipe_open: called when the trace_pipe file is opened |
| 247 | * @wait_pipe: override how the user waits for traces on trace_pipe | 273 | * @wait_pipe: override how the user waits for traces on trace_pipe |
| 248 | * @close: called when the trace file is released | 274 | * @close: called when the trace file is released |
| 275 | * @pipe_close: called when the trace_pipe file is released | ||
| 249 | * @read: override the default read callback on trace_pipe | 276 | * @read: override the default read callback on trace_pipe |
| 250 | * @splice_read: override the default splice_read callback on trace_pipe | 277 | * @splice_read: override the default splice_read callback on trace_pipe |
| 251 | * @selftest: selftest to run on boot (see trace_selftest.c) | 278 | * @selftest: selftest to run on boot (see trace_selftest.c) |
| @@ -264,6 +291,7 @@ struct tracer { | |||
| 264 | void (*pipe_open)(struct trace_iterator *iter); | 291 | void (*pipe_open)(struct trace_iterator *iter); |
| 265 | void (*wait_pipe)(struct trace_iterator *iter); | 292 | void (*wait_pipe)(struct trace_iterator *iter); |
| 266 | void (*close)(struct trace_iterator *iter); | 293 | void (*close)(struct trace_iterator *iter); |
| 294 | void (*pipe_close)(struct trace_iterator *iter); | ||
| 267 | ssize_t (*read)(struct trace_iterator *iter, | 295 | ssize_t (*read)(struct trace_iterator *iter, |
| 268 | struct file *filp, char __user *ubuf, | 296 | struct file *filp, char __user *ubuf, |
| 269 | size_t cnt, loff_t *ppos); | 297 | size_t cnt, loff_t *ppos); |
| @@ -364,6 +392,8 @@ int register_tracer(struct tracer *type); | |||
| 364 | void unregister_tracer(struct tracer *type); | 392 | void unregister_tracer(struct tracer *type); |
| 365 | int is_tracing_stopped(void); | 393 | int is_tracing_stopped(void); |
| 366 | 394 | ||
| 395 | extern int process_new_ksym_entry(char *ksymname, int op, unsigned long addr); | ||
| 396 | |||
| 367 | extern unsigned long nsecs_to_usecs(unsigned long nsecs); | 397 | extern unsigned long nsecs_to_usecs(unsigned long nsecs); |
| 368 | 398 | ||
| 369 | #ifdef CONFIG_TRACER_MAX_TRACE | 399 | #ifdef CONFIG_TRACER_MAX_TRACE |
| @@ -438,6 +468,8 @@ extern int trace_selftest_startup_branch(struct tracer *trace, | |||
| 438 | struct trace_array *tr); | 468 | struct trace_array *tr); |
| 439 | extern int trace_selftest_startup_hw_branches(struct tracer *trace, | 469 | extern int trace_selftest_startup_hw_branches(struct tracer *trace, |
| 440 | struct trace_array *tr); | 470 | struct trace_array *tr); |
| 471 | extern int trace_selftest_startup_ksym(struct tracer *trace, | ||
| 472 | struct trace_array *tr); | ||
| 441 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | 473 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ |
| 442 | 474 | ||
| 443 | extern void *head_page(struct trace_array_cpu *data); | 475 | extern void *head_page(struct trace_array_cpu *data); |
| @@ -483,10 +515,6 @@ static inline int ftrace_graph_addr(unsigned long addr) | |||
| 483 | return 0; | 515 | return 0; |
| 484 | } | 516 | } |
| 485 | #else | 517 | #else |
| 486 | static inline int ftrace_trace_addr(unsigned long addr) | ||
| 487 | { | ||
| 488 | return 1; | ||
| 489 | } | ||
| 490 | static inline int ftrace_graph_addr(unsigned long addr) | 518 | static inline int ftrace_graph_addr(unsigned long addr) |
| 491 | { | 519 | { |
| 492 | return 1; | 520 | return 1; |
| @@ -500,12 +528,12 @@ print_graph_function(struct trace_iterator *iter) | |||
| 500 | } | 528 | } |
| 501 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 529 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
| 502 | 530 | ||
| 503 | extern struct pid *ftrace_pid_trace; | 531 | extern struct list_head ftrace_pids; |
| 504 | 532 | ||
| 505 | #ifdef CONFIG_FUNCTION_TRACER | 533 | #ifdef CONFIG_FUNCTION_TRACER |
| 506 | static inline int ftrace_trace_task(struct task_struct *task) | 534 | static inline int ftrace_trace_task(struct task_struct *task) |
| 507 | { | 535 | { |
| 508 | if (!ftrace_pid_trace) | 536 | if (list_empty(&ftrace_pids)) |
| 509 | return 1; | 537 | return 1; |
| 510 | 538 | ||
| 511 | return test_tsk_trace_trace(task); | 539 | return test_tsk_trace_trace(task); |
| @@ -687,7 +715,6 @@ struct event_filter { | |||
| 687 | int n_preds; | 715 | int n_preds; |
| 688 | struct filter_pred **preds; | 716 | struct filter_pred **preds; |
| 689 | char *filter_string; | 717 | char *filter_string; |
| 690 | bool no_reset; | ||
| 691 | }; | 718 | }; |
| 692 | 719 | ||
| 693 | struct event_subsystem { | 720 | struct event_subsystem { |
| @@ -699,22 +726,40 @@ struct event_subsystem { | |||
| 699 | }; | 726 | }; |
| 700 | 727 | ||
| 701 | struct filter_pred; | 728 | struct filter_pred; |
| 729 | struct regex; | ||
| 702 | 730 | ||
| 703 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event, | 731 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event, |
| 704 | int val1, int val2); | 732 | int val1, int val2); |
| 705 | 733 | ||
| 734 | typedef int (*regex_match_func)(char *str, struct regex *r, int len); | ||
| 735 | |||
| 736 | enum regex_type { | ||
| 737 | MATCH_FULL = 0, | ||
| 738 | MATCH_FRONT_ONLY, | ||
| 739 | MATCH_MIDDLE_ONLY, | ||
| 740 | MATCH_END_ONLY, | ||
| 741 | }; | ||
| 742 | |||
| 743 | struct regex { | ||
| 744 | char pattern[MAX_FILTER_STR_VAL]; | ||
| 745 | int len; | ||
| 746 | int field_len; | ||
| 747 | regex_match_func match; | ||
| 748 | }; | ||
| 749 | |||
| 706 | struct filter_pred { | 750 | struct filter_pred { |
| 707 | filter_pred_fn_t fn; | 751 | filter_pred_fn_t fn; |
| 708 | u64 val; | 752 | u64 val; |
| 709 | char str_val[MAX_FILTER_STR_VAL]; | 753 | struct regex regex; |
| 710 | int str_len; | 754 | char *field_name; |
| 711 | char *field_name; | 755 | int offset; |
| 712 | int offset; | 756 | int not; |
| 713 | int not; | 757 | int op; |
| 714 | int op; | 758 | int pop_n; |
| 715 | int pop_n; | ||
| 716 | }; | 759 | }; |
| 717 | 760 | ||
| 761 | extern enum regex_type | ||
| 762 | filter_parse_regex(char *buff, int len, char **search, int *not); | ||
| 718 | extern void print_event_filter(struct ftrace_event_call *call, | 763 | extern void print_event_filter(struct ftrace_event_call *call, |
| 719 | struct trace_seq *s); | 764 | struct trace_seq *s); |
| 720 | extern int apply_event_filter(struct ftrace_event_call *call, | 765 | extern int apply_event_filter(struct ftrace_event_call *call, |
| @@ -730,7 +775,8 @@ filter_check_discard(struct ftrace_event_call *call, void *rec, | |||
| 730 | struct ring_buffer *buffer, | 775 | struct ring_buffer *buffer, |
| 731 | struct ring_buffer_event *event) | 776 | struct ring_buffer_event *event) |
| 732 | { | 777 | { |
| 733 | if (unlikely(call->filter_active) && !filter_match_preds(call, rec)) { | 778 | if (unlikely(call->filter_active) && |
| 779 | !filter_match_preds(call->filter, rec)) { | ||
| 734 | ring_buffer_discard_commit(buffer, event); | 780 | ring_buffer_discard_commit(buffer, event); |
| 735 | return 1; | 781 | return 1; |
| 736 | } | 782 | } |
