diff mbox

[RFC/CI] drm/i915/crc: make locking and source check more robust

Message ID 20180417135610.22513-1-jani.nikula@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jani Nikula April 17, 2018, 1:56 p.m. UTC
It seems to me intel_pipe_crc source and skipped should be checked and
modified atomically. Skipped could concievably be changed when source
has already been disabled. Alas I can't think of a real world scenario
where this could impact CRCs in IGT.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c       | 8 +++++++-
 drivers/gpu/drm/i915/intel_pipe_crc.c | 5 ++++-
 2 files changed, 11 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b03d18561b55..03fd1ecaf16a 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1687,7 +1687,13 @@  static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
 	int head, tail;
 
 	spin_lock(&pipe_crc->lock);
-	if (pipe_crc->source && !crtc->base.crc.opened) {
+	if (!pipe_crc->source) {
+		spin_unlock(&pipe_crc->lock);
+		DRM_DEBUG_KMS("ignoring crc irq while disabling\n");
+		return;
+	}
+
+	if (!crtc->base.crc.opened) {
 		if (!pipe_crc->entries) {
 			spin_unlock(&pipe_crc->lock);
 			DRM_DEBUG_KMS("spurious interrupt\n");
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 4f367c16e9e5..94a6d3178a2d 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -940,7 +940,11 @@  int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
 	if (ret != 0)
 		goto out;
 
+	spin_lock(&pipe_crc->lock);
 	pipe_crc->source = source;
+	pipe_crc->skipped = 0;
+	spin_unlock(&pipe_crc->lock);
+
 	I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
 	POSTING_READ(PIPE_CRC_CTL(crtc->index));
 
@@ -954,7 +958,6 @@  int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
 			hsw_pipe_A_crc_wa(dev_priv, false);
 	}
 
-	pipe_crc->skipped = 0;
 	*values_cnt = 5;
 
 out: