aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-27 09:00:07 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2017-03-27 10:02:56 -0400
commit450362d3fe866b14304f309b5fffba0c33fbfbc3 (patch)
treec53e201e5df3e0382777dad59052deb7d9de1d06 /drivers/gpu/drm/i915/intel_ringbuffer.h
parentf9407ae1533111cd43161734582932b13397ab7e (diff)
drm/i915/execlists: Wrap tail pointer after reset tweaking
If the request->wa_tail is 0 (because it landed exactly on the end of the ringbuffer), when we reconstruct request->tail following a reset we fill in an illegal value (-8 or 0x001ffff8). As a result, RING_HEAD is never able to catch up with RING_TAIL and the GPU spins endlessly. If the ring contains a couple of breadcrumbs, even our hangcheck is unable to catch the busy-looping as the ACTHD and seqno continually advance. v2: Move the wrap into a common intel_ring_wrap(). Fixes: a3aabe86a340 ("drm/i915/execlists: Reinitialise context image after GPU hang") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Cc: <stable@vger.kernel.org> # v4.10+ Link: http://patchwork.freedesktop.org/patch/msgid/20170327130009.4678-1-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.h')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 166aa1ae65cf..17ac44980d84 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -515,12 +515,18 @@ intel_ring_advance(struct drm_i915_gem_request *req, u32 *cs)
515} 515}
516 516
517static inline u32 517static inline u32
518intel_ring_offset(struct drm_i915_gem_request *req, void *addr) 518intel_ring_wrap(const struct intel_ring *ring, u32 pos)
519{
520 return pos & (ring->size - 1);
521}
522
523static inline u32
524intel_ring_offset(const struct drm_i915_gem_request *req, void *addr)
519{ 525{
520 /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */ 526 /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */
521 u32 offset = addr - req->ring->vaddr; 527 u32 offset = addr - req->ring->vaddr;
522 GEM_BUG_ON(offset > req->ring->size); 528 GEM_BUG_ON(offset > req->ring->size);
523 return offset & (req->ring->size - 1); 529 return intel_ring_wrap(req->ring, offset);
524} 530}
525 531
526void intel_ring_update_space(struct intel_ring *ring); 532void intel_ring_update_space(struct intel_ring *ring);