aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-12-02 23:50:05 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-03 02:56:26 -0500
commite49dc19c6a19ea112fcb94b7c62ec62cdd5c08aa (patch)
tree851dcdfe321e16a327d656ecd7040ef6e8590bec
parent7ee991fbc6f947e9b04f29c9c6c1d057d0671a16 (diff)
ftrace: function graph return for function entry
Impact: feature, let entry function decide to trace or not This patch lets the graph tracer entry function decide if the tracing should be done at the end as well. This requires all function graph entry functions return 1 if it should trace, or 0 if the return should not be traced. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/entry_32.S3
-rw-r--r--arch/x86/kernel/entry_64.S3
-rw-r--r--arch/x86/kernel/ftrace.c7
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--kernel/trace/ftrace.c10
-rw-r--r--kernel/trace/trace.c4
-rw-r--r--kernel/trace/trace.h2
7 files changed, 24 insertions, 7 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 826682abed1d..43ceb3f454bf 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1196,6 +1196,9 @@ ENTRY(mcount)
1196#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1196#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1197 cmpl $ftrace_stub, ftrace_graph_return 1197 cmpl $ftrace_stub, ftrace_graph_return
1198 jnz ftrace_graph_caller 1198 jnz ftrace_graph_caller
1199
1200 cmpl $ftrace_graph_entry_stub, ftrace_graph_entry
1201 jnz ftrace_graph_caller
1199#endif 1202#endif
1200.globl ftrace_stub 1203.globl ftrace_stub
1201ftrace_stub: 1204ftrace_stub:
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 9060ba6497e2..54e0bbdccb99 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -120,6 +120,9 @@ ENTRY(mcount)
120#ifdef CONFIG_FUNCTION_GRAPH_TRACER 120#ifdef CONFIG_FUNCTION_GRAPH_TRACER
121 cmpq $ftrace_stub, ftrace_graph_return 121 cmpq $ftrace_stub, ftrace_graph_return
122 jnz ftrace_graph_caller 122 jnz ftrace_graph_caller
123
124 cmpq $ftrace_graph_entry_stub, ftrace_graph_entry
125 jnz ftrace_graph_caller
123#endif 126#endif
124 127
125.globl ftrace_stub 128.globl ftrace_stub
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index adba8e9a427c..d278ad2ebda2 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -425,6 +425,7 @@ static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
425 trace->calltime = current->ret_stack[index].calltime; 425 trace->calltime = current->ret_stack[index].calltime;
426 trace->overrun = atomic_read(&current->trace_overrun); 426 trace->overrun = atomic_read(&current->trace_overrun);
427 trace->depth = index; 427 trace->depth = index;
428 barrier();
428 current->curr_ret_stack--; 429 current->curr_ret_stack--;
429} 430}
430 431
@@ -506,7 +507,11 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
506 } 507 }
507 508
508 trace.func = self_addr; 509 trace.func = self_addr;
509 ftrace_graph_entry(&trace);
510 510
511 /* Only trace if the calling function expects to */
512 if (!ftrace_graph_entry(&trace)) {
513 current->curr_ret_stack--;
514 *parent = old;
515 }
511} 516}
512#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 517#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 58ca1c3a3f4d..469ceb3e85ba 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -371,7 +371,7 @@ struct ftrace_graph_ret {
371#define FTRACE_RETSTACK_ALLOC_SIZE 32 371#define FTRACE_RETSTACK_ALLOC_SIZE 32
372/* Type of the callback handlers for tracing function graph*/ 372/* Type of the callback handlers for tracing function graph*/
373typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */ 373typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
374typedef void (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */ 374typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
375 375
376extern int register_ftrace_graph(trace_func_graph_ret_t retfunc, 376extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
377 trace_func_graph_ent_t entryfunc); 377 trace_func_graph_ent_t entryfunc);
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a44af05ae2d0..65b9e863056b 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1636,11 +1636,15 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
1636 1636
1637static atomic_t ftrace_graph_active; 1637static atomic_t ftrace_graph_active;
1638 1638
1639int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
1640{
1641 return 0;
1642}
1643
1639/* The callbacks that hook a function */ 1644/* The callbacks that hook a function */
1640trace_func_graph_ret_t ftrace_graph_return = 1645trace_func_graph_ret_t ftrace_graph_return =
1641 (trace_func_graph_ret_t)ftrace_stub; 1646 (trace_func_graph_ret_t)ftrace_stub;
1642trace_func_graph_ent_t ftrace_graph_entry = 1647trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
1643 (trace_func_graph_ent_t)ftrace_stub;
1644 1648
1645/* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */ 1649/* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */
1646static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) 1650static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
@@ -1738,7 +1742,7 @@ void unregister_ftrace_graph(void)
1738 1742
1739 atomic_dec(&ftrace_graph_active); 1743 atomic_dec(&ftrace_graph_active);
1740 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; 1744 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
1741 ftrace_graph_entry = (trace_func_graph_ent_t)ftrace_stub; 1745 ftrace_graph_entry = ftrace_graph_entry_stub;
1742 ftrace_shutdown(FTRACE_STOP_FUNC_RET); 1746 ftrace_shutdown(FTRACE_STOP_FUNC_RET);
1743 1747
1744 mutex_unlock(&ftrace_sysctl_lock); 1748 mutex_unlock(&ftrace_sysctl_lock);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 380de630ebce..8b6409a62b54 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1200,7 +1200,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
1200} 1200}
1201 1201
1202#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1202#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1203void trace_graph_entry(struct ftrace_graph_ent *trace) 1203int trace_graph_entry(struct ftrace_graph_ent *trace)
1204{ 1204{
1205 struct trace_array *tr = &global_trace; 1205 struct trace_array *tr = &global_trace;
1206 struct trace_array_cpu *data; 1206 struct trace_array_cpu *data;
@@ -1219,6 +1219,8 @@ void trace_graph_entry(struct ftrace_graph_ent *trace)
1219 } 1219 }
1220 atomic_dec(&data->disabled); 1220 atomic_dec(&data->disabled);
1221 local_irq_restore(flags); 1221 local_irq_restore(flags);
1222
1223 return 1;
1222} 1224}
1223 1225
1224void trace_graph_return(struct ftrace_graph_ret *trace) 1226void trace_graph_return(struct ftrace_graph_ret *trace)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index f96f4e787ff3..0565ae9a2210 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -412,7 +412,7 @@ void trace_function(struct trace_array *tr,
412 unsigned long flags, int pc); 412 unsigned long flags, int pc);
413 413
414void trace_graph_return(struct ftrace_graph_ret *trace); 414void trace_graph_return(struct ftrace_graph_ret *trace);
415void trace_graph_entry(struct ftrace_graph_ent *trace); 415int trace_graph_entry(struct ftrace_graph_ent *trace);
416void trace_bts(struct trace_array *tr, 416void trace_bts(struct trace_array *tr,
417 unsigned long from, 417 unsigned long from,
418 unsigned long to); 418 unsigned long to);