diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8a499e2adaec..d86e3252f300 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -705,6 +705,7 @@ static void ftrace_trace_stack(struct trace_array *tr, | |||
705 | unsigned long flags, | 705 | unsigned long flags, |
706 | int skip, int pc) | 706 | int skip, int pc) |
707 | { | 707 | { |
708 | #ifdef CONFIG_STACKTRACE | ||
708 | struct ring_buffer_event *event; | 709 | struct ring_buffer_event *event; |
709 | struct stack_entry *entry; | 710 | struct stack_entry *entry; |
710 | struct stack_trace trace; | 711 | struct stack_trace trace; |
@@ -730,6 +731,7 @@ static void ftrace_trace_stack(struct trace_array *tr, | |||
730 | 731 | ||
731 | save_stack_trace(&trace); | 732 | save_stack_trace(&trace); |
732 | ring_buffer_unlock_commit(tr->buffer, event, irq_flags); | 733 | ring_buffer_unlock_commit(tr->buffer, event, irq_flags); |
734 | #endif | ||
733 | } | 735 | } |
734 | 736 | ||
735 | void __trace_stack(struct trace_array *tr, | 737 | void __trace_stack(struct trace_array *tr, |
@@ -1086,17 +1088,20 @@ static void s_stop(struct seq_file *m, void *p) | |||
1086 | mutex_unlock(&trace_types_lock); | 1088 | mutex_unlock(&trace_types_lock); |
1087 | } | 1089 | } |
1088 | 1090 | ||
1089 | #define KRETPROBE_MSG "[unknown/kretprobe'd]" | ||
1090 | |||
1091 | #ifdef CONFIG_KRETPROBES | 1091 | #ifdef CONFIG_KRETPROBES |
1092 | static inline int kretprobed(unsigned long addr) | 1092 | static inline const char *kretprobed(const char *name) |
1093 | { | 1093 | { |
1094 | return addr == (unsigned long)kretprobe_trampoline; | 1094 | static const char tramp_name[] = "kretprobe_trampoline"; |
1095 | int size = sizeof(tramp_name); | ||
1096 | |||
1097 | if (strncmp(tramp_name, name, size) == 0) | ||
1098 | return "[unknown/kretprobe'd]"; | ||
1099 | return name; | ||
1095 | } | 1100 | } |
1096 | #else | 1101 | #else |
1097 | static inline int kretprobed(unsigned long addr) | 1102 | static inline const char *kretprobed(const char *name) |
1098 | { | 1103 | { |
1099 | return 0; | 1104 | return name; |
1100 | } | 1105 | } |
1101 | #endif /* CONFIG_KRETPROBES */ | 1106 | #endif /* CONFIG_KRETPROBES */ |
1102 | 1107 | ||
@@ -1105,10 +1110,13 @@ seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) | |||
1105 | { | 1110 | { |
1106 | #ifdef CONFIG_KALLSYMS | 1111 | #ifdef CONFIG_KALLSYMS |
1107 | char str[KSYM_SYMBOL_LEN]; | 1112 | char str[KSYM_SYMBOL_LEN]; |
1113 | const char *name; | ||
1108 | 1114 | ||
1109 | kallsyms_lookup(address, NULL, NULL, NULL, str); | 1115 | kallsyms_lookup(address, NULL, NULL, NULL, str); |
1110 | 1116 | ||
1111 | return trace_seq_printf(s, fmt, str); | 1117 | name = kretprobed(str); |
1118 | |||
1119 | return trace_seq_printf(s, fmt, name); | ||
1112 | #endif | 1120 | #endif |
1113 | return 1; | 1121 | return 1; |
1114 | } | 1122 | } |
@@ -1119,9 +1127,12 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt, | |||
1119 | { | 1127 | { |
1120 | #ifdef CONFIG_KALLSYMS | 1128 | #ifdef CONFIG_KALLSYMS |
1121 | char str[KSYM_SYMBOL_LEN]; | 1129 | char str[KSYM_SYMBOL_LEN]; |
1130 | const char *name; | ||
1122 | 1131 | ||
1123 | sprint_symbol(str, address); | 1132 | sprint_symbol(str, address); |
1124 | return trace_seq_printf(s, fmt, str); | 1133 | name = kretprobed(str); |
1134 | |||
1135 | return trace_seq_printf(s, fmt, name); | ||
1125 | #endif | 1136 | #endif |
1126 | return 1; | 1137 | return 1; |
1127 | } | 1138 | } |
@@ -1375,10 +1386,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu) | |||
1375 | 1386 | ||
1376 | seq_print_ip_sym(s, field->ip, sym_flags); | 1387 | seq_print_ip_sym(s, field->ip, sym_flags); |
1377 | trace_seq_puts(s, " ("); | 1388 | trace_seq_puts(s, " ("); |
1378 | if (kretprobed(field->parent_ip)) | 1389 | seq_print_ip_sym(s, field->parent_ip, sym_flags); |
1379 | trace_seq_puts(s, KRETPROBE_MSG); | ||
1380 | else | ||
1381 | seq_print_ip_sym(s, field->parent_ip, sym_flags); | ||
1382 | trace_seq_puts(s, ")\n"); | 1390 | trace_seq_puts(s, ")\n"); |
1383 | break; | 1391 | break; |
1384 | } | 1392 | } |
@@ -1494,12 +1502,9 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) | |||
1494 | ret = trace_seq_printf(s, " <-"); | 1502 | ret = trace_seq_printf(s, " <-"); |
1495 | if (!ret) | 1503 | if (!ret) |
1496 | return TRACE_TYPE_PARTIAL_LINE; | 1504 | return TRACE_TYPE_PARTIAL_LINE; |
1497 | if (kretprobed(field->parent_ip)) | 1505 | ret = seq_print_ip_sym(s, |
1498 | ret = trace_seq_puts(s, KRETPROBE_MSG); | 1506 | field->parent_ip, |
1499 | else | 1507 | sym_flags); |
1500 | ret = seq_print_ip_sym(s, | ||
1501 | field->parent_ip, | ||
1502 | sym_flags); | ||
1503 | if (!ret) | 1508 | if (!ret) |
1504 | return TRACE_TYPE_PARTIAL_LINE; | 1509 | return TRACE_TYPE_PARTIAL_LINE; |
1505 | } | 1510 | } |
@@ -1750,7 +1755,7 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | |||
1750 | return TRACE_TYPE_HANDLED; | 1755 | return TRACE_TYPE_HANDLED; |
1751 | 1756 | ||
1752 | SEQ_PUT_FIELD_RET(s, entry->pid); | 1757 | SEQ_PUT_FIELD_RET(s, entry->pid); |
1753 | SEQ_PUT_FIELD_RET(s, iter->cpu); | 1758 | SEQ_PUT_FIELD_RET(s, entry->cpu); |
1754 | SEQ_PUT_FIELD_RET(s, iter->ts); | 1759 | SEQ_PUT_FIELD_RET(s, iter->ts); |
1755 | 1760 | ||
1756 | switch (entry->type) { | 1761 | switch (entry->type) { |
@@ -1931,6 +1936,7 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) | |||
1931 | ring_buffer_read_finish(iter->buffer_iter[cpu]); | 1936 | ring_buffer_read_finish(iter->buffer_iter[cpu]); |
1932 | } | 1937 | } |
1933 | mutex_unlock(&trace_types_lock); | 1938 | mutex_unlock(&trace_types_lock); |
1939 | kfree(iter); | ||
1934 | 1940 | ||
1935 | return ERR_PTR(-ENOMEM); | 1941 | return ERR_PTR(-ENOMEM); |
1936 | } | 1942 | } |
@@ -2671,7 +2677,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
2671 | { | 2677 | { |
2672 | unsigned long val; | 2678 | unsigned long val; |
2673 | char buf[64]; | 2679 | char buf[64]; |
2674 | int ret; | 2680 | int ret, cpu; |
2675 | struct trace_array *tr = filp->private_data; | 2681 | struct trace_array *tr = filp->private_data; |
2676 | 2682 | ||
2677 | if (cnt >= sizeof(buf)) | 2683 | if (cnt >= sizeof(buf)) |
@@ -2699,6 +2705,14 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
2699 | goto out; | 2705 | goto out; |
2700 | } | 2706 | } |
2701 | 2707 | ||
2708 | /* disable all cpu buffers */ | ||
2709 | for_each_tracing_cpu(cpu) { | ||
2710 | if (global_trace.data[cpu]) | ||
2711 | atomic_inc(&global_trace.data[cpu]->disabled); | ||
2712 | if (max_tr.data[cpu]) | ||
2713 | atomic_inc(&max_tr.data[cpu]->disabled); | ||
2714 | } | ||
2715 | |||
2702 | if (val != global_trace.entries) { | 2716 | if (val != global_trace.entries) { |
2703 | ret = ring_buffer_resize(global_trace.buffer, val); | 2717 | ret = ring_buffer_resize(global_trace.buffer, val); |
2704 | if (ret < 0) { | 2718 | if (ret < 0) { |
@@ -2730,6 +2744,13 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
2730 | if (tracing_disabled) | 2744 | if (tracing_disabled) |
2731 | cnt = -ENOMEM; | 2745 | cnt = -ENOMEM; |
2732 | out: | 2746 | out: |
2747 | for_each_tracing_cpu(cpu) { | ||
2748 | if (global_trace.data[cpu]) | ||
2749 | atomic_dec(&global_trace.data[cpu]->disabled); | ||
2750 | if (max_tr.data[cpu]) | ||
2751 | atomic_dec(&max_tr.data[cpu]->disabled); | ||
2752 | } | ||
2753 | |||
2733 | max_tr.entries = global_trace.entries; | 2754 | max_tr.entries = global_trace.entries; |
2734 | mutex_unlock(&trace_types_lock); | 2755 | mutex_unlock(&trace_types_lock); |
2735 | 2756 | ||