All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Ingo Molnar <mingo@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	linux-arch@vger.kernel.org,
	Joel Fernandes <joel@joelfernandes.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Andy Lutomirski <luto@kernel.org>,
	Frederic Weisbecker <frederic@kernel.org>,
	stable@kernel.org
Subject: [for-next][PATCH 15/18] function_graph: Use new curr_ret_depth to manage depth instead of curr_ret_stack
Date: Wed, 21 Nov 2018 19:28:16 -0500	[thread overview]
Message-ID: <20181122003333.592319701@goodmis.org> (raw)
In-Reply-To: 20181122002801.501220343@goodmis.org

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Currently, the depth of the ret_stack is determined by curr_ret_stack index.
The issue is that there's a race between setting of the curr_ret_stack and
calling of the callback attached to the return of the function.

Commit 03274a3ffb44 ("tracing/fgraph: Adjust fgraph depth before calling
trace return callback") moved the calling of the callback to after the
setting of the curr_ret_stack, even stating that it was safe to do so, when
in fact, it was the reason there was a barrier() there (yes, I should have
commented that barrier()).

Not only does the curr_ret_stack keep track of the current call graph depth,
it also keeps the ret_stack content from being overwritten by new data.

The function profiler, uses the "subtime" variable of ret_stack structure
and by moving the curr_ret_stack, it allows for interrupts to use the same
structure it was using, corrupting the data, and breaking the profiler.

To fix this, there needs to be two variables to handle the call stack depth
and the pointer to where the ret_stack is being used, as they need to change
at two different locations.

Cc: stable@kernel.org
Fixes: 03274a3ffb449 ("tracing/fgraph: Adjust fgraph depth before calling trace return callback")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/linux/sched.h                |  1 +
 kernel/trace/ftrace.c                |  3 +++
 kernel/trace/trace_functions_graph.c | 21 +++++++++++++--------
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index a51c13c2b1a0..d6183a55e8eb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1116,6 +1116,7 @@ struct task_struct {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	/* Index of current stored address in ret_stack: */
 	int				curr_ret_stack;
+	int				curr_ret_depth;
 
 	/* Stack of return addresses for return function tracing: */
 	struct ftrace_ret_stack		*ret_stack;
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f536f601bd46..48513954713c 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6814,6 +6814,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
 			atomic_set(&t->tracing_graph_pause, 0);
 			atomic_set(&t->trace_overrun, 0);
 			t->curr_ret_stack = -1;
+			t->curr_ret_depth = -1;
 			/* Make sure the tasks see the -1 first: */
 			smp_wmb();
 			t->ret_stack = ret_stack_list[start++];
@@ -7038,6 +7039,7 @@ graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack)
 void ftrace_graph_init_idle_task(struct task_struct *t, int cpu)
 {
 	t->curr_ret_stack = -1;
+	t->curr_ret_depth = -1;
 	/*
 	 * The idle task has no parent, it either has its own
 	 * stack or no stack at all.
@@ -7068,6 +7070,7 @@ void ftrace_graph_init_task(struct task_struct *t)
 	/* Make sure we do not use the parent ret_stack */
 	t->ret_stack = NULL;
 	t->curr_ret_stack = -1;
+	t->curr_ret_depth = -1;
 
 	if (ftrace_graph_active) {
 		struct ftrace_ret_stack *ret_stack;
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 88ca787a1cdc..02d4081a7f5a 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -119,7 +119,7 @@ print_graph_duration(struct trace_array *tr, unsigned long long duration,
 
 /* Add a function return address to the trace stack on thread info.*/
 static int
-ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
+ftrace_push_return_trace(unsigned long ret, unsigned long func,
 			 unsigned long frame_pointer, unsigned long *retp)
 {
 	unsigned long long calltime;
@@ -177,8 +177,6 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
 #ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
 	current->ret_stack[index].retp = retp;
 #endif
-	*depth = current->curr_ret_stack;
-
 	return 0;
 }
 
@@ -188,14 +186,20 @@ int function_graph_enter(unsigned long ret, unsigned long func,
 	struct ftrace_graph_ent trace;
 
 	trace.func = func;
-	trace.depth = current->curr_ret_stack + 1;
+	trace.depth = ++current->curr_ret_depth;
 
 	/* Only trace if the calling function expects to */
 	if (!ftrace_graph_entry(&trace))
-		return -EBUSY;
+		goto out;
 
-	return ftrace_push_return_trace(ret, func, &trace.depth,
-					frame_pointer, retp);
+	if (ftrace_push_return_trace(ret, func,
+				     frame_pointer, retp))
+		goto out;
+
+	return 0;
+ out:
+	current->curr_ret_depth--;
+	return -EBUSY;
 }
 
 /* Retrieve a function return address to the trace stack on thread info.*/
@@ -257,7 +261,7 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,
 	trace->func = current->ret_stack[index].func;
 	trace->calltime = current->ret_stack[index].calltime;
 	trace->overrun = atomic_read(&current->trace_overrun);
-	trace->depth = index;
+	trace->depth = current->curr_ret_depth;
 }
 
 /*
@@ -273,6 +277,7 @@ unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
 	trace.rettime = trace_clock_local();
 	barrier();
 	current->curr_ret_stack--;
+	current->curr_ret_depth--;
 	/*
 	 * The curr_ret_stack can be less than -1 only if it was
 	 * filtered out and it's about to return from the function.
-- 
2.19.1



  parent reply	other threads:[~2018-11-22  0:34 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-22  0:28 [for-next][PATCH 00/18] function_graph: Add separate depth counter to prevent trace corruption Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 01/18] function_graph: Create function_graph_enter() to consolidate architecture code Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 02/18] x86/function_graph: Simplify with function_graph_entry() Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 03/18] ARM: function_graph: " Steven Rostedt
2018-11-22  0:28   ` Steven Rostedt
2018-11-23  7:30   ` Sasha Levin
2018-11-22  0:28 ` [for-next][PATCH 04/18] arm64: " Steven Rostedt
2018-11-22  0:28   ` Steven Rostedt
2018-11-22  0:28   ` Steven Rostedt
2018-11-27 18:07   ` Will Deacon
2018-11-27 18:07     ` Will Deacon
2018-11-27 18:26     ` Steven Rostedt
2018-11-27 18:26       ` Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 05/18] microblaze: " Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 06/18] MIPS: " Steven Rostedt
2018-11-23  7:30   ` Sasha Levin
2018-11-23  7:30     ` Sasha Levin
2018-11-22  0:28 ` [for-next][PATCH 07/18] nds32: " Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 08/18] parisc: " Steven Rostedt
     [not found]   ` <20181123073033.2083020863@mail.kernel.org>
2018-11-23  9:06     ` Helge Deller
2018-11-23 17:12       ` Steven Rostedt
2018-11-23 18:34         ` Sasha Levin
2018-11-23 19:26           ` Steven Rostedt
2018-11-23 20:00             ` Sasha Levin
2018-11-24 18:46               ` Steven Rostedt
2018-12-03 14:54                 ` Sasha Levin
2018-11-22  0:28 ` [for-next][PATCH 09/18] powerpc/function_graph: " Steven Rostedt
2018-11-22  0:28   ` Steven Rostedt
2018-11-23  7:30   ` Sasha Levin
2018-11-22  0:28 ` [for-next][PATCH 10/18] riscv/function_graph: " Steven Rostedt
2018-11-26 16:47   ` Palmer Dabbelt
2018-11-22  0:28 ` [for-next][PATCH 11/18] s390/function_graph: " Steven Rostedt
2018-11-22  6:43   ` Martin Schwidefsky
2018-11-23 17:15     ` Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 12/18] sh/function_graph: " Steven Rostedt
2018-11-22  0:28   ` Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 13/18] sparc/function_graph: " Steven Rostedt
2018-11-22  0:28   ` Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 14/18] function_graph: Make ftrace_push_return_trace() static Steven Rostedt
2018-11-22  0:28 ` Steven Rostedt [this message]
2018-11-22 10:03   ` [for-next][PATCH 15/18] function_graph: Use new curr_ret_depth to manage depth instead of curr_ret_stack Peter Zijlstra
2018-11-23 14:14     ` Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 16/18] function_graph: Move return callback before update " Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 17/18] function_graph: Reverse the order of pushing the ret_stack and the callback Steven Rostedt
2018-11-22  0:28 ` [for-next][PATCH 18/18] function_graph: Have profiler use curr_ret_stack and not depth Steven Rostedt
2018-11-26  5:15 ` [for-next][PATCH 00/18] function_graph: Add separate depth counter to prevent trace corruption Masami Hiramatsu
2018-11-28 20:39 ` Joe Lawrence
2018-11-28 21:00   ` Steven Rostedt
2018-11-29  3:29     ` Steven Rostedt
2018-11-29  4:24       ` Steven Rostedt
2018-11-29 15:08         ` Joe Lawrence
2018-11-29 16:17           ` Steven Rostedt
2018-11-29 16:32             ` Joe Lawrence

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=20181122003333.592319701@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=akpm@linux-foundation.org \
    --cc=frederic@kernel.org \
    --cc=joel@joelfernandes.org \
    --cc=jpoimboe@redhat.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=stable@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.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.