[tip:tracing/urgent] tracing: Fix invalid function_graph entry

From: tip-bot for Lai Jiangshan
Date: Tue Aug 04 2009 - 08:13:16 EST


Commit-ID: 38ceb592fcac9110c6b3c87ea0a27bff68c43486
Gitweb: http://git.kernel.org/tip/38ceb592fcac9110c6b3c87ea0a27bff68c43486
Author: Lai Jiangshan <laijs@xxxxxxxxxxxxxx>
AuthorDate: Tue, 28 Jul 2009 20:11:24 +0800
Committer: Frederic Weisbecker <fweisbec@xxxxxxxxx>
CommitDate: Tue, 28 Jul 2009 23:17:23 +0200

tracing: Fix invalid function_graph entry

When print_graph_entry() computes a function call entry event, it needs
to also check the next entry to guess if it matches the return event of
the current function entry.
In order to look at this next event, it needs to consume the current
entry before going ahead in the ring buffer.

However, if the current event that gets consumed is the last one in the
ring buffer head page, the ring_buffer may reuse the page for writers.
The consumed entry will then become invalid because of possible
racy overwriting.

Me must then handle this entry by making a copy of it.

The fix also applies on 2.6.30

Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: stable@xxxxxxxxxx
LKML-Reference: <4A6EEAEC.3050508@xxxxxxxxxxxxxx>
Signed-off-by: Frederic Weisbecker <fweisbec@xxxxxxxxx>


---
kernel/trace/trace_functions_graph.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index d2249ab..420ec34 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -843,9 +843,16 @@ print_graph_function(struct trace_iterator *iter)

switch (entry->type) {
case TRACE_GRAPH_ENT: {
- struct ftrace_graph_ent_entry *field;
+ /*
+ * print_graph_entry() may consume the current event,
+ * thus @field may become invalid, so we need to save it.
+ * sizeof(struct ftrace_graph_ent_entry) is very small,
+ * it can be safely saved at the stack.
+ */
+ struct ftrace_graph_ent_entry *field, saved;
trace_assign_type(field, entry);
- return print_graph_entry(field, s, iter);
+ saved = *field;
+ return print_graph_entry(&saved, s, iter);
}
case TRACE_GRAPH_RET: {
struct ftrace_graph_ret_entry *field;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/