Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 449f6615 authored by Chris Wilson's avatar Chris Wilson Committed by Jani Nikula
Browse files

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: dadd481b ("drm/i915/guc: Prepare for nonblocking execbuf submission")
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97978


Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Reviewed-by: default avatarMichał Winiarski <michal.winiarski@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161007065327.24515-4-chris@chris-wilson.co.uk


(cherry picked from commit 5ba89908)
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 61a05870
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -451,6 +451,18 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
	return ret;
	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 */
/* Construct a Work Item and append it to the GuC's Work Queue */
static void guc_wq_item_append(struct i915_guc_client *gc,
static void guc_wq_item_append(struct i915_guc_client *gc,
			       struct drm_i915_gem_request *rq)
			       struct drm_i915_gem_request *rq)
+1 −0
Original line number Original line Diff line number Diff line
@@ -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_init(struct drm_i915_private *dev_priv);
int i915_guc_submission_enable(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);
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_disable(struct drm_i915_private *dev_priv);
void i915_guc_submission_fini(struct drm_i915_private *dev_priv);
void i915_guc_submission_fini(struct drm_i915_private *dev_priv);


+10 −7
Original line number Original line Diff line number Diff line
@@ -627,6 +627,10 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request


	request->ring = ce->ring;
	request->ring = ce->ring;


	ret = intel_lr_context_pin(request->ctx, engine);
	if (ret)
		return ret;

	if (i915.enable_guc_submission) {
	if (i915.enable_guc_submission) {
		/*
		/*
		 * Check that the GuC has space for the request before
		 * 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);
		ret = i915_guc_wq_reserve(request);
		if (ret)
		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);
	ret = intel_ring_begin(request, 0);
	if (ret)
	if (ret)
		goto err_unpin;
		goto err_unreserve;


	if (!ce->initialised) {
	if (!ce->initialised) {
		ret = engine->init_context(request);
		ret = engine->init_context(request);
		if (ret)
		if (ret)
			goto err_unpin;
			goto err_unreserve;


		ce->initialised = true;
		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;
	request->reserved_space -= EXECLISTS_REQUEST_SIZE;
	return 0;
	return 0;


err_unreserve:
	if (i915.enable_guc_submission)
		i915_guc_wq_unreserve(request);
err_unpin:
err_unpin:
	intel_lr_context_unpin(request->ctx, engine);
	intel_lr_context_unpin(request->ctx, engine);
	return ret;
	return ret;