Commit 71b76d00 authored by Ben Widawsky's avatar Ben Widawsky Committed by Daniel Vetter

drm/i915: cleanup context fini

I had this lying around from he original PPGTT series, and thought we
might try to get it in by itself.

With the introduction of context refcounting we never explicitly
ref/unref the backing object. As such, the previous fix was a bit wonky.

Aside from fixing the above, this patch also puts us in good shape for
an upcoming patch which allows a failure to occur in between
context_init and the first do_switch.

CC: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: default avatarBen Widawsky <ben@bwidawsk.net>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 3d57e5bd
...@@ -220,7 +220,6 @@ static int create_default_context(struct drm_i915_private *dev_priv) ...@@ -220,7 +220,6 @@ static int create_default_context(struct drm_i915_private *dev_priv)
* may not be available. To avoid this we always pin the * may not be available. To avoid this we always pin the
* default context. * default context.
*/ */
dev_priv->ring[RCS].default_context = ctx;
ret = i915_gem_obj_ggtt_pin(ctx->obj, CONTEXT_ALIGN, false, false); ret = i915_gem_obj_ggtt_pin(ctx->obj, CONTEXT_ALIGN, false, false);
if (ret) { if (ret) {
DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
...@@ -233,6 +232,8 @@ static int create_default_context(struct drm_i915_private *dev_priv) ...@@ -233,6 +232,8 @@ static int create_default_context(struct drm_i915_private *dev_priv)
goto err_unpin; goto err_unpin;
} }
dev_priv->ring[RCS].default_context = ctx;
DRM_DEBUG_DRIVER("Default HW context loaded\n"); DRM_DEBUG_DRIVER("Default HW context loaded\n");
return 0; return 0;
...@@ -288,16 +289,24 @@ void i915_gem_context_fini(struct drm_device *dev) ...@@ -288,16 +289,24 @@ void i915_gem_context_fini(struct drm_device *dev)
* other code, leading to spurious errors. */ * other code, leading to spurious errors. */
intel_gpu_reset(dev); intel_gpu_reset(dev);
i915_gem_object_unpin(dctx->obj);
/* When default context is created and switched to, base object refcount /* When default context is created and switched to, base object refcount
* will be 2 (+1 from object creation and +1 from do_switch()). * will be 2 (+1 from object creation and +1 from do_switch()).
* i915_gem_context_fini() will be called after gpu_idle() has switched * i915_gem_context_fini() will be called after gpu_idle() has switched
* to default context. So we need to unreference the base object once * to default context. So we need to unreference the base object once
* to offset the do_switch part, so that i915_gem_context_unreference() * to offset the do_switch part, so that i915_gem_context_unreference()
* can then free the base object correctly. */ * can then free the base object correctly. */
drm_gem_object_unreference(&dctx->obj->base); WARN_ON(!dev_priv->ring[RCS].last_context);
if (dev_priv->ring[RCS].last_context == dctx) {
/* Fake switch to NULL context */
WARN_ON(dctx->obj->active);
i915_gem_object_unpin(dctx->obj);
i915_gem_context_unreference(dctx);
}
i915_gem_object_unpin(dctx->obj);
i915_gem_context_unreference(dctx); i915_gem_context_unreference(dctx);
dev_priv->ring[RCS].default_context = NULL;
dev_priv->ring[RCS].last_context = NULL;
} }
static int context_idr_cleanup(int id, void *p, void *data) static int context_idr_cleanup(int id, void *p, void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment