[168/190] drm/i915: Skip holding context reference for duration of execbuffer call
diff mbox

Message ID 1452510091-6833-27-git-send-email-chris@chris-wilson.co.uk
State New
Headers show

Commit Message

Chris Wilson Jan. 11, 2016, 11:01 a.m. UTC
Since the context can only be referenced and unreferenced whilst holding
the bkl, we can safely forgo holding the reference on the context for
the duration of our lock inside the execbuffer. After dropping the lock
for the slow path, we then need to take care to reacquire the context,
which has the benefit of rechecking whether we were gazzumped and now
the GPU is wedged.

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

Patch
diff mbox

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 2a535eb35dff..7d758610a095 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -262,8 +262,6 @@  eb_unreserve_vma(struct i915_vma *vma)
 
 static void eb_destroy(struct i915_execbuffer *eb)
 {
-	i915_gem_context_unreference(eb->ctx);
-
 	while (!list_empty(&eb->vmas)) {
 		struct i915_vma *vma;
 
@@ -906,6 +904,27 @@  err:
 	} while (1);
 }
 
+static int eb_select_context(struct i915_execbuffer *eb)
+{
+	struct intel_context *ctx;
+	unsigned ctx_id;
+
+	ctx_id = i915_execbuffer2_get_context_id(*eb->args);
+	ctx = i915_gem_context_get(eb->file->driver_priv, ctx_id);
+	if (unlikely(IS_ERR(ctx)))
+		return PTR_ERR(ctx);
+
+	if (unlikely(ctx->hang_stats.banned)) {
+		DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
+		return -EIO;
+	}
+
+	eb->ctx = ctx;
+	eb->vm = ctx->ppgtt ? &ctx->ppgtt->base : &eb->i915->gtt.base;
+
+	return 0;
+}
+
 static int
 eb_relocate_slow(struct i915_execbuffer *eb)
 {
@@ -982,6 +1001,10 @@  eb_relocate_slow(struct i915_execbuffer *eb)
 		goto err;
 	}
 
+	ret = eb_select_context(eb);
+	if (ret)
+		goto err;
+
 	/* reacquire the objects */
 	eb_reset(eb);
 	ret = eb_lookup_vmas(eb);
@@ -1141,28 +1164,6 @@  validate_exec_list(struct drm_device *dev,
 	return 0;
 }
 
-static int eb_select_context(struct i915_execbuffer *eb)
-{
-	struct intel_context *ctx;
-	unsigned ctx_id;
-
-	ctx_id = i915_execbuffer2_get_context_id(*eb->args);
-	ctx = i915_gem_context_get(eb->file->driver_priv, ctx_id);
-	if (unlikely(IS_ERR(ctx)))
-		return PTR_ERR(ctx);
-
-	if (unlikely(ctx->hang_stats.banned)) {
-		DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
-		return -EIO;
-	}
-
-	eb->ctx = ctx;
-	i915_gem_context_reference(ctx);
-	eb->vm = ctx->ppgtt ? &ctx->ppgtt->base : &eb->i915->gtt.base;
-
-	return 0;
-}
-
 void i915_vma_move_to_active(struct i915_vma *vma,
 			     struct drm_i915_gem_request *req,
 			     unsigned flags)
@@ -1528,7 +1529,6 @@  i915_gem_do_execbuffer(struct drm_device *dev,
 	}
 
 	if (eb_create(&eb)) {
-		i915_gem_context_unreference(eb.ctx);
 		mutex_unlock(&dev->struct_mutex);
 		ret = -ENOMEM;
 		goto pre_mutex_err;