summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c124
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.h30
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c29
-rw-r--r--include/uapi/drm/i915_drm.h3
4 files changed, 129 insertions, 57 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 1ddaa8a58855..e9a1afb07912 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -926,11 +926,66 @@ out:
return 0;
}
+static bool ctx_has_veng(struct i915_gem_context *ctx)
+{
+ return ctx->engines && ctx->engines[0] &&
+ (ctx->engines[0]->flags & I915_ENGINE_IS_VIRTUAL);
+}
+
+static bool ctx_has_map(struct i915_gem_context *ctx)
+{
+ return ctx->engines;
+}
+
+static struct intel_context *
+ctx_sseu_lookup_context(struct i915_gem_context *ctx,
+ const struct drm_i915_gem_context_param_sseu *user_sseu)
+{
+ struct intel_engine_cs *engine = NULL;
+ struct intel_context *ce = NULL;
+
+ if (user_sseu->flags & I915_SSEU_USE_ENGINE_MAP_INDEX) {
+ struct virtual_engine *ve;
+
+ if (!ctx_has_map(ctx) ||
+ user_sseu->engine_class != (u16)I915_ENGINE_CLASS_INVALID)
+ return NULL;
+
+ if (user_sseu->engine_instance == 0) {
+ unsigned int i;
+
+ if (!ctx_has_veng(ctx))
+ return NULL;
+
+ for (i = 1; i < ctx->nengine; i++) {
+ if (ctx->engines[i]->class != RENDER_CLASS)
+ return NULL;
+ }
+
+ ve = to_virtual_engine(ctx->engines[0]);
+ ce = &ve->context;
+ } else {
+ if (user_sseu->engine_instance >= ctx->nengine)
+ return NULL;
+
+ engine = ctx->engines[user_sseu->engine_instance];
+ }
+ } else {
+ engine = intel_engine_lookup_user(ctx->i915,
+ user_sseu->engine_class,
+ user_sseu->engine_instance);
+ }
+
+ if (!ce && engine)
+ return to_intel_context(ctx, engine);
+ else
+ return ce;
+}
+
static int get_sseu(struct i915_gem_context *ctx,
struct drm_i915_gem_context_param *args)
{
struct drm_i915_gem_context_param_sseu user_sseu;
- struct intel_engine_cs *engine;
struct intel_context *ce;
int ret;
@@ -943,13 +998,10 @@ static int get_sseu(struct i915_gem_context *ctx,
sizeof(user_sseu)))
return -EFAULT;
- if (user_sseu.flags || user_sseu.rsvd)
+ if (user_sseu.rsvd)
return -EINVAL;
- engine = intel_engine_lookup_user(ctx->i915,
- user_sseu.engine_class,
- user_sseu.engine_instance);
- if (!engine)
+ if (user_sseu.flags & ~I915_SSEU_USE_ENGINE_MAP_INDEX)
return -EINVAL;
/* Only use for mutex here is to serialize get_param and set_param. */
@@ -957,7 +1009,11 @@ static int get_sseu(struct i915_gem_context *ctx,
if (ret)
return ret;
- ce = to_intel_context(ctx, engine);
+ ce = ctx_sseu_lookup_context(ctx, &user_sseu);
+ if (!ce) {
+ ret = -EINVAL;
+ goto err_unlock;
+ }
user_sseu.slice_mask = ce->sseu.slice_mask;
user_sseu.subslice_mask = ce->sseu.subslice_mask;
@@ -974,6 +1030,11 @@ out:
args->size = sizeof(user_sseu);
return 0;
+
+err_unlock:
+ mutex_unlock(&ctx->i915->drm.struct_mutex);
+
+ return ret;
}
int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
@@ -1261,11 +1322,10 @@ static int gen8_emit_rpcs_config(struct i915_request *rq,
}
static int
-gen8_modify_rpcs_gpu(struct intel_context *ce,
- struct intel_engine_cs *engine,
- struct intel_sseu sseu)
+gen8_modify_rpcs_gpu(struct intel_context *ce, struct intel_sseu sseu)
{
- struct drm_i915_private *i915 = engine->i915;
+ struct drm_i915_private *i915 = ce->gem_context->i915;
+ struct intel_engine_cs *engine;
struct i915_request *rq, *prev;
intel_wakeref_t wakeref;
int ret;
@@ -1274,6 +1334,13 @@ gen8_modify_rpcs_gpu(struct intel_context *ce,
lockdep_assert_held(&i915->drm.struct_mutex);
+ if (ce->owner->flags & I915_ENGINE_IS_VIRTUAL)
+ engine = ce->gem_context->engines[1];
+ else
+ engine = ce->owner;
+
+ GEM_BUG_ON(engine->class != RENDER_CLASS);
+
/* Submitting requests etc needs the hw awake. */
wakeref = intel_runtime_pm_get(i915);
@@ -1321,17 +1388,15 @@ out_put:
}
static int
-i915_gem_context_reconfigure_sseu(struct i915_gem_context *ctx,
- struct intel_engine_cs *engine,
+i915_gem_context_reconfigure_sseu(struct intel_context *ce,
struct intel_sseu sseu)
{
- struct intel_context *ce = to_intel_context(ctx, engine);
+ struct drm_i915_private *i915 = ce->gem_context->i915;
int ret;
- GEM_BUG_ON(INTEL_GEN(ctx->i915) < 8);
- GEM_BUG_ON(engine->id != RCS);
+ GEM_BUG_ON(INTEL_GEN(i915) < 8);
- ret = mutex_lock_interruptible(&ctx->i915->drm.struct_mutex);
+ ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
if (ret)
return ret;
@@ -1345,13 +1410,13 @@ i915_gem_context_reconfigure_sseu(struct i915_gem_context *ctx,
* will be configured on pinning.
*/
if (ce->pin_count)
- ret = gen8_modify_rpcs_gpu(ce, engine, sseu);
+ ret = gen8_modify_rpcs_gpu(ce, sseu);
if (!ret)
ce->sseu = sseu;
out:
- mutex_unlock(&ctx->i915->drm.struct_mutex);
+ mutex_unlock(&i915->drm.struct_mutex);
return ret;
}
@@ -1461,7 +1526,7 @@ static int set_sseu(struct i915_gem_context *ctx,
{
struct drm_i915_private *i915 = ctx->i915;
struct drm_i915_gem_context_param_sseu user_sseu;
- struct intel_engine_cs *engine;
+ struct intel_context *ce;
struct intel_sseu sseu;
int ret;
@@ -1475,24 +1540,29 @@ static int set_sseu(struct i915_gem_context *ctx,
sizeof(user_sseu)))
return -EFAULT;
- if (user_sseu.flags || user_sseu.rsvd)
+ if (user_sseu.rsvd)
return -EINVAL;
- engine = intel_engine_lookup_user(i915,
- user_sseu.engine_class,
- user_sseu.engine_instance);
- if (!engine)
+ if (user_sseu.flags & ~I915_SSEU_USE_ENGINE_MAP_INDEX)
+ return -EINVAL;
+
+ ce = ctx_sseu_lookup_context(ctx, &user_sseu);
+ if (!ce)
return -EINVAL;
/* Only render engine supports RPCS configuration. */
- if (engine->class != RENDER_CLASS)
+ if (ce->owner->flags & I915_ENGINE_IS_VIRTUAL) {
+ if (ctx->engines[1]->class != RENDER_CLASS)
+ return -ENODEV;
+ } else if (ce->owner->class != RENDER_CLASS) {
return -ENODEV;
+ }
ret = user_to_context_sseu(i915, &user_sseu, &sseu);
if (ret)
return ret;
- ret = i915_gem_context_reconfigure_sseu(ctx, engine, sseu);
+ ret = i915_gem_context_reconfigure_sseu(ce, sseu);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 778a18a6c08e..328e16001cfd 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -225,6 +225,36 @@ struct i915_gem_context {
struct list_head handles_list;
};
+struct virtual_engine {
+ struct intel_engine_cs base;
+
+ struct intel_context context;
+ struct kref kref;
+
+ struct intel_engine_cs *bound;
+
+ struct i915_request *request;
+ struct ve_node {
+ struct rb_node rb;
+ int prio;
+ } nodes[I915_NUM_ENGINES];
+
+ struct ve_bond {
+ struct intel_engine_cs *master;
+ unsigned int sibling_mask;
+ } *bonds;
+ unsigned int nbond;
+
+ unsigned int count;
+ struct intel_engine_cs *siblings[0];
+};
+
+static inline struct virtual_engine *
+to_virtual_engine(struct intel_engine_cs *engine)
+{
+ return container_of(engine, struct virtual_engine, base);
+}
+
static inline bool i915_gem_context_is_closed(const struct i915_gem_context *ctx)
{
return test_bit(CONTEXT_CLOSED, &ctx->flags);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 1f5e687f3b7f..c80624c01fa5 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -164,35 +164,6 @@
#define WA_TAIL_DWORDS 2
#define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS)
-struct virtual_engine {
- struct intel_engine_cs base;
-
- struct intel_context context;
- struct kref kref;
-
- struct intel_engine_cs *bound;
-
- struct i915_request *request;
- struct ve_node {
- struct rb_node rb;
- int prio;
- } nodes[I915_NUM_ENGINES];
-
- struct ve_bond {
- struct intel_engine_cs *master;
- unsigned int sibling_mask;
- } *bonds;
- unsigned int nbond;
-
- unsigned int count;
- struct intel_engine_cs *siblings[0];
-};
-
-static struct virtual_engine *to_virtual_engine(struct intel_engine_cs *engine)
-{
- return container_of(engine, struct virtual_engine, base);
-}
-
static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
struct intel_engine_cs *engine,
struct intel_context *ce);
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 8d10683e8430..49651114e40a 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1619,9 +1619,10 @@ struct drm_i915_gem_context_param_sseu {
__u16 engine_instance;
/*
- * Unused for now. Must be cleared to zero.
+ * Set of flags controlling the ioctl behaviour.
*/
__u32 flags;
+#define I915_SSEU_USE_ENGINE_MAP_INDEX (1 << 0)
/*
* Mask of slices to enable for the context. Valid values are a subset