summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_ringbuffer.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-06-11 12:08:45 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2018-06-11 14:03:49 +0100
commit41d37680ca0b157ad1ed29409bcdc2b0bc21d11f (patch)
tree755292c6753cfc09aa1707871eba43a20e041ffd /drivers/gpu/drm/i915/intel_ringbuffer.h
parentb3ee09a4de33259a89d30aca6b2ebb0bc26640af (diff)
drm/i915: Wrap around the tail offset before setting ring->tail
The HW only accepts offsets within ring->size, and fails peculiarly if the RING_HEAD or RING_TAIL is set to ring->size. Therefore whenever we set ring->head/ring->tail we want to make sure it is within value (using intel_ring_wrap()). v2: Double check execlists as well v3: Remove redundancy with assert_ring_tail_valid() v4: Just assert in intel_ring_reset() rather than be over-defensive. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Cc: Matthew Auld <matthew.william.auld@gmail.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> #v2 Link: https://patchwork.freedesktop.org/patch/msgid/20180611110845.31890-2-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index b44c67849749..e9494557aaa1 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -805,6 +805,19 @@ static inline u32 intel_ring_wrap(const struct intel_ring *ring, u32 pos)
return pos & (ring->size - 1);
}
+static inline bool
+intel_ring_offset_valid(const struct intel_ring *ring,
+ unsigned int pos)
+{
+ if (pos & -ring->size) /* must be strictly within the ring */
+ return false;
+
+ if (!IS_ALIGNED(pos, 8)) /* must be qword aligned */
+ return false;
+
+ return true;
+}
+
static inline u32 intel_ring_offset(const struct i915_request *rq, void *addr)
{
/* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */
@@ -816,12 +829,7 @@ static inline u32 intel_ring_offset(const struct i915_request *rq, void *addr)
static inline void
assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
{
- /* We could combine these into a single tail operation, but keeping
- * them as seperate tests will help identify the cause should one
- * ever fire.
- */
- GEM_BUG_ON(!IS_ALIGNED(tail, 8));
- GEM_BUG_ON(tail >= ring->size);
+ GEM_BUG_ON(!intel_ring_offset_valid(ring, tail));
/*
* "Ring Buffer Use"