drm/i915: Add a hook for making the engines idle (parking) and unparking
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 25 Oct 2017 14:39:41 +0000 (15:39 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 25 Oct 2017 17:47:30 +0000 (18:47 +0100)
In the next patch, we will want to install a callback when the engines
(GT as a whole) become idle and similarly when they first become busy.
To enable that callback, first rename intel_engines_mark_idle() to
intel_engines_park() and provide the companion intel_engines_unpark().

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: MichaƂ Winiarski <michal.winiarski@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171025143943.7661-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index bafe1cdd57d8d9cdf2e2d46314701692d3e91885..8364304e9d2b23924d509aa15a67c278aaca7880 100644 (file)
@@ -3347,7 +3347,7 @@ i915_gem_idle_work_handler(struct work_struct *work)
        if (!intel_engines_are_idle(dev_priv))
                DRM_ERROR("Timeout waiting for engines to idle\n");
 
-       intel_engines_mark_idle(dev_priv);
+       intel_engines_park(dev_priv);
        i915_gem_timelines_mark_idle(dev_priv);
 
        GEM_BUG_ON(!dev_priv->gt.awake);
index d140fcf5c6a396d7a288d6b6e8d26b0da82ae284..e0d6221022a83ac9a159e72e7a8537c6334d12a5 100644 (file)
@@ -259,6 +259,8 @@ static void mark_busy(struct drm_i915_private *i915)
        if (INTEL_GEN(i915) >= 6)
                gen6_rps_busy(i915);
 
+       intel_engines_unpark(i915);
+
        queue_delayed_work(i915->wq,
                           &i915->gt.retire_work,
                           round_jiffies_up_relative(HZ));
index f6cdc50d423710b2a480d03c59ef67a3718c763f..fedb839dff6111768dd14dfd0a917191db1dfee4 100644 (file)
@@ -1600,19 +1600,48 @@ void intel_engines_reset_default_submission(struct drm_i915_private *i915)
                engine->set_default_submission(engine);
 }
 
-void intel_engines_mark_idle(struct drm_i915_private *i915)
+/**
+ * intel_engines_park: called when the GT is transitioning from busy->idle
+ * @i915: the i915 device
+ *
+ * The GT is now idle and about to go to sleep (maybe never to wake again?).
+ * Time for us to tidy and put away our toys (release resources back to the
+ * system).
+ */
+void intel_engines_park(struct drm_i915_private *i915)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
 
        for_each_engine(engine, i915, id) {
+               if (engine->park)
+                       engine->park(engine);
+
                intel_engine_disarm_breadcrumbs(engine);
-               i915_gem_batch_pool_fini(&engine->batch_pool);
                tasklet_kill(&engine->execlists.irq_tasklet);
+
+               i915_gem_batch_pool_fini(&engine->batch_pool);
                engine->execlists.no_priolist = false;
        }
 }
 
+/**
+ * intel_engines_unpark: called when the GT is transitioning from idle->busy
+ * @i915: the i915 device
+ *
+ * The GT was idle and now about to fire up with some new user requests.
+ */
+void intel_engines_unpark(struct drm_i915_private *i915)
+{
+       struct intel_engine_cs *engine;
+       enum intel_engine_id id;
+
+       for_each_engine(engine, i915, id) {
+               if (engine->unpark)
+                       engine->unpark(engine);
+       }
+}
+
 bool intel_engine_can_store_dword(struct intel_engine_cs *engine)
 {
        switch (INTEL_GEN(engine->i915)) {
index d36e2560743545cef7b32b24adb794e719ca5da2..eeb3622803a8f73f40d7c197ab56822efc55afc8 100644 (file)
@@ -1891,6 +1891,9 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine)
        engine->cancel_requests = execlists_cancel_requests;
        engine->schedule = execlists_schedule;
        engine->execlists.irq_tasklet.func = intel_lrc_irq_handler;
+
+       engine->park = NULL;
+       engine->unpark = NULL;
 }
 
 static void
index 8da1bde442dd94a677335ee8f3ffc44983ee33b8..05e01446b00b321bc92411751a74ba02d32c1de5 100644 (file)
@@ -2028,12 +2028,15 @@ static void i9xx_set_default_submission(struct intel_engine_cs *engine)
 {
        engine->submit_request = i9xx_submit_request;
        engine->cancel_requests = cancel_requests;
+
+       engine->park = NULL;
+       engine->unpark = NULL;
 }
 
 static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine)
 {
+       i9xx_set_default_submission(engine);
        engine->submit_request = gen6_bsd_submit_request;
-       engine->cancel_requests = cancel_requests;
 }
 
 static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
index a2589aa891639db6d46cb6126ebb58cabb1fd35b..a7c95f0c3101adab6278d1c40eb0fc1ec7b6f95d 100644 (file)
@@ -365,6 +365,9 @@ struct intel_engine_cs {
        void            (*reset_hw)(struct intel_engine_cs *engine,
                                    struct drm_i915_gem_request *req);
 
+       void            (*park)(struct intel_engine_cs *engine);
+       void            (*unpark)(struct intel_engine_cs *engine);
+
        void            (*set_default_submission)(struct intel_engine_cs *engine);
 
        struct intel_ring *(*context_pin)(struct intel_engine_cs *engine,
@@ -868,7 +871,9 @@ bool intel_engines_are_idle(struct drm_i915_private *dev_priv);
 
 bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine);
 
-void intel_engines_mark_idle(struct drm_i915_private *i915);
+void intel_engines_park(struct drm_i915_private *i915);
+void intel_engines_unpark(struct drm_i915_private *i915);
+
 void intel_engines_reset_default_submission(struct drm_i915_private *i915);
 
 bool intel_engine_can_store_dword(struct intel_engine_cs *engine);