drm/i915: Track requests inside each intel_ring
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 4 Aug 2016 06:52:36 +0000 (07:52 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 4 Aug 2016 07:09:26 +0000 (08:09 +0100)
By tracking each request occupying space inside an individual
intel_ring, we can greatly simplify the logic of tracking available
space and not worry about other timelines. (Each ring is an ordered
timeline of committed requests.)

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470293567-10811-17-git-send-email-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_gem_request.h
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index cdaaeb6dd9131b9ff4899a4028c34a4f8801a655..a91e79fc555367d8dd63ae1c9a154278bcda9b5f 100644 (file)
@@ -180,6 +180,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
         * Note this requires that we are always called in request
         * completion order.
         */
+       list_del(&request->ring_link);
        request->ring->last_retired_head = request->postfix;
 
        /* Walk through the active list, calling retire on each. This allows
@@ -487,6 +488,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
        request->previous_seqno = engine->last_submitted_seqno;
        smp_store_mb(engine->last_submitted_seqno, request->fence.seqno);
        list_add_tail(&request->link, &engine->request_list);
+       list_add_tail(&request->ring_link, &ring->request_list);
 
        /* Record the position of the start of the request so that
         * should we detect the updated seqno part-way through the
index 6cfae2079e192899b2a6abb6deb0697aa104458b..ed1670446d36bbe53fae6716f57e7ae34a91f92b 100644 (file)
@@ -109,6 +109,9 @@ struct drm_i915_gem_request {
        /** engine->request_list entry for this request */
        struct list_head link;
 
+       /** ring->request_list entry for this request */
+       struct list_head ring_link;
+
        struct drm_i915_file_private *file_priv;
        /** file_priv list entry for this request */
        struct list_head client_list;
index 76ddc7cc6d253b8605479988a2ed7f95987be4b1..5b0eac2af28c37f40ab858e593dbdce33fb0428e 100644 (file)
@@ -2046,6 +2046,8 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
        ring->engine = engine;
        list_add(&ring->link, &engine->buffers);
 
+       INIT_LIST_HEAD(&ring->request_list);
+
        ring->size = size;
        /* Workaround an erratum on the i830 which causes a hang if
         * the TAIL pointer points to within the last 2 cachelines
@@ -2266,7 +2268,6 @@ int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request)
 static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 {
        struct intel_ring *ring = req->ring;
-       struct intel_engine_cs *engine = req->engine;
        struct drm_i915_gem_request *target;
 
        intel_ring_update_space(ring);
@@ -2284,17 +2285,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
         */
        GEM_BUG_ON(!req->reserved_space);
 
-       list_for_each_entry(target, &engine->request_list, link) {
+       list_for_each_entry(target, &ring->request_list, ring_link) {
                unsigned space;
 
-               /*
-                * The request queue is per-engine, so can contain requests
-                * from multiple ringbuffers. Here, we must ignore any that
-                * aren't from the ringbuffer we're considering.
-                */
-               if (target->ring != ring)
-                       continue;
-
                /* Would completion of this request free enough space? */
                space = __intel_ring_space(target->postfix, ring->tail,
                                           ring->size);
@@ -2302,7 +2295,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
                        break;
        }
 
-       if (WARN_ON(&target->link == &engine->request_list))
+       if (WARN_ON(&target->ring_link == &ring->request_list))
                return -ENOSPC;
 
        return i915_wait_request(target);
index 236e7a2f5689e61781106c9a86ed5bbeab8d7fb7..88952bf10b9d4317de55edfa8f9897179bc6e3e6 100644 (file)
@@ -90,6 +90,8 @@ struct intel_ring {
        struct intel_engine_cs *engine;
        struct list_head link;
 
+       struct list_head request_list;
+
        u32 head;
        u32 tail;
        int space;