drm/i915: Move find_active_request() to the engine
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 5 Mar 2019 18:03:32 +0000 (18:03 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 5 Mar 2019 18:20:06 +0000 (18:20 +0000)
To find the active request, we need only search along the individual
engine for the right request. This does not require touching any global
GEM state, so move it into the engine compartment.

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/20190305180332.30900-3-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 08ead854ac2dd6a72ac2ca1cd03ca72ef6234b1f..ff039750069d796fb18d12964cfe0728215f18ab 100644 (file)
@@ -2996,9 +2996,6 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
 
 int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
 
-struct i915_request *
-i915_gem_find_active_request(struct intel_engine_cs *engine);
-
 static inline bool __i915_wedged(struct i915_gpu_error *error)
 {
        return unlikely(test_bit(I915_WEDGED, &error->flags));
index 69413f99ed044dcec709cab148bba5f6a4e3272e..c67369bd145bee3d275df6e68502ae5d2d49e5be 100644 (file)
@@ -2803,51 +2803,6 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
        return 0;
 }
 
-static bool match_ring(struct i915_request *rq)
-{
-       struct drm_i915_private *dev_priv = rq->i915;
-       u32 ring = I915_READ(RING_START(rq->engine->mmio_base));
-
-       return ring == i915_ggtt_offset(rq->ring->vma);
-}
-
-struct i915_request *
-i915_gem_find_active_request(struct intel_engine_cs *engine)
-{
-       struct i915_request *request, *active = NULL;
-       unsigned long flags;
-
-       /*
-        * We are called by the error capture, reset and to dump engine
-        * state at random points in time. In particular, note that neither is
-        * crucially ordered with an interrupt. After a hang, the GPU is dead
-        * and we assume that no more writes can happen (we waited long enough
-        * for all writes that were in transaction to be flushed) - adding an
-        * extra delay for a recent interrupt is pointless. Hence, we do
-        * not need an engine->irq_seqno_barrier() before the seqno reads.
-        * At all other times, we must assume the GPU is still running, but
-        * we only care about the snapshot of this moment.
-        */
-       spin_lock_irqsave(&engine->timeline.lock, flags);
-       list_for_each_entry(request, &engine->timeline.requests, link) {
-               if (i915_request_completed(request))
-                       continue;
-
-               if (!i915_request_started(request))
-                       break;
-
-               /* More than one preemptible request may match! */
-               if (!match_ring(request))
-                       break;
-
-               active = request;
-               break;
-       }
-       spin_unlock_irqrestore(&engine->timeline.lock, flags);
-
-       return active;
-}
-
 static void
 i915_gem_retire_work_handler(struct work_struct *work)
 {
index 5f1cdbc9eb5d4dfac3b09da970eb557e5f390c9f..3d80208886042f6b24de01a25a4a17bc49b295cc 100644 (file)
@@ -1411,7 +1411,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
                error_record_engine_registers(error, engine, ee);
                error_record_engine_execlists(engine, ee);
 
-               request = i915_gem_find_active_request(engine);
+               request = intel_engine_find_active_request(engine);
                if (request) {
                        struct i915_gem_context *ctx = request->gem_context;
                        struct intel_ring *ring;
index 62a2bbbbcc646f166edd83d1a14b98baf20903f3..555a4590fa239645286806806370dcca113b027c 100644 (file)
@@ -1545,7 +1545,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
        if (&rq->link != &engine->timeline.requests)
                print_request(m, rq, "\t\tlast   ");
 
-       rq = i915_gem_find_active_request(engine);
+       rq = intel_engine_find_active_request(engine);
        if (rq) {
                print_request(m, rq, "\t\tactive ");
 
@@ -1712,6 +1712,51 @@ void intel_disable_engine_stats(struct intel_engine_cs *engine)
        write_sequnlock_irqrestore(&engine->stats.lock, flags);
 }
 
+static bool match_ring(struct i915_request *rq)
+{
+       struct drm_i915_private *dev_priv = rq->i915;
+       u32 ring = I915_READ(RING_START(rq->engine->mmio_base));
+
+       return ring == i915_ggtt_offset(rq->ring->vma);
+}
+
+struct i915_request *
+intel_engine_find_active_request(struct intel_engine_cs *engine)
+{
+       struct i915_request *request, *active = NULL;
+       unsigned long flags;
+
+       /*
+        * We are called by the error capture, reset and to dump engine
+        * state at random points in time. In particular, note that neither is
+        * crucially ordered with an interrupt. After a hang, the GPU is dead
+        * and we assume that no more writes can happen (we waited long enough
+        * for all writes that were in transaction to be flushed) - adding an
+        * extra delay for a recent interrupt is pointless. Hence, we do
+        * not need an engine->irq_seqno_barrier() before the seqno reads.
+        * At all other times, we must assume the GPU is still running, but
+        * we only care about the snapshot of this moment.
+        */
+       spin_lock_irqsave(&engine->timeline.lock, flags);
+       list_for_each_entry(request, &engine->timeline.requests, link) {
+               if (i915_request_completed(request))
+                       continue;
+
+               if (!i915_request_started(request))
+                       break;
+
+               /* More than one preemptible request may match! */
+               if (!match_ring(request))
+                       break;
+
+               active = request;
+               break;
+       }
+       spin_unlock_irqrestore(&engine->timeline.lock, flags);
+
+       return active;
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_engine.c"
 #include "selftests/intel_engine_cs.c"
index 18e865ff66376686bf7729dd80343c5baa796298..84b7047e2df54ad12c481de18e525ed582ef19ff 100644 (file)
@@ -1014,6 +1014,9 @@ void intel_disable_engine_stats(struct intel_engine_cs *engine);
 
 ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine);
 
+struct i915_request *
+intel_engine_find_active_request(struct intel_engine_cs *engine);
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 
 static inline bool inject_preempt_hang(struct intel_engine_execlists *execlists)