diff options
-rw-r--r-- | arch/x86/kernel/entry_32.S | 3 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 3 | ||||
-rw-r--r-- | arch/x86/kernel/ftrace.c | 7 | ||||
-rw-r--r-- | include/linux/ftrace.h | 2 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 10 | ||||
-rw-r--r-- | kernel/trace/trace.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace.h | 2 |
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 |
1201 | ftrace_stub: | 1204 | ftrace_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(¤t->trace_overrun); | 426 | trace->overrun = atomic_read(¤t->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*/ |
373 | typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */ | 373 | typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */ |
374 | typedef void (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */ | 374 | typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */ |
375 | 375 | ||
376 | extern int register_ftrace_graph(trace_func_graph_ret_t retfunc, | 376 | extern 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 | ||
1637 | static atomic_t ftrace_graph_active; | 1637 | static atomic_t ftrace_graph_active; |
1638 | 1638 | ||
1639 | int 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 */ |
1640 | trace_func_graph_ret_t ftrace_graph_return = | 1645 | trace_func_graph_ret_t ftrace_graph_return = |
1641 | (trace_func_graph_ret_t)ftrace_stub; | 1646 | (trace_func_graph_ret_t)ftrace_stub; |
1642 | trace_func_graph_ent_t ftrace_graph_entry = | 1647 | trace_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. */ |
1646 | static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) | 1650 | static 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 |
1203 | void trace_graph_entry(struct ftrace_graph_ent *trace) | 1203 | int 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 | ||
1224 | void trace_graph_return(struct ftrace_graph_ret *trace) | 1226 | void 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 | ||
414 | void trace_graph_return(struct ftrace_graph_ret *trace); | 414 | void trace_graph_return(struct ftrace_graph_ret *trace); |
415 | void trace_graph_entry(struct ftrace_graph_ent *trace); | 415 | int trace_graph_entry(struct ftrace_graph_ent *trace); |
416 | void trace_bts(struct trace_array *tr, | 416 | void trace_bts(struct trace_array *tr, |
417 | unsigned long from, | 417 | unsigned long from, |
418 | unsigned long to); | 418 | unsigned long to); |