[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