diff options
| author | 2008-07-18 22:50:34 +0200 | |
|---|---|---|
| committer | 2008-07-18 22:50:34 +0200 | |
| commit | a208f37a465e222218974ab20a31b42b7b4893b2 (patch) | |
| tree | 77c6acdd4be32024330a14f2618b814126ce7a20 /arch/powerpc/kernel/stacktrace.c | |
| parent | x86: apic_ops for lguest (diff) | |
| parent | Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2 (diff) | |
| download | wireguard-linux-a208f37a465e222218974ab20a31b42b7b4893b2.tar.xz wireguard-linux-a208f37a465e222218974ab20a31b42b7b4893b2.zip | |
Merge branch 'linus' into x86/x2apic
Diffstat (limited to 'arch/powerpc/kernel/stacktrace.c')
| -rw-r--r-- | arch/powerpc/kernel/stacktrace.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index 962944038430..071bee3ec749 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -10,33 +10,35 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/module.h> #include <linux/sched.h> #include <linux/stacktrace.h> +#include <linux/module.h> #include <asm/ptrace.h> +#include <asm/processor.h> /* * Save stack-backtrace addresses into a stack_trace buffer. */ -void save_stack_trace(struct stack_trace *trace) +static void save_context_stack(struct stack_trace *trace, unsigned long sp, + struct task_struct *tsk, int savesched) { - unsigned long sp; - - asm("mr %0,1" : "=r" (sp)); - for (;;) { unsigned long *stack = (unsigned long *) sp; unsigned long newsp, ip; - if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) + if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD)) return; newsp = stack[0]; ip = stack[STACK_FRAME_LR_SAVE]; - if (!trace->skip) - trace->entries[trace->nr_entries++] = ip; - else - trace->skip--; + if (savesched || !in_sched_functions(ip)) { + if (!trace->skip) + trace->entries[trace->nr_entries++] = ip; + else + trace->skip--; + } if (trace->nr_entries >= trace->max_entries) return; @@ -44,3 +46,19 @@ void save_stack_trace(struct stack_trace *trace) sp = newsp; } } + +void save_stack_trace(struct stack_trace *trace) +{ + unsigned long sp; + + asm("mr %0,1" : "=r" (sp)); + + save_context_stack(trace, sp, current, 1); +} +EXPORT_SYMBOL_GPL(save_stack_trace); + +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + save_context_stack(trace, tsk->thread.regs->gpr[1], tsk, 0); +} +EXPORT_SYMBOL_GPL(save_stack_trace_tsk); |
