Skip to content

Commit

Permalink
drm/i915/gt: Move the [class][inst] lookup for engines onto the GT
Browse files Browse the repository at this point in the history
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: Chris 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
  • Loading branch information
Chris Wilson committed Aug 6, 2019
1 parent c29579d commit 750e76b
Show file tree
Hide file tree
Showing 21 changed files with 328 additions and 161 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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))) {
Expand Down
6 changes: 0 additions & 6 deletions drivers/gpu/drm/i915/gt/intel_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down
109 changes: 15 additions & 94 deletions drivers/gpu/drm/i915/gt/intel_engine_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -677,47 +676,6 @@ int intel_engines_setup(struct drm_i915_private *i915)
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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/i915/gt/intel_engine_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 750e76b

Please sign in to comment.