From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
To: Steven Rostedt <rostedt@goodmis.org>,
Michael Ellerman <mpe@ellerman.id.au>,
Michal Suchanek <msuchanek@suse.de>, Torsten Duwe <duwe@suse.de>
Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 1/6] trace/stack: Move code to save the stack trace into a separate function
Date: Fri, 21 May 2021 12:18:36 +0530 [thread overview]
Message-ID: <6a8b68f8bd64f8c16d97ef943534c639781e7f77.1621577151.git.naveen.n.rao@linux.vnet.ibm.com> (raw)
In-Reply-To: <cover.1621577151.git.naveen.n.rao@linux.vnet.ibm.com>
In preparation to add support for stack tracer to powerpc, move code to
save stack trace and to calculate the frame sizes into a separate weak
function. Also provide access to some of the data structures used by the
stack trace code so that architectures can update those.
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
include/linux/ftrace.h | 8 ++++
kernel/trace/trace_stack.c | 98 ++++++++++++++++++++------------------
2 files changed, 60 insertions(+), 46 deletions(-)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index a69f363b61bf73..8263427379f05c 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -368,10 +368,18 @@ static inline void arch_ftrace_set_direct_caller(struct pt_regs *regs,
#ifdef CONFIG_STACK_TRACER
+#define STACK_TRACE_ENTRIES 500
+
+extern unsigned long stack_dump_trace[STACK_TRACE_ENTRIES];
+extern unsigned stack_trace_index[STACK_TRACE_ENTRIES];
+extern unsigned int stack_trace_nr_entries;
+extern unsigned long stack_trace_max_size;
extern int stack_tracer_enabled;
int stack_trace_sysctl(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos);
+void stack_get_trace(unsigned long traced_ip, unsigned long *stack_ref,
+ unsigned long stack_size, int *tracer_frame);
/* DO NOT MODIFY THIS VARIABLE DIRECTLY! */
DECLARE_PER_CPU(int, disable_stack_tracer);
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 63c28504205162..5b63dbd37c8c25 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -19,13 +19,11 @@
#include "trace.h"
-#define STACK_TRACE_ENTRIES 500
+unsigned long stack_dump_trace[STACK_TRACE_ENTRIES];
+unsigned stack_trace_index[STACK_TRACE_ENTRIES];
-static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES];
-static unsigned stack_trace_index[STACK_TRACE_ENTRIES];
-
-static unsigned int stack_trace_nr_entries;
-static unsigned long stack_trace_max_size;
+unsigned int stack_trace_nr_entries;
+unsigned long stack_trace_max_size;
static arch_spinlock_t stack_trace_max_lock =
(arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
@@ -152,49 +150,19 @@ static void print_max_stack(void)
* Although the entry function is not displayed, the first function (sys_foo)
* will still include the stack size of it.
*/
-static void check_stack(unsigned long ip, unsigned long *stack)
+void __weak stack_get_trace(unsigned long traced_ip, unsigned long *stack_ref,
+ unsigned long stack_size, int *tracer_frame)
{
- unsigned long this_size, flags; unsigned long *p, *top, *start;
- static int tracer_frame;
- int frame_size = READ_ONCE(tracer_frame);
+ unsigned long *p, *top, *start;
int i, x;
- this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
- this_size = THREAD_SIZE - this_size;
- /* Remove the frame of the tracer */
- this_size -= frame_size;
-
- if (this_size <= stack_trace_max_size)
- return;
-
- /* we do not handle interrupt stacks yet */
- if (!object_is_on_stack(stack))
- return;
-
- /* Can't do this from NMI context (can cause deadlocks) */
- if (in_nmi())
- return;
-
- local_irq_save(flags);
- arch_spin_lock(&stack_trace_max_lock);
-
- /* In case another CPU set the tracer_frame on us */
- if (unlikely(!frame_size))
- this_size -= tracer_frame;
-
- /* a race could have already updated it */
- if (this_size <= stack_trace_max_size)
- goto out;
-
- stack_trace_max_size = this_size;
-
stack_trace_nr_entries = stack_trace_save(stack_dump_trace,
ARRAY_SIZE(stack_dump_trace) - 1,
0);
/* Skip over the overhead of the stack tracer itself */
for (i = 0; i < stack_trace_nr_entries; i++) {
- if (stack_dump_trace[i] == ip)
+ if (stack_dump_trace[i] == traced_ip)
break;
}
@@ -209,7 +177,7 @@ static void check_stack(unsigned long ip, unsigned long *stack)
* Now find where in the stack these are.
*/
x = 0;
- start = stack;
+ start = stack_ref;
top = (unsigned long *)
(((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);
@@ -223,7 +191,7 @@ static void check_stack(unsigned long ip, unsigned long *stack)
while (i < stack_trace_nr_entries) {
int found = 0;
- stack_trace_index[x] = this_size;
+ stack_trace_index[x] = stack_size;
p = start;
for (; p < top && i < stack_trace_nr_entries; p++) {
@@ -233,7 +201,7 @@ static void check_stack(unsigned long ip, unsigned long *stack)
*/
if ((READ_ONCE_NOCHECK(*p)) == stack_dump_trace[i]) {
stack_dump_trace[x] = stack_dump_trace[i++];
- this_size = stack_trace_index[x++] =
+ stack_size = stack_trace_index[x++] =
(top - p) * sizeof(unsigned long);
found = 1;
/* Start the search from here */
@@ -245,10 +213,10 @@ static void check_stack(unsigned long ip, unsigned long *stack)
* out what that is, then figure it out
* now.
*/
- if (unlikely(!tracer_frame)) {
- tracer_frame = (p - stack) *
+ if (unlikely(!*tracer_frame)) {
+ *tracer_frame = (p - stack_ref) *
sizeof(unsigned long);
- stack_trace_max_size -= tracer_frame;
+ stack_trace_max_size -= *tracer_frame;
}
}
}
@@ -272,6 +240,44 @@ static void check_stack(unsigned long ip, unsigned long *stack)
#endif
stack_trace_nr_entries = x;
+}
+
+static void check_stack(unsigned long ip, unsigned long *stack)
+{
+ unsigned long this_size, flags;
+ static int tracer_frame;
+ int frame_size = READ_ONCE(tracer_frame);
+
+ this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
+ this_size = THREAD_SIZE - this_size;
+ /* Remove the frame of the tracer */
+ this_size -= frame_size;
+
+ if (this_size <= stack_trace_max_size)
+ return;
+
+ /* we do not handle interrupt stacks yet */
+ if (!object_is_on_stack(stack))
+ return;
+
+ /* Can't do this from NMI context (can cause deadlocks) */
+ if (in_nmi())
+ return;
+
+ local_irq_save(flags);
+ arch_spin_lock(&stack_trace_max_lock);
+
+ /* In case another CPU set the tracer_frame on us */
+ if (unlikely(!frame_size))
+ this_size -= tracer_frame;
+
+ /* a race could have already updated it */
+ if (this_size <= stack_trace_max_size)
+ goto out;
+
+ stack_trace_max_size = this_size;
+
+ stack_get_trace(ip, stack, this_size, &tracer_frame);
if (task_stack_end_corrupted(current)) {
print_max_stack();
--
2.30.2
next prev parent reply other threads:[~2021-05-21 6:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-21 6:48 [RFC PATCH 0/6] powerpc: Stack tracer fixes Naveen N. Rao
2021-05-21 6:48 ` Naveen N. Rao [this message]
2021-06-01 15:28 ` [RFC PATCH 1/6] trace/stack: Move code to save the stack trace into a separate function Steven Rostedt
2021-06-02 10:35 ` Naveen N. Rao
2021-06-02 14:09 ` Steven Rostedt
2021-05-21 6:48 ` [RFC PATCH 2/6] powerpc/trace: Add support for stack tracer Naveen N. Rao
2021-06-01 13:51 ` Naveen N. Rao
2021-05-21 6:48 ` [RFC PATCH 3/6] powerpc: Indicate traced function name in show_stack() Naveen N. Rao
2021-05-21 6:48 ` [RFC PATCH 4/6] powerpc/perf: Include traced function in the callchain Naveen N. Rao
2021-05-21 6:48 ` [RFC PATCH 5/6] powerpc/stacktrace: Include ftraced function in arch_stack_walk_reliable() Naveen N. Rao
2021-05-21 6:48 ` [RFC PATCH 6/6] powerpc/stacktrace: Include ftraced function in arch_stack_walk() Naveen N. Rao
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=6a8b68f8bd64f8c16d97ef943534c639781e7f77.1621577151.git.naveen.n.rao@linux.vnet.ibm.com \
--to=naveen.n.rao@linux.vnet.ibm.com \
--cc=duwe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=msuchanek@suse.de \
--cc=rostedt@goodmis.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).