Messages in this thread Patch in this message | | | Date | Wed, 17 Mar 2021 18:36:36 +0000 | From | Catalin Marinas <> | Subject | Re: [PATCH 2/2] arm64: stacktrace: Add skip when task == current |
| |
On Wed, Mar 17, 2021 at 02:20:50PM +0000, Chen Jun wrote: > On ARM64, cat /sys/kernel/debug/page_owner, all pages return the same > stack: > stack_trace_save+0x4c/0x78 > register_early_stack+0x34/0x70 > init_page_owner+0x34/0x230 > page_ext_init+0x1bc/0x1dc > > The reason is that: > check_recursive_alloc always return 1 because that > entries[0] is always equal to ip (__set_page_owner+0x3c/0x60). > > The root cause is that: > commit 5fc57df2f6fd ("arm64: stacktrace: Convert to ARCH_STACKWALK") > make the save_trace save 2 more entries. > > Add skip in arch_stack_walk when task == current. > > Fixes: 5fc57df2f6fd ("arm64: stacktrace: Convert to ARCH_STACKWALK") > Signed-off-by: Chen Jun <chenjun102@huawei.com> > --- > arch/arm64/kernel/stacktrace.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c > index ad20981..c26b0ac 100644 > --- a/arch/arm64/kernel/stacktrace.c > +++ b/arch/arm64/kernel/stacktrace.c > @@ -201,11 +201,12 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, > > if (regs) > start_backtrace(&frame, regs->regs[29], regs->pc); > - else if (task == current) > + else if (task == current) { > + ((struct stacktrace_cookie *)cookie)->skip += 2; > start_backtrace(&frame, > (unsigned long)__builtin_frame_address(0), > (unsigned long)arch_stack_walk); > - else > + } else > start_backtrace(&frame, thread_saved_fp(task), > thread_saved_pc(task));
I don't like abusing the cookie here. It's void * as it's meant to be an opaque type. I'd rather skip the first two frames in walk_stackframe() instead before invoking fn().
Prior to the conversion to ARCH_STACKWALK, we were indeed skipping two more entries in __save_stack_trace() if tsk == current. Something like below, completely untested:
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index ad20981dfda4..2a9f759aa41a 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -115,10 +115,15 @@ NOKPROBE_SYMBOL(unwind_frame); void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame, bool (*fn)(void *, unsigned long), void *data) { + /* for the current task, we don't want this function nor its caller */ + int skip = tsk == current ? 2 : 0; + while (1) { int ret; - if (!fn(data, frame->pc)) + if (skip) + skip--; + else if (!fn(data, frame->pc)) break; ret = unwind_frame(tsk, frame); if (ret < 0)
-- Catalin
| |