aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 216bbe7547a4..a3f7ae9cd8e1 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -244,13 +244,6 @@ unsigned long nsecs_to_usecs(unsigned long nsecs)
244 return nsecs / 1000; 244 return nsecs / 1000;
245} 245}
246 246
247/*
248 * TRACE_ITER_SYM_MASK masks the options in trace_flags that
249 * control the output of kernel symbols.
250 */
251#define TRACE_ITER_SYM_MASK \
252 (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR)
253
254/* These must match the bit postions in trace_iterator_flags */ 247/* These must match the bit postions in trace_iterator_flags */
255static const char *trace_options[] = { 248static const char *trace_options[] = {
256 "print-parent", 249 "print-parent",
@@ -810,6 +803,35 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data,
810 ring_buffer_unlock_commit(tr->buffer, event, irq_flags); 803 ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
811} 804}
812 805
806#ifdef CONFIG_FUNCTION_RET_TRACER
807static void __trace_function_return(struct trace_array *tr,
808 struct trace_array_cpu *data,
809 struct ftrace_retfunc *trace,
810 unsigned long flags,
811 int pc)
812{
813 struct ring_buffer_event *event;
814 struct ftrace_ret_entry *entry;
815 unsigned long irq_flags;
816
817 if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
818 return;
819
820 event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry),
821 &irq_flags);
822 if (!event)
823 return;
824 entry = ring_buffer_event_data(event);
825 tracing_generic_entry_update(&entry->ent, flags, pc);
826 entry->ent.type = TRACE_FN_RET;
827 entry->ip = trace->func;
828 entry->parent_ip = trace->ret;
829 entry->rettime = trace->rettime;
830 entry->calltime = trace->calltime;
831 ring_buffer_unlock_commit(global_trace.buffer, event, irq_flags);
832}
833#endif
834
813void 835void
814ftrace(struct trace_array *tr, struct trace_array_cpu *data, 836ftrace(struct trace_array *tr, struct trace_array_cpu *data,
815 unsigned long ip, unsigned long parent_ip, unsigned long flags, 837 unsigned long ip, unsigned long parent_ip, unsigned long flags,
@@ -1038,6 +1060,29 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
1038 raw_local_irq_restore(flags); 1060 raw_local_irq_restore(flags);
1039} 1061}
1040 1062
1063#ifdef CONFIG_FUNCTION_RET_TRACER
1064void trace_function_return(struct ftrace_retfunc *trace)
1065{
1066 struct trace_array *tr = &global_trace;
1067 struct trace_array_cpu *data;
1068 unsigned long flags;
1069 long disabled;
1070 int cpu;
1071 int pc;
1072
1073 raw_local_irq_save(flags);
1074 cpu = raw_smp_processor_id();
1075 data = tr->data[cpu];
1076 disabled = atomic_inc_return(&data->disabled);
1077 if (likely(disabled == 1)) {
1078 pc = preempt_count();
1079 __trace_function_return(tr, data, trace, flags, pc);
1080 }
1081 atomic_dec(&data->disabled);
1082 raw_local_irq_restore(flags);
1083}
1084#endif /* CONFIG_FUNCTION_RET_TRACER */
1085
1041static struct ftrace_ops trace_ops __read_mostly = 1086static struct ftrace_ops trace_ops __read_mostly =
1042{ 1087{
1043 .func = function_trace_call, 1088 .func = function_trace_call,
@@ -1285,7 +1330,7 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt,
1285# define IP_FMT "%016lx" 1330# define IP_FMT "%016lx"
1286#endif 1331#endif
1287 1332
1288static int 1333int
1289seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) 1334seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
1290{ 1335{
1291 int ret; 1336 int ret;
@@ -1738,6 +1783,10 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
1738 trace_seq_print_cont(s, iter); 1783 trace_seq_print_cont(s, iter);
1739 break; 1784 break;
1740 } 1785 }
1786 case TRACE_FN_RET: {
1787 return print_return_function(iter);
1788 break;
1789 }
1741 } 1790 }
1742 return TRACE_TYPE_HANDLED; 1791 return TRACE_TYPE_HANDLED;
1743} 1792}