[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <a6d623e36f8d08f9a17bd74d804d201177a23afd.1471607358.git.jpoimboe@redhat.com>
Date: Fri, 19 Aug 2016 06:53:00 -0500
From: Josh Poimboeuf <jpoimboe@...hat.com>
To: Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...nel.org>,
"H . Peter Anvin" <hpa@...or.com>
Cc: x86@...nel.org, linux-kernel@...r.kernel.org,
Andy Lutomirski <luto@...capital.net>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Steven Rostedt <rostedt@...dmis.org>,
Brian Gerst <brgerst@...il.com>,
Kees Cook <keescook@...omium.org>,
Peter Zijlstra <peterz@...radead.org>,
Frederic Weisbecker <fweisbec@...il.com>,
Byungchul Park <byungchul.park@....com>,
Nilay Vaish <nilayvaish@...il.com>
Subject: [PATCH 6/8] ftrace/x86: implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
Use the more reliable version of ftrace_graph_ret_addr() so we no longer
have to worry about the unwinder getting out of sync with the function
graph ret_stack index, which can happen if the unwinder skips any frames
before calling ftrace_graph_ret_addr().
This fixes this issue (and several others like it):
$ cat /proc/self/stack
[<ffffffff810489a2>] save_stack_trace_tsk+0x22/0x40
[<ffffffff81311a89>] proc_pid_stack+0xb9/0x110
[<ffffffff813127c4>] proc_single_show+0x54/0x80
[<ffffffff812be088>] seq_read+0x108/0x3e0
[<ffffffff812923d7>] __vfs_read+0x37/0x140
[<ffffffff812929d9>] vfs_read+0x99/0x140
[<ffffffff81293f28>] SyS_read+0x58/0xc0
[<ffffffff818af97c>] entry_SYSCALL_64_fastpath+0x1f/0xbd
[<ffffffffffffffff>] 0xffffffffffffffff
$ echo function_graph > /sys/kernel/debug/tracing/current_tracer
$ cat /proc/self/stack
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff810394cc>] print_context_stack+0xfc/0x100
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff8103891b>] dump_trace+0x12b/0x350
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff810489a2>] save_stack_trace_tsk+0x22/0x40
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff81311a89>] proc_pid_stack+0xb9/0x110
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff813127c4>] proc_single_show+0x54/0x80
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff812be088>] seq_read+0x108/0x3e0
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff812923d7>] __vfs_read+0x37/0x140
[<ffffffff818b2428>] return_to_handler+0x0/0x27
[<ffffffff812929d9>] vfs_read+0x99/0x140
[<ffffffffffffffff>] 0xffffffffffffffff
Enabling function graph tracing causes the stack trace to change in two
ways:
First, the real call addresses are confusingly interspersed with
'return_to_handler' addresses. This issue will be fixed by the next
patch.
Second, the stack trace is offset by two frames, because the unwinder
skipped the first two frames and got out of sync with the ret_stack
index. This patch fixes this issue.
Signed-off-by: Josh Poimboeuf <jpoimboe@...hat.com>
---
arch/x86/include/asm/ftrace.h | 2 ++
arch/x86/kernel/ftrace.c | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index 37f67cb..eccd0ac 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -14,6 +14,8 @@
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
+#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
+
#ifndef __ASSEMBLY__
extern void mcount(void);
extern atomic_t modifying_ftrace_code;
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index ae3b1fb..8639bb2 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -1029,7 +1029,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
}
if (ftrace_push_return_trace(old, self_addr, &trace.depth,
- frame_pointer, NULL) == -EBUSY) {
+ frame_pointer, parent) == -EBUSY) {
*parent = old;
return;
}
--
2.7.4
Powered by blists - more mailing lists