summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 87efc6da7368..d7ca8f97b315 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2501,13 +2501,17 @@ void trace_buffered_event_disable(void)
free_page((unsigned long)per_cpu(trace_buffered_event, cpu));
per_cpu(trace_buffered_event, cpu) = NULL;
}
+
/*
- * Make sure trace_buffered_event is NULL before clearing
- * trace_buffered_event_cnt.
+ * Wait for all CPUs that potentially started checking if they can use
+ * their event buffer only after the previous synchronize_rcu() call and
+ * they still read a valid pointer from trace_buffered_event. It must be
+ * ensured they don't see cleared trace_buffered_event_cnt else they
+ * could wrongly decide to use the pointed-to buffer which is now freed.
*/
- smp_wmb();
+ synchronize_rcu();
- /* Do the work on each cpu */
+ /* For each CPU, relinquish the buffer */
on_each_cpu_mask(tracing_buffer_mask, enable_trace_buffered_event, NULL,
true);
}