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

Chris Wilson chris at chris-wilson.co.uk
Tue Jan 23 15:33:39 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 23ecb8981b08..333a75a3b5d2 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