From: madvenka@linux.microsoft.com To: mark.rutland@arm.com, broonie@kernel.org, jpoimboe@redhat.com, ardb@kernel.org, nobuta.keiya@fujitsu.com, sjitindarsingh@gmail.com, catalin.marinas@arm.com, will@kernel.org, jmorris@namei.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [PATCH v10 07/11] arm64: Call stack_backtrace() only from within walk_stackframe() Date: Thu, 14 Oct 2021 21:58:43 -0500 [thread overview] Message-ID: <20211015025847.17694-8-madvenka@linux.microsoft.com> (raw) In-Reply-To: <20211015025847.17694-1-madvenka@linux.microsoft.com> From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com> Currently, arch_stack_walk() calls start_backtrace() and walk_stackframe() separately. There is no need to do that. Instead, call start_backtrace() from within walk_stackframe(). In other words, walk_stackframe() is the only unwind function a consumer needs to call. Currently, the only consumer is arch_stack_walk(). In the future, arch_stack_walk_reliable() will be another consumer. start_backtrace(), unwind_frame() and walk_stackframe() are only used within arm64/kernel/stacktrace.c. Make them static and remove them from arch/arm64/include/asm/stacktrace.h. Currently, there is a check for a NULL task in unwind_frame(). It is not needed since all current consumers pass a non-NULL task. Use struct stackframe only within the unwind functions. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> --- arch/arm64/include/asm/stacktrace.h | 6 ---- arch/arm64/kernel/stacktrace.c | 51 ++++++++++++++++------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 8aebc00c1718..c239f357d779 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -61,9 +61,6 @@ struct stackframe { #endif }; -extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame); -extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame, - bool (*fn)(void *, unsigned long), void *data); extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, const char *loglvl); @@ -148,7 +145,4 @@ static inline bool on_accessible_stack(const struct task_struct *tsk, return false; } -void start_backtrace(struct stackframe *frame, unsigned long fp, - unsigned long pc); - #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 776c4debb5a7..7d32cee9ef4b 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -33,8 +33,8 @@ */ -void start_backtrace(struct stackframe *frame, unsigned long fp, - unsigned long pc) +static void start_backtrace(struct stackframe *frame, unsigned long fp, + unsigned long pc) { frame->fp = fp; frame->pc = pc; @@ -63,14 +63,12 @@ void start_backtrace(struct stackframe *frame, unsigned long fp, * records (e.g. a cycle), determined based on the location and fp value of A * and the location (but not the fp value) of B. */ -int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) +static int notrace unwind_frame(struct task_struct *tsk, + struct stackframe *frame) { unsigned long fp = frame->fp; struct stack_info info; - if (!tsk) - tsk = current; - /* Final frame; nothing to unwind */ if (fp == (unsigned long)task_pt_regs(tsk)->stackframe) return -ENOENT; @@ -136,15 +134,21 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) } NOKPROBE_SYMBOL(unwind_frame); -void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame, - bool (*fn)(void *, unsigned long), void *data) +static void notrace walk_stackframe(struct task_struct *tsk, + unsigned long fp, unsigned long pc, + bool (*fn)(void *, unsigned long), + void *data) { + struct stackframe frame; + + start_backtrace(&frame, fp, pc); + while (1) { int ret; - if (!fn(data, frame->pc)) + if (!fn(data, frame.pc)) break; - ret = unwind_frame(tsk, frame); + ret = unwind_frame(tsk, &frame); if (ret < 0) break; } @@ -190,19 +194,22 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, struct task_struct *task, struct pt_regs *regs) { - struct stackframe frame; + unsigned long fp, pc; + + if (regs) { + fp = regs->regs[29]; + pc = regs->pc; + } else if (task == current) { + /* Skip arch_stack_walk() in the stack trace. */ + fp = (unsigned long)__builtin_frame_address(1); + pc = (unsigned long)__builtin_return_address(0); + } else { + /* Caller guarantees that the task is not running. */ + fp = thread_saved_fp(task); + pc = thread_saved_pc(task); + } + walk_stackframe(task, fp, pc, consume_entry, cookie); - if (regs) - start_backtrace(&frame, regs->regs[29], regs->pc); - else if (task == current) - start_backtrace(&frame, - (unsigned long)__builtin_frame_address(1), - (unsigned long)__builtin_return_address(0)); - else - start_backtrace(&frame, thread_saved_fp(task), - thread_saved_pc(task)); - - walk_stackframe(task, &frame, consume_entry, cookie); } #endif -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: madvenka@linux.microsoft.com To: mark.rutland@arm.com, broonie@kernel.org, jpoimboe@redhat.com, ardb@kernel.org, nobuta.keiya@fujitsu.com, sjitindarsingh@gmail.com, catalin.marinas@arm.com, will@kernel.org, jmorris@namei.org, linux-arm-kernel@lists.infradead.org, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com Subject: [PATCH v10 07/11] arm64: Call stack_backtrace() only from within walk_stackframe() Date: Thu, 14 Oct 2021 21:58:43 -0500 [thread overview] Message-ID: <20211015025847.17694-8-madvenka@linux.microsoft.com> (raw) In-Reply-To: <20211015025847.17694-1-madvenka@linux.microsoft.com> From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com> Currently, arch_stack_walk() calls start_backtrace() and walk_stackframe() separately. There is no need to do that. Instead, call start_backtrace() from within walk_stackframe(). In other words, walk_stackframe() is the only unwind function a consumer needs to call. Currently, the only consumer is arch_stack_walk(). In the future, arch_stack_walk_reliable() will be another consumer. start_backtrace(), unwind_frame() and walk_stackframe() are only used within arm64/kernel/stacktrace.c. Make them static and remove them from arch/arm64/include/asm/stacktrace.h. Currently, there is a check for a NULL task in unwind_frame(). It is not needed since all current consumers pass a non-NULL task. Use struct stackframe only within the unwind functions. Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com> --- arch/arm64/include/asm/stacktrace.h | 6 ---- arch/arm64/kernel/stacktrace.c | 51 ++++++++++++++++------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 8aebc00c1718..c239f357d779 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -61,9 +61,6 @@ struct stackframe { #endif }; -extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame); -extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame, - bool (*fn)(void *, unsigned long), void *data); extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, const char *loglvl); @@ -148,7 +145,4 @@ static inline bool on_accessible_stack(const struct task_struct *tsk, return false; } -void start_backtrace(struct stackframe *frame, unsigned long fp, - unsigned long pc); - #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 776c4debb5a7..7d32cee9ef4b 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -33,8 +33,8 @@ */ -void start_backtrace(struct stackframe *frame, unsigned long fp, - unsigned long pc) +static void start_backtrace(struct stackframe *frame, unsigned long fp, + unsigned long pc) { frame->fp = fp; frame->pc = pc; @@ -63,14 +63,12 @@ void start_backtrace(struct stackframe *frame, unsigned long fp, * records (e.g. a cycle), determined based on the location and fp value of A * and the location (but not the fp value) of B. */ -int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) +static int notrace unwind_frame(struct task_struct *tsk, + struct stackframe *frame) { unsigned long fp = frame->fp; struct stack_info info; - if (!tsk) - tsk = current; - /* Final frame; nothing to unwind */ if (fp == (unsigned long)task_pt_regs(tsk)->stackframe) return -ENOENT; @@ -136,15 +134,21 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) } NOKPROBE_SYMBOL(unwind_frame); -void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame, - bool (*fn)(void *, unsigned long), void *data) +static void notrace walk_stackframe(struct task_struct *tsk, + unsigned long fp, unsigned long pc, + bool (*fn)(void *, unsigned long), + void *data) { + struct stackframe frame; + + start_backtrace(&frame, fp, pc); + while (1) { int ret; - if (!fn(data, frame->pc)) + if (!fn(data, frame.pc)) break; - ret = unwind_frame(tsk, frame); + ret = unwind_frame(tsk, &frame); if (ret < 0) break; } @@ -190,19 +194,22 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, struct task_struct *task, struct pt_regs *regs) { - struct stackframe frame; + unsigned long fp, pc; + + if (regs) { + fp = regs->regs[29]; + pc = regs->pc; + } else if (task == current) { + /* Skip arch_stack_walk() in the stack trace. */ + fp = (unsigned long)__builtin_frame_address(1); + pc = (unsigned long)__builtin_return_address(0); + } else { + /* Caller guarantees that the task is not running. */ + fp = thread_saved_fp(task); + pc = thread_saved_pc(task); + } + walk_stackframe(task, fp, pc, consume_entry, cookie); - if (regs) - start_backtrace(&frame, regs->regs[29], regs->pc); - else if (task == current) - start_backtrace(&frame, - (unsigned long)__builtin_frame_address(1), - (unsigned long)__builtin_return_address(0)); - else - start_backtrace(&frame, thread_saved_fp(task), - thread_saved_pc(task)); - - walk_stackframe(task, &frame, consume_entry, cookie); } #endif -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-10-15 2:59 UTC|newest] Thread overview: 104+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <c05ce30dcc9be1bd6b5e24a2ca8fe1d66246980b> 2021-10-15 2:34 ` [PATCH v9 00/11] arm64: Reorganize the unwinder and implement stack trace reliability checks madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 01/11] arm64: Select STACKTRACE in arch/arm64/Kconfig madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 10/11] arm64: Introduce stack trace reliability checks in the unwinder madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 11/11] arm64: Create a list of SYM_CODE functions, check return PC against list madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 02/11] arm64: Make perf_callchain_kernel() use arch_stack_walk() madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 03/11] arm64: Make get_wchan() " madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 04/11] arm64: Make return_address() " madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 05/11] arm64: Make dump_stacktrace() " madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 06/11] arm64: Make profile_pc() " madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 07/11] arm64: Call stack_backtrace() only from within walk_stackframe() madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 08/11] arm64: Rename unwinder functions, prevent them from being traced and kprobed madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:34 ` [PATCH v9 09/11] arm64: Make the unwind loop in unwind() similar to other architectures madvenka 2021-10-15 2:34 ` madvenka 2021-10-15 2:53 ` [PATCH v9 00/11] arm64: Reorganize the unwinder and implement stack trace reliability checks Madhavan T. Venkataraman 2021-10-15 2:53 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 " madvenka 2021-10-15 2:58 ` madvenka 2021-10-15 2:58 ` [PATCH v10 01/11] arm64: Select STACKTRACE in arch/arm64/Kconfig madvenka 2021-10-15 2:58 ` madvenka 2021-10-15 18:28 ` Mark Brown 2021-10-15 18:28 ` Mark Brown 2021-10-21 12:28 ` Madhavan T. Venkataraman 2021-10-21 12:28 ` Madhavan T. Venkataraman 2021-10-22 18:02 ` Mark Rutland 2021-10-22 18:02 ` Mark Rutland 2021-11-12 17:44 ` Mark Rutland 2021-11-12 17:44 ` Mark Rutland 2021-11-14 16:15 ` Madhavan T. Venkataraman 2021-11-14 16:15 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 02/11] arm64: Make perf_callchain_kernel() use arch_stack_walk() madvenka 2021-10-15 2:58 ` madvenka 2021-10-20 14:59 ` Mark Brown 2021-10-20 14:59 ` Mark Brown 2021-10-21 12:28 ` Madhavan T. Venkataraman 2021-10-21 12:28 ` Madhavan T. Venkataraman 2021-10-22 18:11 ` Mark Rutland 2021-10-22 18:11 ` Mark Rutland 2021-10-23 12:49 ` Madhavan T. Venkataraman 2021-10-23 12:49 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 03/11] arm64: Make get_wchan() " madvenka 2021-10-15 2:58 ` madvenka 2021-10-20 16:10 ` Mark Brown 2021-10-20 16:10 ` Mark Brown 2021-10-21 12:30 ` Madhavan T. Venkataraman 2021-10-21 12:30 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 04/11] arm64: Make return_address() " madvenka 2021-10-15 2:58 ` madvenka 2021-10-20 15:03 ` Mark Brown 2021-10-20 15:03 ` Mark Brown 2021-10-21 12:29 ` Madhavan T. Venkataraman 2021-10-21 12:29 ` Madhavan T. Venkataraman 2021-10-22 18:51 ` Mark Rutland 2021-10-22 18:51 ` Mark Rutland 2021-10-23 12:51 ` Madhavan T. Venkataraman 2021-10-23 12:51 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 05/11] arm64: Make dump_stacktrace() " madvenka 2021-10-15 2:58 ` madvenka 2021-10-25 16:49 ` Mark Rutland 2021-10-25 16:49 ` Mark Rutland 2021-10-26 12:05 ` Mark Rutland 2021-10-26 12:05 ` Mark Rutland 2021-10-27 16:09 ` Madhavan T. Venkataraman 2021-10-27 16:09 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 06/11] arm64: Make profile_pc() " madvenka 2021-10-15 2:58 ` madvenka 2021-10-25 2:18 ` nobuta.keiya 2021-10-25 2:18 ` nobuta.keiya 2021-10-27 16:10 ` Madhavan T. Venkataraman 2021-10-27 16:10 ` Madhavan T. Venkataraman 2021-10-27 13:32 ` Mark Rutland 2021-10-27 13:32 ` Mark Rutland 2021-10-27 16:15 ` Madhavan T. Venkataraman 2021-10-27 16:15 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` madvenka [this message] 2021-10-15 2:58 ` [PATCH v10 07/11] arm64: Call stack_backtrace() only from within walk_stackframe() madvenka 2021-10-15 2:58 ` [PATCH v10 08/11] arm64: Rename unwinder functions, prevent them from being traced and kprobed madvenka 2021-10-15 2:58 ` madvenka 2021-10-27 17:53 ` Mark Rutland 2021-10-27 17:53 ` Mark Rutland 2021-10-27 20:07 ` Madhavan T. Venkataraman 2021-10-27 20:07 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 09/11] arm64: Make the unwind loop in unwind() similar to other architectures madvenka 2021-10-15 2:58 ` madvenka 2021-10-15 2:58 ` [PATCH v10 10/11] arm64: Introduce stack trace reliability checks in the unwinder madvenka 2021-10-15 2:58 ` madvenka 2021-11-04 12:39 ` nobuta.keiya 2021-11-04 12:39 ` nobuta.keiya 2021-11-10 3:13 ` Madhavan T. Venkataraman 2021-11-10 3:13 ` Madhavan T. Venkataraman 2021-10-15 2:58 ` [PATCH v10 11/11] arm64: Create a list of SYM_CODE functions, check return PC against list madvenka 2021-10-15 2:58 ` madvenka 2021-10-15 17:00 ` [PATCH v10 00/11] arm64: Reorganize the unwinder and implement stack trace reliability checks Madhavan T. Venkataraman 2021-10-15 17:00 ` Madhavan T. Venkataraman
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211015025847.17694-8-madvenka@linux.microsoft.com \ --to=madvenka@linux.microsoft.com \ --cc=ardb@kernel.org \ --cc=broonie@kernel.org \ --cc=catalin.marinas@arm.com \ --cc=jmorris@namei.org \ --cc=jpoimboe@redhat.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=live-patching@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=nobuta.keiya@fujitsu.com \ --cc=sjitindarsingh@gmail.com \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.