Commit f1c4d157 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Fix up the inverse mapping for default ctx->engines[]

The order in which we store the engines inside default_engines() for the
legacy ctx->engines[] has to match the legacy I915_EXEC_RING selector
mapping in execbuf::user_map. If we present VCS2 as being the second
instance of the video engine, legacy userspace calls that I915_EXEC_BSD2
and so we need to insert it into the second video slot.

v2: Record the legacy mapping (hopefully we can remove this need in the
future)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111328


Fixes: 2edda80d ("drm/i915: Rename engines to match their user interface")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> #v1
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190808110612.23539-2-chris@chris-wilson.co.uk
parent 38775829
Loading
Loading
Loading
Loading
+4 −3
Original line number Original line Diff line number Diff line
@@ -159,7 +159,7 @@ lookup_user_engine(struct i915_gem_context *ctx,
		if (!engine)
		if (!engine)
			return ERR_PTR(-EINVAL);
			return ERR_PTR(-EINVAL);


		idx = engine->id;
		idx = engine->legacy_idx;
	} else {
	} else {
		idx = ci->engine_instance;
		idx = ci->engine_instance;
	}
	}
@@ -279,6 +279,7 @@ static void free_engines_rcu(struct rcu_head *rcu)


static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
{
{
	const struct intel_gt *gt = &ctx->i915->gt;
	struct intel_engine_cs *engine;
	struct intel_engine_cs *engine;
	struct i915_gem_engines *e;
	struct i915_gem_engines *e;
	enum intel_engine_id id;
	enum intel_engine_id id;
@@ -288,7 +289,7 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(-ENOMEM);


	init_rcu_head(&e->rcu);
	init_rcu_head(&e->rcu);
	for_each_engine(engine, ctx->i915, id) {
	for_each_engine(engine, gt, id) {
		struct intel_context *ce;
		struct intel_context *ce;


		ce = intel_context_create(ctx, engine);
		ce = intel_context_create(ctx, engine);
@@ -298,8 +299,8 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
		}
		}


		e->engines[id] = ce;
		e->engines[id] = ce;
		e->num_engines = id + 1;
	}
	}
	e->num_engines = id;


	return e;
	return e;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -23,7 +23,7 @@ igt_request_alloc(struct i915_gem_context *ctx, struct intel_engine_cs *engine)
	 * GGTT space, so do this first before we reserve a seqno for
	 * GGTT space, so do this first before we reserve a seqno for
	 * ourselves.
	 * ourselves.
	 */
	 */
	ce = i915_gem_context_get_engine(ctx, engine->id);
	ce = i915_gem_context_get_engine(ctx, engine->legacy_idx);
	if (IS_ERR(ce))
	if (IS_ERR(ce))
		return ERR_CAST(ce);
		return ERR_CAST(ce);


+3 −0
Original line number Original line Diff line number Diff line
@@ -264,8 +264,11 @@ struct intel_engine_cs {
	char name[INTEL_ENGINE_CS_MAX_NAME];
	char name[INTEL_ENGINE_CS_MAX_NAME];


	enum intel_engine_id id;
	enum intel_engine_id id;
	enum intel_engine_id legacy_idx;

	unsigned int hw_id;
	unsigned int hw_id;
	unsigned int guc_id;
	unsigned int guc_id;

	intel_engine_mask_t mask;
	intel_engine_mask_t mask;


	u8 class;
	u8 class;
+52 −0
Original line number Original line Diff line number Diff line
@@ -142,8 +142,57 @@ const char *intel_engine_class_repr(u8 class)
	return uabi_names[class];
	return uabi_names[class];
}
}


struct legacy_ring {
	struct intel_gt *gt;
	u8 class;
	u8 instance;
};

static int legacy_ring_idx(const struct legacy_ring *ring)
{
	static const struct {
		u8 base, max;
	} map[] = {
		[RENDER_CLASS] = { RCS0, 1 },
		[COPY_ENGINE_CLASS] = { BCS0, 1 },
		[VIDEO_DECODE_CLASS] = { VCS0, I915_MAX_VCS },
		[VIDEO_ENHANCEMENT_CLASS] = { VECS0, I915_MAX_VECS },
	};

	if (GEM_DEBUG_WARN_ON(ring->class >= ARRAY_SIZE(map)))
		return -1;

	if (GEM_DEBUG_WARN_ON(ring->instance >= map[ring->class].max))
		return -1;

	return map[ring->class].base + ring->instance;
}

static void add_legacy_ring(struct legacy_ring *ring,
			    struct intel_engine_cs *engine)
{
	int idx;

	if (engine->gt != ring->gt || engine->class != ring->class) {
		ring->gt = engine->gt;
		ring->class = engine->class;
		ring->instance = 0;
	}

	idx = legacy_ring_idx(ring);
	if (unlikely(idx == -1))
		return;

	GEM_BUG_ON(idx >= ARRAY_SIZE(ring->gt->engine));
	ring->gt->engine[idx] = engine;
	ring->instance++;

	engine->legacy_idx = idx;
}

void intel_engines_driver_register(struct drm_i915_private *i915)
void intel_engines_driver_register(struct drm_i915_private *i915)
{
{
	struct legacy_ring ring = {};
	u8 uabi_instances[4] = {};
	u8 uabi_instances[4] = {};
	struct list_head *it, *next;
	struct list_head *it, *next;
	struct rb_node **p, *prev;
	struct rb_node **p, *prev;
@@ -179,6 +228,9 @@ void intel_engines_driver_register(struct drm_i915_private *i915)
						    engine->uabi_class,
						    engine->uabi_class,
						    engine->uabi_instance) != engine);
						    engine->uabi_instance) != engine);


		/* Fix up the mapping to match default execbuf::user_map[] */
		add_legacy_ring(&ring, engine);

		prev = &engine->uabi_node;
		prev = &engine->uabi_node;
		p = &prev->rb_right;
		p = &prev->rb_right;
	}
	}
+1 −0
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ struct intel_gt {


	u32 pm_guc_events;
	u32 pm_guc_events;


	struct intel_engine_cs *engine[I915_NUM_ENGINES];
	struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
	struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
					    [MAX_ENGINE_INSTANCE + 1];
					    [MAX_ENGINE_INSTANCE + 1];
};
};
Loading