summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-10-07 07:53:27 +0100
committerJani Nikula <jani.nikula@intel.com>2016-10-10 16:06:44 +0300
commit449f6615473db3a0d16cbafcbe0572ef81872db0 (patch)
tree4c267377bbbae105e16cfd021d8436fe5392a8fe
parent61a05870b939b9c5551817ad65b74194ea84140c (diff)
drm/i915/guc: Unwind GuC workqueue reservation if request construction fails
We reserve space in the GuC workqueue for submitting the request in the future. However, if we fail to construct the request, we need to give that reserved space back to the system. Fixes: dadd481bfe55 ("drm/i915/guc: Prepare for nonblocking execbuf submission") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97978 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Michał Winiarski <michal.winiarski@intel.com> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161007065327.24515-4-chris@chris-wilson.co.uk (cherry picked from commit 5ba899082cbffb779ccb39420fe1718850daf857) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_guc_submission.c12
-rw-r--r--drivers/gpu/drm/i915/intel_guc.h1
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c17
3 files changed, 23 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 43358e18d34c..3106dcc06fe9 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -451,6 +451,18 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
return ret;
}
+void i915_guc_wq_unreserve(struct drm_i915_gem_request *request)
+{
+ const size_t wqi_size = sizeof(struct guc_wq_item);
+ struct i915_guc_client *gc = request->i915->guc.execbuf_client;
+
+ GEM_BUG_ON(READ_ONCE(gc->wq_rsvd) < wqi_size);
+
+ spin_lock(&gc->wq_lock);
+ gc->wq_rsvd -= wqi_size;
+ spin_unlock(&gc->wq_lock);
+}
+
/* Construct a Work Item and append it to the GuC's Work Queue */
static void guc_wq_item_append(struct i915_guc_client *gc,
struct drm_i915_gem_request *rq)
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index b1ba86958811..5cdf7aa75be5 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -160,6 +160,7 @@ extern int intel_guc_resume(struct drm_device *dev);
int i915_guc_submission_init(struct drm_i915_private *dev_priv);
int i915_guc_submission_enable(struct drm_i915_private *dev_priv);
int i915_guc_wq_reserve(struct drm_i915_gem_request *rq);
+void i915_guc_wq_unreserve(struct drm_i915_gem_request *request);
void i915_guc_submission_disable(struct drm_i915_private *dev_priv);
void i915_guc_submission_fini(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 413760b1f1b9..0adb879833ff 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -627,6 +627,10 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request
request->ring = ce->ring;
+ ret = intel_lr_context_pin(request->ctx, engine);
+ if (ret)
+ return ret;
+
if (i915.enable_guc_submission) {
/*
* Check that the GuC has space for the request before
@@ -635,21 +639,17 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request
*/
ret = i915_guc_wq_reserve(request);
if (ret)
- return ret;
+ goto err_unpin;
}
- ret = intel_lr_context_pin(request->ctx, engine);
- if (ret)
- return ret;
-
ret = intel_ring_begin(request, 0);
if (ret)
- goto err_unpin;
+ goto err_unreserve;
if (!ce->initialised) {
ret = engine->init_context(request);
if (ret)
- goto err_unpin;
+ goto err_unreserve;
ce->initialised = true;
}
@@ -664,6 +664,9 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request
request->reserved_space -= EXECLISTS_REQUEST_SIZE;
return 0;
+err_unreserve:
+ if (i915.enable_guc_submission)
+ i915_guc_wq_unreserve(request);
err_unpin:
intel_lr_context_unpin(request->ctx, engine);
return ret;