[PATCH 2/2] drm/i915/perf: Flush context writes before destroying the perf stream

Chris Wilson chris at chris-wilson.co.uk
Thu Mar 4 11:31:20 UTC 2021


As the context state manipulation is running independently of the perf
stream destruction, it is possible for the i915_oa_init_reg_state() to
continue to access the perf stream after it is freed. Reintroduction
serialisation between i915_oa_stream_destroy and i915_oa_init_reg_state
by virtue of rcu read locks and synchronisation.

Fixes: feed5c7be22c ("drm/i915: Pin the context as we work on it")
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3156
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: <stable at vger.kernel.org> # v5.6+
---
 drivers/gpu/drm/i915/i915_perf.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index c15bead2dac7..286dc5d5da49 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -1372,6 +1372,7 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
 	 * See i915_oa_init_reg_state() and lrc_configure_all_contexts()
 	 */
 	WRITE_ONCE(perf->exclusive_stream, NULL);
+	synchronize_rcu(); /* Serialise with i915_oa_init_reg_state */
 	perf->ops.disable_metric_set(stream);
 
 	free_oa_buffer(stream);
@@ -2977,10 +2978,12 @@ void i915_oa_init_reg_state(const struct intel_context *ce,
 	if (engine->class != RENDER_CLASS)
 		return;
 
-	/* perf.exclusive_stream serialised by lrc_configure_all_contexts() */
+	/* perf.exclusive_stream serialised by i915_oa_stream_destroy() */
+	rcu_read_lock();
 	stream = READ_ONCE(engine->i915->perf.exclusive_stream);
 	if (stream && INTEL_GEN(stream->perf->i915) < 12)
 		gen8_update_reg_state_unlocked(ce, stream);
+	rcu_read_unlock();
 }
 
 /**
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list