diff options
author | Ben Widawsky <ben@bwidawsk.net> | 2013-10-14 10:01:37 -0700 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-10-16 11:08:30 +0200 |
commit | 71b76d004f48b4b217a3895bfe058e2e5eefed39 (patch) | |
tree | f0432e7b6f81d75f22519be57b8312f620a75b02 /drivers/gpu/drm/i915 | |
parent | 3d57e5bd1284f44e325f3a52d966259ed42f9e05 (diff) | |
download | blackbird-obmc-linux-71b76d004f48b4b217a3895bfe058e2e5eefed39.tar.gz blackbird-obmc-linux-71b76d004f48b4b217a3895bfe058e2e5eefed39.zip |
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: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 1a877a547290..cc619c138777 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -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 * default context. */ - dev_priv->ring[RCS].default_context = ctx; ret = i915_gem_obj_ggtt_pin(ctx->obj, CONTEXT_ALIGN, false, false); if (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) goto err_unpin; } + dev_priv->ring[RCS].default_context = ctx; + DRM_DEBUG_DRIVER("Default HW context loaded\n"); return 0; @@ -288,16 +289,24 @@ void i915_gem_context_fini(struct drm_device *dev) * other code, leading to spurious errors. */ intel_gpu_reset(dev); - i915_gem_object_unpin(dctx->obj); - /* When default context is created and switched to, base object refcount * will be 2 (+1 from object creation and +1 from do_switch()). * 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 offset the do_switch part, so that i915_gem_context_unreference() * 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); + 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) |