summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsg <jsg@openbsd.org>2020-06-26 05:36:26 +0000
committerjsg <jsg@openbsd.org>2020-06-26 05:36:26 +0000
commit2fdb5a15b104ad5b5631349b25bd1b3feb37f2bc (patch)
tree5cef80ac55587de7d3421fcc61ffc39ef2c6ac73
parentdrm/i915/tc: fix the reset of ln0 (diff)
downloadwireguard-openbsd-2fdb5a15b104ad5b5631349b25bd1b3feb37f2bc.tar.xz
wireguard-openbsd-2fdb5a15b104ad5b5631349b25bd1b3feb37f2bc.zip
drm/i915/gt: Incrementally check for rewinding
From Chris Wilson 79eb9f19dbd2418c25e67f70d3b2fdc98a60dbea in linux 5.7.y/5.7.6 8ab3a3812aa90e488813e719308ffd807b865624 in mainline linux
-rw-r--r--sys/dev/pci/drm/i915/gt/intel_engine_cs.c4
-rw-r--r--sys/dev/pci/drm/i915/gt/intel_lrc.c21
-rw-r--r--sys/dev/pci/drm/i915/gt/intel_ring.c4
-rw-r--r--sys/dev/pci/drm/i915/gt/selftest_mocs.c18
4 files changed, 43 insertions, 4 deletions
diff --git a/sys/dev/pci/drm/i915/gt/intel_engine_cs.c b/sys/dev/pci/drm/i915/gt/intel_engine_cs.c
index 2a702cceacb..fbb0eeeee17 100644
--- a/sys/dev/pci/drm/i915/gt/intel_engine_cs.c
+++ b/sys/dev/pci/drm/i915/gt/intel_engine_cs.c
@@ -639,7 +639,7 @@ static int engine_setup_common(struct intel_engine_cs *engine)
struct measure_breadcrumb {
struct i915_request rq;
struct intel_ring ring;
- u32 cs[1024];
+ u32 cs[2048];
};
static int measure_breadcrumb_dw(struct intel_context *ce)
@@ -661,6 +661,8 @@ static int measure_breadcrumb_dw(struct intel_context *ce)
frame->ring.vaddr = frame->cs;
frame->ring.size = sizeof(frame->cs);
+ frame->ring.wrap =
+ BITS_PER_TYPE(frame->ring.size) - ilog2(frame->ring.size);
frame->ring.effective_size = frame->ring.size;
intel_ring_update_space(&frame->ring);
frame->rq.ring = &frame->ring;
diff --git a/sys/dev/pci/drm/i915/gt/intel_lrc.c b/sys/dev/pci/drm/i915/gt/intel_lrc.c
index 4b1de5337bf..b6071c7f689 100644
--- a/sys/dev/pci/drm/i915/gt/intel_lrc.c
+++ b/sys/dev/pci/drm/i915/gt/intel_lrc.c
@@ -972,6 +972,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
list_move(&rq->sched.link, pl);
set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags);
+ /* Check in case we rollback so far we wrap [size/2] */
+ if (intel_ring_direction(rq->ring,
+ intel_ring_wrap(rq->ring,
+ rq->tail),
+ rq->ring->tail) > 0)
+ rq->context->lrc.desc |= CTX_DESC_FORCE_RESTORE;
+
active = rq;
} else {
struct intel_engine_cs *owner = rq->context->engine;
@@ -1385,8 +1392,9 @@ static u64 execlists_update_context(struct i915_request *rq)
* HW has a tendency to ignore us rewinding the TAIL to the end of
* an earlier request.
*/
+ GEM_BUG_ON(ce->lrc_reg_state[CTX_RING_TAIL] != rq->ring->tail);
+ prev = rq->ring->tail;
tail = intel_ring_set_tail(rq->ring, rq->tail);
- prev = ce->lrc_reg_state[CTX_RING_TAIL];
if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0))
desc |= CTX_DESC_FORCE_RESTORE;
ce->lrc_reg_state[CTX_RING_TAIL] = tail;
@@ -4233,6 +4241,14 @@ static int gen12_emit_flush_render(struct i915_request *request,
return 0;
}
+static void assert_request_valid(struct i915_request *rq)
+{
+ struct intel_ring *ring __maybe_unused = rq->ring;
+
+ /* Can we unwind this request without appearing to go forwards? */
+ GEM_BUG_ON(intel_ring_direction(ring, rq->wa_tail, rq->head) <= 0);
+}
+
/*
* Reserve space for 2 NOOPs at the end of each request to be
* used as a workaround for not being allowed to do lite
@@ -4245,6 +4261,9 @@ static u32 *gen8_emit_wa_tail(struct i915_request *request, u32 *cs)
*cs++ = MI_NOOP;
request->wa_tail = intel_ring_offset(request, cs);
+ /* Check that entire request is less than half the ring */
+ assert_request_valid(request);
+
return cs;
}
diff --git a/sys/dev/pci/drm/i915/gt/intel_ring.c b/sys/dev/pci/drm/i915/gt/intel_ring.c
index 8cda1b7e17b..bdb324167ef 100644
--- a/sys/dev/pci/drm/i915/gt/intel_ring.c
+++ b/sys/dev/pci/drm/i915/gt/intel_ring.c
@@ -315,3 +315,7 @@ int intel_ring_cacheline_align(struct i915_request *rq)
GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1));
return 0;
}
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_ring.c"
+#endif
diff --git a/sys/dev/pci/drm/i915/gt/selftest_mocs.c b/sys/dev/pci/drm/i915/gt/selftest_mocs.c
index 8831ffee206..63f87d8608c 100644
--- a/sys/dev/pci/drm/i915/gt/selftest_mocs.c
+++ b/sys/dev/pci/drm/i915/gt/selftest_mocs.c
@@ -18,6 +18,20 @@ struct live_mocs {
void *vaddr;
};
+static struct intel_context *mocs_context_create(struct intel_engine_cs *engine)
+{
+ struct intel_context *ce;
+
+ ce = intel_context_create(engine);
+ if (IS_ERR(ce))
+ return ce;
+
+ /* We build large requests to read the registers from the ring */
+ ce->ring = __intel_context_ring_size(SZ_16K);
+
+ return ce;
+}
+
static int request_add_sync(struct i915_request *rq, int err)
{
i915_request_get(rq);
@@ -301,7 +315,7 @@ static int live_mocs_clean(void *arg)
for_each_engine(engine, gt, id) {
struct intel_context *ce;
- ce = intel_context_create(engine);
+ ce = mocs_context_create(engine);
if (IS_ERR(ce)) {
err = PTR_ERR(ce);
break;
@@ -395,7 +409,7 @@ static int live_mocs_reset(void *arg)
for_each_engine(engine, gt, id) {
struct intel_context *ce;
- ce = intel_context_create(engine);
+ ce = mocs_context_create(engine);
if (IS_ERR(ce)) {
err = PTR_ERR(ce);
break;