diff options
Diffstat (limited to 'kernel/trace/trace_output.c')
-rw-r--r-- | kernel/trace/trace_output.c | 119 |
1 files changed, 110 insertions, 9 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 697e88d13907..bb922d9ee51b 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -14,7 +14,7 @@ | |||
14 | /* must be a power of 2 */ | 14 | /* must be a power of 2 */ |
15 | #define EVENT_HASHSIZE 128 | 15 | #define EVENT_HASHSIZE 128 |
16 | 16 | ||
17 | DECLARE_RWSEM(trace_event_mutex); | 17 | DECLARE_RWSEM(trace_event_sem); |
18 | 18 | ||
19 | static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; | 19 | static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; |
20 | 20 | ||
@@ -37,6 +37,22 @@ int trace_print_seq(struct seq_file *m, struct trace_seq *s) | |||
37 | return ret; | 37 | return ret; |
38 | } | 38 | } |
39 | 39 | ||
40 | enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter) | ||
41 | { | ||
42 | struct trace_seq *s = &iter->seq; | ||
43 | struct trace_entry *entry = iter->ent; | ||
44 | struct bputs_entry *field; | ||
45 | int ret; | ||
46 | |||
47 | trace_assign_type(field, entry); | ||
48 | |||
49 | ret = trace_seq_puts(s, field->str); | ||
50 | if (!ret) | ||
51 | return TRACE_TYPE_PARTIAL_LINE; | ||
52 | |||
53 | return TRACE_TYPE_HANDLED; | ||
54 | } | ||
55 | |||
40 | enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) | 56 | enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) |
41 | { | 57 | { |
42 | struct trace_seq *s = &iter->seq; | 58 | struct trace_seq *s = &iter->seq; |
@@ -397,6 +413,32 @@ ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) | |||
397 | } | 413 | } |
398 | EXPORT_SYMBOL(ftrace_print_hex_seq); | 414 | EXPORT_SYMBOL(ftrace_print_hex_seq); |
399 | 415 | ||
416 | int ftrace_raw_output_prep(struct trace_iterator *iter, | ||
417 | struct trace_event *trace_event) | ||
418 | { | ||
419 | struct ftrace_event_call *event; | ||
420 | struct trace_seq *s = &iter->seq; | ||
421 | struct trace_seq *p = &iter->tmp_seq; | ||
422 | struct trace_entry *entry; | ||
423 | int ret; | ||
424 | |||
425 | event = container_of(trace_event, struct ftrace_event_call, event); | ||
426 | entry = iter->ent; | ||
427 | |||
428 | if (entry->type != event->event.type) { | ||
429 | WARN_ON_ONCE(1); | ||
430 | return TRACE_TYPE_UNHANDLED; | ||
431 | } | ||
432 | |||
433 | trace_seq_init(p); | ||
434 | ret = trace_seq_printf(s, "%s: ", event->name); | ||
435 | if (!ret) | ||
436 | return TRACE_TYPE_PARTIAL_LINE; | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | EXPORT_SYMBOL(ftrace_raw_output_prep); | ||
441 | |||
400 | #ifdef CONFIG_KRETPROBES | 442 | #ifdef CONFIG_KRETPROBES |
401 | static inline const char *kretprobed(const char *name) | 443 | static inline const char *kretprobed(const char *name) |
402 | { | 444 | { |
@@ -617,7 +659,7 @@ lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) | |||
617 | { | 659 | { |
618 | unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE; | 660 | unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE; |
619 | unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; | 661 | unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; |
620 | unsigned long long abs_ts = iter->ts - iter->tr->time_start; | 662 | unsigned long long abs_ts = iter->ts - iter->trace_buffer->time_start; |
621 | unsigned long long rel_ts = next_ts - iter->ts; | 663 | unsigned long long rel_ts = next_ts - iter->ts; |
622 | struct trace_seq *s = &iter->seq; | 664 | struct trace_seq *s = &iter->seq; |
623 | 665 | ||
@@ -783,12 +825,12 @@ static int trace_search_list(struct list_head **list) | |||
783 | 825 | ||
784 | void trace_event_read_lock(void) | 826 | void trace_event_read_lock(void) |
785 | { | 827 | { |
786 | down_read(&trace_event_mutex); | 828 | down_read(&trace_event_sem); |
787 | } | 829 | } |
788 | 830 | ||
789 | void trace_event_read_unlock(void) | 831 | void trace_event_read_unlock(void) |
790 | { | 832 | { |
791 | up_read(&trace_event_mutex); | 833 | up_read(&trace_event_sem); |
792 | } | 834 | } |
793 | 835 | ||
794 | /** | 836 | /** |
@@ -811,7 +853,7 @@ int register_ftrace_event(struct trace_event *event) | |||
811 | unsigned key; | 853 | unsigned key; |
812 | int ret = 0; | 854 | int ret = 0; |
813 | 855 | ||
814 | down_write(&trace_event_mutex); | 856 | down_write(&trace_event_sem); |
815 | 857 | ||
816 | if (WARN_ON(!event)) | 858 | if (WARN_ON(!event)) |
817 | goto out; | 859 | goto out; |
@@ -866,14 +908,14 @@ int register_ftrace_event(struct trace_event *event) | |||
866 | 908 | ||
867 | ret = event->type; | 909 | ret = event->type; |
868 | out: | 910 | out: |
869 | up_write(&trace_event_mutex); | 911 | up_write(&trace_event_sem); |
870 | 912 | ||
871 | return ret; | 913 | return ret; |
872 | } | 914 | } |
873 | EXPORT_SYMBOL_GPL(register_ftrace_event); | 915 | EXPORT_SYMBOL_GPL(register_ftrace_event); |
874 | 916 | ||
875 | /* | 917 | /* |
876 | * Used by module code with the trace_event_mutex held for write. | 918 | * Used by module code with the trace_event_sem held for write. |
877 | */ | 919 | */ |
878 | int __unregister_ftrace_event(struct trace_event *event) | 920 | int __unregister_ftrace_event(struct trace_event *event) |
879 | { | 921 | { |
@@ -888,9 +930,9 @@ int __unregister_ftrace_event(struct trace_event *event) | |||
888 | */ | 930 | */ |
889 | int unregister_ftrace_event(struct trace_event *event) | 931 | int unregister_ftrace_event(struct trace_event *event) |
890 | { | 932 | { |
891 | down_write(&trace_event_mutex); | 933 | down_write(&trace_event_sem); |
892 | __unregister_ftrace_event(event); | 934 | __unregister_ftrace_event(event); |
893 | up_write(&trace_event_mutex); | 935 | up_write(&trace_event_sem); |
894 | 936 | ||
895 | return 0; | 937 | return 0; |
896 | } | 938 | } |
@@ -1217,6 +1259,64 @@ static struct trace_event trace_user_stack_event = { | |||
1217 | .funcs = &trace_user_stack_funcs, | 1259 | .funcs = &trace_user_stack_funcs, |
1218 | }; | 1260 | }; |
1219 | 1261 | ||
1262 | /* TRACE_BPUTS */ | ||
1263 | static enum print_line_t | ||
1264 | trace_bputs_print(struct trace_iterator *iter, int flags, | ||
1265 | struct trace_event *event) | ||
1266 | { | ||
1267 | struct trace_entry *entry = iter->ent; | ||
1268 | struct trace_seq *s = &iter->seq; | ||
1269 | struct bputs_entry *field; | ||
1270 | |||
1271 | trace_assign_type(field, entry); | ||
1272 | |||
1273 | if (!seq_print_ip_sym(s, field->ip, flags)) | ||
1274 | goto partial; | ||
1275 | |||
1276 | if (!trace_seq_puts(s, ": ")) | ||
1277 | goto partial; | ||
1278 | |||
1279 | if (!trace_seq_puts(s, field->str)) | ||
1280 | goto partial; | ||
1281 | |||
1282 | return TRACE_TYPE_HANDLED; | ||
1283 | |||
1284 | partial: | ||
1285 | return TRACE_TYPE_PARTIAL_LINE; | ||
1286 | } | ||
1287 | |||
1288 | |||
1289 | static enum print_line_t | ||
1290 | trace_bputs_raw(struct trace_iterator *iter, int flags, | ||
1291 | struct trace_event *event) | ||
1292 | { | ||
1293 | struct bputs_entry *field; | ||
1294 | struct trace_seq *s = &iter->seq; | ||
1295 | |||
1296 | trace_assign_type(field, iter->ent); | ||
1297 | |||
1298 | if (!trace_seq_printf(s, ": %lx : ", field->ip)) | ||
1299 | goto partial; | ||
1300 | |||
1301 | if (!trace_seq_puts(s, field->str)) | ||
1302 | goto partial; | ||
1303 | |||
1304 | return TRACE_TYPE_HANDLED; | ||
1305 | |||
1306 | partial: | ||
1307 | return TRACE_TYPE_PARTIAL_LINE; | ||
1308 | } | ||
1309 | |||
1310 | static struct trace_event_functions trace_bputs_funcs = { | ||
1311 | .trace = trace_bputs_print, | ||
1312 | .raw = trace_bputs_raw, | ||
1313 | }; | ||
1314 | |||
1315 | static struct trace_event trace_bputs_event = { | ||
1316 | .type = TRACE_BPUTS, | ||
1317 | .funcs = &trace_bputs_funcs, | ||
1318 | }; | ||
1319 | |||
1220 | /* TRACE_BPRINT */ | 1320 | /* TRACE_BPRINT */ |
1221 | static enum print_line_t | 1321 | static enum print_line_t |
1222 | trace_bprint_print(struct trace_iterator *iter, int flags, | 1322 | trace_bprint_print(struct trace_iterator *iter, int flags, |
@@ -1329,6 +1429,7 @@ static struct trace_event *events[] __initdata = { | |||
1329 | &trace_wake_event, | 1429 | &trace_wake_event, |
1330 | &trace_stack_event, | 1430 | &trace_stack_event, |
1331 | &trace_user_stack_event, | 1431 | &trace_user_stack_event, |
1432 | &trace_bputs_event, | ||
1332 | &trace_bprint_event, | 1433 | &trace_bprint_event, |
1333 | &trace_print_event, | 1434 | &trace_print_event, |
1334 | NULL | 1435 | NULL |