Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c        |    5 ++-
 drivers/gpu/drm/i915/i915_drv.h            |   17 +++------
 drivers/gpu/drm/i915/i915_gem.c            |   55 +++++++++++++++++++---------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |    1 -
 drivers/gpu/drm/i915/i915_irq.c            |    4 +-
 5 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 87c8e29..2aedceb 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -118,14 +118,15 @@ static const char *agp_type_str(int type)
 static void
 describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 {
-       seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s",
+       seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d %d%s%s%s",
                   &obj->base,
                   get_pin_flag(obj),
                   get_tiling_flag(obj),
                   obj->base.size,
                   obj->base.read_domains,
                   obj->base.write_domain,
-                  obj->last_rendering_seqno,
+                  obj->last_read_seqno,
+                  obj->last_write_seqno,
                   obj->last_fenced_seqno,
                   agp_type_str(obj->agp_type == AGP_USER_CACHED_MEMORY),
                   obj->dirty ? " dirty" : "",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ed970bd..967a599 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -554,7 +554,7 @@ typedef struct drm_i915_private {
                 * List of objects currently involved in rendering.
                 *
                 * Includes buffers having the contents of their GPU caches
-                * flushed, not necessarily primitives.  last_rendering_seqno
+                * flushed, not necessarily primitives.  last_read_seqno
                 * represents when the rendering involved will be completed.
                 *
                 * A reference is held on the buffer while on this list.
@@ -566,7 +566,7 @@ typedef struct drm_i915_private {
                 * still have a write_domain which needs to be flushed before
                 * unbinding.
                 *
-                * last_rendering_seqno is 0 while an object is in this list.
+                * last_read_seqno is 0 while an object is in this list.
                 *
                 * A reference is held on the buffer while on this list.
                 */
@@ -576,7 +576,7 @@ typedef struct drm_i915_private {
                 * LRU list of objects which are not in the ringbuffer and
                 * are ready to unbind, but are still in the GTT.
                 *
-                * last_rendering_seqno is 0 while an object is in this list.
+                * All seqno are 0 while an object is in this list.
                 *
                 * A reference is not held on the buffer while on this list,
                 * as merely being GTT-bound shouldn't prevent its being
@@ -734,12 +734,6 @@ struct drm_i915_gem_object {
        unsigned int dirty : 1;
 
        /**
-        * This is set if the object has been written to since the last
-        * GPU flush.
-        */
-       unsigned int pending_gpu_write : 1;
-
-       /**
         * Fence register bits (if any) for this object.  Will be set
         * as needed when mapped into the GTT.
         * Protected by dev->struct_mutex.
@@ -814,7 +808,8 @@ struct drm_i915_gem_object {
        uint32_t gtt_offset;
 
        /** Breadcrumb of last rendering to the buffer. */
-       uint32_t last_rendering_seqno;
+       uint32_t last_read_seqno;
+       uint32_t last_write_seqno;
        struct intel_ring_buffer *ring;
 
        /** Breadcrumb of last fenced GPU access to the buffer. */
@@ -859,7 +854,7 @@ struct drm_i915_gem_object {
  * and may be associated with active buffers to be retired.
  *
  * By keeping this list, we can avoid having to do questionable
- * sequence-number comparisons on buffer last_rendering_seqnos, and associate
+ * sequence-number comparisons on buffer last_read_seqnos, and associate
  * an emission time with seqnos for tracking how far ahead of the GPU we are.
  */
 struct drm_i915_gem_request {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d8a0f7b..f63d33c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1623,13 +1623,17 @@ i915_gem_object_move_to_ring(struct drm_i915_gem_object 
*obj,
        if (from == NULL || to == from)
                return 0;
 
-       /* XXX gpu semaphores are implicated in various hard hangs on SNB */
+       ret = i915_gem_object_flush_gpu_write_domain(obj);
+       if (ret)
+               return ret;
+
        if (to == NULL || !HAS_GPU_SEMAPHORES(obj->base.dev))
-               return i915_gem_object_wait_rendering(obj);
+               return i915_wait_request(obj->ring,
+                                        obj->last_read_seqno);
 
        idx = intel_ring_sync_index(from, to);
 
-       seqno = obj->last_rendering_seqno;
+       seqno = obj->last_read_seqno;
        if (seqno <= from->sync_seqno[idx])
                return 0;
 
@@ -1672,7 +1676,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object 
*obj,
        list_move_tail(&obj->mm_list, &dev_priv->mm.active_list);
        list_move_tail(&obj->ring_list, &ring->active_list);
 
-       obj->last_rendering_seqno = seqno;
+       obj->last_read_seqno = seqno;
        if (obj->fenced_gpu_access) {
                struct drm_i915_fence_reg *reg;
 
@@ -1689,7 +1693,7 @@ static void
 i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
 {
        list_del_init(&obj->ring_list);
-       obj->last_rendering_seqno = 0;
+       obj->last_read_seqno = 0;
 }
 
 static void
@@ -1722,10 +1726,10 @@ i915_gem_object_move_to_inactive(struct 
drm_i915_gem_object *obj)
        i915_gem_object_move_off_active(obj);
        obj->fenced_gpu_access = false;
 
+       obj->last_write_seqno = 0;
        obj->last_fenced_seqno = 0;
 
        obj->active = 0;
-       obj->pending_gpu_write = false;
        drm_gem_object_unreference(&obj->base);
 
        WARN_ON(i915_verify_lists(dev));
@@ -1773,6 +1777,7 @@ i915_gem_process_flushing_list(struct intel_ring_buffer 
*ring,
                        seqno = i915_gem_next_request_seqno(ring);
 
                        obj->base.write_domain = 0;
+                       obj->last_write_seqno = seqno;
                        list_del_init(&obj->gpu_write_list);
                        i915_gem_object_move_to_active(obj, ring, seqno);
 
@@ -1967,7 +1972,7 @@ i915_ring_outstanding_dispatch(struct intel_ring_buffer 
*ring)
 
        last_dispatch = list_entry(ring->active_list.prev,
                                   struct drm_i915_gem_object,
-                                  ring_list)->last_rendering_seqno;
+                                  ring_list)->last_read_seqno;
 
        return !i915_seqno_passed(last_request, last_dispatch);
 }
@@ -2027,7 +2032,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer 
*ring)
                                      struct drm_i915_gem_object,
                                      ring_list);
 
-               if (!i915_seqno_passed(seqno, obj->last_rendering_seqno))
+               if (!i915_seqno_passed(seqno, obj->last_read_seqno))
                        break;
 
                if (obj->base.write_domain != 0)
@@ -2222,7 +2227,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object 
*obj)
         * it.
         */
        if (obj->active) {
-               ret = i915_wait_request(obj->ring, obj->last_rendering_seqno);
+               ret = i915_wait_request(obj->ring, obj->last_read_seqno);
                if (ret)
                        return ret;
        }
@@ -2565,7 +2570,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object 
*obj,
                        return ret;
 
                /* Since last_fence_seqno can retire much earlier than
-                * last_rendering_seqno, we track that here for efficiency.
+                * last_read_seqno, we track that here for efficiency.
                 * (With a catch-all in move_to_inactive() to prevent very
                 * old seqno from lying around.)
                 */
@@ -3048,6 +3053,7 @@ int
 i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
 {
        uint32_t old_write_domain, old_read_domains;
+       u32 seqno;
        int ret;
 
        /* Not valid to be called on unbound objects. */
@@ -3061,10 +3067,13 @@ i915_gem_object_set_to_gtt_domain(struct 
drm_i915_gem_object *obj, bool write)
        if (ret)
                return ret;
 
-       if (obj->pending_gpu_write || write) {
-               ret = i915_gem_object_wait_rendering(obj);
+       seqno = write ? obj->last_read_seqno : obj->last_write_seqno;
+       if (seqno) {
+               ret = i915_wait_request(obj->ring, seqno);
                if (ret)
                        return ret;
+
+               obj->last_write_seqno = 0;
        }
 
        i915_gem_object_flush_cpu_write_domain(obj);
@@ -3147,6 +3156,7 @@ static int
 i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
 {
        uint32_t old_write_domain, old_read_domains;
+       u32 seqno;
        int ret;
 
        if (obj->base.write_domain == I915_GEM_DOMAIN_CPU)
@@ -3156,9 +3166,14 @@ i915_gem_object_set_to_cpu_domain(struct 
drm_i915_gem_object *obj, bool write)
        if (ret)
                return ret;
 
-       ret = i915_gem_object_wait_rendering(obj);
-       if (ret)
-               return ret;
+       seqno = write ? obj->last_read_seqno : obj->last_write_seqno;
+       if (seqno) {
+               ret = i915_wait_request(obj->ring, seqno);
+               if (ret)
+                       return ret;
+
+               obj->last_write_seqno = 0;
+       }
 
        i915_gem_object_flush_gtt_write_domain(obj);
 
@@ -3254,9 +3269,13 @@ i915_gem_object_set_cpu_read_domain_range(struct 
drm_i915_gem_object *obj,
        if (ret)
                return ret;
 
-       ret = i915_gem_object_wait_rendering(obj);
-       if (ret)
-               return ret;
+       if (obj->last_write_seqno) {
+               ret = i915_wait_request(obj->ring, obj->last_write_seqno);
+               if (ret)
+                       return ret;
+
+               obj->last_write_seqno = 0;
+       }
 
        i915_gem_object_flush_gtt_write_domain(obj);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 60aaf99..3c54911 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -863,7 +863,6 @@ i915_gem_execbuffer_move_to_active(struct list_head 
*objects,
                i915_gem_object_move_to_active(obj, ring, seqno);
                if (obj->base.write_domain) {
                        obj->dirty = 1;
-                       obj->pending_gpu_write = true;
                        list_move_tail(&obj->gpu_write_list,
                                       &ring->gpu_write_list);
                        intel_mark_busy(ring->dev, obj);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 188b497..c1e4368 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -662,7 +662,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer 
*err,
        list_for_each_entry(obj, head, mm_list) {
                err->size = obj->base.size;
                err->name = obj->base.name;
-               err->seqno = obj->last_rendering_seqno;
+               err->seqno = obj->last_read_seqno;
                err->gtt_offset = obj->gtt_offset;
                err->read_domains = obj->base.read_domains;
                err->write_domain = obj->base.write_domain;
@@ -731,7 +731,7 @@ i915_error_first_batchbuffer(struct drm_i915_private 
*dev_priv,
                if (obj->ring != ring)
                        continue;
 
-               if (i915_seqno_passed(seqno, obj->last_rendering_seqno))
+               if (i915_seqno_passed(seqno, obj->last_read_seqno))
                        continue;
 
                if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0)
-- 
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