Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce28d64f authored by Prakash Gupta's avatar Prakash Gupta
Browse files

arm64: stacktrace: avoid listing stacktrace functions in stacktrace

The stacktraces always begin as follows:

 [<c00117b4>] save_stack_trace_tsk+0x0/0x98
 [<c0011870>] save_stack_trace+0x24/0x28
 ...

This is because the stack trace code includes the stack frames for itself.
This is incorrect behaviour, and also leads to "skip" doing the wrong
thing (which is the number of stack frames to avoid recording.)

Perversely, it does the right thing when passed a non-current thread.  Fix
this by ensuring that we have a known constant number of frames above the
main stack trace function, and always skip these.

This was fixed for arch arm by commit 3683f44c ("ARM: stacktrace:
avoid listing stacktrace functions in stacktrace")

Change-Id: I1a65ee011f022227204b406bb0288828a7beb0b8
Link: http://lkml.kernel.org/r/1504078343-28754-1-git-send-email-guptap@codeaurora.org


Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
Git-commit: 457b9ab50babff7100fe7902d195069561bc1db7
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git


[guptap@codeaurora.org: resolve trivial merge conflicts]
Signed-off-by: default avatarPrakash Gupta <guptap@codeaurora.org>
parent e08dfa6b
Loading
Loading
Loading
Loading
+13 −5
Original line number Original line Diff line number Diff line
@@ -176,7 +176,8 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
		trace->entries[trace->nr_entries++] = ULONG_MAX;
		trace->entries[trace->nr_entries++] = ULONG_MAX;
}
}


void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
static noinline void __save_stack_trace(struct task_struct *tsk,
	struct stack_trace *trace, unsigned int nosched)
{
{
	struct stack_trace_data data;
	struct stack_trace_data data;
	struct stackframe frame;
	struct stackframe frame;
@@ -186,17 +187,18 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)


	data.trace = trace;
	data.trace = trace;
	data.skip = trace->skip;
	data.skip = trace->skip;
	data.no_sched_functions = nosched;


	if (tsk != current) {
	if (tsk != current) {
		data.no_sched_functions = 1;
		frame.fp = thread_saved_fp(tsk);
		frame.fp = thread_saved_fp(tsk);
		frame.sp = thread_saved_sp(tsk);
		frame.sp = thread_saved_sp(tsk);
		frame.pc = thread_saved_pc(tsk);
		frame.pc = thread_saved_pc(tsk);
	} else {
	} else {
		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.fp = (unsigned long)__builtin_frame_address(0);
		frame.sp = current_stack_pointer;
		frame.sp = current_stack_pointer;
		frame.pc = (unsigned long)save_stack_trace_tsk;
		frame.pc = (unsigned long)__save_stack_trace;
	}
	}
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	frame.graph = tsk->curr_ret_stack;
	frame.graph = tsk->curr_ret_stack;
@@ -210,9 +212,15 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
}
}
EXPORT_SYMBOL(save_stack_trace_tsk);
EXPORT_SYMBOL(save_stack_trace_tsk);


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)
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);
EXPORT_SYMBOL_GPL(save_stack_trace);
#endif
#endif