{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *engine;
- int ret, j;
+ int ret;
/* Carefully retire all requests without writing to the rings */
for_each_engine(engine, dev_priv) {
i915_gem_retire_requests(dev);
/* Finally reset hw state */
- for_each_engine(engine, dev_priv) {
+ for_each_engine(engine, dev_priv)
intel_ring_init_seqno(engine, seqno);
- for (j = 0; j < ARRAY_SIZE(engine->semaphore.sync_seqno); j++)
- engine->semaphore.sync_seqno[j] = 0;
- }
-
return 0;
}
{
struct drm_i915_private *dev_priv = to_i915(engine->dev);
+ /* Our semaphore implementation is strictly monotonic (i.e. we proceed
+ * so long as the semaphore value in the register/page is greater
+ * than the sync value), so whenever we reset the seqno,
+ * so long as we reset the tracking semaphore value to 0, it will
+ * always be before the next request's seqno. If we don't reset
+ * the semaphore value, then when the seqno moves backwards all
+ * future waits will complete instantly (causing rendering corruption).
+ */
if (INTEL_INFO(dev_priv)->gen == 6 || INTEL_INFO(dev_priv)->gen == 7) {
I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
if (HAS_VEBOX(dev_priv))
I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
}
+ memset(engine->semaphore.sync_seqno, 0,
+ sizeof(engine->semaphore.sync_seqno));
engine->set_seqno(engine, seqno);
+
engine->hangcheck.seqno = seqno;
}