Beispiel #1
0
/**
 * i915_gem_context_create_gvt - create a GVT GEM context
 * @dev: drm device *
 *
 * This function is used to create a GVT specific GEM context.
 *
 * Returns:
 * pointer to i915_gem_context on success, error pointer if failed
 *
 */
struct i915_gem_context *
i915_gem_context_create_gvt(struct drm_device *dev)
{
	struct i915_gem_context *ctx;
	int ret;

	if (!IS_ENABLED(CONFIG_DRM_I915_GVT))
		return ERR_PTR(-ENODEV);

	ret = i915_mutex_lock_interruptible(dev);
	if (ret)
		return ERR_PTR(ret);

	ctx = __create_hw_context(to_i915(dev), NULL);
	if (IS_ERR(ctx))
		goto out;

	ctx->file_priv = ERR_PTR(-EBADF);
	i915_gem_context_set_closed(ctx); /* not user accessible */
	i915_gem_context_clear_bannable(ctx);
	i915_gem_context_set_force_single_submission(ctx);
	if (!i915.enable_guc_submission)
		ctx->ring_size = 512 * PAGE_SIZE; /* Max ring buffer size */

	GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
out:
	mutex_unlock(&dev->struct_mutex);
	return ctx;
}
Beispiel #2
0
/**
 * 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);
}