[PATCH 2/3] drm/i915: Force sync command ordering (Gen6+)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 08 Dec 2011 18:35:24 -0800
Eric Anholt <eric at anholt.net> wrote:
> Since MI_FLUSH_DW exists on gen6, and keithp says we still have
> outstanding issues with missed blit IRQs there, I started trying it
> today.  Two kernel branches posted at
> git://people.freedesktop.org/~anholt/linux/
> 
> flush-dw-notify: This is the initial attempt I did with MI_FLUSH_DW with
> internal notify.  Quickly produced missed blit IRQs.  I thought this was
> because the notify was in parallel with the post-sync op, not synced to
> be after.  So I reverted part of the patch and produced...

Bummer, that one looks like it ought to work.

On current drm-intel-next, this patch seems to be preventing missed
IRQs on IVB at least.  Anyone else wanna give it a try and confirm?
I've only tested with Eric's blit-and-wait.c test so far.

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b40004b..cb821a0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -482,78 +482,83 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
 	I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
 	POSTING_READ(DEIER);
 
-	de_iir = I915_READ(DEIIR);
-	gt_iir = I915_READ(GTIIR);
-	pch_iir = I915_READ(SDEIIR);
-	pm_iir = I915_READ(GEN6_PMIIR);
+	/*
+	 * Try to mitigate dropped IRQs by handling as many as possible
+	 * each time we get a physical interrupt.
+	 */
+	while (1) {
+		de_iir = I915_READ(DEIIR);
+		gt_iir = I915_READ(GTIIR);
+		pch_iir = I915_READ(SDEIIR);
+		pm_iir = I915_READ(GEN6_PMIIR);
+
+		if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && pm_iir == 0) {
+			I915_WRITE(DEIER, de_ier);
+			POSTING_READ(DEIER);
+			return ret;
+		}
 
-	if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && pm_iir == 0)
-		goto done;
+		ret = IRQ_HANDLED;
 
-	ret = IRQ_HANDLED;
+		if (dev->primary->master) {
+			master_priv = dev->primary->master->driver_priv;
+			if (master_priv->sarea_priv)
+				master_priv->sarea_priv->last_dispatch =
+					READ_BREADCRUMB(dev_priv);
+		}
 
-	if (dev->primary->master) {
-		master_priv = dev->primary->master->driver_priv;
-		if (master_priv->sarea_priv)
-			master_priv->sarea_priv->last_dispatch =
-				READ_BREADCRUMB(dev_priv);
-	}
+		if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
+			notify_ring(dev, &dev_priv->ring[RCS]);
+		if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
+			notify_ring(dev, &dev_priv->ring[VCS]);
+		if (gt_iir & GT_BLT_USER_INTERRUPT)
+			notify_ring(dev, &dev_priv->ring[BCS]);
 
-	if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
-		notify_ring(dev, &dev_priv->ring[RCS]);
-	if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
-		notify_ring(dev, &dev_priv->ring[VCS]);
-	if (gt_iir & GT_BLT_USER_INTERRUPT)
-		notify_ring(dev, &dev_priv->ring[BCS]);
+		if (de_iir & DE_GSE_IVB)
+			intel_opregion_gse_intr(dev);
 
-	if (de_iir & DE_GSE_IVB)
-		intel_opregion_gse_intr(dev);
+		if (de_iir & DE_PLANEA_FLIP_DONE_IVB) {
+			intel_prepare_page_flip(dev, 0);
+			intel_finish_page_flip_plane(dev, 0);
+		}
 
-	if (de_iir & DE_PLANEA_FLIP_DONE_IVB) {
-		intel_prepare_page_flip(dev, 0);
-		intel_finish_page_flip_plane(dev, 0);
-	}
+		if (de_iir & DE_PLANEB_FLIP_DONE_IVB) {
+			intel_prepare_page_flip(dev, 1);
+			intel_finish_page_flip_plane(dev, 1);
+		}
 
-	if (de_iir & DE_PLANEB_FLIP_DONE_IVB) {
-		intel_prepare_page_flip(dev, 1);
-		intel_finish_page_flip_plane(dev, 1);
-	}
+		if (de_iir & DE_PIPEA_VBLANK_IVB)
+			drm_handle_vblank(dev, 0);
 
-	if (de_iir & DE_PIPEA_VBLANK_IVB)
-		drm_handle_vblank(dev, 0);
+		if (de_iir & DE_PIPEB_VBLANK_IVB)
+			drm_handle_vblank(dev, 1);
 
-	if (de_iir & DE_PIPEB_VBLANK_IVB)
-		drm_handle_vblank(dev, 1);
+		/* check event from PCH */
+		if (de_iir & DE_PCH_EVENT_IVB) {
+			if (pch_iir & SDE_HOTPLUG_MASK_CPT)
+				queue_work(dev_priv->wq,
+					   &dev_priv->hotplug_work);
+			pch_irq_handler(dev);
+		}
 
-	/* check event from PCH */
-	if (de_iir & DE_PCH_EVENT_IVB) {
-		if (pch_iir & SDE_HOTPLUG_MASK_CPT)
-			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
-		pch_irq_handler(dev);
-	}
+		if (pm_iir & GEN6_PM_DEFERRED_EVENTS) {
+			unsigned long flags;
+			spin_lock_irqsave(&dev_priv->rps_lock, flags);
+			WARN(dev_priv->pm_iir & pm_iir,
+			     "Missed a PM interrupt\n");
+			dev_priv->pm_iir |= pm_iir;
+			I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
+			POSTING_READ(GEN6_PMIMR);
+			spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
+			queue_work(dev_priv->wq, &dev_priv->rps_work);
+		}
 
-	if (pm_iir & GEN6_PM_DEFERRED_EVENTS) {
-		unsigned long flags;
-		spin_lock_irqsave(&dev_priv->rps_lock, flags);
-		WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n");
-		dev_priv->pm_iir |= pm_iir;
-		I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
-		POSTING_READ(GEN6_PMIMR);
-		spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
-		queue_work(dev_priv->wq, &dev_priv->rps_work);
+		/* should clear PCH hotplug event before clear CPU irq */
+		I915_WRITE(SDEIIR, pch_iir);
+		I915_WRITE(GTIIR, gt_iir);
+		I915_WRITE(DEIIR, de_iir);
+		I915_WRITE(GEN6_PMIIR, pm_iir);
 	}
-
-	/* should clear PCH hotplug event before clear CPU irq */
-	I915_WRITE(SDEIIR, pch_iir);
-	I915_WRITE(GTIIR, gt_iir);
-	I915_WRITE(DEIIR, de_iir);
-	I915_WRITE(GEN6_PMIIR, pm_iir);
-
-done:
-	I915_WRITE(DEIER, de_ier);
-	POSTING_READ(DEIER);
-
-	return ret;
 }
 
 static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index ca70e2f..a9bdcd6 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1301,9 +1301,11 @@ gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring)
 static void
 gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring)
 {
+#if 0
 	return gen6_ring_put_irq(ring,
 				 GT_GEN6_BSD_USER_INTERRUPT,
 				 GEN6_BSD_USER_INTERRUPT);
+#endif
 }
 
 /* ring buffer for Video Codec for Gen6+ */

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20111214/6705c82b/attachment.pgp>


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux