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); |
