[PATCH 28/66] drm/i915/execlists: Repeat CSB mmio until it returns a sensible result

Chris Wilson chris at chris-wilson.co.uk
Sat Jan 20 19:43:50 UTC 2018


Even though we wait until the HW has sent us its first CS interrupt
before believing that it is powered on, a read from the powercontext
saved CSB registers may still return garbage. So we must wait a little
bit for the right result. This, of course, assumes that we always see an
invalid result when the powercontext is not loaded, otherwise we will
attempt to read stale data.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_lrc.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index bbf849430303..c75b46f8e777 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -795,7 +795,8 @@ static void execlists_submission_tasklet(unsigned long data)
 			execlists->csb_head = -1; /* force mmio read of CSB ptrs */
 		}
 
-		/* The write will be ordered by the uncached read (itself
+		/*
+		 * The write will be ordered by the uncached read (itself
 		 * a memory barrier), so we do not need another in the form
 		 * of a locked instruction. The race between the interrupt
 		 * handler and the split test/clear is harmless as we order
@@ -813,8 +814,20 @@ static void execlists_submission_tasklet(unsigned long data)
 				fw = true;
 			}
 
-			head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)));
-			tail = GEN8_CSB_WRITE_PTR(head);
+			do {
+				head = readl(dev_priv->regs +
+					     i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)));
+				tail = GEN8_CSB_WRITE_PTR(head);
+				/*
+				 * We have to wait until the powercontext has
+				 * been loaded by the GPU before it starts
+				 * reporting correctly. As we sometimes see
+				 * an CS interrupt before we are able to
+				 * read from the powercontext saved
+				 * register, we repeat the read. Baffling and
+				 * quite scary.
+				 */
+			} while (unlikely(tail >= GEN8_CSB_ENTRIES));
 			head = GEN8_CSB_READ_PTR(head);
 			execlists->csb_head = head;
 		} else {
-- 
2.15.1



More information about the Intel-gfx-trybot mailing list