diff options
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 165 | 
1 files changed, 74 insertions, 91 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c0e9c1263393..cc94f8642485 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c  | |||
| @@ -1169,6 +1169,67 @@ void trace_graph_return(struct ftrace_graph_ret *trace) | |||
| 1169 | } | 1169 | } | 
| 1170 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 1170 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 
| 1171 | 1171 | ||
| 1172 | |||
| 1173 | /** | ||
| 1174 | * trace_vprintk - write binary msg to tracing buffer | ||
| 1175 | * | ||
| 1176 | */ | ||
| 1177 | int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | ||
| 1178 | { | ||
| 1179 | static DEFINE_SPINLOCK(trace_buf_lock); | ||
| 1180 | static u32 trace_buf[TRACE_BUF_SIZE]; | ||
| 1181 | |||
| 1182 | struct ring_buffer_event *event; | ||
| 1183 | struct trace_array *tr = &global_trace; | ||
| 1184 | struct trace_array_cpu *data; | ||
| 1185 | struct print_entry *entry; | ||
| 1186 | unsigned long flags; | ||
| 1187 | int resched; | ||
| 1188 | int cpu, len = 0, size, pc; | ||
| 1189 | |||
| 1190 | if (unlikely(tracing_selftest_running || tracing_disabled)) | ||
| 1191 | return 0; | ||
| 1192 | |||
| 1193 | /* Don't pollute graph traces with trace_vprintk internals */ | ||
| 1194 | pause_graph_tracing(); | ||
| 1195 | |||
| 1196 | pc = preempt_count(); | ||
| 1197 | resched = ftrace_preempt_disable(); | ||
| 1198 | cpu = raw_smp_processor_id(); | ||
| 1199 | data = tr->data[cpu]; | ||
| 1200 | |||
| 1201 | if (unlikely(atomic_read(&data->disabled))) | ||
| 1202 | goto out; | ||
| 1203 | |||
| 1204 | spin_lock_irqsave(&trace_buf_lock, flags); | ||
| 1205 | len = vbin_printf(trace_buf, TRACE_BUF_SIZE, fmt, args); | ||
| 1206 | |||
| 1207 | if (len > TRACE_BUF_SIZE || len < 0) | ||
| 1208 | goto out_unlock; | ||
| 1209 | |||
| 1210 | size = sizeof(*entry) + sizeof(u32) * len; | ||
| 1211 | event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, flags, pc); | ||
| 1212 | if (!event) | ||
| 1213 | goto out_unlock; | ||
| 1214 | entry = ring_buffer_event_data(event); | ||
| 1215 | entry->ip = ip; | ||
| 1216 | entry->depth = depth; | ||
| 1217 | entry->fmt = fmt; | ||
| 1218 | |||
| 1219 | memcpy(entry->buf, trace_buf, sizeof(u32) * len); | ||
| 1220 | ring_buffer_unlock_commit(tr->buffer, event); | ||
| 1221 | |||
| 1222 | out_unlock: | ||
| 1223 | spin_unlock_irqrestore(&trace_buf_lock, flags); | ||
| 1224 | |||
| 1225 | out: | ||
| 1226 | ftrace_preempt_enable(resched); | ||
| 1227 | unpause_graph_tracing(); | ||
| 1228 | |||
| 1229 | return len; | ||
| 1230 | } | ||
| 1231 | EXPORT_SYMBOL_GPL(trace_vprintk); | ||
| 1232 | |||
| 1172 | enum trace_file_type { | 1233 | enum trace_file_type { | 
| 1173 | TRACE_FILE_LAT_FMT = 1, | 1234 | TRACE_FILE_LAT_FMT = 1, | 
| 1174 | TRACE_FILE_ANNOTATE = 2, | 1235 | TRACE_FILE_ANNOTATE = 2, | 
| @@ -1564,7 +1625,7 @@ static enum print_line_t print_printk_msg_only(struct trace_iterator *iter) | |||
| 1564 | 1625 | ||
| 1565 | trace_assign_type(field, entry); | 1626 | trace_assign_type(field, entry); | 
| 1566 | 1627 | ||
| 1567 | ret = trace_seq_printf(s, "%s", field->buf); | 1628 | ret = trace_seq_bprintf(s, field->fmt, field->buf); | 
| 1568 | if (!ret) | 1629 | if (!ret) | 
| 1569 | return TRACE_TYPE_PARTIAL_LINE; | 1630 | return TRACE_TYPE_PARTIAL_LINE; | 
| 1570 | 1631 | ||
| @@ -1882,14 +1943,14 @@ static int show_traces_open(struct inode *inode, struct file *file) | |||
| 1882 | return ret; | 1943 | return ret; | 
| 1883 | } | 1944 | } | 
| 1884 | 1945 | ||
| 1885 | static struct file_operations tracing_fops = { | 1946 | static const struct file_operations tracing_fops = { | 
| 1886 | .open = tracing_open, | 1947 | .open = tracing_open, | 
| 1887 | .read = seq_read, | 1948 | .read = seq_read, | 
| 1888 | .llseek = seq_lseek, | 1949 | .llseek = seq_lseek, | 
| 1889 | .release = tracing_release, | 1950 | .release = tracing_release, | 
| 1890 | }; | 1951 | }; | 
| 1891 | 1952 | ||
| 1892 | static struct file_operations show_traces_fops = { | 1953 | static const struct file_operations show_traces_fops = { | 
| 1893 | .open = show_traces_open, | 1954 | .open = show_traces_open, | 
| 1894 | .read = seq_read, | 1955 | .read = seq_read, | 
| 1895 | .release = seq_release, | 1956 | .release = seq_release, | 
| @@ -1982,7 +2043,7 @@ err_unlock: | |||
| 1982 | return err; | 2043 | return err; | 
| 1983 | } | 2044 | } | 
| 1984 | 2045 | ||
| 1985 | static struct file_operations tracing_cpumask_fops = { | 2046 | static const struct file_operations tracing_cpumask_fops = { | 
| 1986 | .open = tracing_open_generic, | 2047 | .open = tracing_open_generic, | 
| 1987 | .read = tracing_cpumask_read, | 2048 | .read = tracing_cpumask_read, | 
| 1988 | .write = tracing_cpumask_write, | 2049 | .write = tracing_cpumask_write, | 
| @@ -2134,7 +2195,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, | |||
| 2134 | return cnt; | 2195 | return cnt; | 
| 2135 | } | 2196 | } | 
| 2136 | 2197 | ||
| 2137 | static struct file_operations tracing_iter_fops = { | 2198 | static const struct file_operations tracing_iter_fops = { | 
| 2138 | .open = tracing_open_generic, | 2199 | .open = tracing_open_generic, | 
| 2139 | .read = tracing_trace_options_read, | 2200 | .read = tracing_trace_options_read, | 
| 2140 | .write = tracing_trace_options_write, | 2201 | .write = tracing_trace_options_write, | 
| @@ -2167,7 +2228,7 @@ tracing_readme_read(struct file *filp, char __user *ubuf, | |||
| 2167 | readme_msg, strlen(readme_msg)); | 2228 | readme_msg, strlen(readme_msg)); | 
| 2168 | } | 2229 | } | 
| 2169 | 2230 | ||
| 2170 | static struct file_operations tracing_readme_fops = { | 2231 | static const struct file_operations tracing_readme_fops = { | 
| 2171 | .open = tracing_open_generic, | 2232 | .open = tracing_open_generic, | 
| 2172 | .read = tracing_readme_read, | 2233 | .read = tracing_readme_read, | 
| 2173 | }; | 2234 | }; | 
| @@ -2927,25 +2988,25 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, | |||
| 2927 | return cnt; | 2988 | return cnt; | 
| 2928 | } | 2989 | } | 
| 2929 | 2990 | ||
| 2930 | static struct file_operations tracing_max_lat_fops = { | 2991 | static const struct file_operations tracing_max_lat_fops = { | 
| 2931 | .open = tracing_open_generic, | 2992 | .open = tracing_open_generic, | 
| 2932 | .read = tracing_max_lat_read, | 2993 | .read = tracing_max_lat_read, | 
| 2933 | .write = tracing_max_lat_write, | 2994 | .write = tracing_max_lat_write, | 
| 2934 | }; | 2995 | }; | 
| 2935 | 2996 | ||
| 2936 | static struct file_operations tracing_ctrl_fops = { | 2997 | static const struct file_operations tracing_ctrl_fops = { | 
| 2937 | .open = tracing_open_generic, | 2998 | .open = tracing_open_generic, | 
| 2938 | .read = tracing_ctrl_read, | 2999 | .read = tracing_ctrl_read, | 
| 2939 | .write = tracing_ctrl_write, | 3000 | .write = tracing_ctrl_write, | 
| 2940 | }; | 3001 | }; | 
| 2941 | 3002 | ||
| 2942 | static struct file_operations set_tracer_fops = { | 3003 | static const struct file_operations set_tracer_fops = { | 
| 2943 | .open = tracing_open_generic, | 3004 | .open = tracing_open_generic, | 
| 2944 | .read = tracing_set_trace_read, | 3005 | .read = tracing_set_trace_read, | 
| 2945 | .write = tracing_set_trace_write, | 3006 | .write = tracing_set_trace_write, | 
| 2946 | }; | 3007 | }; | 
| 2947 | 3008 | ||
| 2948 | static struct file_operations tracing_pipe_fops = { | 3009 | static const struct file_operations tracing_pipe_fops = { | 
| 2949 | .open = tracing_open_pipe, | 3010 | .open = tracing_open_pipe, | 
| 2950 | .poll = tracing_poll_pipe, | 3011 | .poll = tracing_poll_pipe, | 
| 2951 | .read = tracing_read_pipe, | 3012 | .read = tracing_read_pipe, | 
| @@ -2953,13 +3014,13 @@ static struct file_operations tracing_pipe_fops = { | |||
| 2953 | .release = tracing_release_pipe, | 3014 | .release = tracing_release_pipe, | 
| 2954 | }; | 3015 | }; | 
| 2955 | 3016 | ||
| 2956 | static struct file_operations tracing_entries_fops = { | 3017 | static const struct file_operations tracing_entries_fops = { | 
| 2957 | .open = tracing_open_generic, | 3018 | .open = tracing_open_generic, | 
| 2958 | .read = tracing_entries_read, | 3019 | .read = tracing_entries_read, | 
| 2959 | .write = tracing_entries_write, | 3020 | .write = tracing_entries_write, | 
| 2960 | }; | 3021 | }; | 
| 2961 | 3022 | ||
| 2962 | static struct file_operations tracing_mark_fops = { | 3023 | static const struct file_operations tracing_mark_fops = { | 
| 2963 | .open = tracing_open_generic, | 3024 | .open = tracing_open_generic, | 
| 2964 | .write = tracing_mark_write, | 3025 | .write = tracing_mark_write, | 
| 2965 | }; | 3026 | }; | 
| @@ -3240,7 +3301,7 @@ tracing_read_dyn_info(struct file *filp, char __user *ubuf, | |||
| 3240 | return r; | 3301 | return r; | 
| 3241 | } | 3302 | } | 
| 3242 | 3303 | ||
| 3243 | static struct file_operations tracing_dyn_info_fops = { | 3304 | static const struct file_operations tracing_dyn_info_fops = { | 
| 3244 | .open = tracing_open_generic, | 3305 | .open = tracing_open_generic, | 
| 3245 | .read = tracing_read_dyn_info, | 3306 | .read = tracing_read_dyn_info, | 
| 3246 | }; | 3307 | }; | 
| @@ -3714,84 +3775,6 @@ static __init int tracer_init_debugfs(void) | |||
| 3714 | return 0; | 3775 | return 0; | 
| 3715 | } | 3776 | } | 
| 3716 | 3777 | ||
| 3717 | int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | ||
| 3718 | { | ||
| 3719 | static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; | ||
| 3720 | static char trace_buf[TRACE_BUF_SIZE]; | ||
| 3721 | |||
| 3722 | struct ring_buffer_event *event; | ||
| 3723 | struct trace_array *tr = &global_trace; | ||
| 3724 | struct trace_array_cpu *data; | ||
| 3725 | int cpu, len = 0, size, pc; | ||
| 3726 | struct print_entry *entry; | ||
| 3727 | unsigned long irq_flags; | ||
| 3728 | |||
| 3729 | if (tracing_disabled || tracing_selftest_running) | ||
| 3730 | return 0; | ||
| 3731 | |||
| 3732 | pc = preempt_count(); | ||
| 3733 | preempt_disable_notrace(); | ||
| 3734 | cpu = raw_smp_processor_id(); | ||
| 3735 | data = tr->data[cpu]; | ||
| 3736 | |||
| 3737 | if (unlikely(atomic_read(&data->disabled))) | ||
| 3738 | goto out; | ||
| 3739 | |||
| 3740 | pause_graph_tracing(); | ||
| 3741 | raw_local_irq_save(irq_flags); | ||
| 3742 | __raw_spin_lock(&trace_buf_lock); | ||
| 3743 | len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args); | ||
| 3744 | |||
| 3745 | len = min(len, TRACE_BUF_SIZE-1); | ||
| 3746 | trace_buf[len] = 0; | ||
| 3747 | |||
| 3748 | size = sizeof(*entry) + len + 1; | ||
| 3749 | event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc); | ||
| 3750 | if (!event) | ||
| 3751 | goto out_unlock; | ||
| 3752 | entry = ring_buffer_event_data(event); | ||
| 3753 | entry->ip = ip; | ||
| 3754 | entry->depth = depth; | ||
| 3755 | |||
| 3756 | memcpy(&entry->buf, trace_buf, len); | ||
| 3757 | entry->buf[len] = 0; | ||
| 3758 | ring_buffer_unlock_commit(tr->buffer, event); | ||
| 3759 | |||
| 3760 | out_unlock: | ||
| 3761 | __raw_spin_unlock(&trace_buf_lock); | ||
| 3762 | raw_local_irq_restore(irq_flags); | ||
| 3763 | unpause_graph_tracing(); | ||
| 3764 | out: | ||
| 3765 | preempt_enable_notrace(); | ||
| 3766 | |||
| 3767 | return len; | ||
| 3768 | } | ||
| 3769 | EXPORT_SYMBOL_GPL(trace_vprintk); | ||
| 3770 | |||
| 3771 | int __trace_printk(unsigned long ip, const char *fmt, ...) | ||
| 3772 | { | ||
| 3773 | int ret; | ||
| 3774 | va_list ap; | ||
| 3775 | |||
| 3776 | if (!(trace_flags & TRACE_ITER_PRINTK)) | ||
| 3777 | return 0; | ||
| 3778 | |||
| 3779 | va_start(ap, fmt); | ||
| 3780 | ret = trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap); | ||
| 3781 | va_end(ap); | ||
| 3782 | return ret; | ||
| 3783 | } | ||
| 3784 | EXPORT_SYMBOL_GPL(__trace_printk); | ||
| 3785 | |||
| 3786 | int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap) | ||
| 3787 | { | ||
| 3788 | if (!(trace_flags & TRACE_ITER_PRINTK)) | ||
| 3789 | return 0; | ||
| 3790 | |||
| 3791 | return trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap); | ||
| 3792 | } | ||
| 3793 | EXPORT_SYMBOL_GPL(__ftrace_vprintk); | ||
| 3794 | |||
| 3795 | static int trace_panic_handler(struct notifier_block *this, | 3778 | static int trace_panic_handler(struct notifier_block *this, | 
| 3796 | unsigned long event, void *unused) | 3779 | unsigned long event, void *unused) | 
| 3797 | { | 3780 | { | 
