/** * The default context needs to exist per ring that uses contexts. It stores the * context state of the GPU for applications that don't utilize HW contexts, as * well as an idle case. */ static struct i915_gem_context * i915_gem_create_context(struct drm_i915_private *dev_priv, struct drm_i915_file_private *file_priv) { struct i915_gem_context *ctx; lockdep_assert_held(&dev_priv->drm.struct_mutex); ctx = __create_hw_context(dev_priv, file_priv); if (IS_ERR(ctx)) return ctx; if (USES_FULL_PPGTT(dev_priv)) { struct i915_hw_ppgtt *ppgtt; ppgtt = i915_ppgtt_create(dev_priv, file_priv, ctx->name); if (IS_ERR(ppgtt)) { DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", PTR_ERR(ppgtt)); __destroy_hw_context(ctx, file_priv); return ERR_CAST(ppgtt); } ctx->ppgtt = ppgtt; ctx->desc_template = default_desc_template(dev_priv, ppgtt); } trace_i915_context_create(ctx); return ctx; }
/** * The default context needs to exist per ring that uses contexts. It stores the * context state of the GPU for applications that don't utilize HW contexts, as * well as an idle case. */ static struct intel_context * i915_gem_create_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) { const bool is_global_default_ctx = file_priv == NULL; struct intel_context *ctx; int ret = 0; BUG_ON(!mutex_is_locked(&dev->struct_mutex)); ctx = __create_hw_context(dev, file_priv); if (IS_ERR(ctx)) return ctx; if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) { /* 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->legacy_hw_ctx.rcs_state, get_context_alignment(dev), 0); if (ret) { DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); goto err_destroy; } } if (USES_FULL_PPGTT(dev)) { struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv); if (IS_ERR_OR_NULL(ppgtt)) { DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", PTR_ERR(ppgtt)); ret = PTR_ERR(ppgtt); goto err_unpin; } ctx->ppgtt = ppgtt; } trace_i915_context_create(ctx); return ctx; err_unpin: if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); err_destroy: i915_gem_context_unreference(ctx); return ERR_PTR(ret); }