diff options
Diffstat (limited to 'kernel/trace/trace.h')
| -rw-r--r-- | kernel/trace/trace.h | 243 |
1 files changed, 98 insertions, 145 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index e685ac2b2ba1..6e735d4771f8 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -9,9 +9,12 @@ | |||
| 9 | #include <linux/mmiotrace.h> | 9 | #include <linux/mmiotrace.h> |
| 10 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
| 11 | #include <trace/boot.h> | 11 | #include <trace/boot.h> |
| 12 | #include <trace/kmemtrace.h> | 12 | #include <linux/kmemtrace.h> |
| 13 | #include <trace/power.h> | 13 | #include <trace/power.h> |
| 14 | 14 | ||
| 15 | #include <linux/trace_seq.h> | ||
| 16 | #include <linux/ftrace_event.h> | ||
| 17 | |||
| 15 | enum trace_type { | 18 | enum trace_type { |
| 16 | __TRACE_FIRST_TYPE = 0, | 19 | __TRACE_FIRST_TYPE = 0, |
| 17 | 20 | ||
| @@ -42,20 +45,6 @@ enum trace_type { | |||
| 42 | }; | 45 | }; |
| 43 | 46 | ||
| 44 | /* | 47 | /* |
| 45 | * The trace entry - the most basic unit of tracing. This is what | ||
| 46 | * is printed in the end as a single line in the trace output, such as: | ||
| 47 | * | ||
| 48 | * bash-15816 [01] 235.197585: idle_cpu <- irq_enter | ||
| 49 | */ | ||
| 50 | struct trace_entry { | ||
| 51 | unsigned char type; | ||
| 52 | unsigned char flags; | ||
| 53 | unsigned char preempt_count; | ||
| 54 | int pid; | ||
| 55 | int tgid; | ||
| 56 | }; | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Function trace entry - function address and parent function addres: | 48 | * Function trace entry - function address and parent function addres: |
| 60 | */ | 49 | */ |
| 61 | struct ftrace_entry { | 50 | struct ftrace_entry { |
| @@ -263,8 +252,6 @@ struct trace_array_cpu { | |||
| 263 | char comm[TASK_COMM_LEN]; | 252 | char comm[TASK_COMM_LEN]; |
| 264 | }; | 253 | }; |
| 265 | 254 | ||
| 266 | struct trace_iterator; | ||
| 267 | |||
| 268 | /* | 255 | /* |
| 269 | * The trace array - an array of per-CPU trace arrays. This is the | 256 | * The trace array - an array of per-CPU trace arrays. This is the |
| 270 | * highest level data structure that individual tracers deal with. | 257 | * highest level data structure that individual tracers deal with. |
| @@ -339,15 +326,6 @@ extern void __ftrace_bad_type(void); | |||
| 339 | __ftrace_bad_type(); \ | 326 | __ftrace_bad_type(); \ |
| 340 | } while (0) | 327 | } while (0) |
| 341 | 328 | ||
| 342 | /* Return values for print_line callback */ | ||
| 343 | enum print_line_t { | ||
| 344 | TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */ | ||
| 345 | TRACE_TYPE_HANDLED = 1, | ||
| 346 | TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */ | ||
| 347 | TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */ | ||
| 348 | }; | ||
| 349 | |||
| 350 | |||
| 351 | /* | 329 | /* |
| 352 | * An option specific to a tracer. This is a boolean value. | 330 | * An option specific to a tracer. This is a boolean value. |
| 353 | * The bit is the bit index that sets its value on the | 331 | * The bit is the bit index that sets its value on the |
| @@ -423,60 +401,30 @@ struct tracer { | |||
| 423 | struct tracer_stat *stats; | 401 | struct tracer_stat *stats; |
| 424 | }; | 402 | }; |
| 425 | 403 | ||
| 426 | struct trace_seq { | ||
| 427 | unsigned char buffer[PAGE_SIZE]; | ||
| 428 | unsigned int len; | ||
| 429 | unsigned int readpos; | ||
| 430 | }; | ||
| 431 | |||
| 432 | static inline void | ||
| 433 | trace_seq_init(struct trace_seq *s) | ||
| 434 | { | ||
| 435 | s->len = 0; | ||
| 436 | s->readpos = 0; | ||
| 437 | } | ||
| 438 | |||
| 439 | 404 | ||
| 440 | #define TRACE_PIPE_ALL_CPU -1 | 405 | #define TRACE_PIPE_ALL_CPU -1 |
| 441 | 406 | ||
| 442 | /* | ||
| 443 | * Trace iterator - used by printout routines who present trace | ||
| 444 | * results to users and which routines might sleep, etc: | ||
| 445 | */ | ||
| 446 | struct trace_iterator { | ||
| 447 | struct trace_array *tr; | ||
| 448 | struct tracer *trace; | ||
| 449 | void *private; | ||
| 450 | int cpu_file; | ||
| 451 | struct mutex mutex; | ||
| 452 | struct ring_buffer_iter *buffer_iter[NR_CPUS]; | ||
| 453 | |||
| 454 | /* The below is zeroed out in pipe_read */ | ||
| 455 | struct trace_seq seq; | ||
| 456 | struct trace_entry *ent; | ||
| 457 | int cpu; | ||
| 458 | u64 ts; | ||
| 459 | |||
| 460 | unsigned long iter_flags; | ||
| 461 | loff_t pos; | ||
| 462 | long idx; | ||
| 463 | |||
| 464 | cpumask_var_t started; | ||
| 465 | }; | ||
| 466 | |||
| 467 | int tracer_init(struct tracer *t, struct trace_array *tr); | 407 | int tracer_init(struct tracer *t, struct trace_array *tr); |
| 468 | int tracing_is_enabled(void); | 408 | int tracing_is_enabled(void); |
| 469 | void trace_wake_up(void); | 409 | void trace_wake_up(void); |
| 470 | void tracing_reset(struct trace_array *tr, int cpu); | 410 | void tracing_reset(struct trace_array *tr, int cpu); |
| 471 | void tracing_reset_online_cpus(struct trace_array *tr); | 411 | void tracing_reset_online_cpus(struct trace_array *tr); |
| 412 | void tracing_reset_current(int cpu); | ||
| 413 | void tracing_reset_current_online_cpus(void); | ||
| 472 | int tracing_open_generic(struct inode *inode, struct file *filp); | 414 | int tracing_open_generic(struct inode *inode, struct file *filp); |
| 415 | struct dentry *trace_create_file(const char *name, | ||
| 416 | mode_t mode, | ||
| 417 | struct dentry *parent, | ||
| 418 | void *data, | ||
| 419 | const struct file_operations *fops); | ||
| 420 | |||
| 473 | struct dentry *tracing_init_dentry(void); | 421 | struct dentry *tracing_init_dentry(void); |
| 474 | void init_tracer_sysprof_debugfs(struct dentry *d_tracer); | 422 | void init_tracer_sysprof_debugfs(struct dentry *d_tracer); |
| 475 | 423 | ||
| 476 | struct ring_buffer_event; | 424 | struct ring_buffer_event; |
| 477 | 425 | ||
| 478 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, | 426 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, |
| 479 | unsigned char type, | 427 | int type, |
| 480 | unsigned long len, | 428 | unsigned long len, |
| 481 | unsigned long flags, | 429 | unsigned long flags, |
| 482 | int pc); | 430 | int pc); |
| @@ -484,14 +432,6 @@ void trace_buffer_unlock_commit(struct trace_array *tr, | |||
| 484 | struct ring_buffer_event *event, | 432 | struct ring_buffer_event *event, |
| 485 | unsigned long flags, int pc); | 433 | unsigned long flags, int pc); |
| 486 | 434 | ||
| 487 | struct ring_buffer_event * | ||
| 488 | trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, | ||
| 489 | unsigned long flags, int pc); | ||
| 490 | void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, | ||
| 491 | unsigned long flags, int pc); | ||
| 492 | void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, | ||
| 493 | unsigned long flags, int pc); | ||
| 494 | |||
| 495 | struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, | 435 | struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, |
| 496 | struct trace_array_cpu *data); | 436 | struct trace_array_cpu *data); |
| 497 | 437 | ||
| @@ -514,7 +454,6 @@ void tracing_sched_switch_trace(struct trace_array *tr, | |||
| 514 | struct task_struct *prev, | 454 | struct task_struct *prev, |
| 515 | struct task_struct *next, | 455 | struct task_struct *next, |
| 516 | unsigned long flags, int pc); | 456 | unsigned long flags, int pc); |
| 517 | void tracing_record_cmdline(struct task_struct *tsk); | ||
| 518 | 457 | ||
| 519 | void tracing_sched_wakeup_trace(struct trace_array *tr, | 458 | void tracing_sched_wakeup_trace(struct trace_array *tr, |
| 520 | struct task_struct *wakee, | 459 | struct task_struct *wakee, |
| @@ -599,6 +538,8 @@ extern int trace_selftest_startup_sysprof(struct tracer *trace, | |||
| 599 | struct trace_array *tr); | 538 | struct trace_array *tr); |
| 600 | extern int trace_selftest_startup_branch(struct tracer *trace, | 539 | extern int trace_selftest_startup_branch(struct tracer *trace, |
| 601 | struct trace_array *tr); | 540 | struct trace_array *tr); |
| 541 | extern int trace_selftest_startup_hw_branches(struct tracer *trace, | ||
| 542 | struct trace_array *tr); | ||
| 602 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | 543 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ |
| 603 | 544 | ||
| 604 | extern void *head_page(struct trace_array_cpu *data); | 545 | extern void *head_page(struct trace_array_cpu *data); |
| @@ -613,6 +554,8 @@ extern unsigned long trace_flags; | |||
| 613 | /* Standard output formatting function used for function return traces */ | 554 | /* Standard output formatting function used for function return traces */ |
| 614 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 555 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 615 | extern enum print_line_t print_graph_function(struct trace_iterator *iter); | 556 | extern enum print_line_t print_graph_function(struct trace_iterator *iter); |
| 557 | extern enum print_line_t | ||
| 558 | trace_print_graph_duration(unsigned long long duration, struct trace_seq *s); | ||
| 616 | 559 | ||
| 617 | #ifdef CONFIG_DYNAMIC_FTRACE | 560 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 618 | /* TODO: make this variable */ | 561 | /* TODO: make this variable */ |
| @@ -644,7 +587,6 @@ static inline int ftrace_graph_addr(unsigned long addr) | |||
| 644 | return 1; | 587 | return 1; |
| 645 | } | 588 | } |
| 646 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 589 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 647 | |||
| 648 | #else /* CONFIG_FUNCTION_GRAPH_TRACER */ | 590 | #else /* CONFIG_FUNCTION_GRAPH_TRACER */ |
| 649 | static inline enum print_line_t | 591 | static inline enum print_line_t |
| 650 | print_graph_function(struct trace_iterator *iter) | 592 | print_graph_function(struct trace_iterator *iter) |
| @@ -692,6 +634,7 @@ enum trace_iterator_flags { | |||
| 692 | TRACE_ITER_LATENCY_FMT = 0x40000, | 634 | TRACE_ITER_LATENCY_FMT = 0x40000, |
| 693 | TRACE_ITER_GLOBAL_CLK = 0x80000, | 635 | TRACE_ITER_GLOBAL_CLK = 0x80000, |
| 694 | TRACE_ITER_SLEEP_TIME = 0x100000, | 636 | TRACE_ITER_SLEEP_TIME = 0x100000, |
| 637 | TRACE_ITER_GRAPH_TIME = 0x200000, | ||
| 695 | }; | 638 | }; |
| 696 | 639 | ||
| 697 | /* | 640 | /* |
| @@ -790,103 +733,113 @@ struct ftrace_event_field { | |||
| 790 | char *type; | 733 | char *type; |
| 791 | int offset; | 734 | int offset; |
| 792 | int size; | 735 | int size; |
| 736 | int is_signed; | ||
| 793 | }; | 737 | }; |
| 794 | 738 | ||
| 795 | struct ftrace_event_call { | 739 | struct event_filter { |
| 796 | char *name; | 740 | int n_preds; |
| 797 | char *system; | ||
| 798 | struct dentry *dir; | ||
| 799 | int enabled; | ||
| 800 | int (*regfunc)(void); | ||
| 801 | void (*unregfunc)(void); | ||
| 802 | int id; | ||
| 803 | int (*raw_init)(void); | ||
| 804 | int (*show_format)(struct trace_seq *s); | ||
| 805 | int (*define_fields)(void); | ||
| 806 | struct list_head fields; | ||
| 807 | struct filter_pred **preds; | 741 | struct filter_pred **preds; |
| 808 | 742 | char *filter_string; | |
| 809 | #ifdef CONFIG_EVENT_PROFILE | ||
| 810 | atomic_t profile_count; | ||
| 811 | int (*profile_enable)(struct ftrace_event_call *); | ||
| 812 | void (*profile_disable)(struct ftrace_event_call *); | ||
| 813 | #endif | ||
| 814 | }; | 743 | }; |
| 815 | 744 | ||
| 816 | struct event_subsystem { | 745 | struct event_subsystem { |
| 817 | struct list_head list; | 746 | struct list_head list; |
| 818 | const char *name; | 747 | const char *name; |
| 819 | struct dentry *entry; | 748 | struct dentry *entry; |
| 820 | struct filter_pred **preds; | 749 | void *filter; |
| 821 | }; | 750 | }; |
| 822 | 751 | ||
| 823 | #define events_for_each(event) \ | ||
| 824 | for (event = __start_ftrace_events; \ | ||
| 825 | (unsigned long)event < (unsigned long)__stop_ftrace_events; \ | ||
| 826 | event++) | ||
| 827 | |||
| 828 | #define MAX_FILTER_PRED 8 | ||
| 829 | |||
| 830 | struct filter_pred; | 752 | struct filter_pred; |
| 831 | 753 | ||
| 832 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); | 754 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event, |
| 755 | int val1, int val2); | ||
| 833 | 756 | ||
| 834 | struct filter_pred { | 757 | struct filter_pred { |
| 835 | filter_pred_fn_t fn; | 758 | filter_pred_fn_t fn; |
| 836 | u64 val; | 759 | u64 val; |
| 837 | char *str_val; | 760 | char str_val[MAX_FILTER_STR_VAL]; |
| 838 | int str_len; | 761 | int str_len; |
| 839 | char *field_name; | 762 | char *field_name; |
| 840 | int offset; | 763 | int offset; |
| 841 | int not; | 764 | int not; |
| 842 | int or; | 765 | int op; |
| 843 | int compound; | 766 | int pop_n; |
| 844 | int clear; | ||
| 845 | }; | 767 | }; |
| 846 | 768 | ||
| 847 | int trace_define_field(struct ftrace_event_call *call, char *type, | 769 | extern void print_event_filter(struct ftrace_event_call *call, |
| 848 | char *name, int offset, int size); | ||
| 849 | extern void filter_free_pred(struct filter_pred *pred); | ||
| 850 | extern void filter_print_preds(struct filter_pred **preds, | ||
| 851 | struct trace_seq *s); | 770 | struct trace_seq *s); |
| 852 | extern int filter_parse(char **pbuf, struct filter_pred *pred); | 771 | extern int apply_event_filter(struct ftrace_event_call *call, |
| 853 | extern int filter_add_pred(struct ftrace_event_call *call, | 772 | char *filter_string); |
| 854 | struct filter_pred *pred); | 773 | extern int apply_subsystem_event_filter(struct event_subsystem *system, |
| 855 | extern void filter_free_preds(struct ftrace_event_call *call); | 774 | char *filter_string); |
| 856 | extern int filter_match_preds(struct ftrace_event_call *call, void *rec); | 775 | extern void print_subsystem_event_filter(struct event_subsystem *system, |
| 857 | extern void filter_free_subsystem_preds(struct event_subsystem *system); | 776 | struct trace_seq *s); |
| 858 | extern int filter_add_subsystem_pred(struct event_subsystem *system, | 777 | |
| 859 | struct filter_pred *pred); | 778 | static inline int |
| 860 | 779 | filter_check_discard(struct ftrace_event_call *call, void *rec, | |
| 861 | void event_trace_printk(unsigned long ip, const char *fmt, ...); | 780 | struct ring_buffer *buffer, |
| 862 | extern struct ftrace_event_call __start_ftrace_events[]; | 781 | struct ring_buffer_event *event) |
| 863 | extern struct ftrace_event_call __stop_ftrace_events[]; | 782 | { |
| 864 | 783 | if (unlikely(call->filter_active) && !filter_match_preds(call, rec)) { | |
| 865 | #define for_each_event(event) \ | 784 | ring_buffer_discard_commit(buffer, event); |
| 866 | for (event = __start_ftrace_events; \ | 785 | return 1; |
| 867 | (unsigned long)event < (unsigned long)__stop_ftrace_events; \ | 786 | } |
| 868 | event++) | 787 | |
| 788 | return 0; | ||
| 789 | } | ||
| 790 | |||
| 791 | #define DEFINE_COMPARISON_PRED(type) \ | ||
| 792 | static int filter_pred_##type(struct filter_pred *pred, void *event, \ | ||
| 793 | int val1, int val2) \ | ||
| 794 | { \ | ||
| 795 | type *addr = (type *)(event + pred->offset); \ | ||
| 796 | type val = (type)pred->val; \ | ||
| 797 | int match = 0; \ | ||
| 798 | \ | ||
| 799 | switch (pred->op) { \ | ||
| 800 | case OP_LT: \ | ||
| 801 | match = (*addr < val); \ | ||
| 802 | break; \ | ||
| 803 | case OP_LE: \ | ||
| 804 | match = (*addr <= val); \ | ||
| 805 | break; \ | ||
| 806 | case OP_GT: \ | ||
| 807 | match = (*addr > val); \ | ||
| 808 | break; \ | ||
| 809 | case OP_GE: \ | ||
| 810 | match = (*addr >= val); \ | ||
| 811 | break; \ | ||
| 812 | default: \ | ||
| 813 | break; \ | ||
| 814 | } \ | ||
| 815 | \ | ||
| 816 | return match; \ | ||
| 817 | } | ||
| 818 | |||
| 819 | #define DEFINE_EQUALITY_PRED(size) \ | ||
| 820 | static int filter_pred_##size(struct filter_pred *pred, void *event, \ | ||
| 821 | int val1, int val2) \ | ||
| 822 | { \ | ||
| 823 | u##size *addr = (u##size *)(event + pred->offset); \ | ||
| 824 | u##size val = (u##size)pred->val; \ | ||
| 825 | int match; \ | ||
| 826 | \ | ||
| 827 | match = (val == *addr) ^ pred->not; \ | ||
| 828 | \ | ||
| 829 | return match; \ | ||
| 830 | } | ||
| 831 | |||
| 832 | extern struct mutex event_mutex; | ||
| 833 | extern struct list_head ftrace_events; | ||
| 869 | 834 | ||
| 870 | extern const char *__start___trace_bprintk_fmt[]; | 835 | extern const char *__start___trace_bprintk_fmt[]; |
| 871 | extern const char *__stop___trace_bprintk_fmt[]; | 836 | extern const char *__stop___trace_bprintk_fmt[]; |
| 872 | 837 | ||
| 873 | /* | 838 | #undef TRACE_EVENT_FORMAT |
| 874 | * The double __builtin_constant_p is because gcc will give us an error | 839 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ |
| 875 | * if we try to allocate the static variable to fmt if it is not a | 840 | extern struct ftrace_event_call event_##call; |
| 876 | * constant. Even with the outer if statement optimizing out. | 841 | #undef TRACE_EVENT_FORMAT_NOFILTER |
| 877 | */ | 842 | #define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, tpfmt) |
| 878 | #define event_trace_printk(ip, fmt, args...) \ | 843 | #include "trace_event_types.h" |
| 879 | do { \ | ||
| 880 | __trace_printk_check_format(fmt, ##args); \ | ||
| 881 | tracing_record_cmdline(current); \ | ||
| 882 | if (__builtin_constant_p(fmt)) { \ | ||
| 883 | static const char *trace_printk_fmt \ | ||
| 884 | __attribute__((section("__trace_printk_fmt"))) = \ | ||
| 885 | __builtin_constant_p(fmt) ? fmt : NULL; \ | ||
| 886 | \ | ||
| 887 | __trace_bprintk(ip, trace_printk_fmt, ##args); \ | ||
| 888 | } else \ | ||
| 889 | __trace_printk(ip, fmt, ##args); \ | ||
| 890 | } while (0) | ||
| 891 | 844 | ||
| 892 | #endif /* _LINUX_KERNEL_TRACE_H */ | 845 | #endif /* _LINUX_KERNEL_TRACE_H */ |
