Commit 77072f09 authored by Vlastimil Babka's avatar Vlastimil Babka Committed by Ingo Molnar

x86/stacktrace: Avoid recording save_stack_trace() wrappers

The save_stack_trace() and save_stack_trace_tsk() wrappers of
__save_stack_trace() add themselves to the call stack, and thus appear in the
recorded stacktraces. This is redundant and wasteful when we have limited space
to record the useful part of the backtrace with e.g. page_owner functionality.

Fix this by making sure __save_stack_trace() is noinline (which matches the
current gcc decision) and bumping the skip in the wrappers
(save_stack_trace_tsk() only when called for the current task). This is similar
to what was done for arm in 3683f44c ("ARM: stacktrace: avoid listing
stacktrace functions in stacktrace") and is pending for arm64.

Also make sure that __save_stack_trace_reliable() doesn't get this problem in
the future by marking it __always_inline (which matches current gcc decision),
per Josh Poimboeuf.
Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
Acked-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20170929092335.2744-1-vbabka@suse.czSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 770b782f
...@@ -30,7 +30,7 @@ static int save_stack_address(struct stack_trace *trace, unsigned long addr, ...@@ -30,7 +30,7 @@ static int save_stack_address(struct stack_trace *trace, unsigned long addr,
return 0; return 0;
} }
static void __save_stack_trace(struct stack_trace *trace, static void noinline __save_stack_trace(struct stack_trace *trace,
struct task_struct *task, struct pt_regs *regs, struct task_struct *task, struct pt_regs *regs,
bool nosched) bool nosched)
{ {
...@@ -56,6 +56,7 @@ static void __save_stack_trace(struct stack_trace *trace, ...@@ -56,6 +56,7 @@ static void __save_stack_trace(struct stack_trace *trace,
*/ */
void save_stack_trace(struct stack_trace *trace) void save_stack_trace(struct stack_trace *trace)
{ {
trace->skip++;
__save_stack_trace(trace, current, NULL, false); __save_stack_trace(trace, current, NULL, false);
} }
EXPORT_SYMBOL_GPL(save_stack_trace); EXPORT_SYMBOL_GPL(save_stack_trace);
...@@ -70,6 +71,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) ...@@ -70,6 +71,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
if (!try_get_task_stack(tsk)) if (!try_get_task_stack(tsk))
return; return;
if (tsk == current)
trace->skip++;
__save_stack_trace(trace, tsk, NULL, true); __save_stack_trace(trace, tsk, NULL, true);
put_task_stack(tsk); put_task_stack(tsk);
...@@ -88,7 +91,8 @@ EXPORT_SYMBOL_GPL(save_stack_trace_tsk); ...@@ -88,7 +91,8 @@ EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
} \ } \
}) })
static int __save_stack_trace_reliable(struct stack_trace *trace, static int __always_inline
__save_stack_trace_reliable(struct stack_trace *trace,
struct task_struct *task) struct task_struct *task)
{ {
struct unwind_state state; struct unwind_state state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment