diff options
-rw-r--r-- | include/linux/kernel.h | 40 | ||||
-rw-r--r-- | kernel/trace/trace.c | 85 | ||||
-rw-r--r-- | kernel/trace/trace.h | 13 | ||||
-rw-r--r-- | kernel/trace/trace_event_types.h | 11 | ||||
-rw-r--r-- | kernel/trace/trace_functions_graph.c | 6 | ||||
-rw-r--r-- | kernel/trace/trace_mmiotrace.c | 7 | ||||
-rw-r--r-- | kernel/trace/trace_output.c | 57 | ||||
-rw-r--r-- | kernel/trace/trace_printk.c | 33 |
8 files changed, 213 insertions, 39 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 7742798c9208..1daca3b062bb 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -452,32 +452,46 @@ do { \ | |||
452 | 452 | ||
453 | #define trace_printk(fmt, args...) \ | 453 | #define trace_printk(fmt, args...) \ |
454 | do { \ | 454 | do { \ |
455 | static const char *trace_printk_fmt \ | ||
456 | __attribute__((section("__trace_printk_fmt"))); \ | ||
457 | \ | ||
458 | if (!trace_printk_fmt) \ | ||
459 | trace_printk_fmt = fmt; \ | ||
460 | \ | ||
461 | __trace_printk_check_format(fmt, ##args); \ | 455 | __trace_printk_check_format(fmt, ##args); \ |
462 | __trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \ | 456 | if (__builtin_constant_p(fmt)) { \ |
457 | static const char *trace_printk_fmt \ | ||
458 | __attribute__((section("__trace_printk_fmt"))) = \ | ||
459 | __builtin_constant_p(fmt) ? fmt : NULL; \ | ||
460 | \ | ||
461 | __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \ | ||
462 | } else \ | ||
463 | __trace_printk(_THIS_IP_, fmt, ##args); \ | ||
463 | } while (0) | 464 | } while (0) |
464 | 465 | ||
465 | extern int | 466 | extern int |
467 | __trace_bprintk(unsigned long ip, const char *fmt, ...) | ||
468 | __attribute__ ((format (printf, 2, 3))); | ||
469 | |||
470 | extern int | ||
466 | __trace_printk(unsigned long ip, const char *fmt, ...) | 471 | __trace_printk(unsigned long ip, const char *fmt, ...) |
467 | __attribute__ ((format (printf, 2, 3))); | 472 | __attribute__ ((format (printf, 2, 3))); |
468 | 473 | ||
474 | /* | ||
475 | * The double __builtin_constant_p is because gcc will give us an error | ||
476 | * if we try to allocate the static variable to fmt if it is not a | ||
477 | * constant. Even with the outer if statement. | ||
478 | */ | ||
469 | #define ftrace_vprintk(fmt, vargs) \ | 479 | #define ftrace_vprintk(fmt, vargs) \ |
470 | do { \ | 480 | do { \ |
471 | static const char *trace_printk_fmt \ | 481 | if (__builtin_constant_p(fmt)) { \ |
472 | __attribute__((section("__trace_printk_fmt"))); \ | 482 | static const char *trace_printk_fmt \ |
473 | \ | 483 | __attribute__((section("__trace_printk_fmt"))) = \ |
474 | if (!trace_printk_fmt) \ | 484 | __builtin_constant_p(fmt) ? fmt : NULL; \ |
475 | trace_printk_fmt = fmt; \ | ||
476 | \ | 485 | \ |
477 | __ftrace_vprintk(_THIS_IP_, trace_printk_fmt, vargs); \ | 486 | __ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \ |
487 | } else \ | ||
488 | __ftrace_vprintk(_THIS_IP_, fmt, vargs); \ | ||
478 | } while (0) | 489 | } while (0) |
479 | 490 | ||
480 | extern int | 491 | extern int |
492 | __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap); | ||
493 | |||
494 | extern int | ||
481 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); | 495 | __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); |
482 | 496 | ||
483 | extern void ftrace_dump(void); | 497 | extern void ftrace_dump(void); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 62a63b2b33dd..dbb077d8a172 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -1179,10 +1179,10 @@ void trace_graph_return(struct ftrace_graph_ret *trace) | |||
1179 | 1179 | ||
1180 | 1180 | ||
1181 | /** | 1181 | /** |
1182 | * trace_vprintk - write binary msg to tracing buffer | 1182 | * trace_vbprintk - write binary msg to tracing buffer |
1183 | * | 1183 | * |
1184 | */ | 1184 | */ |
1185 | int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | 1185 | int trace_vbprintk(unsigned long ip, int depth, const char *fmt, va_list args) |
1186 | { | 1186 | { |
1187 | static raw_spinlock_t trace_buf_lock = | 1187 | static raw_spinlock_t trace_buf_lock = |
1188 | (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; | 1188 | (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; |
@@ -1191,7 +1191,7 @@ int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | |||
1191 | struct ring_buffer_event *event; | 1191 | struct ring_buffer_event *event; |
1192 | struct trace_array *tr = &global_trace; | 1192 | struct trace_array *tr = &global_trace; |
1193 | struct trace_array_cpu *data; | 1193 | struct trace_array_cpu *data; |
1194 | struct print_entry *entry; | 1194 | struct bprint_entry *entry; |
1195 | unsigned long flags; | 1195 | unsigned long flags; |
1196 | int resched; | 1196 | int resched; |
1197 | int cpu, len = 0, size, pc; | 1197 | int cpu, len = 0, size, pc; |
@@ -1219,7 +1219,7 @@ int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | |||
1219 | goto out_unlock; | 1219 | goto out_unlock; |
1220 | 1220 | ||
1221 | size = sizeof(*entry) + sizeof(u32) * len; | 1221 | size = sizeof(*entry) + sizeof(u32) * len; |
1222 | event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, flags, pc); | 1222 | event = trace_buffer_lock_reserve(tr, TRACE_BPRINT, size, flags, pc); |
1223 | if (!event) | 1223 | if (!event) |
1224 | goto out_unlock; | 1224 | goto out_unlock; |
1225 | entry = ring_buffer_event_data(event); | 1225 | entry = ring_buffer_event_data(event); |
@@ -1240,6 +1240,60 @@ out: | |||
1240 | 1240 | ||
1241 | return len; | 1241 | return len; |
1242 | } | 1242 | } |
1243 | EXPORT_SYMBOL_GPL(trace_vbprintk); | ||
1244 | |||
1245 | int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args) | ||
1246 | { | ||
1247 | static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; | ||
1248 | static char trace_buf[TRACE_BUF_SIZE]; | ||
1249 | |||
1250 | struct ring_buffer_event *event; | ||
1251 | struct trace_array *tr = &global_trace; | ||
1252 | struct trace_array_cpu *data; | ||
1253 | int cpu, len = 0, size, pc; | ||
1254 | struct print_entry *entry; | ||
1255 | unsigned long irq_flags; | ||
1256 | |||
1257 | if (tracing_disabled || tracing_selftest_running) | ||
1258 | return 0; | ||
1259 | |||
1260 | pc = preempt_count(); | ||
1261 | preempt_disable_notrace(); | ||
1262 | cpu = raw_smp_processor_id(); | ||
1263 | data = tr->data[cpu]; | ||
1264 | |||
1265 | if (unlikely(atomic_read(&data->disabled))) | ||
1266 | goto out; | ||
1267 | |||
1268 | pause_graph_tracing(); | ||
1269 | raw_local_irq_save(irq_flags); | ||
1270 | __raw_spin_lock(&trace_buf_lock); | ||
1271 | len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args); | ||
1272 | |||
1273 | len = min(len, TRACE_BUF_SIZE-1); | ||
1274 | trace_buf[len] = 0; | ||
1275 | |||
1276 | size = sizeof(*entry) + len + 1; | ||
1277 | event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc); | ||
1278 | if (!event) | ||
1279 | goto out_unlock; | ||
1280 | entry = ring_buffer_event_data(event); | ||
1281 | entry->ip = ip; | ||
1282 | entry->depth = depth; | ||
1283 | |||
1284 | memcpy(&entry->buf, trace_buf, len); | ||
1285 | entry->buf[len] = 0; | ||
1286 | ring_buffer_unlock_commit(tr->buffer, event); | ||
1287 | |||
1288 | out_unlock: | ||
1289 | __raw_spin_unlock(&trace_buf_lock); | ||
1290 | raw_local_irq_restore(irq_flags); | ||
1291 | unpause_graph_tracing(); | ||
1292 | out: | ||
1293 | preempt_enable_notrace(); | ||
1294 | |||
1295 | return len; | ||
1296 | } | ||
1243 | EXPORT_SYMBOL_GPL(trace_vprintk); | 1297 | EXPORT_SYMBOL_GPL(trace_vprintk); |
1244 | 1298 | ||
1245 | enum trace_file_type { | 1299 | enum trace_file_type { |
@@ -1628,6 +1682,22 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | |||
1628 | return TRACE_TYPE_HANDLED; | 1682 | return TRACE_TYPE_HANDLED; |
1629 | } | 1683 | } |
1630 | 1684 | ||
1685 | static enum print_line_t print_bprintk_msg_only(struct trace_iterator *iter) | ||
1686 | { | ||
1687 | struct trace_seq *s = &iter->seq; | ||
1688 | struct trace_entry *entry = iter->ent; | ||
1689 | struct bprint_entry *field; | ||
1690 | int ret; | ||
1691 | |||
1692 | trace_assign_type(field, entry); | ||
1693 | |||
1694 | ret = trace_seq_bprintf(s, field->fmt, field->buf); | ||
1695 | if (!ret) | ||
1696 | return TRACE_TYPE_PARTIAL_LINE; | ||
1697 | |||
1698 | return TRACE_TYPE_HANDLED; | ||
1699 | } | ||
1700 | |||
1631 | static enum print_line_t print_printk_msg_only(struct trace_iterator *iter) | 1701 | static enum print_line_t print_printk_msg_only(struct trace_iterator *iter) |
1632 | { | 1702 | { |
1633 | struct trace_seq *s = &iter->seq; | 1703 | struct trace_seq *s = &iter->seq; |
@@ -1637,7 +1707,7 @@ static enum print_line_t print_printk_msg_only(struct trace_iterator *iter) | |||
1637 | 1707 | ||
1638 | trace_assign_type(field, entry); | 1708 | trace_assign_type(field, entry); |
1639 | 1709 | ||
1640 | ret = trace_seq_bprintf(s, field->fmt, field->buf); | 1710 | ret = trace_seq_printf(s, "%s", field->buf); |
1641 | if (!ret) | 1711 | if (!ret) |
1642 | return TRACE_TYPE_PARTIAL_LINE; | 1712 | return TRACE_TYPE_PARTIAL_LINE; |
1643 | 1713 | ||
@@ -1702,6 +1772,11 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter) | |||
1702 | return ret; | 1772 | return ret; |
1703 | } | 1773 | } |
1704 | 1774 | ||
1775 | if (iter->ent->type == TRACE_BPRINT && | ||
1776 | trace_flags & TRACE_ITER_PRINTK && | ||
1777 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | ||
1778 | return print_bprintk_msg_only(iter); | ||
1779 | |||
1705 | if (iter->ent->type == TRACE_PRINT && | 1780 | if (iter->ent->type == TRACE_PRINT && |
1706 | trace_flags & TRACE_ITER_PRINTK && | 1781 | trace_flags & TRACE_ITER_PRINTK && |
1707 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) | 1782 | trace_flags & TRACE_ITER_PRINTK_MSGONLY) |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 336324d717f8..cede1ab49d07 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -20,6 +20,7 @@ enum trace_type { | |||
20 | TRACE_WAKE, | 20 | TRACE_WAKE, |
21 | TRACE_STACK, | 21 | TRACE_STACK, |
22 | TRACE_PRINT, | 22 | TRACE_PRINT, |
23 | TRACE_BPRINT, | ||
23 | TRACE_SPECIAL, | 24 | TRACE_SPECIAL, |
24 | TRACE_MMIO_RW, | 25 | TRACE_MMIO_RW, |
25 | TRACE_MMIO_MAP, | 26 | TRACE_MMIO_MAP, |
@@ -117,7 +118,7 @@ struct userstack_entry { | |||
117 | /* | 118 | /* |
118 | * trace_printk entry: | 119 | * trace_printk entry: |
119 | */ | 120 | */ |
120 | struct print_entry { | 121 | struct bprint_entry { |
121 | struct trace_entry ent; | 122 | struct trace_entry ent; |
122 | unsigned long ip; | 123 | unsigned long ip; |
123 | int depth; | 124 | int depth; |
@@ -125,6 +126,13 @@ struct print_entry { | |||
125 | u32 buf[]; | 126 | u32 buf[]; |
126 | }; | 127 | }; |
127 | 128 | ||
129 | struct print_entry { | ||
130 | struct trace_entry ent; | ||
131 | unsigned long ip; | ||
132 | int depth; | ||
133 | char buf[]; | ||
134 | }; | ||
135 | |||
128 | #define TRACE_OLD_SIZE 88 | 136 | #define TRACE_OLD_SIZE 88 |
129 | 137 | ||
130 | struct trace_field_cont { | 138 | struct trace_field_cont { |
@@ -286,6 +294,7 @@ extern void __ftrace_bad_type(void); | |||
286 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ | 294 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ |
287 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ | 295 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ |
288 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ | 296 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ |
297 | IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ | ||
289 | IF_ASSIGN(var, ent, struct special_entry, 0); \ | 298 | IF_ASSIGN(var, ent, struct special_entry, 0); \ |
290 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ | 299 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ |
291 | TRACE_MMIO_RW); \ | 300 | TRACE_MMIO_RW); \ |
@@ -570,6 +579,8 @@ extern int trace_selftest_startup_branch(struct tracer *trace, | |||
570 | extern void *head_page(struct trace_array_cpu *data); | 579 | extern void *head_page(struct trace_array_cpu *data); |
571 | extern long ns2usecs(cycle_t nsec); | 580 | extern long ns2usecs(cycle_t nsec); |
572 | extern int | 581 | extern int |
582 | trace_vbprintk(unsigned long ip, int depth, const char *fmt, va_list args); | ||
583 | extern int | ||
573 | trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args); | 584 | trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args); |
574 | 585 | ||
575 | extern unsigned long trace_flags; | 586 | extern unsigned long trace_flags; |
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h index 5cca4c978bde..d0907d746425 100644 --- a/kernel/trace/trace_event_types.h +++ b/kernel/trace/trace_event_types.h | |||
@@ -102,7 +102,7 @@ TRACE_EVENT_FORMAT(user_stack, TRACE_USER_STACK, userstack_entry, ignore, | |||
102 | "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n") | 102 | "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n") |
103 | ); | 103 | ); |
104 | 104 | ||
105 | TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore, | 105 | TRACE_EVENT_FORMAT(bprint, TRACE_PRINT, bprint_entry, ignore, |
106 | TRACE_STRUCT( | 106 | TRACE_STRUCT( |
107 | TRACE_FIELD(unsigned long, ip, ip) | 107 | TRACE_FIELD(unsigned long, ip, ip) |
108 | TRACE_FIELD(unsigned int, depth, depth) | 108 | TRACE_FIELD(unsigned int, depth, depth) |
@@ -112,6 +112,15 @@ TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore, | |||
112 | TP_RAW_FMT("%08lx (%d) fmt:%p %s") | 112 | TP_RAW_FMT("%08lx (%d) fmt:%p %s") |
113 | ); | 113 | ); |
114 | 114 | ||
115 | TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore, | ||
116 | TRACE_STRUCT( | ||
117 | TRACE_FIELD(unsigned long, ip, ip) | ||
118 | TRACE_FIELD(unsigned int, depth, depth) | ||
119 | TRACE_FIELD_ZERO_CHAR(buf) | ||
120 | ), | ||
121 | TP_RAW_FMT("%08lx (%d) fmt:%p %s") | ||
122 | ); | ||
123 | |||
115 | TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore, | 124 | TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore, |
116 | TRACE_STRUCT( | 125 | TRACE_STRUCT( |
117 | TRACE_FIELD(unsigned int, line, line) | 126 | TRACE_FIELD(unsigned int, line, line) |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 8566c14b3e9a..4c388607ed67 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
@@ -684,7 +684,7 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, | |||
684 | } | 684 | } |
685 | 685 | ||
686 | static enum print_line_t | 686 | static enum print_line_t |
687 | print_graph_comment(struct print_entry *trace, struct trace_seq *s, | 687 | print_graph_comment(struct bprint_entry *trace, struct trace_seq *s, |
688 | struct trace_entry *ent, struct trace_iterator *iter) | 688 | struct trace_entry *ent, struct trace_iterator *iter) |
689 | { | 689 | { |
690 | int i; | 690 | int i; |
@@ -781,8 +781,8 @@ print_graph_function(struct trace_iterator *iter) | |||
781 | trace_assign_type(field, entry); | 781 | trace_assign_type(field, entry); |
782 | return print_graph_return(&field->ret, s, entry, iter); | 782 | return print_graph_return(&field->ret, s, entry, iter); |
783 | } | 783 | } |
784 | case TRACE_PRINT: { | 784 | case TRACE_BPRINT: { |
785 | struct print_entry *field; | 785 | struct bprint_entry *field; |
786 | trace_assign_type(field, entry); | 786 | trace_assign_type(field, entry); |
787 | return print_graph_comment(field, s, entry, iter); | 787 | return print_graph_comment(field, s, entry, iter); |
788 | } | 788 | } |
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 23e346a734ca..f095916e477f 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c | |||
@@ -254,6 +254,7 @@ 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; | ||
257 | struct trace_seq *s = &iter->seq; | 258 | struct trace_seq *s = &iter->seq; |
258 | unsigned long long t = ns2usecs(iter->ts); | 259 | unsigned long long t = ns2usecs(iter->ts); |
259 | unsigned long usec_rem = do_div(t, USEC_PER_SEC); | 260 | unsigned long usec_rem = do_div(t, USEC_PER_SEC); |
@@ -261,11 +262,7 @@ static enum print_line_t mmio_print_mark(struct trace_iterator *iter) | |||
261 | int ret; | 262 | int ret; |
262 | 263 | ||
263 | /* The trailing newline must be in the message. */ | 264 | /* The trailing newline must be in the message. */ |
264 | ret = trace_seq_printf(s, "MARK %u.%06lu ", secs, usec_rem); | 265 | ret = trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); |
265 | if (!ret) | ||
266 | return TRACE_TYPE_PARTIAL_LINE; | ||
267 | |||
268 | ret = trace_seq_bprintf(s, print->fmt, print->buf); | ||
269 | if (!ret) | 266 | if (!ret) |
270 | return TRACE_TYPE_PARTIAL_LINE; | 267 | return TRACE_TYPE_PARTIAL_LINE; |
271 | 268 | ||
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 491832af9ba1..ea9d3b410c7a 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -832,13 +832,13 @@ static struct trace_event trace_user_stack_event = { | |||
832 | .binary = trace_special_bin, | 832 | .binary = trace_special_bin, |
833 | }; | 833 | }; |
834 | 834 | ||
835 | /* TRACE_PRINT */ | 835 | /* TRACE_BPRINT */ |
836 | static enum print_line_t | 836 | static enum print_line_t |
837 | trace_print_print(struct trace_iterator *iter, int flags) | 837 | trace_bprint_print(struct trace_iterator *iter, int flags) |
838 | { | 838 | { |
839 | struct trace_entry *entry = iter->ent; | 839 | struct trace_entry *entry = iter->ent; |
840 | struct trace_seq *s = &iter->seq; | 840 | struct trace_seq *s = &iter->seq; |
841 | struct print_entry *field; | 841 | struct bprint_entry *field; |
842 | 842 | ||
843 | trace_assign_type(field, entry); | 843 | trace_assign_type(field, entry); |
844 | 844 | ||
@@ -858,9 +858,10 @@ trace_print_print(struct trace_iterator *iter, int flags) | |||
858 | } | 858 | } |
859 | 859 | ||
860 | 860 | ||
861 | static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags) | 861 | static enum print_line_t |
862 | trace_bprint_raw(struct trace_iterator *iter, int flags) | ||
862 | { | 863 | { |
863 | struct print_entry *field; | 864 | struct bprint_entry *field; |
864 | struct trace_seq *s = &iter->seq; | 865 | struct trace_seq *s = &iter->seq; |
865 | 866 | ||
866 | trace_assign_type(field, iter->ent); | 867 | trace_assign_type(field, iter->ent); |
@@ -878,12 +879,55 @@ static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags) | |||
878 | } | 879 | } |
879 | 880 | ||
880 | 881 | ||
882 | static struct trace_event trace_bprint_event = { | ||
883 | .type = TRACE_BPRINT, | ||
884 | .trace = trace_bprint_print, | ||
885 | .raw = trace_bprint_raw, | ||
886 | }; | ||
887 | |||
888 | /* TRACE_PRINT */ | ||
889 | static enum print_line_t trace_print_print(struct trace_iterator *iter, | ||
890 | int flags) | ||
891 | { | ||
892 | struct print_entry *field; | ||
893 | struct trace_seq *s = &iter->seq; | ||
894 | |||
895 | trace_assign_type(field, iter->ent); | ||
896 | |||
897 | if (!seq_print_ip_sym(s, field->ip, flags)) | ||
898 | goto partial; | ||
899 | |||
900 | if (!trace_seq_printf(s, ": %s", field->buf)) | ||
901 | goto partial; | ||
902 | |||
903 | return TRACE_TYPE_HANDLED; | ||
904 | |||
905 | partial: | ||
906 | return TRACE_TYPE_PARTIAL_LINE; | ||
907 | } | ||
908 | |||
909 | static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags) | ||
910 | { | ||
911 | struct print_entry *field; | ||
912 | |||
913 | trace_assign_type(field, iter->ent); | ||
914 | |||
915 | if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf)) | ||
916 | goto partial; | ||
917 | |||
918 | return TRACE_TYPE_HANDLED; | ||
919 | |||
920 | partial: | ||
921 | return TRACE_TYPE_PARTIAL_LINE; | ||
922 | } | ||
923 | |||
881 | static struct trace_event trace_print_event = { | 924 | static struct trace_event trace_print_event = { |
882 | .type = TRACE_PRINT, | 925 | .type = TRACE_PRINT, |
883 | .trace = trace_print_print, | 926 | .trace = trace_print_print, |
884 | .raw = trace_print_raw, | 927 | .raw = trace_print_raw, |
885 | }; | 928 | }; |
886 | 929 | ||
930 | |||
887 | static struct trace_event *events[] __initdata = { | 931 | static struct trace_event *events[] __initdata = { |
888 | &trace_fn_event, | 932 | &trace_fn_event, |
889 | &trace_ctx_event, | 933 | &trace_ctx_event, |
@@ -891,6 +935,7 @@ static struct trace_event *events[] __initdata = { | |||
891 | &trace_special_event, | 935 | &trace_special_event, |
892 | &trace_stack_event, | 936 | &trace_stack_event, |
893 | &trace_user_stack_event, | 937 | &trace_user_stack_event, |
938 | &trace_bprint_event, | ||
894 | &trace_print_event, | 939 | &trace_print_event, |
895 | NULL | 940 | NULL |
896 | }; | 941 | }; |
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index a50aea22e929..f307a11e2332 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c | |||
@@ -99,7 +99,7 @@ struct notifier_block module_trace_bprintk_format_nb = { | |||
99 | .notifier_call = module_trace_bprintk_format_notify, | 99 | .notifier_call = module_trace_bprintk_format_notify, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | int __trace_printk(unsigned long ip, const char *fmt, ...) | 102 | int __trace_bprintk(unsigned long ip, const char *fmt, ...) |
103 | { | 103 | { |
104 | int ret; | 104 | int ret; |
105 | va_list ap; | 105 | va_list ap; |
@@ -111,13 +111,13 @@ int __trace_printk(unsigned long ip, const char *fmt, ...) | |||
111 | return 0; | 111 | return 0; |
112 | 112 | ||
113 | va_start(ap, fmt); | 113 | va_start(ap, fmt); |
114 | ret = trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap); | 114 | ret = trace_vbprintk(ip, task_curr_ret_stack(current), fmt, ap); |
115 | va_end(ap); | 115 | va_end(ap); |
116 | return ret; | 116 | return ret; |
117 | } | 117 | } |
118 | EXPORT_SYMBOL_GPL(__trace_printk); | 118 | EXPORT_SYMBOL_GPL(__trace_bprintk); |
119 | 119 | ||
120 | int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap) | 120 | int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap) |
121 | { | 121 | { |
122 | if (unlikely(!fmt)) | 122 | if (unlikely(!fmt)) |
123 | return 0; | 123 | return 0; |
@@ -125,11 +125,34 @@ int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap) | |||
125 | if (!(trace_flags & TRACE_ITER_PRINTK)) | 125 | if (!(trace_flags & TRACE_ITER_PRINTK)) |
126 | return 0; | 126 | return 0; |
127 | 127 | ||
128 | return trace_vbprintk(ip, task_curr_ret_stack(current), fmt, ap); | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(__ftrace_vbprintk); | ||
131 | |||
132 | int __trace_printk(unsigned long ip, const char *fmt, ...) | ||
133 | { | ||
134 | int ret; | ||
135 | va_list ap; | ||
136 | |||
137 | if (!(trace_flags & TRACE_ITER_PRINTK)) | ||
138 | return 0; | ||
139 | |||
140 | va_start(ap, fmt); | ||
141 | ret = trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap); | ||
142 | va_end(ap); | ||
143 | return ret; | ||
144 | } | ||
145 | EXPORT_SYMBOL_GPL(__trace_printk); | ||
146 | |||
147 | int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap) | ||
148 | { | ||
149 | if (!(trace_flags & TRACE_ITER_PRINTK)) | ||
150 | return 0; | ||
151 | |||
128 | return trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap); | 152 | return trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap); |
129 | } | 153 | } |
130 | EXPORT_SYMBOL_GPL(__ftrace_vprintk); | 154 | EXPORT_SYMBOL_GPL(__ftrace_vprintk); |
131 | 155 | ||
132 | |||
133 | static __init int init_trace_printk(void) | 156 | static __init int init_trace_printk(void) |
134 | { | 157 | { |
135 | return register_module_notifier(&module_trace_bprintk_format_nb); | 158 | return register_module_notifier(&module_trace_bprintk_format_nb); |