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 <ch...@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursu...@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospu...@intel.com>
Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospu...@intel.com> #v2
---
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |   3 +-
 drivers/gpu/drm/i915/gt/intel_engine.h        |   6 -
 drivers/gpu/drm/i915/gt/intel_engine_cs.c     | 109 ++-------
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |   9 +-
 drivers/gpu/drm/i915/gt/intel_engine_user.c   | 228 ++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_engine_user.h   |  23 ++
 drivers/gpu/drm/i915/gt/intel_gt_types.h      |   4 +
 drivers/gpu/drm/i915/gt/selftest_lrc.c        |  15 +-
 .../gpu/drm/i915/gt/selftest_workarounds.c    |   1 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |   2 +-
 drivers/gpu/drm/i915/i915_cmd_parser.c        |   3 +-
 drivers/gpu/drm/i915/i915_debugfs.c           |  23 +-
 drivers/gpu/drm/i915/i915_drv.c               |   1 +
 drivers/gpu/drm/i915/i915_drv.h               |  15 +-
 drivers/gpu/drm/i915/i915_gem.c               |  22 +-
 drivers/gpu/drm/i915/i915_irq.c               |   2 +-
 drivers/gpu/drm/i915/i915_perf.c              |   3 +-
 drivers/gpu/drm/i915/i915_pmu.c               |  11 +-
 drivers/gpu/drm/i915/i915_query.c             |   5 +-
 drivers/gpu/drm/i915/i915_trace.h             |  10 +-
 21 files changed, 330 insertions(+), 166 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_user.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_user.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 331b19cc8247..22f7eb3d789f 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -73,6 +73,7 @@ gt-y += \
        gt/intel_context.o \
        gt/intel_engine_cs.o \
        gt/intel_engine_pm.o \
+       gt/intel_engine_user.o \
        gt/intel_gt.o \
        gt/intel_gt_pm.o \
        gt/intel_hangcheck.o \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 2e8cedce059f..575ff64e1e4a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -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"
@@ -1736,7 +1737,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))) {
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index db5c73ce86ee..01e8c8a6328a 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -123,8 +123,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)
 {
@@ -423,7 +421,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);
 
@@ -432,9 +429,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;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 97ce3589338e..8ae4114c005c 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -32,6 +32,7 @@
 
 #include "intel_engine.h"
 #include "intel_engine_pm.h"
+#include "intel_engine_user.h"
 #include "intel_context.h"
 #include "intel_lrc.h"
 #include "intel_reset.h"
@@ -285,9 +286,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;
@@ -303,10 +302,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;
@@ -315,12 +313,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;
 
@@ -330,14 +328,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;
@@ -349,8 +345,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;
 }
 
@@ -433,7 +432,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;
 
@@ -680,47 +679,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;
@@ -1192,20 +1150,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)
@@ -1503,29 +1447,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
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index da61dd329210..49258884cf11 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -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;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
new file mode 100644
index 000000000000..a4bc3a26646f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -0,0 +1,228 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include <linux/list.h>
+#include <linux/list_sort.h>
+#include <linux/llist.h>
+
+#include "i915_drv.h"
+#include "intel_engine.h"
+#include "intel_engine_user.h"
+
+struct intel_engine_cs *
+intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
+{
+       struct rb_node *p = i915->uabi_engines.rb_node;
+
+       while (p) {
+               struct intel_engine_cs *it =
+                       rb_entry(p, typeof(*it), uabi_node);
+
+               if (class < it->uabi_class)
+                       p = p->rb_left;
+               else if (class > it->uabi_class ||
+                        instance > it->uabi_instance)
+                       p = p->rb_right;
+               else if (instance < it->uabi_instance)
+                       p = p->rb_left;
+               else
+                       return it;
+       }
+
+       return NULL;
+}
+
+void intel_engine_add_user(struct intel_engine_cs *engine)
+{
+       llist_add((struct llist_node *)&engine->uabi_node,
+                 (struct llist_head *)&engine->i915->uabi_engines);
+}
+
+static const u8 uabi_classes[] = {
+       [RENDER_CLASS] = I915_ENGINE_CLASS_RENDER,
+       [COPY_ENGINE_CLASS] = I915_ENGINE_CLASS_COPY,
+       [VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
+       [VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
+};
+
+static int engine_cmp(void *priv, struct list_head *A, struct list_head *B)
+{
+       const struct intel_engine_cs *a =
+               container_of((struct rb_node *)A, typeof(*a), uabi_node);
+       const struct intel_engine_cs *b =
+               container_of((struct rb_node *)B, typeof(*b), uabi_node);
+
+       if (uabi_classes[a->class] < uabi_classes[b->class])
+               return -1;
+       if (uabi_classes[a->class] > uabi_classes[b->class])
+               return 1;
+
+       if (a->instance < b->instance)
+               return -1;
+       if (a->instance > b->instance)
+               return 1;
+
+       return 0;
+}
+
+static struct llist_node *get_engines(struct drm_i915_private *i915)
+{
+       return llist_del_all((struct llist_head *)&i915->uabi_engines);
+}
+
+static void sort_engines(struct drm_i915_private *i915,
+                        struct list_head *engines)
+{
+       struct llist_node *pos, *next;
+
+       llist_for_each_safe(pos, next, get_engines(i915)) {
+               struct intel_engine_cs *engine =
+                       container_of((struct rb_node *)pos, typeof(*engine),
+                                    uabi_node);
+               list_add((struct list_head *)&engine->uabi_node, engines);
+       }
+       list_sort(NULL, engines, engine_cmp);
+}
+
+static void 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;
+       u32 enabled, disabled;
+
+       enabled = 0;
+       disabled = 0;
+       for_each_user_engine(engine, i915) { /* 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;
+}
+
+void intel_engines_driver_register(struct drm_i915_private *i915)
+{
+       u8 uabi_instances[4] = {};
+       struct list_head *it, *next;
+       struct rb_node **p, *prev;
+       LIST_HEAD(engines);
+
+       sort_engines(i915, &engines);
+
+       prev = NULL;
+       p = &i915->uabi_engines.rb_node;
+       list_for_each_safe(it, next, &engines) {
+               struct intel_engine_cs *engine =
+                       container_of((struct rb_node *)it, typeof(*engine),
+                                    uabi_node);
+
+               GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
+               engine->uabi_class = uabi_classes[engine->class];
+
+               GEM_BUG_ON(engine->uabi_class >= ARRAY_SIZE(uabi_instances));
+               engine->uabi_instance = uabi_instances[engine->uabi_class]++;
+
+               rb_link_node(&engine->uabi_node, prev, p);
+               rb_insert_color(&engine->uabi_node, &i915->uabi_engines);
+
+               GEM_BUG_ON(intel_engine_lookup_user(i915,
+                                                   engine->uabi_class,
+                                                   engine->uabi_instance) != 
engine);
+
+               prev = &engine->uabi_node;
+               p = &prev->rb_right;
+       }
+
+       if (IS_ENABLED(CONFIG_DRM_I915_SELFTESTS) &&
+           IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
+               struct intel_engine_cs *engine;
+               unsigned int isolation;
+               int class, inst;
+               int errors = 0;
+
+               for (class = 0; class < ARRAY_SIZE(uabi_instances); class++) {
+                       for (inst = 0; inst < uabi_instances[class]; inst++) {
+                               engine = intel_engine_lookup_user(i915,
+                                                                 class, inst);
+                               if (!engine) {
+                                       pr_err("UABI engine not found for { 
class:%d, instance:%d }\n",
+                                              class, inst);
+                                       errors++;
+                                       continue;
+                               }
+
+                               if (engine->uabi_class != class ||
+                                   engine->uabi_instance != inst) {
+                                       pr_err("Wrong UABI engine:%s { 
class:%d, instance:%d } found for { class:%d, instance:%d }\n",
+                                              engine->name,
+                                              engine->uabi_class,
+                                              engine->uabi_instance,
+                                              class, inst);
+                                       errors++;
+                                       continue;
+                               }
+                       }
+               }
+
+               /*
+                * Make sure that classes with multiple engine instances all
+                * share the same basic configuration.
+                */
+               isolation = intel_engines_has_context_isolation(i915);
+               for_each_user_engine(engine, i915) {
+                       unsigned int bit = BIT(engine->uabi_class);
+                       unsigned int expected = engine->default_state ? bit : 0;
+
+                       if ((isolation & bit) != expected) {
+                               pr_err("mismatching default context state for 
class %d on engine %s\n",
+                                      engine->uabi_class, engine->name);
+                               errors++;
+                       }
+               }
+
+               if (WARN(errors, "Invalid UABI engine mapping found"))
+                       i915->uabi_engines = RB_ROOT;
+       }
+
+       set_scheduler_caps(i915);
+}
+
+unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915)
+{
+       struct intel_engine_cs *engine;
+       unsigned int which;
+
+       which = 0;
+       for_each_user_engine(engine, i915)
+               if (engine->default_state)
+                       which |= BIT(engine->uabi_class);
+
+       return which;
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.h 
b/drivers/gpu/drm/i915/gt/intel_engine_user.h
new file mode 100644
index 000000000000..9e5f113e5027
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.h
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef INTEL_ENGINE_USER_H
+#define INTEL_ENGINE_USER_H
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_engine_cs;
+
+struct intel_engine_cs *
+intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
+
+unsigned int intel_engines_has_context_isolation(struct drm_i915_private 
*i915);
+
+void intel_engine_add_user(struct intel_engine_cs *engine);
+void intel_engines_driver_register(struct drm_i915_private *i915);
+
+#endif /* INTEL_ENGINE_USER_H */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h 
b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index 34d4a868e4f1..5fd11e361d03 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -21,6 +21,7 @@
 
 struct drm_i915_private;
 struct i915_ggtt;
+struct intel_engine_cs;
 struct intel_uncore;
 
 struct intel_hangcheck {
@@ -76,6 +77,9 @@ struct intel_gt {
        u32 pm_ier;
 
        u32 pm_guc_events;
+
+       struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
+                                           [MAX_ENGINE_INSTANCE + 1];
 };
 
 enum intel_gt_scratch_field {
diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c 
b/drivers/gpu/drm/i915/gt/selftest_lrc.c
index 60f27e52d267..eb40a58665be 100644
--- a/drivers/gpu/drm/i915/gt/selftest_lrc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c
@@ -1773,6 +1773,7 @@ static int live_virtual_engine(void *arg)
        struct drm_i915_private *i915 = arg;
        struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1];
        struct intel_engine_cs *engine;
+       struct intel_gt *gt = &i915->gt;
        enum intel_engine_id id;
        unsigned int class, inst;
        int err = -ENODEV;
@@ -1796,10 +1797,10 @@ static int live_virtual_engine(void *arg)
 
                nsibling = 0;
                for (inst = 0; inst <= MAX_ENGINE_INSTANCE; inst++) {
-                       if (!i915->engine_class[class][inst])
+                       if (!gt->engine_class[class][inst])
                                continue;
 
-                       siblings[nsibling++] = i915->engine_class[class][inst];
+                       siblings[nsibling++] = gt->engine_class[class][inst];
                }
                if (nsibling < 2)
                        continue;
@@ -1920,6 +1921,7 @@ static int live_virtual_mask(void *arg)
 {
        struct drm_i915_private *i915 = arg;
        struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1];
+       struct intel_gt *gt = &i915->gt;
        unsigned int class, inst;
        int err = 0;
 
@@ -1933,10 +1935,10 @@ static int live_virtual_mask(void *arg)
 
                nsibling = 0;
                for (inst = 0; inst <= MAX_ENGINE_INSTANCE; inst++) {
-                       if (!i915->engine_class[class][inst])
+                       if (!gt->engine_class[class][inst])
                                break;
 
-                       siblings[nsibling++] = i915->engine_class[class][inst];
+                       siblings[nsibling++] = gt->engine_class[class][inst];
                }
                if (nsibling < 2)
                        continue;
@@ -2097,6 +2099,7 @@ static int live_virtual_bond(void *arg)
        };
        struct drm_i915_private *i915 = arg;
        struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1];
+       struct intel_gt *gt = &i915->gt;
        unsigned int class, inst;
        int err = 0;
 
@@ -2111,11 +2114,11 @@ static int live_virtual_bond(void *arg)
 
                nsibling = 0;
                for (inst = 0; inst <= MAX_ENGINE_INSTANCE; inst++) {
-                       if (!i915->engine_class[class][inst])
+                       if (!gt->engine_class[class][inst])
                                break;
 
                        GEM_BUG_ON(nsibling == ARRAY_SIZE(siblings));
-                       siblings[nsibling++] = i915->engine_class[class][inst];
+                       siblings[nsibling++] = gt->engine_class[class][inst];
                }
                if (nsibling < 2)
                        continue;
diff --git a/drivers/gpu/drm/i915/gt/selftest_workarounds.c 
b/drivers/gpu/drm/i915/gt/selftest_workarounds.c
index ab147985fa74..79884bc6a67d 100644
--- a/drivers/gpu/drm/i915/gt/selftest_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/selftest_workarounds.c
@@ -5,6 +5,7 @@
  */
 
 #include "gem/i915_gem_pm.h"
+#include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "i915_selftest.h"
 #include "intel_reset.h"
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b4238fe16a03..d91e4967217e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -488,7 +488,7 @@ static void guc_add_request(struct intel_guc *guc, struct 
i915_request *rq)
                           ring_tail, rq->fence.seqno);
        guc_ring_doorbell(client);
 
-       client->submissions[engine->id] += 1;
+       client->submissions[engine->guc_id] += 1;
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c 
b/drivers/gpu/drm/i915/i915_cmd_parser.c
index a28bcd2d7c09..730c1ed6d2a7 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -1352,11 +1352,10 @@ int intel_engine_cmd_parser(struct intel_engine_cs 
*engine,
 int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        bool active = false;
 
        /* If the command parser is not enabled, report 0 - unsupported */
-       for_each_engine(engine, dev_priv, id) {
+       for_each_user_engine(engine, dev_priv) {
                if (intel_engine_needs_cmd_parser(engine)) {
                        active = true;
                        break;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index aa61b79a6e0c..9ee0b1f6eb26 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -301,10 +301,9 @@ static void print_batch_pool_stats(struct seq_file *m,
        struct drm_i915_gem_object *obj;
        struct intel_engine_cs *engine;
        struct file_stats stats = {};
-       enum intel_engine_id id;
        int j;
 
-       for_each_engine(engine, dev_priv, id) {
+       for_each_user_engine(engine, dev_priv) {
                for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) 
{
                        list_for_each_entry(obj,
                                            &engine->batch_pool.cache_list[j],
@@ -391,7 +390,6 @@ static int i915_gem_batch_pool_info(struct seq_file *m, 
void *data)
        struct drm_device *dev = &dev_priv->drm;
        struct drm_i915_gem_object *obj;
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        int total = 0;
        int ret, j;
 
@@ -399,7 +397,7 @@ static int i915_gem_batch_pool_info(struct seq_file *m, 
void *data)
        if (ret)
                return ret;
 
-       for_each_engine(engine, dev_priv, id) {
+       for_each_user_engine(engine, dev_priv) {
                for (j = 0; j < ARRAY_SIZE(engine->batch_pool.cache_list); j++) 
{
                        int count;
 
@@ -486,7 +484,6 @@ static int i915_interrupt_info(struct seq_file *m, void 
*data)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        intel_wakeref_t wakeref;
        int i, pipe;
 
@@ -689,7 +686,7 @@ static int i915_interrupt_info(struct seq_file *m, void 
*data)
                           I915_READ(GEN11_GUNIT_CSME_INTR_MASK));
 
        } else if (INTEL_GEN(dev_priv) >= 6) {
-               for_each_engine(engine, dev_priv, id) {
+               for_each_user_engine(engine, dev_priv) {
                        seq_printf(m,
                                   "Graphics Interrupt mask (%s):       %08x\n",
                                   engine->name, ENGINE_READ(engine, RING_IMR));
@@ -1964,7 +1961,6 @@ static void i915_guc_client_info(struct seq_file *m,
                                 struct intel_guc_client *client)
 {
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        u64 tot = 0;
 
        seq_printf(m, "\tPriority %d, GuC stage index: %u, PD offset 0x%x\n",
@@ -1972,8 +1968,8 @@ static void i915_guc_client_info(struct seq_file *m,
        seq_printf(m, "\tDoorbell id %d, offset: 0x%lx\n",
                client->doorbell_id, client->doorbell_offset);
 
-       for_each_engine(engine, dev_priv, id) {
-               u64 submissions = client->submissions[id];
+       for_each_user_engine(engine, dev_priv) {
+               u64 submissions = client->submissions[engine->guc_id];
                tot += submissions;
                seq_printf(m, "\tSubmissions: %llu %s\n",
                                submissions, engine->name);
@@ -2013,7 +2009,6 @@ static int i915_guc_stage_pool(struct seq_file *m, void 
*data)
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
        const struct intel_guc *guc = &dev_priv->gt.uc.guc;
        struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr;
-       intel_engine_mask_t tmp;
        int index;
 
        if (!USES_GUC_SUBMISSION(dev_priv))
@@ -2042,7 +2037,7 @@ static int i915_guc_stage_pool(struct seq_file *m, void 
*data)
                           desc->wq_addr, desc->wq_size);
                seq_putc(m, '\n');
 
-               for_each_engine(engine, dev_priv, tmp) {
+               for_each_user_engine(engine, dev_priv) {
                        u32 guc_engine_id = engine->guc_id;
                        struct guc_execlist_context *lrc =
                                                &desc->lrc[guc_engine_id];
@@ -2875,7 +2870,6 @@ static int i915_engine_info(struct seq_file *m, void 
*unused)
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
        struct intel_engine_cs *engine;
        intel_wakeref_t wakeref;
-       enum intel_engine_id id;
        struct drm_printer p;
 
        wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
@@ -2887,7 +2881,7 @@ static int i915_engine_info(struct seq_file *m, void 
*unused)
                   RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
 
        p = drm_seq_file_printer(m);
-       for_each_engine(engine, dev_priv, id)
+       for_each_user_engine(engine, dev_priv)
                intel_engine_dump(engine, &p, "%s\n", engine->name);
 
        intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
@@ -2968,9 +2962,8 @@ static int i915_wa_registers(struct seq_file *m, void 
*unused)
 {
        struct drm_i915_private *i915 = node_to_i915(m->private);
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
 
-       for_each_engine(engine, i915, id) {
+       for_each_user_engine(engine, i915) {
                const struct i915_wa_list *wal = &engine->ctx_wa_list;
                const struct i915_wa *wa;
                unsigned int count;
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index c934c1040f56..254d19d9b127 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -61,6 +61,7 @@
 
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_ioctls.h"
+#include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_reset.h"
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3ddeba5c7b8d..57160e4c0701 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1371,11 +1371,12 @@ struct drm_i915_private {
        wait_queue_head_t gmbus_wait_queue;
 
        struct pci_dev *bridge_dev;
-       struct intel_engine_cs *engine[I915_NUM_ENGINES];
+
        /* Context used internally to idle the GPU and setup initial state */
        struct i915_gem_context *kernel_context;
-       struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
-                                           [MAX_ENGINE_INSTANCE + 1];
+
+       struct intel_engine_cs *engine[I915_NUM_ENGINES];
+       struct rb_root uabi_engines;
 
        struct resource mch_res;
 
@@ -1919,6 +1920,14 @@ static inline struct drm_i915_private 
*wopcm_to_i915(struct intel_wopcm *wopcm)
             ((engine__) = (dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : \
             0;)
 
+#define rb_to_uabi_engine(rb) \
+       rb_entry_safe(rb, struct intel_engine_cs, uabi_node)
+
+#define for_each_user_engine(engine__, i915__) \
+       for ((engine__) = rb_to_uabi_engine(rb_first(&(i915__)->uabi_engines));\
+            (engine__); \
+            (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
+
 enum hdmi_force_audio {
        HDMI_AUDIO_OFF_DVI = -2,        /* no aux data for HDMI-DVI converter */
        HDMI_AUDIO_OFF,                 /* force turn off HDMI audio */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9b10b879a37f..5eeb7404a362 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -46,6 +46,7 @@
 #include "gem/i915_gem_ioctls.h"
 #include "gem/i915_gem_pm.h"
 #include "gem/i915_gemfs.h"
+#include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_mocs.h"
@@ -1365,24 +1366,6 @@ static int __intel_engines_record_defaults(struct 
drm_i915_private *i915)
                i915_gem_object_unpin_map(engine->default_state);
        }
 
-       if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {
-               unsigned int found = intel_engines_has_context_isolation(i915);
-
-               /*
-                * Make sure that classes with multiple engine instances all
-                * share the same basic configuration.
-                */
-               for_each_engine(engine, i915, id) {
-                       unsigned int bit = BIT(engine->uabi_class);
-                       unsigned int expected = engine->default_state ? bit : 0;
-
-                       if ((found & bit) != expected) {
-                               DRM_ERROR("mismatching default context state 
for class %d on engine %s\n",
-                                         engine->uabi_class, engine->name);
-                       }
-               }
-       }
-
 out_ctx:
        i915_gem_context_unlock_engines(ctx);
        i915_gem_context_set_closed(ctx);
@@ -1612,7 +1595,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 void i915_gem_driver_register(struct drm_i915_private *i915)
 {
        i915_gem_driver_register__shrinker(i915);
-       intel_engines_set_scheduler_caps(i915);
+
+       intel_engines_driver_register(i915);
 }
 
 void i915_gem_driver_unregister(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index a17d4fd17962..7b19d7df9ba1 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3109,7 +3109,7 @@ gen11_engine_irq_handler(struct intel_gt *gt, const u8 
class,
        struct intel_engine_cs *engine;
 
        if (instance <= MAX_ENGINE_INSTANCE)
-               engine = gt->i915->engine_class[class][instance];
+               engine = gt->engine_class[class][instance];
        else
                engine = NULL;
 
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 988a4092164e..c76455885817 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -1875,7 +1875,6 @@ static int gen8_configure_all_contexts(struct 
drm_i915_private *i915,
 #undef ctx_flexeuN
        struct intel_engine_cs *engine;
        struct i915_gem_context *ctx;
-       enum intel_engine_id id;
        int i;
 
        for (i = 2; i < ARRAY_SIZE(regs); i++)
@@ -1915,7 +1914,7 @@ static int gen8_configure_all_contexts(struct 
drm_i915_private *i915,
         * If we don't modify the kernel_context, we do not get events while
         * idle.
         */
-       for_each_engine(engine, i915, id) {
+       for_each_user_engine(engine, i915) {
                struct intel_context *ce = engine->kernel_context;
                int err;
 
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index eff86483bec0..3bc36c3bc035 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -8,6 +8,7 @@
 #include <linux/pm_runtime.h>
 
 #include "gt/intel_engine.h"
+#include "gt/intel_engine_user.h"
 
 #include "i915_drv.h"
 #include "i915_pmu.h"
@@ -160,7 +161,6 @@ static void
 engines_sample(struct drm_i915_private *dev_priv, unsigned int period_ns)
 {
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        intel_wakeref_t wakeref;
        unsigned long flags;
 
@@ -174,7 +174,7 @@ engines_sample(struct drm_i915_private *dev_priv, unsigned 
int period_ns)
                return;
 
        spin_lock_irqsave(&dev_priv->uncore.lock, flags);
-       for_each_engine(engine, dev_priv, id) {
+       for_each_user_engine(engine, dev_priv) {
                struct intel_engine_pmu *pmu = &engine->pmu;
                bool busy;
                u32 val;
@@ -849,7 +849,6 @@ create_event_attributes(struct drm_i915_private *i915)
        struct i915_ext_attribute *i915_attr = NULL, *i915_iter;
        struct attribute **attr = NULL, **attr_iter;
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        unsigned int i;
 
        /* Count how many counters we will be exposing. */
@@ -858,7 +857,7 @@ create_event_attributes(struct drm_i915_private *i915)
                        count++;
        }
 
-       for_each_engine(engine, i915, id) {
+       for_each_user_engine(engine, i915) {
                for (i = 0; i < ARRAY_SIZE(engine_events); i++) {
                        if (!engine_event_status(engine,
                                                 engine_events[i].sample))
@@ -909,7 +908,7 @@ create_event_attributes(struct drm_i915_private *i915)
        }
 
        /* Initialize supported engine counters. */
-       for_each_engine(engine, i915, id) {
+       for_each_user_engine(engine, i915) {
                for (i = 0; i < ARRAY_SIZE(engine_events); i++) {
                        char *str;
 
@@ -926,7 +925,7 @@ create_event_attributes(struct drm_i915_private *i915)
                        i915_iter =
                                add_i915_attr(i915_iter, str,
                                              
__I915_PMU_ENGINE(engine->uabi_class,
-                                                               
engine->instance,
+                                                               
engine->uabi_instance,
                                                                
engine_events[i].sample));
 
                        str = kasprintf(GFP_KERNEL, "%s-%s.unit",
diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index 7b7016171057..8abba3a31767 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -105,7 +105,6 @@ query_engine_info(struct drm_i915_private *i915,
        struct drm_i915_query_engine_info query;
        struct drm_i915_engine_info info = { };
        struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        int len, ret;
 
        if (query_item->flags)
@@ -125,9 +124,9 @@ query_engine_info(struct drm_i915_private *i915,
 
        info_ptr = &query_ptr->engines[0];
 
-       for_each_engine(engine, i915, id) {
+       for_each_user_engine(engine, i915) {
                info.engine.engine_class = engine->uabi_class;
-               info.engine.engine_instance = engine->instance;
+               info.engine.engine_instance = engine->uabi_instance;
                info.capabilities = engine->uabi_capabilities;
 
                if (__copy_to_user(info_ptr, &info, sizeof(info)))
diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index da18b8d6b80c..1d11245c4c87 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -677,7 +677,7 @@ TRACE_EVENT(i915_request_queue,
                           __entry->dev = rq->i915->drm.primary->index;
                           __entry->hw_id = rq->gem_context->hw_id;
                           __entry->class = rq->engine->uabi_class;
-                          __entry->instance = rq->engine->instance;
+                          __entry->instance = rq->engine->uabi_instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->flags = flags;
@@ -706,7 +706,7 @@ DECLARE_EVENT_CLASS(i915_request,
                           __entry->dev = rq->i915->drm.primary->index;
                           __entry->hw_id = rq->gem_context->hw_id;
                           __entry->class = rq->engine->uabi_class;
-                          __entry->instance = rq->engine->instance;
+                          __entry->instance = rq->engine->uabi_instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           ),
@@ -751,7 +751,7 @@ TRACE_EVENT(i915_request_in,
                           __entry->dev = rq->i915->drm.primary->index;
                           __entry->hw_id = rq->gem_context->hw_id;
                           __entry->class = rq->engine->uabi_class;
-                          __entry->instance = rq->engine->instance;
+                          __entry->instance = rq->engine->uabi_instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->prio = rq->sched.attr.priority;
@@ -782,7 +782,7 @@ TRACE_EVENT(i915_request_out,
                           __entry->dev = rq->i915->drm.primary->index;
                           __entry->hw_id = rq->gem_context->hw_id;
                           __entry->class = rq->engine->uabi_class;
-                          __entry->instance = rq->engine->instance;
+                          __entry->instance = rq->engine->uabi_instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->completed = i915_request_completed(rq);
@@ -847,7 +847,7 @@ TRACE_EVENT(i915_request_wait_begin,
                           __entry->dev = rq->i915->drm.primary->index;
                           __entry->hw_id = rq->gem_context->hw_id;
                           __entry->class = rq->engine->uabi_class;
-                          __entry->instance = rq->engine->instance;
+                          __entry->instance = rq->engine->uabi_instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->flags = flags;
-- 
2.22.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to