diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lrc.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2afa4daa88e8..6f972e6ec663 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1327,6 +1327,31 @@ static void reset_common_ring(struct intel_engine_cs *engine, { struct execlist_port *port = engine->execlist_port; struct intel_context *ce; + unsigned int n; + + /* + * Catch up with any missed context-switch interrupts. + * + * Ideally we would just read the remaining CSB entries now that we + * know the gpu is idle. However, the CSB registers are sometimes^W + * often trashed across a GPU reset! Instead we have to rely on + * guessing the missed context-switch events by looking at what + * requests were completed. + */ + if (!request) { + for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) + i915_gem_request_put(port_request(&port[n])); + memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); + return; + } + + if (request->ctx != port_request(port)->ctx) { + i915_gem_request_put(port_request(port)); + port[0] = port[1]; + memset(&port[1], 0, sizeof(port[1])); + } + + GEM_BUG_ON(request->ctx != port_request(port)->ctx); /* If the request was innocent, we leave the request in the ELSP * and will try to replay it on restarting. The context image may @@ -1338,7 +1363,7 @@ static void reset_common_ring(struct intel_engine_cs *engine, * and have to at least restore the RING register in the context * image back to the expected values to skip over the guilty request. */ - if (!request || request->fence.error != -EIO) + if (request->fence.error != -EIO) return; /* We want a simple context + ring to execute the breadcrumb update. @@ -1360,15 +1385,6 @@ static void reset_common_ring(struct intel_engine_cs *engine, request->ring->head = request->postfix; intel_ring_update_space(request->ring); - /* Catch up with any missed context-switch interrupts */ - if (request->ctx != port_request(port)->ctx) { - i915_gem_request_put(port_request(port)); - port[0] = port[1]; - memset(&port[1], 0, sizeof(port[1])); - } - - GEM_BUG_ON(request->ctx != port_request(port)->ctx); - /* Reset WaIdleLiteRestore:bdw,skl as well */ request->tail = intel_ring_wrap(request->ring, @@ -2092,7 +2108,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv) * So to avoid that we reset the context images upon resume. For * simplicity, we just zero everything out. */ - list_for_each_entry(ctx, &dev_priv->context_list, link) { + list_for_each_entry(ctx, &dev_priv->contexts.list, link) { for_each_engine(engine, dev_priv, id) { struct intel_context *ce = &ctx->engine[engine->id]; u32 *reg; |