[PATCH 2/4] drm/i915/guc: Keep the execbuf client allocated across reset

Chris Wilson chris at chris-wilson.co.uk
Thu Nov 17 07:22:46 UTC 2016


In order to avoid some complexity in trying to reconstruct the
workqueues across reset, remember them instead.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_guc_submission.c | 50 ++++++++++++++----------------
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 4462112725ef..94d9e15a0ed6 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1504,29 +1504,31 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv)
 	guc_log_create(guc);
 	guc_addon_create(guc);
 
+	guc->execbuf_client = guc_client_alloc(dev_priv,
+					       INTEL_INFO(dev_priv)->ring_mask,
+					       GUC_CTX_PRIORITY_KMD_NORMAL,
+					       dev_priv->kernel_context);
+	if (!guc->execbuf_client) {
+		DRM_ERROR("Failed to create GuC client for execbuf!\n");
+		goto err;
+	}
+
 	return 0;
+
+err:
+	i915_guc_submission_fini(dev_priv);
+	return -ENOMEM;
 }
 
 int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
 {
 	struct intel_guc *guc = &dev_priv->guc;
+	struct i915_guc_client *gc = guc->execbuf_client;
 	struct drm_i915_gem_request *request;
-	struct i915_guc_client *client;
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 
-	/* client for execbuf submission */
-	client = guc_client_alloc(dev_priv,
-				  INTEL_INFO(dev_priv)->ring_mask,
-				  GUC_CTX_PRIORITY_KMD_NORMAL,
-				  dev_priv->kernel_context);
-	if (!client) {
-		DRM_ERROR("Failed to create normal GuC client!\n");
-		return -ENOMEM;
-	}
-
-	guc->execbuf_client = client;
-	host2guc_sample_forcewake(guc, client);
+	host2guc_sample_forcewake(guc, gc);
 	guc_init_doorbell_hw(guc);
 
 	/* Take over from manual control of ELSP (execlists) */
@@ -1535,12 +1537,11 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
 		engine->schedule = NULL;
 
 		/* Replay the current set of previously submitted requests */
-		list_for_each_entry(request,
-				    &engine->timeline->requests, link) {
-			client->wq_rsvd += sizeof(struct guc_wq_item);
-			if (i915_sw_fence_done(&request->submit))
+		list_for_each_entry(request, &engine->timeline->requests, link)
+			if (i915_sw_fence_done(&request->submit)) {
+				gc->wq_rsvd += sizeof(struct guc_wq_item);
 				i915_guc_submit(request);
-		}
+			}
 	}
 
 	return 0;
@@ -1548,21 +1549,18 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
 
 void i915_guc_submission_disable(struct drm_i915_private *dev_priv)
 {
-	struct intel_guc *guc = &dev_priv->guc;
-
-	if (!guc->execbuf_client)
-		return;
-
 	/* Revert back to manual ELSP submission */
 	intel_execlists_enable_submission(dev_priv);
-
-	guc_client_free(dev_priv, guc->execbuf_client);
-	guc->execbuf_client = NULL;
 }
 
 void i915_guc_submission_fini(struct drm_i915_private *dev_priv)
 {
 	struct intel_guc *guc = &dev_priv->guc;
+	struct i915_guc_client *gc;
+
+	gc = fetch_and_zero(&guc->execbuf_client);
+	if (gc)
+		guc_client_free(dev_priv, gc);
 
 	i915_vma_unpin_and_release(&guc->ads_vma);
 	i915_vma_unpin_and_release(&guc->log.vma);
-- 
2.10.2



More information about the Intel-gfx-trybot mailing list