All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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: link
Be 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.