mbox series

[-next,0/7] riscv: Improvments for stacktrace

Message ID 20220920151202.180057-1-chenzhongjin@huawei.com (mailing list archive)
Headers show
Series riscv: Improvments for stacktrace | expand

Message

Chen Zhongjin Sept. 20, 2022, 3:11 p.m. UTC
Currently, the stacktrace with FRAME_POINTER on riscv has some problem:

1. stacktrace will stop at irq so it can't get the stack frames before
irq entry.
2. stacktrace can't unwind all the real stack frames when there is
k{ret}probes or ftrace.

These are mainly becase when there is a pt_regs on stack, we can't unwind
the stack frame as normal function.

Some architectures (e.g. arm64) create a extra stackframe inside pt_regs.
However this doesn't work for riscv because the ra is not ensured to be
pushed to stack. As explained in:
commit f766f77a74f5("riscv/stacktrace: Fix stack output without ra on the stack top")

So, I choosed the method of x86 that, if there is a pt_regs on stack,
we encoded the frame pointer and save it. When unwinding stack frame,
we can get pt_regs and registers required for unwinding stacks.

In addition, the patch set contains some refactoring of stacktrace.c to
keep the stacktrace code on riscv consistent with other architectures.

Chen Zhongjin (7):
  riscv: stacktrace: Replace walk_stackframe with arch_stack_walk
  riscv: stacktrace: Introduce unwind functions
  riscv: stacktrace: Save pt_regs in encoded fp on irq entry
  riscv: syscall: Don't clobber s0 when syscall
  riscv: stacktrace: Implement stacktrace for irq
  riscv: stacktrace: Fix unwinding on ftrace_regs_call
  riscv: stacktrace: Fix unwinding on __kretporbe_trampoline

 arch/riscv/include/asm/frame.h                |  45 +++++
 arch/riscv/include/asm/stacktrace.h           |  13 +-
 arch/riscv/kernel/entry.S                     |  23 +--
 arch/riscv/kernel/mcount-dyn.S                |   8 +
 arch/riscv/kernel/perf_callchain.c            |   2 +-
 arch/riscv/kernel/probes/kprobes_trampoline.S |   8 +
 arch/riscv/kernel/stacktrace.c                | 155 ++++++++++++------
 7 files changed, 195 insertions(+), 59 deletions(-)
 create mode 100644 arch/riscv/include/asm/frame.h

Comments

Guo Ren Sept. 21, 2022, 2:30 a.m. UTC | #1
Some modifications are related to the patch series [1] [2], please take a look.

[1] https://lore.kernel.org/linux-riscv/20220918155246.1203293-1-guoren@kernel.org/
[2] https://lore.kernel.org/linux-riscv/20220916103817.9490-1-guoren@kernel.org/

On Tue, Sep 20, 2022 at 11:15 PM Chen Zhongjin <chenzhongjin@huawei.com> wrote:
>
> Currently, the stacktrace with FRAME_POINTER on riscv has some problem:
>
> 1. stacktrace will stop at irq so it can't get the stack frames before
> irq entry.
> 2. stacktrace can't unwind all the real stack frames when there is
> k{ret}probes or ftrace.
>
> These are mainly becase when there is a pt_regs on stack, we can't unwind
> the stack frame as normal function.
>
> Some architectures (e.g. arm64) create a extra stackframe inside pt_regs.
> However this doesn't work for riscv because the ra is not ensured to be
> pushed to stack. As explained in:
> commit f766f77a74f5("riscv/stacktrace: Fix stack output without ra on the stack top")
>
> So, I choosed the method of x86 that, if there is a pt_regs on stack,
> we encoded the frame pointer and save it. When unwinding stack frame,
> we can get pt_regs and registers required for unwinding stacks.
>
> In addition, the patch set contains some refactoring of stacktrace.c to
> keep the stacktrace code on riscv consistent with other architectures.
>
> Chen Zhongjin (7):
>   riscv: stacktrace: Replace walk_stackframe with arch_stack_walk
>   riscv: stacktrace: Introduce unwind functions
>   riscv: stacktrace: Save pt_regs in encoded fp on irq entry
>   riscv: syscall: Don't clobber s0 when syscall
>   riscv: stacktrace: Implement stacktrace for irq
>   riscv: stacktrace: Fix unwinding on ftrace_regs_call
>   riscv: stacktrace: Fix unwinding on __kretporbe_trampoline
>
>  arch/riscv/include/asm/frame.h                |  45 +++++
>  arch/riscv/include/asm/stacktrace.h           |  13 +-
>  arch/riscv/kernel/entry.S                     |  23 +--
>  arch/riscv/kernel/mcount-dyn.S                |   8 +
>  arch/riscv/kernel/perf_callchain.c            |   2 +-
>  arch/riscv/kernel/probes/kprobes_trampoline.S |   8 +
>  arch/riscv/kernel/stacktrace.c                | 155 ++++++++++++------
>  7 files changed, 195 insertions(+), 59 deletions(-)
>  create mode 100644 arch/riscv/include/asm/frame.h
>
> --
> 2.17.1
>


--
Best Regards
 Guo Ren
Chen Zhongjin Sept. 21, 2022, 12:33 p.m. UTC | #2
Hi,

On 2022/9/21 10:30, Guo Ren wrote:
> Some modifications are related to the patch series [1] [2], please take a look.
>
> [1] https://lore.kernel.org/linux-riscv/20220918155246.1203293-1-guoren@kernel.org/
> [2] https://lore.kernel.org/linux-riscv/20220916103817.9490-1-guoren@kernel.org/

I have tested my patch on your branches.

For the ftrace one it works properly and passed FTRACE_STARTUP_TEST.

For the entry one I proposed some advice in another reply, with that my 
patch also works well.


I'll post v2 patch which is totally dependent to yours. And after your 
patch applied, the stacktrace

may need to be updated again, for example, print the type of current 
unwinding stack.


Best,

Chen

> On Tue, Sep 20, 2022 at 11:15 PM Chen Zhongjin <chenzhongjin@huawei.com> wrote:
>> Currently, the stacktrace with FRAME_POINTER on riscv has some problem:
>>
>> 1. stacktrace will stop at irq so it can't get the stack frames before
>> irq entry.
>> 2. stacktrace can't unwind all the real stack frames when there is
>> k{ret}probes or ftrace.
>>
>> These are mainly becase when there is a pt_regs on stack, we can't unwind
>> the stack frame as normal function.
>>
>> Some architectures (e.g. arm64) create a extra stackframe inside pt_regs.
>> However this doesn't work for riscv because the ra is not ensured to be
>> pushed to stack. As explained in:
>> commit f766f77a74f5("riscv/stacktrace: Fix stack output without ra on the stack top")
>>
>> So, I choosed the method of x86 that, if there is a pt_regs on stack,
>> we encoded the frame pointer and save it. When unwinding stack frame,
>> we can get pt_regs and registers required for unwinding stacks.
>>
>> In addition, the patch set contains some refactoring of stacktrace.c to
>> keep the stacktrace code on riscv consistent with other architectures.
>>
>> Chen Zhongjin (7):
>>    riscv: stacktrace: Replace walk_stackframe with arch_stack_walk
>>    riscv: stacktrace: Introduce unwind functions
>>    riscv: stacktrace: Save pt_regs in encoded fp on irq entry
>>    riscv: syscall: Don't clobber s0 when syscall
>>    riscv: stacktrace: Implement stacktrace for irq
>>    riscv: stacktrace: Fix unwinding on ftrace_regs_call
>>    riscv: stacktrace: Fix unwinding on __kretporbe_trampoline
>>
>>   arch/riscv/include/asm/frame.h                |  45 +++++
>>   arch/riscv/include/asm/stacktrace.h           |  13 +-
>>   arch/riscv/kernel/entry.S                     |  23 +--
>>   arch/riscv/kernel/mcount-dyn.S                |   8 +
>>   arch/riscv/kernel/perf_callchain.c            |   2 +-
>>   arch/riscv/kernel/probes/kprobes_trampoline.S |   8 +
>>   arch/riscv/kernel/stacktrace.c                | 155 ++++++++++++------
>>   7 files changed, 195 insertions(+), 59 deletions(-)
>>   create mode 100644 arch/riscv/include/asm/frame.h
>>
>> --
>> 2.17.1
>>
>
> --
> Best Regards
>   Guo Ren