static struct i915_hw_context *
create_hw_context(struct drm_device *dev,
		  struct drm_i915_file_private *file_priv)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct i915_hw_context *ctx;
	int ret;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (ctx == NULL)
		return ERR_PTR(-ENOMEM);

	kref_init(&ctx->ref);
	ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
	INIT_LIST_HEAD(&ctx->link);
	if (ctx->obj == NULL) {
		kfree(ctx);
		DRM_DEBUG_DRIVER("Context object allocated failed\n");
		return ERR_PTR(-ENOMEM);
	}

	if (INTEL_INFO(dev)->gen >= 7) {
		ret = i915_gem_object_set_cache_level(ctx->obj,
						      I915_CACHE_L3_LLC);
		/* Failure shouldn't ever happen this early */
		if (WARN_ON(ret))
			goto err_out;
	}

	/* The ring associated with the context object is handled by the normal
	 * object tracking code. We give an initial ring value simple to pass an
	 * assertion in the context switch code.
	 */
	ctx->ring = &dev_priv->ring[RCS];
	list_add_tail(&ctx->link, &dev_priv->context_list);

	/* Default context will never have a file_priv */
	if (file_priv == NULL)
		return ctx;

	ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
			GFP_KERNEL);
	if (ret < 0)
		goto err_out;

	ctx->file_priv = file_priv;
	ctx->id = ret;
	/* NB: Mark all slices as needing a remap so that when the context first
	 * loads it will restore whatever remap state already exists. If there
	 * is no remap info, it will be a NOP. */
	ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;

	return ctx;

err_out:
	i915_gem_context_unreference(ctx);
	return ERR_PTR(ret);
}
Пример #2
0
static struct intel_context *
__create_hw_context(struct drm_device *dev,
                    struct drm_i915_file_private *file_priv)
{
    struct drm_i915_private *dev_priv = dev->dev_private;
    struct intel_context *ctx;
    int ret;

    ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    if (ctx == NULL)
        return ERR_PTR(-ENOMEM);

    kref_init(&ctx->ref);
    list_add_tail(&ctx->link, &dev_priv->context_list);

    if (dev_priv->hw_context_size) {
        struct drm_i915_gem_object *obj =
            i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
        if (IS_ERR(obj)) {
            ret = PTR_ERR(obj);
            goto err_out;
        }
        ctx->legacy_hw_ctx.rcs_state = obj;
    }

    /* Default context will never have a file_priv */
    if (file_priv != NULL) {
        ret = idr_alloc(&file_priv->context_idr, ctx,
                        DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
        if (ret < 0)
            goto err_out;
    } else
        ret = DEFAULT_CONTEXT_HANDLE;

    ctx->file_priv = file_priv;
    ctx->user_handle = ret;
    /* NB: Mark all slices as needing a remap so that when the context first
     * loads it will restore whatever remap state already exists. If there
     * is no remap info, it will be a NOP. */
    ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;

    return ctx;

err_out:
    i915_gem_context_unreference(ctx);
    return ERR_PTR(ret);
}