OSDN Git Service

drm/i915: Compute the global scheduler caps
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 26 Feb 2019 10:24:00 +0000 (10:24 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Feb 2019 08:58:37 +0000 (08:58 +0000)
Do a pass over all the engines upon starting to determine the global
scheduler capability flags (those that are agreed upon by all).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190226102404.29153-7-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 2b26152..de8b92d 100644 (file)
@@ -4698,6 +4698,8 @@ static int __i915_gem_restart_engines(void *data)
                }
        }
 
+       intel_engines_set_scheduler_caps(i915);
+
        return 0;
 }
 
index 4f24401..43ce4c5 100644 (file)
@@ -608,6 +608,45 @@ err_hwsp:
        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_HAS_##x), ilog2(I915_SCHEDULER_CAP_##y) }
+               MAP(PREEMPTION, PREEMPTION),
+#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;
+}
+
 static void __intel_context_unpin(struct i915_gem_context *ctx,
                                  struct intel_engine_cs *engine)
 {
index c4f4966..81d1885 100644 (file)
@@ -2292,12 +2292,6 @@ void intel_execlists_set_default_submission(struct intel_engine_cs *engine)
        engine->flags |= I915_ENGINE_SUPPORTS_STATS;
        if (engine->i915->preempt_context)
                engine->flags |= I915_ENGINE_HAS_PREEMPTION;
-
-       engine->i915->caps.scheduler =
-               I915_SCHEDULER_CAP_ENABLED |
-               I915_SCHEDULER_CAP_PRIORITY;
-       if (intel_engine_has_preemption(engine))
-               engine->i915->caps.scheduler |= I915_SCHEDULER_CAP_PREEMPTION;
 }
 
 static void
index de8dba7..533e205 100644 (file)
@@ -593,6 +593,8 @@ intel_engine_has_preemption(const struct intel_engine_cs *engine)
        return engine->flags & I915_ENGINE_HAS_PREEMPTION;
 }
 
+void intel_engines_set_scheduler_caps(struct drm_i915_private *i915);
+
 static inline bool __execlists_need_preempt(int prio, int last)
 {
        /*