aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ftrace.h25
-rw-r--r--include/linux/kernel.h34
-rw-r--r--include/linux/module.h2
-rw-r--r--kernel/trace/Kconfig7
-rw-r--r--kernel/trace/Makefile2
-rw-r--r--kernel/trace/trace.c212
-rw-r--r--kernel/trace/trace.h14
-rw-r--r--kernel/trace/trace_functions_graph.c6
-rw-r--r--kernel/trace/trace_mmiotrace.c9
-rw-r--r--kernel/trace/trace_output.c70
-rw-r--r--kernel/trace/trace_output.h2
-rw-r--r--kernel/trace/trace_printk.c (renamed from kernel/trace/trace_bprintk.c)84
12 files changed, 158 insertions, 309 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 1cc8ca453a9b..e1583f2639b0 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -223,31 +223,6 @@ extern int ftrace_make_nop(struct module *mod,
223 */ 223 */
224extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr); 224extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
225 225
226#ifdef CONFIG_TRACE_BPRINTK
227extern int trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
228extern int __trace_bprintk(unsigned long ip, const char *fmt, ...)
229 __attribute__ ((format (printf, 2, 3)));
230
231static inline void ____trace_bprintk_check_format(const char *fmt, ...)
232 __attribute__ ((format (printf, 1, 2)));
233static inline void ____trace_bprintk_check_format(const char *fmt, ...) {}
234#define __trace_bprintk_check_format(fmt, args...) \
235do { \
236 if (0) \
237 ____trace_bprintk_check_format(fmt, ##args); \
238} while (0)
239
240#define trace_bprintk(fmt, args...) \
241do { \
242 static char *__attribute__((section("__trace_bprintk_fmt"))) \
243 trace_bprintk_fmt = fmt; \
244 __trace_bprintk_check_format(fmt, ##args); \
245 __trace_bprintk(_THIS_IP_, trace_bprintk_fmt, ##args); \
246} while (0)
247#else
248#define trace_bprintk trace_printk
249#endif
250
251/* May be defined in arch */ 226/* May be defined in arch */
252extern int ftrace_arch_read_dyn_info(char *buf, int size); 227extern int ftrace_arch_read_dyn_info(char *buf, int size);
253 228
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7aef15c4645e..4e726b9a71ec 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -423,6 +423,16 @@ extern void ftrace_off_permanent(void);
423extern void 423extern void
424ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); 424ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
425 425
426static inline void __attribute__ ((format (printf, 1, 2)))
427____trace_printk_check_format(const char *fmt, ...)
428{
429}
430#define __trace_printk_check_format(fmt, args...) \
431do { \
432 if (0) \
433 ____trace_printk_check_format(fmt, ##args); \
434} while (0)
435
426/** 436/**
427 * trace_printk - printf formatting in the ftrace buffer 437 * trace_printk - printf formatting in the ftrace buffer
428 * @fmt: the printf format for printing 438 * @fmt: the printf format for printing
@@ -439,13 +449,31 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
439 * Please refrain from leaving trace_printks scattered around in 449 * Please refrain from leaving trace_printks scattered around in
440 * your code. 450 * your code.
441 */ 451 */
442# define trace_printk(fmt...) __trace_printk(_THIS_IP_, fmt) 452
453#define trace_printk(fmt, args...) \
454do { \
455 static const char *trace_printk_fmt \
456 __attribute__((section("__trace_printk_fmt"))); \
457 trace_printk_fmt = fmt; \
458 __trace_printk_check_format(fmt, ##args); \
459 __trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \
460} while (0)
461
443extern int 462extern int
444__trace_printk(unsigned long ip, const char *fmt, ...) 463__trace_printk(unsigned long ip, const char *fmt, ...)
445 __attribute__ ((format (printf, 2, 3))); 464 __attribute__ ((format (printf, 2, 3)));
446# define ftrace_vprintk(fmt, ap) __trace_printk(_THIS_IP_, fmt, ap) 465
466#define ftrace_vprintk(fmt, vargs) \
467do { \
468 static const char *trace_printk_fmt \
469 __attribute__((section("__trace_printk_fmt"))); \
470 trace_printk_fmt = fmt; \
471 __ftrace_vprintk(_THIS_IP_, trace_printk_fmt, vargs); \
472} while (0)
473
447extern int 474extern int
448__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); 475__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
476
449extern void ftrace_dump(void); 477extern void ftrace_dump(void);
450#else 478#else
451static inline void 479static inline void
@@ -467,7 +495,7 @@ ftrace_vprintk(const char *fmt, va_list ap)
467 return 0; 495 return 0;
468} 496}
469static inline void ftrace_dump(void) { } 497static inline void ftrace_dump(void) { }
470#endif 498#endif /* CONFIG_TRACING */
471 499
472/* 500/*
473 * Display an IP address in readable format. 501 * Display an IP address in readable format.
diff --git a/include/linux/module.h b/include/linux/module.h
index 8cbec972d8e7..22d9878e868c 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -329,7 +329,7 @@ struct module
329 unsigned int num_tracepoints; 329 unsigned int num_tracepoints;
330#endif 330#endif
331 331
332#ifdef CONFIG_TRACE_BPRINTK 332#ifdef CONFIG_TRACING
333 const char **trace_bprintk_fmt_start; 333 const char **trace_bprintk_fmt_start;
334 unsigned int num_trace_bprintk_fmt; 334 unsigned int num_trace_bprintk_fmt;
335#endif 335#endif
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index ad8d3617d0a6..8e4a2a61cd75 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -52,6 +52,7 @@ config TRACING
52 select STACKTRACE if STACKTRACE_SUPPORT 52 select STACKTRACE if STACKTRACE_SUPPORT
53 select TRACEPOINTS 53 select TRACEPOINTS
54 select NOP_TRACER 54 select NOP_TRACER
55 select BINARY_PRINTF
55 56
56# 57#
57# Minimum requirements an architecture has to meet for us to 58# Minimum requirements an architecture has to meet for us to
@@ -97,12 +98,6 @@ config FUNCTION_GRAPH_TRACER
97 This is done by setting the current return address on the current 98 This is done by setting the current return address on the current
98 task structure into a stack of calls. 99 task structure into a stack of calls.
99 100
100config TRACE_BPRINTK
101 bool "Binary printk for tracing"
102 default y
103 depends on TRACING
104 select BINARY_PRINTF
105
106config IRQSOFF_TRACER 101config IRQSOFF_TRACER
107 bool "Interrupts-off Latency Tracer" 102 bool "Interrupts-off Latency Tracer"
108 default n 103 default n
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 46557ef4c379..c7a2943796eb 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_TRACING) += trace.o
22obj-$(CONFIG_TRACING) += trace_clock.o 22obj-$(CONFIG_TRACING) += trace_clock.o
23obj-$(CONFIG_TRACING) += trace_output.o 23obj-$(CONFIG_TRACING) += trace_output.o
24obj-$(CONFIG_TRACING) += trace_stat.o 24obj-$(CONFIG_TRACING) += trace_stat.o
25obj-$(CONFIG_TRACE_BPRINTK) += trace_bprintk.o 25obj-$(CONFIG_TRACING) += trace_printk.o
26obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o 26obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
27obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o 27obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o
28obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o 28obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 46b3cd7a5752..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 */
1177int 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
1222out_unlock:
1223 spin_unlock_irqrestore(&trace_buf_lock, flags);
1224
1225out:
1226 ftrace_preempt_enable(resched);
1227 unpause_graph_tracing();
1228
1229 return len;
1230}
1231EXPORT_SYMBOL_GPL(trace_vprintk);
1232
1172enum trace_file_type { 1233enum 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
@@ -3714,155 +3775,6 @@ static __init int tracer_init_debugfs(void)
3714 return 0; 3775 return 0;
3715} 3776}
3716 3777
3717int 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}
3769EXPORT_SYMBOL_GPL(trace_vprintk);
3770
3771int __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}
3784EXPORT_SYMBOL_GPL(__trace_printk);
3785
3786int __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}
3793EXPORT_SYMBOL_GPL(__ftrace_vprintk);
3794
3795/**
3796 * trace_vbprintk - write binary msg to tracing buffer
3797 *
3798 * Caller must insure @fmt are valid when msg is in tracing buffer.
3799 */
3800int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
3801{
3802 static DEFINE_SPINLOCK(trace_buf_lock);
3803 static u32 trace_buf[TRACE_BUF_SIZE];
3804
3805 struct ring_buffer_event *event;
3806 struct trace_array *tr = &global_trace;
3807 struct trace_array_cpu *data;
3808 struct bprintk_entry *entry;
3809 unsigned long flags;
3810 int resched;
3811 int cpu, len = 0, size, pc;
3812
3813 if (tracing_disabled || !trace_bprintk_enable)
3814 return 0;
3815
3816 pc = preempt_count();
3817 resched = ftrace_preempt_disable();
3818 cpu = raw_smp_processor_id();
3819 data = tr->data[cpu];
3820
3821 if (unlikely(atomic_read(&data->disabled)))
3822 goto out;
3823
3824 spin_lock_irqsave(&trace_buf_lock, flags);
3825 len = vbin_printf(trace_buf, TRACE_BUF_SIZE, fmt, args);
3826
3827 if (len > TRACE_BUF_SIZE || len < 0)
3828 goto out_unlock;
3829
3830 size = sizeof(*entry) + sizeof(u32) * len;
3831 event = trace_buffer_lock_reserve(tr, TRACE_BPRINTK, size, flags, pc);
3832 if (!event)
3833 goto out_unlock;
3834 entry = ring_buffer_event_data(event);
3835 entry->ip = ip;
3836 entry->fmt = fmt;
3837
3838 memcpy(entry->buf, trace_buf, sizeof(u32) * len);
3839 ring_buffer_unlock_commit(tr->buffer, event);
3840
3841out_unlock:
3842 spin_unlock_irqrestore(&trace_buf_lock, flags);
3843
3844out:
3845 ftrace_preempt_enable(resched);
3846
3847 return len;
3848}
3849EXPORT_SYMBOL_GPL(trace_vbprintk);
3850
3851int __trace_bprintk(unsigned long ip, const char *fmt, ...)
3852{
3853 int ret;
3854 va_list ap;
3855
3856 if (!fmt)
3857 return 0;
3858
3859 va_start(ap, fmt);
3860 ret = trace_vbprintk(ip, fmt, ap);
3861 va_end(ap);
3862 return ret;
3863}
3864EXPORT_SYMBOL_GPL(__trace_bprintk);
3865
3866static int trace_panic_handler(struct notifier_block *this, 3778static int trace_panic_handler(struct notifier_block *this,
3867 unsigned long event, void *unused) 3779 unsigned long event, void *unused)
3868{ 3780{
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 0f5077f8f957..6140922392c8 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -20,7 +20,6 @@ enum trace_type {
20 TRACE_WAKE, 20 TRACE_WAKE,
21 TRACE_STACK, 21 TRACE_STACK,
22 TRACE_PRINT, 22 TRACE_PRINT,
23 TRACE_BPRINTK,
24 TRACE_SPECIAL, 23 TRACE_SPECIAL,
25 TRACE_MMIO_RW, 24 TRACE_MMIO_RW,
26 TRACE_MMIO_MAP, 25 TRACE_MMIO_MAP,
@@ -120,16 +119,10 @@ struct userstack_entry {
120 */ 119 */
121struct print_entry { 120struct print_entry {
122 struct trace_entry ent; 121 struct trace_entry ent;
123 unsigned long ip; 122 unsigned long ip;
124 int depth; 123 int depth;
125 char buf[]; 124 const char *fmt;
126}; 125 u32 buf[];
127
128struct bprintk_entry {
129 struct trace_entry ent;
130 unsigned long ip;
131 const char *fmt;
132 u32 buf[];
133}; 126};
134#ifdef CONFIG_TRACE_BPRINTK 127#ifdef CONFIG_TRACE_BPRINTK
135extern int trace_bprintk_enable; 128extern int trace_bprintk_enable;
@@ -296,7 +289,6 @@ extern void __ftrace_bad_type(void);
296 IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ 289 IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \
297 IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ 290 IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
298 IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ 291 IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \
299 IF_ASSIGN(var, ent, struct bprintk_entry, TRACE_BPRINTK);\
300 IF_ASSIGN(var, ent, struct special_entry, 0); \ 292 IF_ASSIGN(var, ent, struct special_entry, 0); \
301 IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ 293 IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \
302 TRACE_MMIO_RW); \ 294 TRACE_MMIO_RW); \
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index e527f2f66c73..453ebd3b636e 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -742,7 +742,11 @@ print_graph_comment(struct print_entry *trace, struct trace_seq *s,
742 } 742 }
743 743
744 /* The comment */ 744 /* The comment */
745 ret = trace_seq_printf(s, "/* %s", trace->buf); 745 ret = trace_seq_printf(s, "/* ");
746 if (!ret)
747 return TRACE_TYPE_PARTIAL_LINE;
748
749 ret = trace_seq_bprintf(s, trace->fmt, trace->buf);
746 if (!ret) 750 if (!ret)
747 return TRACE_TYPE_PARTIAL_LINE; 751 return TRACE_TYPE_PARTIAL_LINE;
748 752
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index c401b908e805..23e346a734ca 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -254,15 +254,18 @@ static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
254{ 254{
255 struct trace_entry *entry = iter->ent; 255 struct trace_entry *entry = iter->ent;
256 struct print_entry *print = (struct print_entry *)entry; 256 struct print_entry *print = (struct print_entry *)entry;
257 const char *msg = print->buf;
258 struct trace_seq *s = &iter->seq; 257 struct trace_seq *s = &iter->seq;
259 unsigned long long t = ns2usecs(iter->ts); 258 unsigned long long t = ns2usecs(iter->ts);
260 unsigned long usec_rem = do_div(t, 1000000ULL); 259 unsigned long usec_rem = do_div(t, USEC_PER_SEC);
261 unsigned secs = (unsigned long)t; 260 unsigned secs = (unsigned long)t;
262 int ret; 261 int ret;
263 262
264 /* The trailing newline must be in the message. */ 263 /* The trailing newline must be in the message. */
265 ret = trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); 264 ret = trace_seq_printf(s, "MARK %u.%06lu ", secs, usec_rem);
265 if (!ret)
266 return TRACE_TYPE_PARTIAL_LINE;
267
268 ret = trace_seq_bprintf(s, print->fmt, print->buf);
266 if (!ret) 269 if (!ret)
267 return TRACE_TYPE_PARTIAL_LINE; 270 return TRACE_TYPE_PARTIAL_LINE;
268 271
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 4ab71201862e..ef8fd661b217 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -53,8 +53,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
53 return len; 53 return len;
54} 54}
55 55
56static int 56int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
57trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
58{ 57{
59 int len = (PAGE_SIZE - 1) - s->len; 58 int len = (PAGE_SIZE - 1) - s->len;
60 int ret; 59 int ret;
@@ -834,54 +833,12 @@ static struct trace_event trace_user_stack_event = {
834}; 833};
835 834
836/* TRACE_PRINT */ 835/* TRACE_PRINT */
837static enum print_line_t trace_print_print(struct trace_iterator *iter,
838 int flags)
839{
840 struct print_entry *field;
841 struct trace_seq *s = &iter->seq;
842
843 trace_assign_type(field, iter->ent);
844
845 if (!seq_print_ip_sym(s, field->ip, flags))
846 goto partial;
847
848 if (!trace_seq_printf(s, ": %s", field->buf))
849 goto partial;
850
851 return TRACE_TYPE_HANDLED;
852
853 partial:
854 return TRACE_TYPE_PARTIAL_LINE;
855}
856
857static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
858{
859 struct print_entry *field;
860
861 trace_assign_type(field, iter->ent);
862
863 if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
864 goto partial;
865
866 return TRACE_TYPE_HANDLED;
867
868 partial:
869 return TRACE_TYPE_PARTIAL_LINE;
870}
871
872static struct trace_event trace_print_event = {
873 .type = TRACE_PRINT,
874 .trace = trace_print_print,
875 .raw = trace_print_raw,
876};
877
878/* TRACE_BPRINTK */
879static enum print_line_t 836static enum print_line_t
880trace_bprintk_print(struct trace_iterator *iter, int flags) 837trace_print_print(struct trace_iterator *iter, int flags)
881{ 838{
882 struct trace_entry *entry = iter->ent; 839 struct trace_entry *entry = iter->ent;
883 struct trace_seq *s = &iter->seq; 840 struct trace_seq *s = &iter->seq;
884 struct bprintk_entry *field; 841 struct print_entry *field;
885 842
886 trace_assign_type(field, entry); 843 trace_assign_type(field, entry);
887 844
@@ -900,14 +857,13 @@ trace_bprintk_print(struct trace_iterator *iter, int flags)
900 return TRACE_TYPE_PARTIAL_LINE; 857 return TRACE_TYPE_PARTIAL_LINE;
901} 858}
902 859
903static enum print_line_t 860
904trace_bprintk_raw(struct trace_iterator *iter, int flags) 861static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
905{ 862{
906 struct trace_entry *entry = iter->ent; 863 struct print_entry *field;
907 struct trace_seq *s = &iter->seq; 864 struct trace_seq *s = &iter->seq;
908 struct bprintk_entry *field;
909 865
910 trace_assign_type(field, entry); 866 trace_assign_type(field, iter->ent);
911 867
912 if (!trace_seq_printf(s, ": %lx : ", field->ip)) 868 if (!trace_seq_printf(s, ": %lx : ", field->ip))
913 goto partial; 869 goto partial;
@@ -921,12 +877,11 @@ trace_bprintk_raw(struct trace_iterator *iter, int flags)
921 return TRACE_TYPE_PARTIAL_LINE; 877 return TRACE_TYPE_PARTIAL_LINE;
922} 878}
923 879
924static struct trace_event trace_bprintk_event = { 880
925 .type = TRACE_BPRINTK, 881static struct trace_event trace_print_event = {
926 .trace = trace_bprintk_print, 882 .type = TRACE_PRINT,
927 .raw = trace_bprintk_raw, 883 .trace = trace_print_print,
928 .hex = trace_nop_print, 884 .raw = trace_print_raw,
929 .binary = trace_nop_print,
930}; 885};
931 886
932static struct trace_event *events[] __initdata = { 887static struct trace_event *events[] __initdata = {
@@ -937,7 +892,6 @@ static struct trace_event *events[] __initdata = {
937 &trace_stack_event, 892 &trace_stack_event,
938 &trace_user_stack_event, 893 &trace_user_stack_event,
939 &trace_print_event, 894 &trace_print_event,
940 &trace_bprintk_event,
941 NULL 895 NULL
942}; 896};
943 897
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
index 8a34d688ed63..3b90e6ade1aa 100644
--- a/kernel/trace/trace_output.h
+++ b/kernel/trace/trace_output.h
@@ -18,6 +18,8 @@ struct trace_event {
18extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) 18extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
19 __attribute__ ((format (printf, 2, 3))); 19 __attribute__ ((format (printf, 2, 3)));
20extern int 20extern int
21trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
22extern int
21seq_print_ip_sym(struct trace_seq *s, unsigned long ip, 23seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
22 unsigned long sym_flags); 24 unsigned long sym_flags);
23extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, 25extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
diff --git a/kernel/trace/trace_bprintk.c b/kernel/trace/trace_printk.c
index f4c245a5cd33..a50aea22e929 100644
--- a/kernel/trace/trace_bprintk.c
+++ b/kernel/trace/trace_printk.c
@@ -21,31 +21,20 @@
21 21
22#ifdef CONFIG_MODULES 22#ifdef CONFIG_MODULES
23 23
24/* binary printk basic */
25static DEFINE_MUTEX(btrace_mutex);
26/* 24/*
27 * modules trace_bprintk()'s formats are autosaved in struct trace_bprintk_fmt 25 * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
28 * which are queued on trace_bprintk_fmt_list. 26 * which are queued on trace_bprintk_fmt_list.
29 */ 27 */
30static LIST_HEAD(trace_bprintk_fmt_list); 28static LIST_HEAD(trace_bprintk_fmt_list);
31 29
30/* serialize accesses to trace_bprintk_fmt_list */
31static DEFINE_MUTEX(btrace_mutex);
32
32struct trace_bprintk_fmt { 33struct trace_bprintk_fmt {
33 struct list_head list; 34 struct list_head list;
34 char fmt[0]; 35 char fmt[0];
35}; 36};
36 37
37
38static inline void lock_btrace(void)
39{
40 mutex_lock(&btrace_mutex);
41}
42
43static inline void unlock_btrace(void)
44{
45 mutex_unlock(&btrace_mutex);
46}
47
48
49static inline struct trace_bprintk_fmt *lookup_format(const char *fmt) 38static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
50{ 39{
51 struct trace_bprintk_fmt *pos; 40 struct trace_bprintk_fmt *pos;
@@ -60,7 +49,8 @@ static
60void hold_module_trace_bprintk_format(const char **start, const char **end) 49void hold_module_trace_bprintk_format(const char **start, const char **end)
61{ 50{
62 const char **iter; 51 const char **iter;
63 lock_btrace(); 52
53 mutex_lock(&btrace_mutex);
64 for (iter = start; iter < end; iter++) { 54 for (iter = start; iter < end; iter++) {
65 struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter); 55 struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
66 if (tb_fmt) { 56 if (tb_fmt) {
@@ -77,7 +67,7 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)
77 } else 67 } else
78 *iter = NULL; 68 *iter = NULL;
79 } 69 }
80 unlock_btrace(); 70 mutex_unlock(&btrace_mutex);
81} 71}
82 72
83static int module_trace_bprintk_format_notify(struct notifier_block *self, 73static int module_trace_bprintk_format_notify(struct notifier_block *self,
@@ -109,46 +99,40 @@ struct notifier_block module_trace_bprintk_format_nb = {
109 .notifier_call = module_trace_bprintk_format_notify, 99 .notifier_call = module_trace_bprintk_format_notify,
110}; 100};
111 101
112/* events tracer */ 102int __trace_printk(unsigned long ip, const char *fmt, ...)
113int trace_bprintk_enable; 103 {
104 int ret;
105 va_list ap;
114 106
115static void start_bprintk_trace(struct trace_array *tr) 107 if (unlikely(!fmt))
116{ 108 return 0;
117 tracing_reset_online_cpus(tr);
118 trace_bprintk_enable = 1;
119}
120 109
121static void stop_bprintk_trace(struct trace_array *tr) 110 if (!(trace_flags & TRACE_ITER_PRINTK))
122{ 111 return 0;
123 trace_bprintk_enable = 0; 112
124 tracing_reset_online_cpus(tr); 113 va_start(ap, fmt);
114 ret = trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
115 va_end(ap);
116 return ret;
125} 117}
118EXPORT_SYMBOL_GPL(__trace_printk);
126 119
127static int init_bprintk_trace(struct trace_array *tr) 120int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
128{ 121 {
129 start_bprintk_trace(tr); 122 if (unlikely(!fmt))
130 return 0; 123 return 0;
124
125 if (!(trace_flags & TRACE_ITER_PRINTK))
126 return 0;
127
128 return trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
131} 129}
130EXPORT_SYMBOL_GPL(__ftrace_vprintk);
132 131
133static struct tracer bprintk_trace __read_mostly =
134{
135 .name = "events",
136 .init = init_bprintk_trace,
137 .reset = stop_bprintk_trace,
138 .start = start_bprintk_trace,
139 .stop = stop_bprintk_trace,
140};
141 132
142static __init int init_bprintk(void) 133static __init int init_trace_printk(void)
143{ 134{
144 int ret = register_module_notifier(&module_trace_bprintk_format_nb); 135 return register_module_notifier(&module_trace_bprintk_format_nb);
145 if (ret)
146 return ret;
147
148 ret = register_tracer(&bprintk_trace);
149 if (ret)
150 unregister_module_notifier(&module_trace_bprintk_format_nb);
151 return ret;
152} 136}
153 137
154device_initcall(init_bprintk); 138early_initcall(init_trace_printk);