diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2008-11-11 01:14:25 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-11 04:29:12 -0500 |
commit | 15e6cb3673ea6277999642802406a764b49391b0 (patch) | |
tree | d0a46a918caa64d5fb1ed37be3e026b30e94fe77 /kernel/trace/trace.c | |
parent | caf4b323b02a16c92fba449952ac6515ddc76d7a (diff) |
tracing: add a tracer to catch execution time of kernel functions
Impact: add new tracing plugin which can trace full (entry+exit) function calls
This tracer uses the low level function return ftrace plugin to
measure the execution time of the kernel functions.
The first field is the caller of the function, the second is the
measured function, and the last one is the execution time in
nanoseconds.
- v3:
- HAVE_FUNCTION_RET_TRACER have been added. Each arch that support ftrace return
should enable it.
- ftrace_return_stub becomes ftrace_stub.
- CONFIG_FUNCTION_RET_TRACER depends now on CONFIG_FUNCTION_TRACER
- Return traces printing can be used for other tracers on trace.c
- Adapt to the new tracing API (no more ctrl_update callback)
- Correct the check of "disabled" during insertion.
- Minor changes...
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 65 |
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 */ |
255 | static const char *trace_options[] = { | 248 | static 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 | ||
807 | static 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 | |||
813 | void | 835 | void |
814 | ftrace(struct trace_array *tr, struct trace_array_cpu *data, | 836 | ftrace(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 | ||
1064 | void 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 | |||
1041 | static struct ftrace_ops trace_ops __read_mostly = | 1086 | static 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 | ||
1288 | static int | 1333 | int |
1289 | seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags) | 1334 | seq_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 | } |