diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 22:58:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 22:58:13 -0500 |
commit | 1dd7dcb6eaa677b034e7ef63df8320277507ae70 (patch) | |
tree | 3f1592b634d7bdde94e00570925be2dade8433d4 /kernel/trace/trace.c | |
parent | b6da0076bab5a12afb19312ffee41c95490af2a0 (diff) | |
parent | 3558a5ac50dbb2419cc649d5e154af161d661037 (diff) |
Merge tag 'trace-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt:
"There was a lot of clean ups and minor fixes. One of those clean ups
was to the trace_seq code. It also removed the return values to the
trace_seq_*() functions and use trace_seq_has_overflowed() to see if
the buffer filled up or not. This is similar to work being done to
the seq_file code as well in another tree.
Some of the other goodies include:
- Added some "!" (NOT) logic to the tracing filter.
- Fixed the frame pointer logic to the x86_64 mcount trampolines
- Added the logic for dynamic trampolines on !CONFIG_PREEMPT systems.
That is, the ftrace trampoline can be dynamically allocated and be
called directly by functions that only have a single hook to them"
* tag 'trace-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (55 commits)
tracing: Truncated output is better than nothing
tracing: Add additional marks to signal very large time deltas
Documentation: describe trace_buf_size parameter more accurately
tracing: Allow NOT to filter AND and OR clauses
tracing: Add NOT to filtering logic
ftrace/fgraph/x86: Have prepare_ftrace_return() take ip as first parameter
ftrace/x86: Get rid of ftrace_caller_setup
ftrace/x86: Have save_mcount_regs macro also save stack frames if needed
ftrace/x86: Add macro MCOUNT_REG_SIZE for amount of stack used to save mcount regs
ftrace/x86: Simplify save_mcount_regs on getting RIP
ftrace/x86: Have save_mcount_regs store RIP in %rdi for first parameter
ftrace/x86: Rename MCOUNT_SAVE_FRAME and add more detailed comments
ftrace/x86: Move MCOUNT_SAVE_FRAME out of header file
ftrace/x86: Have static tracing also use ftrace_caller_setup
ftrace/x86: Have static function tracing always test for function graph
kprobes: Add IPMODIFY flag to kprobe_ftrace_ops
ftrace, kprobes: Support IPMODIFY flag to find IP modify conflict
kprobes/ftrace: Recover original IP if pre_handler doesn't change it
tracing/trivial: Fix typos and make an int into a bool
tracing: Deletion of an unnecessary check before iput()
...
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 159 |
1 files changed, 79 insertions, 80 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 426962b04183..ce11fa50a2f0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -155,10 +155,11 @@ __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); | |||
155 | 155 | ||
156 | static int __init stop_trace_on_warning(char *str) | 156 | static int __init stop_trace_on_warning(char *str) |
157 | { | 157 | { |
158 | __disable_trace_on_warning = 1; | 158 | if ((strcmp(str, "=0") != 0 && strcmp(str, "=off") != 0)) |
159 | __disable_trace_on_warning = 1; | ||
159 | return 1; | 160 | return 1; |
160 | } | 161 | } |
161 | __setup("traceoff_on_warning=", stop_trace_on_warning); | 162 | __setup("traceoff_on_warning", stop_trace_on_warning); |
162 | 163 | ||
163 | static int __init boot_alloc_snapshot(char *str) | 164 | static int __init boot_alloc_snapshot(char *str) |
164 | { | 165 | { |
@@ -2158,9 +2159,7 @@ __trace_array_vprintk(struct ring_buffer *buffer, | |||
2158 | goto out; | 2159 | goto out; |
2159 | } | 2160 | } |
2160 | 2161 | ||
2161 | len = vsnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); | 2162 | len = vscnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); |
2162 | if (len > TRACE_BUF_SIZE) | ||
2163 | goto out; | ||
2164 | 2163 | ||
2165 | local_save_flags(flags); | 2164 | local_save_flags(flags); |
2166 | size = sizeof(*entry) + len + 1; | 2165 | size = sizeof(*entry) + len + 1; |
@@ -2171,8 +2170,7 @@ __trace_array_vprintk(struct ring_buffer *buffer, | |||
2171 | entry = ring_buffer_event_data(event); | 2170 | entry = ring_buffer_event_data(event); |
2172 | entry->ip = ip; | 2171 | entry->ip = ip; |
2173 | 2172 | ||
2174 | memcpy(&entry->buf, tbuffer, len); | 2173 | memcpy(&entry->buf, tbuffer, len + 1); |
2175 | entry->buf[len] = '\0'; | ||
2176 | if (!call_filter_check_discard(call, entry, buffer, event)) { | 2174 | if (!call_filter_check_discard(call, entry, buffer, event)) { |
2177 | __buffer_unlock_commit(buffer, event); | 2175 | __buffer_unlock_commit(buffer, event); |
2178 | ftrace_trace_stack(buffer, flags, 6, pc); | 2176 | ftrace_trace_stack(buffer, flags, 6, pc); |
@@ -2509,14 +2507,14 @@ get_total_entries(struct trace_buffer *buf, | |||
2509 | 2507 | ||
2510 | static void print_lat_help_header(struct seq_file *m) | 2508 | static void print_lat_help_header(struct seq_file *m) |
2511 | { | 2509 | { |
2512 | seq_puts(m, "# _------=> CPU# \n"); | 2510 | seq_puts(m, "# _------=> CPU# \n" |
2513 | seq_puts(m, "# / _-----=> irqs-off \n"); | 2511 | "# / _-----=> irqs-off \n" |
2514 | seq_puts(m, "# | / _----=> need-resched \n"); | 2512 | "# | / _----=> need-resched \n" |
2515 | seq_puts(m, "# || / _---=> hardirq/softirq \n"); | 2513 | "# || / _---=> hardirq/softirq \n" |
2516 | seq_puts(m, "# ||| / _--=> preempt-depth \n"); | 2514 | "# ||| / _--=> preempt-depth \n" |
2517 | seq_puts(m, "# |||| / delay \n"); | 2515 | "# |||| / delay \n" |
2518 | seq_puts(m, "# cmd pid ||||| time | caller \n"); | 2516 | "# cmd pid ||||| time | caller \n" |
2519 | seq_puts(m, "# \\ / ||||| \\ | / \n"); | 2517 | "# \\ / ||||| \\ | / \n"); |
2520 | } | 2518 | } |
2521 | 2519 | ||
2522 | static void print_event_info(struct trace_buffer *buf, struct seq_file *m) | 2520 | static void print_event_info(struct trace_buffer *buf, struct seq_file *m) |
@@ -2533,20 +2531,20 @@ static void print_event_info(struct trace_buffer *buf, struct seq_file *m) | |||
2533 | static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m) | 2531 | static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m) |
2534 | { | 2532 | { |
2535 | print_event_info(buf, m); | 2533 | print_event_info(buf, m); |
2536 | seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n"); | 2534 | seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n" |
2537 | seq_puts(m, "# | | | | |\n"); | 2535 | "# | | | | |\n"); |
2538 | } | 2536 | } |
2539 | 2537 | ||
2540 | static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m) | 2538 | static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m) |
2541 | { | 2539 | { |
2542 | print_event_info(buf, m); | 2540 | print_event_info(buf, m); |
2543 | seq_puts(m, "# _-----=> irqs-off\n"); | 2541 | seq_puts(m, "# _-----=> irqs-off\n" |
2544 | seq_puts(m, "# / _----=> need-resched\n"); | 2542 | "# / _----=> need-resched\n" |
2545 | seq_puts(m, "# | / _---=> hardirq/softirq\n"); | 2543 | "# | / _---=> hardirq/softirq\n" |
2546 | seq_puts(m, "# || / _--=> preempt-depth\n"); | 2544 | "# || / _--=> preempt-depth\n" |
2547 | seq_puts(m, "# ||| / delay\n"); | 2545 | "# ||| / delay\n" |
2548 | seq_puts(m, "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n"); | 2546 | "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n" |
2549 | seq_puts(m, "# | | | |||| | |\n"); | 2547 | "# | | | |||| | |\n"); |
2550 | } | 2548 | } |
2551 | 2549 | ||
2552 | void | 2550 | void |
@@ -2649,24 +2647,21 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) | |||
2649 | event = ftrace_find_event(entry->type); | 2647 | event = ftrace_find_event(entry->type); |
2650 | 2648 | ||
2651 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2649 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2652 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) { | 2650 | if (iter->iter_flags & TRACE_FILE_LAT_FMT) |
2653 | if (!trace_print_lat_context(iter)) | 2651 | trace_print_lat_context(iter); |
2654 | goto partial; | 2652 | else |
2655 | } else { | 2653 | trace_print_context(iter); |
2656 | if (!trace_print_context(iter)) | ||
2657 | goto partial; | ||
2658 | } | ||
2659 | } | 2654 | } |
2660 | 2655 | ||
2656 | if (trace_seq_has_overflowed(s)) | ||
2657 | return TRACE_TYPE_PARTIAL_LINE; | ||
2658 | |||
2661 | if (event) | 2659 | if (event) |
2662 | return event->funcs->trace(iter, sym_flags, event); | 2660 | return event->funcs->trace(iter, sym_flags, event); |
2663 | 2661 | ||
2664 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) | 2662 | trace_seq_printf(s, "Unknown type %d\n", entry->type); |
2665 | goto partial; | ||
2666 | 2663 | ||
2667 | return TRACE_TYPE_HANDLED; | 2664 | return trace_handle_return(s); |
2668 | partial: | ||
2669 | return TRACE_TYPE_PARTIAL_LINE; | ||
2670 | } | 2665 | } |
2671 | 2666 | ||
2672 | static enum print_line_t print_raw_fmt(struct trace_iterator *iter) | 2667 | static enum print_line_t print_raw_fmt(struct trace_iterator *iter) |
@@ -2677,22 +2672,20 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter) | |||
2677 | 2672 | ||
2678 | entry = iter->ent; | 2673 | entry = iter->ent; |
2679 | 2674 | ||
2680 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2675 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) |
2681 | if (!trace_seq_printf(s, "%d %d %llu ", | 2676 | trace_seq_printf(s, "%d %d %llu ", |
2682 | entry->pid, iter->cpu, iter->ts)) | 2677 | entry->pid, iter->cpu, iter->ts); |
2683 | goto partial; | 2678 | |
2684 | } | 2679 | if (trace_seq_has_overflowed(s)) |
2680 | return TRACE_TYPE_PARTIAL_LINE; | ||
2685 | 2681 | ||
2686 | event = ftrace_find_event(entry->type); | 2682 | event = ftrace_find_event(entry->type); |
2687 | if (event) | 2683 | if (event) |
2688 | return event->funcs->raw(iter, 0, event); | 2684 | return event->funcs->raw(iter, 0, event); |
2689 | 2685 | ||
2690 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) | 2686 | trace_seq_printf(s, "%d ?\n", entry->type); |
2691 | goto partial; | ||
2692 | 2687 | ||
2693 | return TRACE_TYPE_HANDLED; | 2688 | return trace_handle_return(s); |
2694 | partial: | ||
2695 | return TRACE_TYPE_PARTIAL_LINE; | ||
2696 | } | 2689 | } |
2697 | 2690 | ||
2698 | static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | 2691 | static enum print_line_t print_hex_fmt(struct trace_iterator *iter) |
@@ -2705,9 +2698,11 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | |||
2705 | entry = iter->ent; | 2698 | entry = iter->ent; |
2706 | 2699 | ||
2707 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2700 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2708 | SEQ_PUT_HEX_FIELD_RET(s, entry->pid); | 2701 | SEQ_PUT_HEX_FIELD(s, entry->pid); |
2709 | SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); | 2702 | SEQ_PUT_HEX_FIELD(s, iter->cpu); |
2710 | SEQ_PUT_HEX_FIELD_RET(s, iter->ts); | 2703 | SEQ_PUT_HEX_FIELD(s, iter->ts); |
2704 | if (trace_seq_has_overflowed(s)) | ||
2705 | return TRACE_TYPE_PARTIAL_LINE; | ||
2711 | } | 2706 | } |
2712 | 2707 | ||
2713 | event = ftrace_find_event(entry->type); | 2708 | event = ftrace_find_event(entry->type); |
@@ -2717,9 +2712,9 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | |||
2717 | return ret; | 2712 | return ret; |
2718 | } | 2713 | } |
2719 | 2714 | ||
2720 | SEQ_PUT_FIELD_RET(s, newline); | 2715 | SEQ_PUT_FIELD(s, newline); |
2721 | 2716 | ||
2722 | return TRACE_TYPE_HANDLED; | 2717 | return trace_handle_return(s); |
2723 | } | 2718 | } |
2724 | 2719 | ||
2725 | static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | 2720 | static enum print_line_t print_bin_fmt(struct trace_iterator *iter) |
@@ -2731,9 +2726,11 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | |||
2731 | entry = iter->ent; | 2726 | entry = iter->ent; |
2732 | 2727 | ||
2733 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { | 2728 | if (trace_flags & TRACE_ITER_CONTEXT_INFO) { |
2734 | SEQ_PUT_FIELD_RET(s, entry->pid); | 2729 | SEQ_PUT_FIELD(s, entry->pid); |
2735 | SEQ_PUT_FIELD_RET(s, iter->cpu); | 2730 | SEQ_PUT_FIELD(s, iter->cpu); |
2736 | SEQ_PUT_FIELD_RET(s, iter->ts); | 2731 | SEQ_PUT_FIELD(s, iter->ts); |
2732 | if (trace_seq_has_overflowed(s)) | ||
2733 | return TRACE_TYPE_PARTIAL_LINE; | ||
2737 | } | 2734 | } |
2738 | 2735 | ||
2739 | event = ftrace_find_event(entry->type); | 2736 | event = ftrace_find_event(entry->type); |
@@ -2779,10 +2776,12 @@ enum print_line_t print_trace_line(struct trace_iterator *iter) | |||
2779 | { | 2776 | { |
2780 | enum print_line_t ret; | 2777 | enum print_line_t ret; |
2781 | 2778 | ||
2782 | if (iter->lost_events && | 2779 | if (iter->lost_events) { |
2783 | !trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", | 2780 | trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", |
2784 | iter->cpu, iter->lost_events)) | 2781 | iter->cpu, iter->lost_events); |
2785 | return TRACE_TYPE_PARTIAL_LINE; | 2782 | if (trace_seq_has_overflowed(&iter->seq)) |
2783 | return TRACE_TYPE_PARTIAL_LINE; | ||
2784 | } | ||
2786 | 2785 | ||
2787 | if (iter->trace && iter->trace->print_line) { | 2786 | if (iter->trace && iter->trace->print_line) { |
2788 | ret = iter->trace->print_line(iter); | 2787 | ret = iter->trace->print_line(iter); |
@@ -2860,44 +2859,44 @@ static void test_ftrace_alive(struct seq_file *m) | |||
2860 | { | 2859 | { |
2861 | if (!ftrace_is_dead()) | 2860 | if (!ftrace_is_dead()) |
2862 | return; | 2861 | return; |
2863 | seq_printf(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n"); | 2862 | seq_puts(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n" |
2864 | seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n"); | 2863 | "# MAY BE MISSING FUNCTION EVENTS\n"); |
2865 | } | 2864 | } |
2866 | 2865 | ||
2867 | #ifdef CONFIG_TRACER_MAX_TRACE | 2866 | #ifdef CONFIG_TRACER_MAX_TRACE |
2868 | static void show_snapshot_main_help(struct seq_file *m) | 2867 | static void show_snapshot_main_help(struct seq_file *m) |
2869 | { | 2868 | { |
2870 | seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n"); | 2869 | seq_puts(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n" |
2871 | seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); | 2870 | "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n" |
2872 | seq_printf(m, "# Takes a snapshot of the main buffer.\n"); | 2871 | "# Takes a snapshot of the main buffer.\n" |
2873 | seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)\n"); | 2872 | "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)\n" |
2874 | seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); | 2873 | "# (Doesn't have to be '2' works with any number that\n" |
2875 | seq_printf(m, "# is not a '0' or '1')\n"); | 2874 | "# is not a '0' or '1')\n"); |
2876 | } | 2875 | } |
2877 | 2876 | ||
2878 | static void show_snapshot_percpu_help(struct seq_file *m) | 2877 | static void show_snapshot_percpu_help(struct seq_file *m) |
2879 | { | 2878 | { |
2880 | seq_printf(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); | 2879 | seq_puts(m, "# echo 0 > snapshot : Invalid for per_cpu snapshot file.\n"); |
2881 | #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP | 2880 | #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP |
2882 | seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n"); | 2881 | seq_puts(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n" |
2883 | seq_printf(m, "# Takes a snapshot of the main buffer for this cpu.\n"); | 2882 | "# Takes a snapshot of the main buffer for this cpu.\n"); |
2884 | #else | 2883 | #else |
2885 | seq_printf(m, "# echo 1 > snapshot : Not supported with this kernel.\n"); | 2884 | seq_puts(m, "# echo 1 > snapshot : Not supported with this kernel.\n" |
2886 | seq_printf(m, "# Must use main snapshot file to allocate.\n"); | 2885 | "# Must use main snapshot file to allocate.\n"); |
2887 | #endif | 2886 | #endif |
2888 | seq_printf(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n"); | 2887 | seq_puts(m, "# echo 2 > snapshot : Clears this cpu's snapshot buffer (but does not allocate)\n" |
2889 | seq_printf(m, "# (Doesn't have to be '2' works with any number that\n"); | 2888 | "# (Doesn't have to be '2' works with any number that\n" |
2890 | seq_printf(m, "# is not a '0' or '1')\n"); | 2889 | "# is not a '0' or '1')\n"); |
2891 | } | 2890 | } |
2892 | 2891 | ||
2893 | static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) | 2892 | static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) |
2894 | { | 2893 | { |
2895 | if (iter->tr->allocated_snapshot) | 2894 | if (iter->tr->allocated_snapshot) |
2896 | seq_printf(m, "#\n# * Snapshot is allocated *\n#\n"); | 2895 | seq_puts(m, "#\n# * Snapshot is allocated *\n#\n"); |
2897 | else | 2896 | else |
2898 | seq_printf(m, "#\n# * Snapshot is freed *\n#\n"); | 2897 | seq_puts(m, "#\n# * Snapshot is freed *\n#\n"); |
2899 | 2898 | ||
2900 | seq_printf(m, "# Snapshot commands:\n"); | 2899 | seq_puts(m, "# Snapshot commands:\n"); |
2901 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) | 2900 | if (iter->cpu_file == RING_BUFFER_ALL_CPUS) |
2902 | show_snapshot_main_help(m); | 2901 | show_snapshot_main_help(m); |
2903 | else | 2902 | else |
@@ -3251,7 +3250,7 @@ static int t_show(struct seq_file *m, void *v) | |||
3251 | if (!t) | 3250 | if (!t) |
3252 | return 0; | 3251 | return 0; |
3253 | 3252 | ||
3254 | seq_printf(m, "%s", t->name); | 3253 | seq_puts(m, t->name); |
3255 | if (t->next) | 3254 | if (t->next) |
3256 | seq_putc(m, ' '); | 3255 | seq_putc(m, ' '); |
3257 | else | 3256 | else |
@@ -5749,10 +5748,10 @@ ftrace_snapshot_print(struct seq_file *m, unsigned long ip, | |||
5749 | 5748 | ||
5750 | seq_printf(m, "%ps:", (void *)ip); | 5749 | seq_printf(m, "%ps:", (void *)ip); |
5751 | 5750 | ||
5752 | seq_printf(m, "snapshot"); | 5751 | seq_puts(m, "snapshot"); |
5753 | 5752 | ||
5754 | if (count == -1) | 5753 | if (count == -1) |
5755 | seq_printf(m, ":unlimited\n"); | 5754 | seq_puts(m, ":unlimited\n"); |
5756 | else | 5755 | else |
5757 | seq_printf(m, ":count=%ld\n", count); | 5756 | seq_printf(m, ":count=%ld\n", count); |
5758 | 5757 | ||