i915_gem_find_active_request(struct intel_ring_buffer *ring);
 
 bool i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
 int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
                                      bool interruptible);
 static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
 
 static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
 static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
 static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
-static void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
 
 static bool cpu_cache_is_coherent(struct drm_device *dev,
                                  enum i915_cache_level level)
 /**
  * This function clears the request list as sequence numbers are passed.
  */
-static void
+void
 i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
 {
        uint32_t seqno;
 
  */
 #define CACHELINE_BYTES 64
 
-static inline int ring_space(struct intel_ring_buffer *ring)
+static inline int __ring_space(int head, int tail, int size)
 {
-       int space = (ring->head & HEAD_ADDR) - (ring->tail + I915_RING_FREE_SPACE);
+       int space = head - (tail + I915_RING_FREE_SPACE);
        if (space < 0)
-               space += ring->size;
+               space += size;
        return space;
 }
 
+static inline int ring_space(struct intel_ring_buffer *ring)
+{
+       return __ring_space(ring->head & HEAD_ADDR, ring->tail, ring->size);
+}
+
 static bool intel_ring_stopped(struct intel_ring_buffer *ring)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
 static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n)
 {
        struct drm_i915_gem_request *request;
-       u32 seqno = 0, tail;
+       u32 seqno = 0;
        int ret;
 
        if (ring->last_retired_head != -1) {
        }
 
        list_for_each_entry(request, &ring->request_list, list) {
-               int space;
-
-               if (request->tail == -1)
-                       continue;
-
-               space = request->tail - (ring->tail + I915_RING_FREE_SPACE);
-               if (space < 0)
-                       space += ring->size;
-               if (space >= n) {
+               if (__ring_space(request->tail, ring->tail, ring->size) >= n) {
                        seqno = request->seqno;
-                       tail = request->tail;
                        break;
                }
-
-               /* Consume this request in case we need more space than
-                * is available and so need to prevent a race between
-                * updating last_retired_head and direct reads of
-                * I915_RING_HEAD. It also provides a nice sanity check.
-                */
-               request->tail = -1;
        }
 
        if (seqno == 0)
        if (ret)
                return ret;
 
-       ring->head = tail;
-       ring->space = ring_space(ring);
-       if (WARN_ON(ring->space < n))
-               return -ENOSPC;
+       i915_gem_retire_requests_ring(ring);
+       ring->head = ring->last_retired_head;
+       ring->last_retired_head = -1;
 
+       ring->space = ring_space(ring);
        return 0;
 }