Skip to content

Commit

Permalink
[ARM] latencytop support
Browse files Browse the repository at this point in the history
Available for !SMP only at the moment.

From Russell:

|Basically, if a thread is running on a CPU, thread_saved_fp() is invalid.
|So, the question is: what guarantees do we have here that 'tsk' is not
|running on another CPU?

Signed-off-by: Nicolas Pitre <nico@marvell.com>
Tested-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
  • Loading branch information
Nicolas Pitre authored and Lennert Buytenhek committed Jun 22, 2008
1 parent b0bfcce commit f76e915
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
5 changes: 5 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ config STACKTRACE_SUPPORT
bool
default y

config HAVE_LATENCYTOP_SUPPORT
bool
depends on !SMP
default y

config LOCKDEP_SUPPORT
bool
default y
Expand Down
34 changes: 30 additions & 4 deletions arch/arm/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,60 @@ EXPORT_SYMBOL(walk_stackframe);
#ifdef CONFIG_STACKTRACE
struct stack_trace_data {
struct stack_trace *trace;
unsigned int no_sched_functions;
unsigned int skip;
};

static int save_trace(struct stackframe *frame, void *d)
{
struct stack_trace_data *data = d;
struct stack_trace *trace = data->trace;
unsigned long addr = frame->lr;

if (data->no_sched_functions && in_sched_functions(addr))
return 0;
if (data->skip) {
data->skip--;
return 0;
}

trace->entries[trace->nr_entries++] = frame->lr;
trace->entries[trace->nr_entries++] = addr;

return trace->nr_entries >= trace->max_entries;
}

void save_stack_trace(struct stack_trace *trace)
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
struct stack_trace_data data;
unsigned long fp, base;

data.trace = trace;
data.skip = trace->skip;
base = (unsigned long)task_stack_page(current);
asm("mov %0, fp" : "=r" (fp));
base = (unsigned long)task_stack_page(tsk);

if (tsk != current) {
#ifdef CONFIG_SMP
/*
* What guarantees do we have here that 'tsk'
* is not running on another CPU?
*/
BUG();
#else
data.no_sched_functions = 1;
fp = thread_saved_fp(tsk);
#endif
} else {
data.no_sched_functions = 0;
asm("mov %0, fp" : "=r" (fp));
}

walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}

void save_stack_trace(struct stack_trace *trace)
{
save_stack_trace_tsk(current, trace);
}
#endif

0 comments on commit f76e915

Please sign in to comment.