Skip to contentSkip to conversation

tracing: A couple more last minute fixes

PATCH New Steven Rostedt 1 participant 3 messages Sep 6, 2017

Subsystems (2)
lore
Share & tools
lore

Steven Rostedt

author maintainer
#0 lore raw

cover tracing: A couple more last minute fixes

git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next

Head SHA1: 7685ab6c58557c6234f3540260195ecbee7fc4b3

Chunyu Hu (1):
tracing: Fix clear of RECORDED_TGID flag when disabling trace event

Steven Rostedt (VMware) (1):
tracing: Add barrier to trace_printk() buffer nesting modification

----

 kernel/trace/trace.c        | 8 +++++++-
 kernel/trace/trace_events.c | 2 +-
 2 files changed, 8 insertions(+), 2 deletions(-)
author maintainer
#1 lore raw

PATCH 1/2 tracing: Add barrier to trace_printk() buffer nesting modification

From: "Steven Rostedt (VMware)" <[email protected]>

trace_printk() uses 4 buffers, one for each context (normal, softirq, irq and NMI), such that it does not need to worry about one context preempting the other. There's a nesting counter that gets incremented to figure out which buffer to use. If the context gets preempted by another context which calls trace_printk() it will increment the counter and use the next buffer, and restore the counter when it is finished.

The problem is that gcc may optimize the modification of the buffer nesting counter and it may not be incremented in memory before the buffer is used. If this happens, and the context gets interrupted by another context, it could pick the same buffer and corrupt the one that is being used.

Compiler barriers need to be added after the nesting variable is incremented and before it is decremented to prevent usage of the context buffers by more than one context at the same time.

Cc Andy Lutomirski <[email protected]>
Fixes e2ace00117 ("tracing: Choose static tp_printk buffer by explicit nesting count")

Hat-tip-to: Peter Zijlstra <[email protected]>

---
 kernel/trace/trace.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
kernel/trace/trace.c +7 -1
index 30338a835a51..78842557eea0 100644
@@ -2802,11 +2802,17 @@ static char *get_trace_buf(void)
 	if (!buffer || buffer->nesting >= 4)
 		return NULL;
 
-	return &buffer->buffer[buffer->nesting++][0];
+	buffer->nesting++;
+
+	/* Interrupts must see nesting incremented before we use the buffer */
+	barrier();
+	return &buffer->buffer[buffer->nesting][0];
 }
 
 static void put_trace_buf(void)
 {
+	/* Don't let the decrement of nesting leak before this */
+	barrier();
 	this_cpu_dec(trace_percpu_buffer->nesting);
 }
 
Signature · 1 line
2.13.2
author maintainer
#2 lore raw

PATCH 2/2 tracing: Fix clear of RECORDED_TGID flag when disabling trace event

In reply to Steven Rostedt

From: Chunyu Hu <[email protected]>

When disabling one trace event, the RECORDED_TGID flag in the event file is not correctly cleared. It's clearing RECORDED_CMD flag when it should clear RECORDED_TGID flag.

Cc Joel Fernandes <[email protected]>
Fixes d914ba37d7 ("tracing: Add support for recording tgid of tasks")
---
 kernel/trace/trace_events.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_events.c +1 -1
index c93540c5df21..87468398b9ed 100644
@@ -406,7 +406,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
 
 			if (file->flags & EVENT_FILE_FL_RECORDED_TGID) {
 				tracing_stop_tgid_record();
-				clear_bit(EVENT_FILE_FL_RECORDED_CMD_BIT, &file->flags);
+				clear_bit(EVENT_FILE_FL_RECORDED_TGID_BIT, &file->flags);
 			}
 
 			call->class->reg(call, TRACE_REG_UNREGISTER, file);
Signature · 1 line
2.13.2