Commit 750e76b4 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/gt: Move the [class][inst] lookup for engines onto the GT



To maintain a fast lookup from a GT centric irq handler, we want the
engine lookup tables on the intel_gt. To avoid having multiple copies of
the same multi-dimension lookup table, move the generic user engine
lookup into an rbtree (for fast and flexible indexing).

v2: Split uabi_instance cf uabi_class
v3: Set uabi_class/uabi_instance after collating all engines to provide a
stable uabi across parallel unordered construction.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20190806124300.24945-2-chris@chris-wilson.co.uk
parent c29579d2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -72,9 +72,10 @@ obj-y += gt/
gt-y += \
	gt/intel_breadcrumbs.o \
	gt/intel_context.o \
	gt/intel_engine_pool.o \
	gt/intel_engine_cs.o \
	gt/intel_engine_pool.o \
	gt/intel_engine_pm.o \
	gt/intel_engine_user.o \
	gt/intel_gt.o \
	gt/intel_gt_pm.o \
	gt/intel_hangcheck.o \
+2 −1
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@
#include <drm/i915_drm.h>

#include "gt/intel_lrc_reg.h"
#include "gt/intel_engine_user.h"

#include "i915_gem_context.h"
#include "i915_globals.h"
@@ -1729,7 +1730,7 @@ get_engines(struct i915_gem_context *ctx,

		if (e->engines[n]) {
			ci.engine_class = e->engines[n]->engine->uabi_class;
			ci.engine_instance = e->engines[n]->engine->instance;
			ci.engine_instance = e->engines[n]->engine->uabi_instance;
		}

		if (copy_to_user(&user->engines[n], &ci, sizeof(ci))) {
+0 −6
Original line number Diff line number Diff line
@@ -122,8 +122,6 @@ hangcheck_action_to_str(const enum intel_engine_hangcheck_action a)
	return "unknown";
}

void intel_engines_set_scheduler_caps(struct drm_i915_private *i915);

static inline unsigned int
execlists_num_ports(const struct intel_engine_execlists * const execlists)
{
@@ -422,7 +420,6 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine);
bool intel_engines_are_idle(struct intel_gt *gt);

void intel_engines_reset_default_submission(struct intel_gt *gt);
unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915);

bool intel_engine_can_store_dword(struct intel_engine_cs *engine);

@@ -431,9 +428,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
		       struct drm_printer *m,
		       const char *header, ...);

struct intel_engine_cs *
intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);

static inline void intel_engine_context_in(struct intel_engine_cs *engine)
{
	unsigned long flags;
+15 −94
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "intel_engine.h"
#include "intel_engine_pm.h"
#include "intel_engine_pool.h"
#include "intel_engine_user.h"
#include "intel_context.h"
#include "intel_lrc.h"
#include "intel_reset.h"
@@ -286,9 +287,7 @@ static void intel_engine_sanitize_mmio(struct intel_engine_cs *engine)
	intel_engine_set_hwsp_writemask(engine, ~0u);
}

static int
intel_engine_setup(struct drm_i915_private *dev_priv,
		   enum intel_engine_id id)
static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
{
	const struct engine_info *info = &intel_engines[id];
	struct intel_engine_cs *engine;
@@ -304,10 +303,9 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
	if (GEM_DEBUG_WARN_ON(info->instance > MAX_ENGINE_INSTANCE))
		return -EINVAL;

	if (GEM_DEBUG_WARN_ON(dev_priv->engine_class[info->class][info->instance]))
	if (GEM_DEBUG_WARN_ON(gt->engine_class[info->class][info->instance]))
		return -EINVAL;

	GEM_BUG_ON(dev_priv->engine[id]);
	engine = kzalloc(sizeof(*engine), GFP_KERNEL);
	if (!engine)
		return -ENOMEM;
@@ -316,12 +314,12 @@ intel_engine_setup(struct drm_i915_private *dev_priv,

	engine->id = id;
	engine->mask = BIT(id);
	engine->i915 = dev_priv;
	engine->gt = &dev_priv->gt;
	engine->uncore = &dev_priv->uncore;
	engine->i915 = gt->i915;
	engine->gt = gt;
	engine->uncore = gt->uncore;
	__sprint_engine_name(engine->name, info);
	engine->hw_id = engine->guc_id = info->hw_id;
	engine->mmio_base = __engine_mmio_base(dev_priv, info->mmio_bases);
	engine->mmio_base = __engine_mmio_base(gt->i915, info->mmio_bases);
	engine->class = info->class;
	engine->instance = info->instance;

@@ -331,14 +329,12 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
	 */
	engine->destroy = (typeof(engine->destroy))kfree;

	engine->uabi_class = intel_engine_classes[info->class].uabi_class;

	engine->context_size = intel_engine_context_size(dev_priv,
	engine->context_size = intel_engine_context_size(gt->i915,
							 engine->class);
	if (WARN_ON(engine->context_size > BIT(20)))
		engine->context_size = 0;
	if (engine->context_size)
		DRIVER_CAPS(dev_priv)->has_logical_contexts = true;
		DRIVER_CAPS(gt->i915)->has_logical_contexts = true;

	/* Nothing to do here, execute in order of dependencies */
	engine->schedule = NULL;
@@ -350,8 +346,11 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
	/* Scrub mmio state on takeover */
	intel_engine_sanitize_mmio(engine);

	dev_priv->engine_class[info->class][info->instance] = engine;
	dev_priv->engine[id] = engine;
	gt->engine_class[info->class][info->instance] = engine;

	intel_engine_add_user(engine);
	gt->i915->engine[id] = engine;

	return 0;
}

@@ -434,7 +433,7 @@ int intel_engines_init_mmio(struct drm_i915_private *i915)
		if (!HAS_ENGINE(i915, i))
			continue;

		err = intel_engine_setup(i915, i);
		err = intel_engine_setup(&i915->gt, i);
		if (err)
			goto cleanup;

@@ -677,47 +676,6 @@ cleanup:
	return err;
}

void intel_engines_set_scheduler_caps(struct drm_i915_private *i915)
{
	static const struct {
		u8 engine;
		u8 sched;
	} map[] = {
#define MAP(x, y) { ilog2(I915_ENGINE_##x), ilog2(I915_SCHEDULER_CAP_##y) }
		MAP(HAS_PREEMPTION, PREEMPTION),
		MAP(HAS_SEMAPHORES, SEMAPHORES),
		MAP(SUPPORTS_STATS, ENGINE_BUSY_STATS),
#undef MAP
	};
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	u32 enabled, disabled;

	enabled = 0;
	disabled = 0;
	for_each_engine(engine, i915, id) { /* all engines must agree! */
		int i;

		if (engine->schedule)
			enabled |= (I915_SCHEDULER_CAP_ENABLED |
				    I915_SCHEDULER_CAP_PRIORITY);
		else
			disabled |= (I915_SCHEDULER_CAP_ENABLED |
				     I915_SCHEDULER_CAP_PRIORITY);

		for (i = 0; i < ARRAY_SIZE(map); i++) {
			if (engine->flags & BIT(map[i].engine))
				enabled |= BIT(map[i].sched);
			else
				disabled |= BIT(map[i].sched);
		}
	}

	i915->caps.scheduler = enabled & ~disabled;
	if (!(i915->caps.scheduler & I915_SCHEDULER_CAP_ENABLED))
		i915->caps.scheduler = 0;
}

struct measure_breadcrumb {
	struct i915_request rq;
	struct intel_timeline timeline;
@@ -1187,20 +1145,6 @@ bool intel_engine_can_store_dword(struct intel_engine_cs *engine)
	}
}

unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915)
{
	struct intel_engine_cs *engine;
	enum intel_engine_id id;
	unsigned int which;

	which = 0;
	for_each_engine(engine, i915, id)
		if (engine->default_state)
			which |= BIT(engine->uabi_class);

	return which;
}

static int print_sched_attr(struct drm_i915_private *i915,
			    const struct i915_sched_attr *attr,
			    char *buf, int x, int len)
@@ -1498,29 +1442,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
	intel_engine_print_breadcrumbs(engine, m);
}

static u8 user_class_map[] = {
	[I915_ENGINE_CLASS_RENDER] = RENDER_CLASS,
	[I915_ENGINE_CLASS_COPY] = COPY_ENGINE_CLASS,
	[I915_ENGINE_CLASS_VIDEO] = VIDEO_DECODE_CLASS,
	[I915_ENGINE_CLASS_VIDEO_ENHANCE] = VIDEO_ENHANCEMENT_CLASS,
};

struct intel_engine_cs *
intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
{
	if (class >= ARRAY_SIZE(user_class_map))
		return NULL;

	class = user_class_map[class];

	GEM_BUG_ON(class > MAX_ENGINE_CLASS);

	if (instance > MAX_ENGINE_INSTANCE)
		return NULL;

	return i915->engine_class[class][instance];
}

/**
 * intel_enable_engine_stats() - Enable engine busy tracking on engine
 * @engine: engine to enable stats collection
+7 −2
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/llist.h>
#include <linux/rbtree.h>
#include <linux/timer.h>
#include <linux/types.h>

@@ -267,15 +268,19 @@ struct intel_engine_cs {
	unsigned int guc_id;
	intel_engine_mask_t mask;

	u8 uabi_class;

	u8 class;
	u8 instance;

	u8 uabi_class;
	u8 uabi_instance;

	u32 context_size;
	u32 mmio_base;

	u32 uabi_capabilities;

	struct rb_node uabi_node;

	struct intel_sseu sseu;

	struct intel_ring *buffer;
Loading