Skip to content

Commit

Permalink
drm/i915: Prevent recursion by retiring requests when the ring is full
Browse files Browse the repository at this point in the history
As the VM do not track activity of objects and instead use a large
hammer to forcibly idle and evict all of their associated objects when
one is released, it is possible for that to cause a recursion when we
need to wait for free space on a ring and call retire requests.
(intel_ring_begin -> intel_ring_wait_request ->
i915_gem_retire_requests_ring -> i915_gem_context_free ->
i915_gem_evict_vm -> i915_gpu_idle -> intel_ring_begin etc)

In order to remove the requirement for calling retire-requests from
intel_ring_wait_request, we have to inline a couple of steps from
retiring requests, notably we have to record the position of the request
we wait for and use that to update the available ring space.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Feb 6, 2014
1 parent 011cf57 commit 1f70999
Showing 1 changed file with 5 additions and 20 deletions.
25 changes: 5 additions & 20 deletions drivers/gpu/drm/i915/intel_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,28 +1430,16 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring)
cleanup_status_page(ring);
}

static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno)
{
int ret;

ret = i915_wait_seqno(ring, seqno);
if (!ret)
i915_gem_retire_requests_ring(ring);

return ret;
}

static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n)
{
struct drm_i915_gem_request *request;
u32 seqno = 0;
u32 seqno = 0, tail;
int ret;

i915_gem_retire_requests_ring(ring);

if (ring->last_retired_head != -1) {
ring->head = ring->last_retired_head;
ring->last_retired_head = -1;

ring->space = ring_space(ring);
if (ring->space >= n)
return 0;
Expand All @@ -1468,6 +1456,7 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n)
space += ring->size;
if (space >= n) {
seqno = request->seqno;
tail = request->tail;
break;
}

Expand All @@ -1482,15 +1471,11 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n)
if (seqno == 0)
return -ENOSPC;

ret = intel_ring_wait_seqno(ring, seqno);
ret = i915_wait_seqno(ring, seqno);
if (ret)
return ret;

if (WARN_ON(ring->last_retired_head == -1))
return -ENOSPC;

ring->head = ring->last_retired_head;
ring->last_retired_head = -1;
ring->head = tail;
ring->space = ring_space(ring);
if (WARN_ON(ring->space < n))
return -ENOSPC;
Expand Down

0 comments on commit 1f70999

Please sign in to comment.