|
@@ -83,13 +83,16 @@ static int save_trace(struct stackframe *frame, void *d)
|
|
|
return trace->nr_entries >= trace->max_entries;
|
|
|
}
|
|
|
|
|
|
-void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|
|
+/* This must be noinline to so that our skip calculation works correctly */
|
|
|
+static noinline void __save_stack_trace(struct task_struct *tsk,
|
|
|
+ struct stack_trace *trace, unsigned int nosched)
|
|
|
{
|
|
|
struct stack_trace_data data;
|
|
|
struct stackframe frame;
|
|
|
|
|
|
data.trace = trace;
|
|
|
data.skip = trace->skip;
|
|
|
+ data.no_sched_functions = nosched;
|
|
|
|
|
|
if (tsk != current) {
|
|
|
#ifdef CONFIG_SMP
|
|
@@ -102,7 +105,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|
|
trace->entries[trace->nr_entries++] = ULONG_MAX;
|
|
|
return;
|
|
|
#else
|
|
|
- data.no_sched_functions = 1;
|
|
|
frame.fp = thread_saved_fp(tsk);
|
|
|
frame.sp = thread_saved_sp(tsk);
|
|
|
frame.lr = 0; /* recovered from the stack */
|
|
@@ -111,11 +113,12 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|
|
} else {
|
|
|
register unsigned long current_sp asm ("sp");
|
|
|
|
|
|
- data.no_sched_functions = 0;
|
|
|
+ /* We don't want this function nor the caller */
|
|
|
+ data.skip += 2;
|
|
|
frame.fp = (unsigned long)__builtin_frame_address(0);
|
|
|
frame.sp = current_sp;
|
|
|
frame.lr = (unsigned long)__builtin_return_address(0);
|
|
|
- frame.pc = (unsigned long)save_stack_trace_tsk;
|
|
|
+ frame.pc = (unsigned long)__save_stack_trace;
|
|
|
}
|
|
|
|
|
|
walk_stackframe(&frame, save_trace, &data);
|
|
@@ -123,9 +126,14 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|
|
trace->entries[trace->nr_entries++] = ULONG_MAX;
|
|
|
}
|
|
|
|
|
|
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|
|
+{
|
|
|
+ __save_stack_trace(tsk, trace, 1);
|
|
|
+}
|
|
|
+
|
|
|
void save_stack_trace(struct stack_trace *trace)
|
|
|
{
|
|
|
- save_stack_trace_tsk(current, trace);
|
|
|
+ __save_stack_trace(current, trace, 0);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(save_stack_trace);
|
|
|
#endif
|