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:a3aabe86a3
("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> (cherry picked from commit450362d3fe
) Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170329121315.1290-1-chris@chris-wilson.co.uk
This commit is contained in:
parent
aa62acfd63
commit
dd68f2ba07
@ -1440,7 +1440,9 @@ static void reset_common_ring(struct intel_engine_cs *engine,
|
||||
GEM_BUG_ON(request->ctx != port[0].request->ctx);
|
||||
|
||||
/* Reset WaIdleLiteRestore:bdw,skl as well */
|
||||
request->tail = request->wa_tail - WA_TAIL_DWORDS * sizeof(u32);
|
||||
request->tail =
|
||||
intel_ring_wrap(request->ring,
|
||||
request->wa_tail - WA_TAIL_DWORDS*sizeof(u32));
|
||||
}
|
||||
|
||||
static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req)
|
||||
|
@ -521,11 +521,17 @@ static inline void intel_ring_advance(struct intel_ring *ring)
|
||||
*/
|
||||
}
|
||||
|
||||
static inline u32
|
||||
intel_ring_wrap(const struct intel_ring *ring, u32 pos)
|
||||
{
|
||||
return pos & (ring->size - 1);
|
||||
}
|
||||
|
||||
static inline u32 intel_ring_offset(struct intel_ring *ring, void *addr)
|
||||
{
|
||||
/* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */
|
||||
u32 offset = addr - ring->vaddr;
|
||||
return offset & (ring->size - 1);
|
||||
return intel_ring_wrap(ring, offset);
|
||||
}
|
||||
|
||||
int __intel_ring_space(int head, int tail, int size);
|
||||
|
Loading…
Reference in New Issue
Block a user