aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 22:58:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 22:58:13 -0500
commit1dd7dcb6eaa677b034e7ef63df8320277507ae70 (patch)
tree3f1592b634d7bdde94e00570925be2dade8433d4 /kernel/trace/trace.c
parentb6da0076bab5a12afb19312ffee41c95490af2a0 (diff)
parent3558a5ac50dbb2419cc649d5e154af161d661037 (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.c159
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
156static int __init stop_trace_on_warning(char *str) 156static 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
163static int __init boot_alloc_snapshot(char *str) 164static 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
2510static void print_lat_help_header(struct seq_file *m) 2508static 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
2522static void print_event_info(struct trace_buffer *buf, struct seq_file *m) 2520static 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)
2533static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m) 2531static 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
2540static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m) 2538static 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
2552void 2550void
@@ -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);
2668partial:
2669 return TRACE_TYPE_PARTIAL_LINE;
2670} 2665}
2671 2666
2672static enum print_line_t print_raw_fmt(struct trace_iterator *iter) 2667static 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);
2694partial:
2695 return TRACE_TYPE_PARTIAL_LINE;
2696} 2689}
2697 2690
2698static enum print_line_t print_hex_fmt(struct trace_iterator *iter) 2691static 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
2725static enum print_line_t print_bin_fmt(struct trace_iterator *iter) 2720static 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
2868static void show_snapshot_main_help(struct seq_file *m) 2867static 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
2878static void show_snapshot_percpu_help(struct seq_file *m) 2877static 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
2893static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) 2892static 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