aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/stacktrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/stacktrace.c')
-rw-r--r--arch/mips/kernel/stacktrace.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index 1ba775d24d38..506021f62549 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -12,14 +12,15 @@
12 * Save stack-backtrace addresses into a stack_trace buffer: 12 * Save stack-backtrace addresses into a stack_trace buffer:
13 */ 13 */
14static void save_raw_context_stack(struct stack_trace *trace, 14static void save_raw_context_stack(struct stack_trace *trace,
15 unsigned long reg29) 15 unsigned long reg29, int savesched)
16{ 16{
17 unsigned long *sp = (unsigned long *)reg29; 17 unsigned long *sp = (unsigned long *)reg29;
18 unsigned long addr; 18 unsigned long addr;
19 19
20 while (!kstack_end(sp)) { 20 while (!kstack_end(sp)) {
21 addr = *sp++; 21 addr = *sp++;
22 if (__kernel_text_address(addr)) { 22 if (__kernel_text_address(addr) &&
23 (savesched || !in_sched_functions(addr))) {
23 if (trace->skip > 0) 24 if (trace->skip > 0)
24 trace->skip--; 25 trace->skip--;
25 else 26 else
@@ -31,7 +32,7 @@ static void save_raw_context_stack(struct stack_trace *trace,
31} 32}
32 33
33static void save_context_stack(struct stack_trace *trace, 34static void save_context_stack(struct stack_trace *trace,
34 struct task_struct *tsk, struct pt_regs *regs) 35 struct task_struct *tsk, struct pt_regs *regs, int savesched)
35{ 36{
36 unsigned long sp = regs->regs[29]; 37 unsigned long sp = regs->regs[29];
37#ifdef CONFIG_KALLSYMS 38#ifdef CONFIG_KALLSYMS
@@ -43,20 +44,22 @@ static void save_context_stack(struct stack_trace *trace,
43 (unsigned long)task_stack_page(tsk); 44 (unsigned long)task_stack_page(tsk);
44 if (stack_page && sp >= stack_page && 45 if (stack_page && sp >= stack_page &&
45 sp <= stack_page + THREAD_SIZE - 32) 46 sp <= stack_page + THREAD_SIZE - 32)
46 save_raw_context_stack(trace, sp); 47 save_raw_context_stack(trace, sp, savesched);
47 return; 48 return;
48 } 49 }
49 do { 50 do {
50 if (trace->skip > 0) 51 if (savesched || !in_sched_functions(pc)) {
51 trace->skip--; 52 if (trace->skip > 0)
52 else 53 trace->skip--;
53 trace->entries[trace->nr_entries++] = pc; 54 else
54 if (trace->nr_entries >= trace->max_entries) 55 trace->entries[trace->nr_entries++] = pc;
55 break; 56 if (trace->nr_entries >= trace->max_entries)
57 break;
58 }
56 pc = unwind_stack(tsk, &sp, pc, &ra); 59 pc = unwind_stack(tsk, &sp, pc, &ra);
57 } while (pc); 60 } while (pc);
58#else 61#else
59 save_raw_context_stack(trace, sp); 62 save_raw_context_stack(trace, sp, savesched);
60#endif 63#endif
61} 64}
62 65
@@ -82,6 +85,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
82 regs->cp0_epc = tsk->thread.reg31; 85 regs->cp0_epc = tsk->thread.reg31;
83 } else 86 } else
84 prepare_frametrace(regs); 87 prepare_frametrace(regs);
85 save_context_stack(trace, tsk, regs); 88 save_context_stack(trace, tsk, regs, tsk == current);
86} 89}
87EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 90EXPORT_SYMBOL_GPL(save_stack_trace_tsk);