The list walking over objects and requests to retire may take a
significant amount of time, enough time for the GPU to have finished
more batches. So repeat the list walking until the GPU seqno is stable.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem.c |   66 ++++++++++++++++++++-------------------
 1 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b9515ac..58e77d6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1952,47 +1952,45 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer 
*ring)
 
        WARN_ON(i915_verify_lists(ring->dev));
 
-       seqno = ring->get_seqno(ring);
+       do {
+               seqno = ring->get_seqno(ring);
 
-       for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
-               if (seqno >= ring->sync_seqno[i])
-                       ring->sync_seqno[i] = 0;
+               while (!list_empty(&ring->request_list)) {
+                       struct drm_i915_gem_request *request;
 
-       while (!list_empty(&ring->request_list)) {
-               struct drm_i915_gem_request *request;
+                       request = list_first_entry(&ring->request_list,
+                                                  struct drm_i915_gem_request,
+                                                  list);
 
-               request = list_first_entry(&ring->request_list,
-                                          struct drm_i915_gem_request,
-                                          list);
-
-               if (!i915_seqno_passed(seqno, request->seqno))
-                       break;
+                       if (!i915_seqno_passed(seqno, request->seqno))
+                               break;
 
-               trace_i915_gem_request_retire(ring, request->seqno);
+                       trace_i915_gem_request_retire(ring, request->seqno);
 
-               list_del(&request->list);
-               i915_gem_request_remove_from_client(request);
-               kfree(request);
-       }
+                       list_del(&request->list);
+                       i915_gem_request_remove_from_client(request);
+                       kfree(request);
+               }
 
-       /* Move any buffers on the active list that are no longer referenced
-        * by the ringbuffer to the flushing/inactive lists as appropriate.
-        */
-       while (!list_empty(&ring->active_list)) {
-               struct drm_i915_gem_object *obj;
+               /* Move any buffers on the active list that are no longer 
referenced
+                * by the ringbuffer to the flushing/inactive lists as 
appropriate.
+                */
+               while (!list_empty(&ring->active_list)) {
+                       struct drm_i915_gem_object *obj;
 
-               obj= list_first_entry(&ring->active_list,
-                                     struct drm_i915_gem_object,
-                                     ring_list);
+                       obj = list_first_entry(&ring->active_list,
+                                              struct drm_i915_gem_object,
+                                              ring_list);
 
-               if (!i915_seqno_passed(seqno, obj->last_rendering_seqno))
-                       break;
+                       if (!i915_seqno_passed(seqno, 
obj->last_rendering_seqno))
+                               break;
 
-               if (obj->base.write_domain != 0)
-                       i915_gem_object_move_to_flushing(obj);
-               else
-                       i915_gem_object_move_to_inactive(obj);
-       }
+                       if (obj->base.write_domain != 0)
+                               i915_gem_object_move_to_flushing(obj);
+                       else
+                               i915_gem_object_move_to_inactive(obj);
+               }
+       } while (seqno != ring->get_seqno(ring));
 
        if (unlikely(ring->trace_irq_seqno &&
                     i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
@@ -2000,6 +1998,10 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer 
*ring)
                ring->trace_irq_seqno = 0;
        }
 
+       for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
+               if (seqno >= ring->sync_seqno[i])
+                       ring->sync_seqno[i] = 0;
+
        WARN_ON(i915_verify_lists(ring->dev));
 }
 
-- 
1.7.4.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to