summaryrefslogtreecommitdiff
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-03-24 23:17:58 -0400
committerSteven Rostedt <srostedt@redhat.com>2009-03-24 23:41:11 -0400
commita2a16d6a3156ef7309ca7328a20c35df9418e670 (patch)
tree8f21d9c56eb34f9bd1057929661c96d04329dd69 /kernel/trace/ftrace.c
parentcafb168a1c92e4c9e1731fe3d666c39611762c49 (diff)
downloadlwn-a2a16d6a3156ef7309ca7328a20c35df9418e670.tar.gz
lwn-a2a16d6a3156ef7309ca7328a20c35df9418e670.zip
function-graph: add option to calculate graph time or not
graph time is the time that a function is executing another function. Thus if function A calls B, if graph-time is set, then the time for A includes B. This is the default behavior. But if graph-time is off, then the time spent executing B is subtracted from A. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index ed1fc5021d44..71e5faef12ab 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -604,6 +604,7 @@ static int profile_graph_entry(struct ftrace_graph_ent *trace)
static void profile_graph_return(struct ftrace_graph_ret *trace)
{
struct ftrace_profile_stat *stat;
+ unsigned long long calltime;
struct ftrace_profile *rec;
unsigned long flags;
@@ -612,9 +613,27 @@ static void profile_graph_return(struct ftrace_graph_ret *trace)
if (!stat->hash)
goto out;
+ calltime = trace->rettime - trace->calltime;
+
+ if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
+ int index;
+
+ index = trace->depth;
+
+ /* Append this call time to the parent time to subtract */
+ if (index)
+ current->ret_stack[index - 1].subtime += calltime;
+
+ if (current->ret_stack[index].subtime < calltime)
+ calltime -= current->ret_stack[index].subtime;
+ else
+ calltime = 0;
+ }
+
rec = ftrace_find_profiled_func(stat, trace->func);
if (rec)
- rec->time += trace->rettime - trace->calltime;
+ rec->time += calltime;
+
out:
local_irq_restore(flags);
}