aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);