[Intel-gfx] [RFC 32/38] drm/i915/preempt: add hook to catch 'unexpected' ring submissions

John.C.Harrison at Intel.com John.C.Harrison at Intel.com
Fri Dec 11 06:49:09 PST 2015


From: Dave Gordon <david.s.gordon at intel.com>

Author: John Harrison <John.C.Harrison at Intel.com>
Date:   Thu Apr 10 10:41:06 2014 +0100

The scheduler needs to know what each seqno that pops out of the ring is
referring to. This change adds a hook into the the 'submit some random
work that got forgotten about' clean up code to inform the scheduler
that a new seqno has been sent to the ring for some non-batch buffer
operation.

Reworked for latest scheduler+preemption by Dave Gordon: with the newer
implementation, knowing about untracked requests is merely helpful for
debugging rather than being mandatory, as we have already taken steps to
prevent untracked requests intruding at awkward moments!

v2: Removed unnecessary debug spew.

For: VIZ-2021
Signed-off-by: John Harrison <John.C.Harrison at Intel.com>
Signed-off-by: Dave Gordon <david.s.gordon at intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c       |  4 ++++
 drivers/gpu/drm/i915/i915_gpu_error.c |  2 ++
 drivers/gpu/drm/i915/i915_scheduler.c | 21 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_scheduler.h |  1 +
 4 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ea3d224..a91b916 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2597,6 +2597,10 @@ void __i915_add_request(struct drm_i915_gem_request *request,
 		WARN_ON(request->seqno != dev_priv->last_seqno);
 	}
 
+	/* Notify the scheduler, if it doesn't already track this request */
+	if (!request->scheduler_qe)
+		i915_scheduler_fly_request(request);
+
 	/* Record the position of the start of the request so that
 	 * should we detect the updated seqno part-way through the
 	 * GPU processing the request, we never over-estimate the
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2d9dd3f..72c861e 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1331,6 +1331,8 @@ static void i915_gem_record_rings(struct drm_device *dev,
 			erq->ringbuffer_gtt = i915_gem_obj_ggtt_offset(request->ringbuf->obj);
 			erq->scheduler_state = !sqe ? 'u' :
 				i915_scheduler_queue_status_chr(sqe->status);
+			if (request->scheduler_flags & i915_req_sf_untracked)
+				erq->scheduler_state = 'U';
 		}
 	}
 }
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index 54b6c32..8cd89d2 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -455,6 +455,27 @@ int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe)
 	return 0;
 }
 
+/* An untracked request is being launched ... */
+void i915_scheduler_fly_request(struct drm_i915_gem_request *req)
+{
+	struct drm_i915_private *dev_priv = req->i915;
+	struct i915_scheduler *scheduler = dev_priv->scheduler;
+
+	BUG_ON(!scheduler);
+	BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+	/* This shouldn't happen */
+	WARN_ON(i915_scheduler_is_ring_busy(req->ring));
+
+	/* We don't expect to see nodes that are already tracked */
+	if (!WARN_ON(req->scheduler_qe)) {
+		/* Untracked node, must not be inside scheduler submission path */
+		WARN_ON((scheduler->flags[req->ring->id] & i915_sf_submitting));
+		scheduler->stats[req->ring->id].non_batch++;
+		req->scheduler_flags |= i915_req_sf_untracked;
+	}
+}
+
 static int i915_scheduler_fly_node(struct i915_scheduler_queue_entry *node)
 {
 	struct drm_i915_private *dev_priv = node->params.dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 5b871b0..7e7e974 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -199,6 +199,7 @@ bool        i915_scheduler_is_ring_flying(struct intel_engine_cs *ring);
 bool        i915_scheduler_is_ring_preempting(struct intel_engine_cs *ring);
 bool        i915_scheduler_is_ring_busy(struct intel_engine_cs *ring);
 void        i915_gem_scheduler_work_handler(struct work_struct *work);
+void        i915_scheduler_fly_request(struct drm_i915_gem_request *req);
 int         i915_scheduler_flush(struct intel_engine_cs *ring, bool is_locked);
 int         i915_scheduler_flush_stamp(struct intel_engine_cs *ring,
 				       unsigned long stamp, bool is_locked);
-- 
1.9.1



More information about the Intel-gfx mailing list