With the introduction of ctx->engines[] we allow multiple logical contexts to be used on the same engine (e.g. with virtual engines). According to bspec, aach logical context requires a unique tag in order for context-switching to occur correctly between them. [Simple experiments show that it is not so easy to trick the HW into performing a lite-restore with matching logical IDs, though my memory from early Broadwell experiments do suggest that it should be generating lite-restores.] We only need to keep a unique tag for the active lifetime of the context, and for as long as we need to identify that context. The HW uses the tag to determine if it should use a lite-restore (why not the LRCA?) and passes the tag back for various status identifies. The only status we need to track is for OA, so when using perf, we assign the specific context a unique tag. v2: Calculate required number of tags to fill ELSP. Fixes: 976b55f0e1db ("drm/i915: Allow a context to define its set of engines") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111895 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191004134015.13204-14-chris@chris-wilson.co.uk
104 lines
1.8 KiB
C
104 lines
1.8 KiB
C
/*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Copyright © 2016 Intel Corporation
|
|
*/
|
|
|
|
#include "mock_context.h"
|
|
#include "selftests/mock_gtt.h"
|
|
|
|
struct i915_gem_context *
|
|
mock_context(struct drm_i915_private *i915,
|
|
const char *name)
|
|
{
|
|
struct i915_gem_context *ctx;
|
|
struct i915_gem_engines *e;
|
|
|
|
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
|
if (!ctx)
|
|
return NULL;
|
|
|
|
kref_init(&ctx->ref);
|
|
INIT_LIST_HEAD(&ctx->link);
|
|
ctx->i915 = i915;
|
|
|
|
mutex_init(&ctx->engines_mutex);
|
|
e = default_engines(ctx);
|
|
if (IS_ERR(e))
|
|
goto err_free;
|
|
RCU_INIT_POINTER(ctx->engines, e);
|
|
|
|
INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
|
|
mutex_init(&ctx->mutex);
|
|
|
|
if (name) {
|
|
struct i915_ppgtt *ppgtt;
|
|
|
|
ctx->name = kstrdup(name, GFP_KERNEL);
|
|
if (!ctx->name)
|
|
goto err_put;
|
|
|
|
ppgtt = mock_ppgtt(i915, name);
|
|
if (!ppgtt)
|
|
goto err_put;
|
|
|
|
__set_ppgtt(ctx, &ppgtt->vm);
|
|
i915_vm_put(&ppgtt->vm);
|
|
}
|
|
|
|
return ctx;
|
|
|
|
err_free:
|
|
kfree(ctx);
|
|
return NULL;
|
|
|
|
err_put:
|
|
i915_gem_context_set_closed(ctx);
|
|
i915_gem_context_put(ctx);
|
|
return NULL;
|
|
}
|
|
|
|
void mock_context_close(struct i915_gem_context *ctx)
|
|
{
|
|
context_close(ctx);
|
|
}
|
|
|
|
void mock_init_contexts(struct drm_i915_private *i915)
|
|
{
|
|
init_contexts(i915);
|
|
}
|
|
|
|
struct i915_gem_context *
|
|
live_context(struct drm_i915_private *i915, struct drm_file *file)
|
|
{
|
|
struct i915_gem_context *ctx;
|
|
int err;
|
|
|
|
lockdep_assert_held(&i915->drm.struct_mutex);
|
|
|
|
ctx = i915_gem_create_context(i915, 0);
|
|
if (IS_ERR(ctx))
|
|
return ctx;
|
|
|
|
err = gem_context_register(ctx, file->driver_priv);
|
|
if (err < 0)
|
|
goto err_ctx;
|
|
|
|
return ctx;
|
|
|
|
err_ctx:
|
|
context_close(ctx);
|
|
return ERR_PTR(err);
|
|
}
|
|
|
|
struct i915_gem_context *
|
|
kernel_context(struct drm_i915_private *i915)
|
|
{
|
|
return i915_gem_context_create_kernel(i915, I915_PRIORITY_NORMAL);
|
|
}
|
|
|
|
void kernel_context_close(struct i915_gem_context *ctx)
|
|
{
|
|
context_close(ctx);
|
|
}
|