aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_functions_graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_functions_graph.c')
-rw-r--r--kernel/trace/trace_functions_graph.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index d28687e7b3a7..8b592418d8b2 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -65,6 +65,12 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth)
65 if (!current->ret_stack) 65 if (!current->ret_stack)
66 return -EBUSY; 66 return -EBUSY;
67 67
68 /*
69 * We must make sure the ret_stack is tested before we read
70 * anything else.
71 */
72 smp_rmb();
73
68 /* The return trace stack is full */ 74 /* The return trace stack is full */
69 if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) { 75 if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
70 atomic_inc(&current->trace_overrun); 76 atomic_inc(&current->trace_overrun);
@@ -78,13 +84,14 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth)
78 current->ret_stack[index].ret = ret; 84 current->ret_stack[index].ret = ret;
79 current->ret_stack[index].func = func; 85 current->ret_stack[index].func = func;
80 current->ret_stack[index].calltime = calltime; 86 current->ret_stack[index].calltime = calltime;
87 current->ret_stack[index].subtime = 0;
81 *depth = index; 88 *depth = index;
82 89
83 return 0; 90 return 0;
84} 91}
85 92
86/* Retrieve a function return address to the trace stack on thread info.*/ 93/* Retrieve a function return address to the trace stack on thread info.*/
87void 94static void
88ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret) 95ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
89{ 96{
90 int index; 97 int index;
@@ -104,9 +111,6 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
104 trace->calltime = current->ret_stack[index].calltime; 111 trace->calltime = current->ret_stack[index].calltime;
105 trace->overrun = atomic_read(&current->trace_overrun); 112 trace->overrun = atomic_read(&current->trace_overrun);
106 trace->depth = index; 113 trace->depth = index;
107 barrier();
108 current->curr_ret_stack--;
109
110} 114}
111 115
112/* 116/*
@@ -121,6 +125,8 @@ unsigned long ftrace_return_to_handler(void)
121 ftrace_pop_return_trace(&trace, &ret); 125 ftrace_pop_return_trace(&trace, &ret);
122 trace.rettime = trace_clock_local(); 126 trace.rettime = trace_clock_local();
123 ftrace_graph_return(&trace); 127 ftrace_graph_return(&trace);
128 barrier();
129 current->curr_ret_stack--;
124 130
125 if (unlikely(!ret)) { 131 if (unlikely(!ret)) {
126 ftrace_graph_stop(); 132 ftrace_graph_stop();
@@ -426,8 +432,8 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
426 return TRACE_TYPE_HANDLED; 432 return TRACE_TYPE_HANDLED;
427} 433}
428 434
429static enum print_line_t 435enum print_line_t
430print_graph_duration(unsigned long long duration, struct trace_seq *s) 436trace_print_graph_duration(unsigned long long duration, struct trace_seq *s)
431{ 437{
432 unsigned long nsecs_rem = do_div(duration, 1000); 438 unsigned long nsecs_rem = do_div(duration, 1000);
433 /* log10(ULONG_MAX) + '\0' */ 439 /* log10(ULONG_MAX) + '\0' */
@@ -464,12 +470,23 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
464 if (!ret) 470 if (!ret)
465 return TRACE_TYPE_PARTIAL_LINE; 471 return TRACE_TYPE_PARTIAL_LINE;
466 } 472 }
473 return TRACE_TYPE_HANDLED;
474}
475
476static enum print_line_t
477print_graph_duration(unsigned long long duration, struct trace_seq *s)
478{
479 int ret;
480
481 ret = trace_print_graph_duration(duration, s);
482 if (ret != TRACE_TYPE_HANDLED)
483 return ret;
467 484
468 ret = trace_seq_printf(s, "| "); 485 ret = trace_seq_printf(s, "| ");
469 if (!ret) 486 if (!ret)
470 return TRACE_TYPE_PARTIAL_LINE; 487 return TRACE_TYPE_PARTIAL_LINE;
471 return TRACE_TYPE_HANDLED;
472 488
489 return TRACE_TYPE_HANDLED;
473} 490}
474 491
475/* Case of a leaf function on its call entry */ 492/* Case of a leaf function on its call entry */