Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 121159
b: refs/heads/master
c: 0231022
h: refs/heads/master
i:
  121157: 5e1cda7
  121155: 29bde24
  121151: 670c021
v: v3
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Nov 18, 2008
1 parent c318c87 commit 0e8ecc4
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0619faf657806b943e6acf51f60f1cd023a96c78
refs/heads/master: 0231022cc32d5f2e7f3c06b75691dda0ad6aec33
7 changes: 7 additions & 0 deletions trunk/arch/x86/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct task_struct;
struct exec_domain;
#include <asm/processor.h>
#include <asm/ftrace.h>
#include <asm/atomic.h>

struct thread_info {
struct task_struct *task; /* main task structure */
Expand All @@ -45,6 +46,11 @@ struct thread_info {
int curr_ret_stack;
/* Stack of return addresses for return function tracing */
struct ftrace_ret_stack ret_stack[FTRACE_RET_STACK_SIZE];
/*
* Number of functions that haven't been traced
* because of depth overrun.
*/
atomic_t trace_overrun;
#endif
};

Expand All @@ -61,6 +67,7 @@ struct thread_info {
.fn = do_no_restart_syscall, \
}, \
.curr_ret_stack = -1,\
.trace_overrun = ATOMIC_INIT(0) \
}
#else
#define INIT_THREAD_INFO(tsk) \
Expand Down
10 changes: 7 additions & 3 deletions trunk/arch/x86/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,10 @@ static int push_return_trace(unsigned long ret, unsigned long long time,
struct thread_info *ti = current_thread_info();

/* The return trace stack is full */
if (ti->curr_ret_stack == FTRACE_RET_STACK_SIZE - 1)
if (ti->curr_ret_stack == FTRACE_RET_STACK_SIZE - 1) {
atomic_inc(&ti->trace_overrun);
return -EBUSY;
}

index = ++ti->curr_ret_stack;
barrier();
Expand All @@ -367,7 +369,7 @@ static int push_return_trace(unsigned long ret, unsigned long long time,

/* Retrieve a function return address to the trace stack on thread info.*/
static void pop_return_trace(unsigned long *ret, unsigned long long *time,
unsigned long *func)
unsigned long *func, unsigned long *overrun)
{
int index;

Expand All @@ -376,6 +378,7 @@ static void pop_return_trace(unsigned long *ret, unsigned long long *time,
*ret = ti->ret_stack[index].ret;
*func = ti->ret_stack[index].func;
*time = ti->ret_stack[index].calltime;
*overrun = atomic_read(&ti->trace_overrun);
ti->curr_ret_stack--;
}

Expand All @@ -386,7 +389,8 @@ static void pop_return_trace(unsigned long *ret, unsigned long long *time,
unsigned long ftrace_return_to_handler(void)
{
struct ftrace_retfunc trace;
pop_return_trace(&trace.ret, &trace.calltime, &trace.func);
pop_return_trace(&trace.ret, &trace.calltime, &trace.func,
&trace.overrun);
trace.rettime = cpu_clock(raw_smp_processor_id());
ftrace_function_return(&trace);

Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ struct ftrace_retfunc {
unsigned long func; /* Current function */
unsigned long long calltime;
unsigned long long rettime;
/* Number of functions that overran the depth limit for current task */
unsigned long overrun;
};

#ifdef CONFIG_FUNCTION_RET_TRACER
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,7 @@ static inline void setup_thread_stack(struct task_struct *p, struct task_struct
* used.
*/
task_thread_info(p)->curr_ret_stack = -1;
atomic_set(&task_thread_info(p)->trace_overrun, 0);
#endif
}

Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,7 @@ static void __trace_function_return(struct trace_array *tr,
entry->parent_ip = trace->ret;
entry->rettime = trace->rettime;
entry->calltime = trace->calltime;
entry->overrun = trace->overrun;
ring_buffer_unlock_commit(global_trace.buffer, event, irq_flags);
}
#endif
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct ftrace_ret_entry {
unsigned long parent_ip;
unsigned long long calltime;
unsigned long long rettime;
unsigned long overrun;
};
extern struct tracer boot_tracer;

Expand Down
38 changes: 32 additions & 6 deletions trunk/kernel/trace/trace_functions_return.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@
#include "trace.h"


#define TRACE_RETURN_PRINT_OVERRUN 0x1
static struct tracer_opt trace_opts[] = {
/* Display overruns or not */
{ TRACER_OPT(overrun, TRACE_RETURN_PRINT_OVERRUN) },
{ } /* Empty entry */
};

static struct tracer_flags tracer_flags = {
.val = 0, /* Don't display overruns by default */
.opts = trace_opts
};


static int return_trace_init(struct trace_array *tr)
{
int cpu;
Expand Down Expand Up @@ -42,26 +55,39 @@ print_return_function(struct trace_iterator *iter)
ret = trace_seq_printf(s, "%pF -> ", (void *)field->parent_ip);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

ret = seq_print_ip_sym(s, field->ip,
trace_flags & TRACE_ITER_SYM_MASK);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
ret = trace_seq_printf(s, " (%llu ns)\n",

ret = trace_seq_printf(s, " (%llu ns)",
field->rettime - field->calltime);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
else
return TRACE_TYPE_HANDLED;

if (tracer_flags.val & TRACE_RETURN_PRINT_OVERRUN) {
ret = trace_seq_printf(s, " (Overruns: %lu)",
field->overrun);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
}

ret = trace_seq_printf(s, "\n");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;

return TRACE_TYPE_HANDLED;
}
return TRACE_TYPE_UNHANDLED;
}

static struct tracer return_trace __read_mostly =
{
static struct tracer return_trace __read_mostly = {
.name = "return",
.init = return_trace_init,
.reset = return_trace_reset,
.print_line = print_return_function
.print_line = print_return_function,
.flags = &tracer_flags,
};

static __init int init_return_trace(void)
Expand Down

0 comments on commit 0e8ecc4

Please sign in to comment.