diff mbox

arm64: ftrace: function_graph: dump real return addr in call trace

Message ID 1444911155-17480-1-git-send-email-huawei.libin@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Li Bin Oct. 15, 2015, 12:12 p.m. UTC
When using function graph tracer, the printed call trace will be as
following that has many ftrace_graph_caller (return_to_handler - 4),
which is been placed in the stack by ftrace_graph tracer to replace
the real return address.

    [  198.582568] Call trace:
    [  198.583313] [<ffffffc0002a1070>] next_tgid+0x30/0x100
    [  198.584359] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
    [  198.585503] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
    [  198.586574] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
    [  198.587660] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
    [  198.588896] Code: aa0003f5 2a0103f4 b4000102 91004043 (885f7c60)
    [  198.591092] ---[ end trace 6a346f8f20949ac8 ]---

This patch fix it, and dump the real return address in the call trace.

Signed-off-by: Li Bin <huawei.libin@huawei.com>
---
 arch/arm64/kernel/traps.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

Comments

Arnd Bergmann Oct. 15, 2015, 12:46 p.m. UTC | #1
On Thursday 15 October 2015 20:12:35 Li Bin wrote:
> 
> +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> +static void print_ftrace_graph_addr(unsigned long addr,
> +                                       struct task_struct *tsk,
> +                                       unsigned long sp, int *graph)
> +{
> +       unsigned long ret_addr;
> +       int index = tsk->curr_ret_stack;
> +
> +       if (addr != ((unsigned long)return_to_handler - 4))
> +               return;
> +
> +       if (!tsk->ret_stack || index < *graph)
> 

I think it would be nicer to remove the #ifdef and write this as

static void print_ftrace_graph_addr(unsigned long addr,
                                    struct task_struct *tsk,
                                    unsigned long sp, int *graph)
{
       unsigned long ret_addr;
       int index = tsk->curr_ret_stack;

       if (!IS_ENABLED(CONFIG_FUNCTION_GRAPH_TRACER))
		return;

       if (addr != ((unsigned long)return_to_handler - 4))
               return;
Will Deacon Oct. 15, 2015, 12:51 p.m. UTC | #2
On Thu, Oct 15, 2015 at 02:46:16PM +0200, Arnd Bergmann wrote:
> On Thursday 15 October 2015 20:12:35 Li Bin wrote:
> > 
> > +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> > +static void print_ftrace_graph_addr(unsigned long addr,
> > +                                       struct task_struct *tsk,
> > +                                       unsigned long sp, int *graph)
> > +{
> > +       unsigned long ret_addr;
> > +       int index = tsk->curr_ret_stack;
> > +
> > +       if (addr != ((unsigned long)return_to_handler - 4))
> > +               return;
> > +
> > +       if (!tsk->ret_stack || index < *graph)
> > 
> 
> I think it would be nicer to remove the #ifdef and write this as
> 
> static void print_ftrace_graph_addr(unsigned long addr,
>                                     struct task_struct *tsk,
>                                     unsigned long sp, int *graph)
> {
>        unsigned long ret_addr;
>        int index = tsk->curr_ret_stack;
> 
>        if (!IS_ENABLED(CONFIG_FUNCTION_GRAPH_TRACER))
> 		return;
> 
>        if (addr != ((unsigned long)return_to_handler - 4))
>                return;

Is this the same old problem caused by e306dfd06fcb ("ARM64: unwind: Fix
PC calculation")? I've said previously that I'm happy to revert that if
we're the only architecture with this behaviour, but Akashi resisted
because there are other issues with ftrace that he was hoping to address
and they would resolve this too.

Will
Steven Rostedt Oct. 15, 2015, 2:18 p.m. UTC | #3
On Thu, 15 Oct 2015 13:51:33 +0100
Will Deacon <will.deacon@arm.com> wrote:

> Is this the same old problem caused by e306dfd06fcb ("ARM64: unwind: Fix
> PC calculation")? I've said previously that I'm happy to revert that if
> we're the only architecture with this behaviour, but Akashi resisted
> because there are other issues with ftrace that he was hoping to address
> and they would resolve this too.

Just a reference, but this patch is pretty much exactly what x86
currently has. I wonder if I should make that function generic for all
archs to use.

If you accept this patch, I can look at what archs do and pull out the
common code and place it into the core code and have the archs call
that instead.

-- Steve
Catalin Marinas Oct. 20, 2015, 3:32 p.m. UTC | #4
On Thu, Oct 15, 2015 at 10:18:12AM -0400, Steven Rostedt wrote:
> On Thu, 15 Oct 2015 13:51:33 +0100
> Will Deacon <will.deacon@arm.com> wrote:
> 
> > Is this the same old problem caused by e306dfd06fcb ("ARM64: unwind: Fix
> > PC calculation")? I've said previously that I'm happy to revert that if
> > we're the only architecture with this behaviour, but Akashi resisted
> > because there are other issues with ftrace that he was hoping to address
> > and they would resolve this too.
> 
> Just a reference, but this patch is pretty much exactly what x86
> currently has. I wonder if I should make that function generic for all
> archs to use.
> 
> If you accept this patch, I can look at what archs do and pull out the
> common code and place it into the core code and have the archs call
> that instead.

The difference I see from the sh and x86 version is that we have this -4
on arm64, introduced by e306dfd06fcb as Will mentioned above (it seemed
to have caused more problems that it solved). I think we should revert
that commit first just to be in line with other architectures and then
apply additional fixes as needed.

Question for Li Bin: is your patch still needed if we revert commit
e306dfd06fcb?

Thanks.
Li Bin Oct. 22, 2015, 12:55 a.m. UTC | #5
? 2015/10/20 23:32, Catalin Marinas ??:
> On Thu, Oct 15, 2015 at 10:18:12AM -0400, Steven Rostedt wrote:
>> On Thu, 15 Oct 2015 13:51:33 +0100
>> Will Deacon <will.deacon@arm.com> wrote:
>>
>>> Is this the same old problem caused by e306dfd06fcb ("ARM64: unwind: Fix
>>> PC calculation")? I've said previously that I'm happy to revert that if
>>> we're the only architecture with this behaviour, but Akashi resisted
>>> because there are other issues with ftrace that he was hoping to address
>>> and they would resolve this too.
>>
>> Just a reference, but this patch is pretty much exactly what x86
>> currently has. I wonder if I should make that function generic for all
>> archs to use.
>>
>> If you accept this patch, I can look at what archs do and pull out the
>> common code and place it into the core code and have the archs call
>> that instead.
>
> The difference I see from the sh and x86 version is that we have this -4
> on arm64, introduced by e306dfd06fcb as Will mentioned above (it seemed
> to have caused more problems that it solved). I think we should revert
> that commit first just to be in line with other architectures and then
> apply additional fixes as needed.
>
> Question for Li Bin: is your patch still needed if we revert commit
> e306dfd06fcb?
>

It still be needed, but it can be implemented in generic for all archs
as Steve suggested.

Thanks,
Li Bin

> Thanks.
>
Steven Rostedt Oct. 22, 2015, 1:13 a.m. UTC | #6
On Thu, 22 Oct 2015 08:55:43 +0800
libin <huawei.libin@huawei.com> wrote:


> It still be needed, but it can be implemented in generic for all archs
> as Steve suggested.

I still recommend implementing it for arm64 as well, and then we can
look at what was done and how we can make it all generic.

-- Steve
Will Deacon Oct. 28, 2015, 3:21 p.m. UTC | #7
On Thu, Oct 22, 2015 at 08:55:43AM +0800, libin wrote:
> ? 2015/10/20 23:32, Catalin Marinas ??:
> >On Thu, Oct 15, 2015 at 10:18:12AM -0400, Steven Rostedt wrote:
> >>On Thu, 15 Oct 2015 13:51:33 +0100
> >>Will Deacon <will.deacon@arm.com> wrote:
> >>
> >>>Is this the same old problem caused by e306dfd06fcb ("ARM64: unwind: Fix
> >>>PC calculation")? I've said previously that I'm happy to revert that if
> >>>we're the only architecture with this behaviour, but Akashi resisted
> >>>because there are other issues with ftrace that he was hoping to address
> >>>and they would resolve this too.
> >>
> >>Just a reference, but this patch is pretty much exactly what x86
> >>currently has. I wonder if I should make that function generic for all
> >>archs to use.
> >>
> >>If you accept this patch, I can look at what archs do and pull out the
> >>common code and place it into the core code and have the archs call
> >>that instead.
> >
> >The difference I see from the sh and x86 version is that we have this -4
> >on arm64, introduced by e306dfd06fcb as Will mentioned above (it seemed
> >to have caused more problems that it solved). I think we should revert
> >that commit first just to be in line with other architectures and then
> >apply additional fixes as needed.
> >
> >Question for Li Bin: is your patch still needed if we revert commit
> >e306dfd06fcb?
> >
> 
> It still be needed, but it can be implemented in generic for all archs
> as Steve suggested.

Well, there's still an argument for reverting e306dfd06fcb because it
makes us behave differently to other architectures (in particular,
arch/arm).

Will
diff mbox

Patch

diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index f93aae5..4a4e679 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -143,9 +143,38 @@  static void dump_instr(const char *lvl, struct pt_regs *regs)
 	set_fs(fs);
 }
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static void print_ftrace_graph_addr(unsigned long addr,
+					struct task_struct *tsk,
+					unsigned long sp, int *graph)
+{
+	unsigned long ret_addr;
+	int index = tsk->curr_ret_stack;
+
+	if (addr != ((unsigned long)return_to_handler - 4))
+		return;
+
+	if (!tsk->ret_stack || index < *graph)
+		return;
+
+	index -= *graph;
+	ret_addr = tsk->ret_stack[index].ret;
+
+	dump_backtrace_entry(ret_addr - 4, sp);
+
+	(*graph)++;
+}
+#else
+static inline void print_ftrace_graph_addr(unsigned long addr,
+					struct task_struct *tsk,
+					unsigned long sp, int *graph)
+{}
+#endif
+
 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 {
 	struct stackframe frame;
+	int graph = 0;
 
 	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
 
@@ -177,7 +206,9 @@  static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 		ret = unwind_frame(&frame);
 		if (ret < 0)
 			break;
+
 		dump_backtrace_entry(where, frame.sp);
+		print_ftrace_graph_addr(where, tsk, frame.sp, &graph);
 	}
 }