diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 16:34:20 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 16:34:20 -0400 |
| commit | 711f77f53c5ff6aa61dbe8e5f518e50d6306e89d (patch) | |
| tree | 93bc99051b26586916a628b1a276543085f80ff2 /arch/sparc/kernel/stacktrace.c | |
| parent | 024a6b95181f2df6090975c8a293499d24bf8b28 (diff) | |
| parent | 273fca0ecad9305247043815e185d1bfd04047d4 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
sparc: Define ARCH_SLAB_MINALIGN
drivers/sbus/char/flash.c: flash_read should update ppos instead of file->f_pos
sparc64: Fix stack dumping and tracing when function graph is enabled.
sparc64: Show stack backtrace from show_regs() just like other platforms.
Diffstat (limited to 'arch/sparc/kernel/stacktrace.c')
| -rw-r--r-- | arch/sparc/kernel/stacktrace.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c index acb12f673757..3e0815349630 100644 --- a/arch/sparc/kernel/stacktrace.c +++ b/arch/sparc/kernel/stacktrace.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include <linux/sched.h> | 1 | #include <linux/sched.h> |
| 2 | #include <linux/stacktrace.h> | 2 | #include <linux/stacktrace.h> |
| 3 | #include <linux/thread_info.h> | 3 | #include <linux/thread_info.h> |
| 4 | #include <linux/ftrace.h> | ||
| 4 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| 5 | #include <asm/ptrace.h> | 6 | #include <asm/ptrace.h> |
| 6 | #include <asm/stacktrace.h> | 7 | #include <asm/stacktrace.h> |
| @@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp, | |||
| 12 | bool skip_sched) | 13 | bool skip_sched) |
| 13 | { | 14 | { |
| 14 | unsigned long ksp, fp; | 15 | unsigned long ksp, fp; |
| 16 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 17 | struct task_struct *t; | ||
| 18 | int graph = 0; | ||
| 19 | #endif | ||
| 15 | 20 | ||
| 16 | if (tp == current_thread_info()) { | 21 | if (tp == current_thread_info()) { |
| 17 | stack_trace_flush(); | 22 | stack_trace_flush(); |
| @@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp, | |||
| 21 | } | 26 | } |
| 22 | 27 | ||
| 23 | fp = ksp + STACK_BIAS; | 28 | fp = ksp + STACK_BIAS; |
| 29 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 30 | t = tp->task; | ||
| 31 | #endif | ||
| 24 | do { | 32 | do { |
| 25 | struct sparc_stackf *sf; | 33 | struct sparc_stackf *sf; |
| 26 | struct pt_regs *regs; | 34 | struct pt_regs *regs; |
| @@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp, | |||
| 44 | 52 | ||
| 45 | if (trace->skip > 0) | 53 | if (trace->skip > 0) |
| 46 | trace->skip--; | 54 | trace->skip--; |
| 47 | else if (!skip_sched || !in_sched_functions(pc)) | 55 | else if (!skip_sched || !in_sched_functions(pc)) { |
| 48 | trace->entries[trace->nr_entries++] = pc; | 56 | trace->entries[trace->nr_entries++] = pc; |
| 57 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 58 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { | ||
| 59 | int index = t->curr_ret_stack; | ||
| 60 | if (t->ret_stack && index >= graph) { | ||
| 61 | pc = t->ret_stack[index - graph].ret; | ||
| 62 | if (trace->nr_entries < | ||
| 63 | trace->max_entries) | ||
| 64 | trace->entries[trace->nr_entries++] = pc; | ||
| 65 | graph++; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | #endif | ||
| 69 | } | ||
| 49 | } while (trace->nr_entries < trace->max_entries); | 70 | } while (trace->nr_entries < trace->max_entries); |
| 50 | } | 71 | } |
| 51 | 72 | ||
