drm/i915: Make the ring IMR handling private
As the IMR for the USER interrupts are not modified elsewhere, we can
separate the spinlock used for these from that of hpd and pipestats.
Those two IMR are manipulated under an IRQ and so need heavier locking.
Reported-and-tested-by: Alexey Fisher <bug-track@fisher-privat.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 13cad98..03e3370 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -526,7 +526,7 @@
if (!dev->irq_enabled)
return false;
- spin_lock(&dev_priv->irq_lock);
+ spin_lock(&ring->irq_lock);
if (ring->irq_refcount++ == 0) {
if (HAS_PCH_SPLIT(dev))
ironlake_enable_irq(dev_priv,
@@ -534,7 +534,7 @@
else
i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
}
- spin_unlock(&dev_priv->irq_lock);
+ spin_unlock(&ring->irq_lock);
return true;
}
@@ -545,7 +545,7 @@
struct drm_device *dev = ring->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- spin_lock(&dev_priv->irq_lock);
+ spin_lock(&ring->irq_lock);
if (--ring->irq_refcount == 0) {
if (HAS_PCH_SPLIT(dev))
ironlake_disable_irq(dev_priv,
@@ -554,7 +554,7 @@
else
i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
}
- spin_unlock(&dev_priv->irq_lock);
+ spin_unlock(&ring->irq_lock);
}
void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
@@ -620,10 +620,10 @@
if (!dev->irq_enabled)
return false;
- spin_lock(&dev_priv->irq_lock);
+ spin_lock(&ring->irq_lock);
if (ring->irq_refcount++ == 0)
ironlake_enable_irq(dev_priv, flag);
- spin_unlock(&dev_priv->irq_lock);
+ spin_unlock(&ring->irq_lock);
return true;
}
@@ -634,10 +634,10 @@
struct drm_device *dev = ring->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- spin_lock(&dev_priv->irq_lock);
+ spin_lock(&ring->irq_lock);
if (--ring->irq_refcount == 0)
ironlake_disable_irq(dev_priv, flag);
- spin_unlock(&dev_priv->irq_lock);
+ spin_unlock(&ring->irq_lock);
}
static bool
@@ -649,13 +649,13 @@
if (!dev->irq_enabled)
return false;
- spin_lock(&dev_priv->irq_lock);
+ spin_lock(&ring->irq_lock);
if (ring->irq_refcount++ == 0) {
ring->irq_mask &= ~rflag;
I915_WRITE_IMR(ring, ring->irq_mask);
ironlake_enable_irq(dev_priv, gflag);
}
- spin_unlock(&dev_priv->irq_lock);
+ spin_unlock(&ring->irq_lock);
return true;
}
@@ -666,13 +666,13 @@
struct drm_device *dev = ring->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- spin_lock(&dev_priv->irq_lock);
+ spin_lock(&ring->irq_lock);
if (--ring->irq_refcount == 0) {
ring->irq_mask |= rflag;
I915_WRITE_IMR(ring, ring->irq_mask);
ironlake_disable_irq(dev_priv, gflag);
}
- spin_unlock(&dev_priv->irq_lock);
+ spin_unlock(&ring->irq_lock);
}
static bool
@@ -814,6 +814,8 @@
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
INIT_LIST_HEAD(&ring->gpu_write_list);
+
+ spin_lock_init(&ring->irq_lock);
ring->irq_mask = ~0;
if (I915_NEED_GFX_HWS(dev)) {