[PATCH 31/31] drm/i915: Encode extra tags into request.global_seqno

Chris Wilson chris at chris-wilson.co.uk
Tue Sep 25 15:48:34 UTC 2018


To support a virtual engine on which may cause a preemption event to
transfer a request from one engine to another, we need to encode the
engine that we are waiting on into the seqno or else we face a risk that
we may evaluate (and signal) a request as completed if we transfer it to
another engine.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c              |  6 ++++--
 drivers/gpu/drm/i915/i915_drv.h                  |  2 +-
 drivers/gpu/drm/i915/i915_request.c              | 16 ++++++++--------
 drivers/gpu/drm/i915/i915_request.h              | 10 +++++-----
 drivers/gpu/drm/i915/i915_reset.c                |  2 +-
 drivers/gpu/drm/i915/intel_breadcrumbs.c         |  4 ++--
 drivers/gpu/drm/i915/intel_engine_cs.c           |  4 ++--
 drivers/gpu/drm/i915/intel_lrc.c                 | 10 +++++-----
 drivers/gpu/drm/i915/intel_ringbuffer.c          |  6 ++++--
 drivers/gpu/drm/i915/intel_ringbuffer.h          |  6 +++---
 drivers/gpu/drm/i915/selftests/i915_request.c    |  3 ++-
 .../gpu/drm/i915/selftests/intel_breadcrumbs.c   |  8 ++++----
 drivers/gpu/drm/i915/selftests/intel_hangcheck.c |  6 +++---
 13 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 6f38f00e3765..cb98f5484c82 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1352,8 +1352,10 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
 		for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
 			struct intel_wait *w = rb_entry(rb, typeof(*w), node);
 
-			seq_printf(m, "\t%s [%d] waiting for %x\n",
-				   w->tsk->comm, w->tsk->pid, w->seqno);
+			seq_printf(m, "\t%s [%d] waiting for %x:%x\n",
+				   w->tsk->comm, w->tsk->pid,
+				   upper_32_bits(w->seqno),
+				   lower_32_bits(w->seqno));
 		}
 		spin_unlock_irq(&b->rb_lock);
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 92819977282a..7aa29cc2e463 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3745,7 +3745,7 @@ static inline bool
 __i915_request_irq_complete(const struct i915_request *rq)
 {
 	struct intel_engine_cs *engine = rq->engine;
-	u32 seqno;
+	u64 seqno;
 
 	/* Note that the engine may have wrapped around the seqno, and
 	 * so our request->global_seqno will be ahead of the hardware,
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 34d410cfa577..baca4a6f01d0 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -267,7 +267,7 @@ static void __retire_engine_request(struct intel_engine_cs *engine,
 	GEM_TRACE("%s(%s) fence %llx:%d, global=%d, current %d\n",
 		  __func__, engine->name,
 		  rq->fence.context, rq->fence.seqno,
-		  rq->global_seqno,
+		  lower_32_bits(rq->global_seqno),
 		  intel_engine_get_seqno(engine));
 
 	GEM_BUG_ON(!i915_request_completed(rq));
@@ -329,7 +329,7 @@ static void i915_request_retire(struct i915_request *request)
 	GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n",
 		  request->engine->name,
 		  request->fence.context, request->fence.seqno,
-		  request->global_seqno,
+		  lower_32_bits(request->global_seqno),
 		  intel_engine_get_seqno(request->engine));
 
 	lockdep_assert_held(&request->i915->drm.struct_mutex);
@@ -392,7 +392,7 @@ void i915_request_retire_upto(struct i915_request *rq)
 	GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n",
 		  rq->engine->name,
 		  rq->fence.context, rq->fence.seqno,
-		  rq->global_seqno,
+		  lower_32_bits(rq->global_seqno),
 		  intel_engine_get_seqno(rq->engine));
 
 	lockdep_assert_held(&rq->i915->drm.struct_mutex);
@@ -447,7 +447,7 @@ void __i915_request_submit(struct i915_request *request)
 
 	/* We may be recursing from the signal callback of another i915 fence */
 	spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
-	request->global_seqno = seqno;
+	request->global_seqno = (u64)engine->id << 32 | seqno;
 	if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
 		intel_engine_enable_signaling(request, false);
 	spin_unlock(&request->lock);
@@ -483,7 +483,7 @@ void __i915_request_unsubmit(struct i915_request *request)
 	GEM_TRACE("%s fence %llx:%d <- global=%d, current %d\n",
 		  engine->name,
 		  request->fence.context, request->fence.seqno,
-		  request->global_seqno,
+		  lower_32_bits(request->global_seqno),
 		  intel_engine_get_seqno(engine));
 
 	GEM_BUG_ON(!irqs_disabled());
@@ -494,7 +494,7 @@ void __i915_request_unsubmit(struct i915_request *request)
 	 * is kept in seqno/ring order.
 	 */
 	GEM_BUG_ON(!request->global_seqno);
-	GEM_BUG_ON(request->global_seqno != engine->timeline.seqno);
+	GEM_BUG_ON(lower_32_bits(request->global_seqno) != engine->timeline.seqno);
 	GEM_BUG_ON(intel_engine_has_completed(engine, request->global_seqno));
 	engine->timeline.seqno--;
 
@@ -789,7 +789,7 @@ i915_request_await_request(struct i915_request *to, struct i915_request *from)
 
 		GEM_BUG_ON(!from->engine->semaphore.signal);
 
-		seqno = i915_request_global_seqno(from);
+		seqno = lower_32_bits(i915_request_global_seqno(from));
 		if (!seqno)
 			goto await_dma_fence;
 
@@ -1122,7 +1122,7 @@ static bool busywait_stop(unsigned long timeout, unsigned int cpu)
 }
 
 static bool __i915_spin_request(const struct i915_request *rq,
-				u32 seqno, int state, unsigned long timeout_us)
+				u64 seqno, int state, unsigned long timeout_us)
 {
 	struct intel_engine_cs *engine = rq->engine;
 	unsigned int irq, cpu;
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 68d36eeb5edb..d7fe917c48d4 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -43,7 +43,7 @@ struct intel_wait {
 	struct rb_node node;
 	struct task_struct *tsk;
 	struct i915_request *request;
-	u32 seqno;
+	u64 seqno;
 };
 
 struct intel_signal_node {
@@ -140,7 +140,7 @@ struct i915_request {
 	 * on the HW queue (i.e. not on the engine timeline list).
 	 * Its value is guarded by the timeline spinlock.
 	 */
-	u32 global_seqno;
+	u64 global_seqno;
 
 	/** Position in the ring of the start of the request */
 	u32 head;
@@ -252,7 +252,7 @@ i915_request_put(struct i915_request *rq)
  * that it has passed the global seqno and the global seqno is unchanged
  * after the read, it is indeed complete).
  */
-static u32
+static u64
 i915_request_global_seqno(const struct i915_request *request)
 {
 	return READ_ONCE(request->global_seqno);
@@ -318,7 +318,7 @@ static inline bool i915_request_started(const struct i915_request *rq)
 }
 
 static inline bool
-__i915_request_completed(const struct i915_request *rq, u32 seqno)
+__i915_request_completed(const struct i915_request *rq, u64 seqno)
 {
 	GEM_BUG_ON(!seqno);
 	return intel_engine_has_completed(rq->engine, seqno) &&
@@ -327,7 +327,7 @@ __i915_request_completed(const struct i915_request *rq, u32 seqno)
 
 static inline bool i915_request_completed(const struct i915_request *rq)
 {
-	u32 seqno;
+	u64 seqno;
 
 	seqno = i915_request_global_seqno(rq);
 	if (!seqno)
diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c
index 7a19fb78601b..15069d03eb91 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -586,7 +586,7 @@ reset_request(struct intel_engine_cs *engine,
 
 	if (i915_request_completed(rq)) {
 		GEM_TRACE("%s pardoned global=%d (fence %llx:%d), current %d\n",
-			  engine->name, rq->global_seqno,
+			  engine->name, lower_32_bits(rq->global_seqno),
 			  rq->fence.context, rq->fence.seqno,
 			  intel_engine_get_seqno(engine));
 		stalled = false;
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 84bf8d827136..d2975e6473bb 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -642,7 +642,7 @@ static int intel_breadcrumbs_signaler(void *arg)
 
 		spin_lock_irq(&b->rb_lock);
 		list_for_each_entry_safe(rq, n, &b->signals, signaling.link) {
-			u32 this = rq->signaling.wait.seqno;
+			u64 this = rq->signaling.wait.seqno;
 
 			GEM_BUG_ON(!rq->signaling.wait.seqno);
 
@@ -743,7 +743,7 @@ bool intel_engine_enable_signaling(struct i915_request *request, bool wakeup)
 	struct intel_engine_cs *engine = request->engine;
 	struct intel_breadcrumbs *b = &engine->breadcrumbs;
 	struct intel_wait *wait = &request->signaling.wait;
-	u32 seqno;
+	u64 seqno;
 
 	/*
 	 * Note that we may be called from an interrupt handler on another
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index b122d82465d0..786fb03c288d 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1240,7 +1240,7 @@ static void print_request(struct drm_printer *m,
 
 	drm_printf(m, "%s%x%s [%llx:%x]%s @ %dms: %s\n",
 		   prefix,
-		   rq->global_seqno,
+		   lower_32_bits(rq->global_seqno),
 		   i915_request_completed(rq) ? "!" : "",
 		   rq->fence.context, rq->fence.seqno,
 		   buf,
@@ -1564,7 +1564,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 		struct intel_wait *w = rb_entry(rb, typeof(*w), node);
 
 		drm_printf(m, "\t%s [%d] waiting for %x\n",
-			   w->tsk->comm, w->tsk->pid, w->seqno);
+			   w->tsk->comm, w->tsk->pid, lower_32_bits(w->seqno));
 	}
 	spin_unlock(&b->rb_lock);
 	local_irq_restore(flags);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index f4905595754a..2cc69da88244 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -435,7 +435,7 @@ static void execlists_submit_ports(struct intel_engine_cs *engine)
 			GEM_TRACE("%s in[%d]:  ctx=%d.%d, global=%d (fence %llx:%d) (current %d), prio=%d\n",
 				  engine->name, n,
 				  port[n].context_id, count,
-				  rq->global_seqno,
+				  lower_32_bits(rq->global_seqno),
 				  rq->fence.context, rq->fence.seqno,
 				  intel_engine_get_seqno(engine),
 				  rq_prio(rq));
@@ -728,7 +728,7 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
 		GEM_TRACE("%s:port%u global=%d (fence %llx:%d), (current %d)\n",
 			  rq->engine->name,
 			  (unsigned int)(port - execlists->port),
-			  rq->global_seqno,
+			  lower_32_bits(rq->global_seqno),
 			  rq->fence.context, rq->fence.seqno,
 			  intel_engine_get_seqno(rq->engine));
 
@@ -937,7 +937,7 @@ static void process_csb(struct intel_engine_cs *engine)
 		GEM_TRACE("%s out[0]: ctx=%d.%d, global=%d (fence %llx:%d) (current %d), prio=%d\n",
 			  engine->name,
 			  port->context_id, count,
-			  rq ? rq->global_seqno : 0,
+			  rq ? lower_32_bits(rq->global_seqno) : 0,
 			  rq ? rq->fence.context : 0,
 			  rq ? rq->fence.seqno : 0,
 			  intel_engine_get_seqno(engine),
@@ -1710,8 +1710,8 @@ static void execlists_reset(struct intel_engine_cs *engine,
 	unsigned long flags;
 	u32 *regs;
 
-	GEM_TRACE("%s request global=%x, current=%d\n",
-		  engine->name, request ? request->global_seqno : 0,
+	GEM_TRACE("%s request global=%d, current=%d\n",
+		  engine->name, request ? lower_32_bits(request->global_seqno) : 0,
 		  intel_engine_get_seqno(engine));
 
 	spin_lock_irqsave(&engine->timeline.lock, flags);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index fe5b8ead5f97..acde3efbf3b8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -574,7 +574,9 @@ static void skip_request(struct i915_request *rq)
 
 static void reset_ring(struct intel_engine_cs *engine, struct i915_request *rq)
 {
-	GEM_TRACE("%s seqno=%x\n", engine->name, rq ? rq->global_seqno : 0);
+	GEM_TRACE("%s seqno=%x\n",
+		  engine->name,
+		  rq ? lower_32_bits(rq->global_seqno) : 0);
 
 	/*
 	 * Try to restore the logical GPU state to match the continuation
@@ -763,7 +765,7 @@ gen6_ring_sync_to(struct i915_request *rq, struct i915_request *signal)
 	 * seqno is >= the last seqno executed. However for hardware the
 	 * comparison is strictly greater than.
 	 */
-	*cs++ = signal->global_seqno - 1;
+	*cs++ = lower_32_bits(signal->global_seqno) - 1;
 	*cs++ = 0;
 	*cs++ = MI_NOOP;
 	intel_ring_advance(rq, cs);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index f6ec48a75a69..dc7eebfd0794 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -992,7 +992,7 @@ static inline void intel_wait_init(struct intel_wait *wait)
 	wait->request = NULL;
 }
 
-static inline void intel_wait_init_for_seqno(struct intel_wait *wait, u32 seqno)
+static inline void intel_wait_init_for_seqno(struct intel_wait *wait, u64 seqno)
 {
 	wait->tsk = current;
 	wait->seqno = seqno;
@@ -1004,7 +1004,7 @@ static inline bool intel_wait_has_seqno(const struct intel_wait *wait)
 }
 
 static inline bool
-intel_wait_update_seqno(struct intel_wait *wait, u32 seqno)
+intel_wait_update_seqno(struct intel_wait *wait, u64 seqno)
 {
 	wait->seqno = seqno;
 	return intel_wait_has_seqno(wait);
@@ -1018,7 +1018,7 @@ intel_wait_update_request(struct intel_wait *wait,
 }
 
 static inline bool
-intel_wait_check_seqno(const struct intel_wait *wait, u32 seqno)
+intel_wait_check_seqno(const struct intel_wait *wait, u64 seqno)
 {
 	return wait->seqno == seqno;
 }
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index 8b73a8c21377..9553b9336ce3 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -223,7 +223,8 @@ static int igt_request_rewind(void *arg)
 
 	if (i915_request_wait(vip, 0, HZ) == -ETIME) {
 		pr_err("timed out waiting for high priority request, vip.seqno=%d, current seqno=%d\n",
-		       vip->global_seqno, intel_engine_get_seqno(i915->engine[RCS]));
+		       lower_32_bits(vip->global_seqno),
+		       intel_engine_get_seqno(i915->engine[RCS]));
 		goto err;
 	}
 
diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
index f03b407fdbe2..a84daeeb9cd7 100644
--- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
@@ -49,13 +49,13 @@ static int check_rbtree(struct intel_engine_cs *engine,
 
 		if (!test_bit(idx, bitmap)) {
 			pr_err("waiter[%d, seqno=%d] removed but still in wait-tree\n",
-			       idx, w->seqno);
+			       idx, lower_32_bits(w->seqno));
 			return -EINVAL;
 		}
 
 		if (n != idx) {
 			pr_err("waiter[%d, seqno=%d] does not match expected next element in tree [%d]\n",
-			       idx, w->seqno, n);
+			       idx, lower_32_bits(w->seqno), n);
 			return -EINVAL;
 		}
 
@@ -77,7 +77,7 @@ static int check_completion(struct intel_engine_cs *engine,
 			continue;
 
 		pr_err("waiter[%d, seqno=%d] is %s, but expected %s\n",
-		       n, waiters[n].seqno,
+		       n,lower_32_bits( waiters[n].seqno),
 		       intel_wait_complete(&waiters[n]) ? "complete" : "active",
 		       test_bit(n, bitmap) ? "active" : "complete");
 		return -EINVAL;
@@ -217,7 +217,7 @@ static int igt_insert_complete(void *arg)
 
 		if (intel_wait_complete(&waiters[n])) {
 			pr_err("waiter[%d, seqno=%d] completed too early\n",
-			       n, waiters[n].seqno);
+			       n, lower_32_bits(waiters[n].seqno));
 			err = -EINVAL;
 			goto out_bitmap;
 		}
diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
index 7966b9538288..db271722b274 100644
--- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
@@ -489,7 +489,7 @@ static int __igt_reset_engine(struct drm_i915_private *i915, bool active)
 				}
 
 				GEM_BUG_ON(!rq->global_seqno);
-				seqno = rq->global_seqno - 1;
+				seqno = lower_32_bits(rq->global_seqno) - 1;
 				i915_request_put(rq);
 			}
 
@@ -583,7 +583,7 @@ static int active_request_put(struct i915_request *rq)
 			  rq->engine->name,
 			  rq->fence.context,
 			  rq->fence.seqno,
-			  i915_request_global_seqno(rq));
+			  lower_32_bits(i915_request_global_seqno(rq)));
 		GEM_TRACE_DUMP();
 
 		i915_gem_set_wedged(rq->i915);
@@ -767,7 +767,7 @@ static int __igt_reset_engines(struct drm_i915_private *i915,
 				}
 
 				GEM_BUG_ON(!rq->global_seqno);
-				seqno = rq->global_seqno - 1;
+				seqno = lower_32_bits(rq->global_seqno) - 1;
 			}
 
 			err = i915_reset_engine(engine, NULL);
-- 
2.19.0



More information about the Intel-gfx-trybot mailing list