diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 112f8657db21a2610fc15999dd4e8ea477058cde..f37ae104c08ec85bc1d4e98fe844f9cc41d8f199 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -243,6 +243,7 @@ i915_gem_create_context(struct drm_device *dev, struct drm_i915_file_private *file_priv, bool create_vm) { + const bool is_global_default_ctx = file_priv == NULL; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; int ret = 0; @@ -253,6 +254,23 @@ i915_gem_create_context(struct drm_device *dev, if (IS_ERR(ctx)) return ctx; + if (is_global_default_ctx) { + /* We may need to do things with the shrinker which + * require us to immediately switch back to the default + * context. This can cause a problem as pinning the + * default context also requires GTT space which may not + * be available. To avoid this we always pin the default + * context. + */ + ret = i915_gem_obj_ggtt_pin(ctx->obj, + get_context_alignment(dev), + false, false); + if (ret) { + DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); + goto err_destroy; + } + } + if (create_vm) { struct i915_hw_ppgtt *ppgtt = create_vm_for_ctx(dev, ctx); @@ -260,36 +278,19 @@ i915_gem_create_context(struct drm_device *dev, DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", PTR_ERR(ppgtt)); ret = PTR_ERR(ppgtt); - goto err_destroy; + goto err_unpin; } else ctx->vm = &ppgtt->base; /* This case is reserved for the global default context and * should only happen once. */ - if (!file_priv) { + if (is_global_default_ctx) { if (WARN_ON(dev_priv->mm.aliasing_ppgtt)) { ret = -EEXIST; - goto err_destroy; + goto err_unpin; } dev_priv->mm.aliasing_ppgtt = ppgtt; - - /* We may need to do things with the shrinker which - * require us to immediately switch back to the default - * context. This can cause a problem as pinning the - * default context also requires GTT space which may not - * be available. To avoid this we always pin the default - * context. - */ - ret = i915_gem_obj_ggtt_pin(ctx->obj, - get_context_alignment(dev), - false, false); - if (ret) { - DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); - goto err_destroy; - } - - ctx->vm = &dev_priv->mm.aliasing_ppgtt->base; } } else if (USES_ALIASING_PPGTT(dev)) { /* For platforms which only have aliasing PPGTT, we fake the @@ -301,6 +302,9 @@ i915_gem_create_context(struct drm_device *dev, return ctx; +err_unpin: + if (is_global_default_ctx) + i915_gem_object_ggtt_unpin(ctx->obj); err_destroy: i915_gem_context_unreference(ctx); return ERR_PTR(ret);