aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-07-20 07:41:01 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-07-25 12:23:52 -0400
commit0201f1ecf4b81f08799b1fb9c8cdf1125b9b78a6 (patch)
tree51b722aace265466c15f884500542b1e54aa25e5
parente5f1d962a8e4c5fd6b3a8155c0f7a40b0bff4a96 (diff)
drm/i915: Replace the pending_gpu_write flag with an explicit seqno
As we always flush the GPU cache prior to emitting the breadcrumb, we no longer have to worry about the deferred flush causing the pending_gpu_write to be delayed. So we can instead utilize the known last_write_seqno to hopefully minimise the wait times. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c9
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h12
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c66
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c5
5 files changed, 51 insertions, 43 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 359f6e8b9b00..a8b7db6161ca 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -121,14 +121,15 @@ static const char *cache_level_str(int type)
121static void 121static void
122describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) 122describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
123{ 123{
124 seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", 124 seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d %d%s%s%s",
125 &obj->base, 125 &obj->base,
126 get_pin_flag(obj), 126 get_pin_flag(obj),
127 get_tiling_flag(obj), 127 get_tiling_flag(obj),
128 obj->base.size / 1024, 128 obj->base.size / 1024,
129 obj->base.read_domains, 129 obj->base.read_domains,
130 obj->base.write_domain, 130 obj->base.write_domain,
131 obj->last_rendering_seqno, 131 obj->last_read_seqno,
132 obj->last_write_seqno,
132 obj->last_fenced_seqno, 133 obj->last_fenced_seqno,
133 cache_level_str(obj->cache_level), 134 cache_level_str(obj->cache_level),
134 obj->dirty ? " dirty" : "", 135 obj->dirty ? " dirty" : "",
@@ -630,12 +631,12 @@ static void print_error_buffers(struct seq_file *m,
630 seq_printf(m, "%s [%d]:\n", name, count); 631 seq_printf(m, "%s [%d]:\n", name, count);
631 632
632 while (count--) { 633 while (count--) {
633 seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s", 634 seq_printf(m, " %08x %8u %04x %04x %x %x%s%s%s%s%s%s%s",
634 err->gtt_offset, 635 err->gtt_offset,
635 err->size, 636 err->size,
636 err->read_domains, 637 err->read_domains,
637 err->write_domain, 638 err->write_domain,
638 err->seqno, 639 err->rseqno, err->wseqno,
639 pin_flag(err->pinned), 640 pin_flag(err->pinned),
640 tiling_flag(err->tiling), 641 tiling_flag(err->tiling),
641 dirty_flag(err->dirty), 642 dirty_flag(err->dirty),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1f5f5ff6f897..49a532e338e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -221,7 +221,7 @@ struct drm_i915_error_state {
221 struct drm_i915_error_buffer { 221 struct drm_i915_error_buffer {
222 u32 size; 222 u32 size;
223 u32 name; 223 u32 name;
224 u32 seqno; 224 u32 rseqno, wseqno;
225 u32 gtt_offset; 225 u32 gtt_offset;
226 u32 read_domains; 226 u32 read_domains;
227 u32 write_domain; 227 u32 write_domain;
@@ -895,12 +895,6 @@ struct drm_i915_gem_object {
895 unsigned int dirty:1; 895 unsigned int dirty:1;
896 896
897 /** 897 /**
898 * This is set if the object has been written to since the last
899 * GPU flush.
900 */
901 unsigned int pending_gpu_write:1;
902
903 /**
904 * Fence register bits (if any) for this object. Will be set 898 * Fence register bits (if any) for this object. Will be set
905 * as needed when mapped into the GTT. 899 * as needed when mapped into the GTT.
906 * Protected by dev->struct_mutex. 900 * Protected by dev->struct_mutex.
@@ -992,7 +986,8 @@ struct drm_i915_gem_object {
992 struct intel_ring_buffer *ring; 986 struct intel_ring_buffer *ring;
993 987
994 /** Breadcrumb of last rendering to the buffer. */ 988 /** Breadcrumb of last rendering to the buffer. */
995 uint32_t last_rendering_seqno; 989 uint32_t last_read_seqno;
990 uint32_t last_write_seqno;
996 /** Breadcrumb of last fenced GPU access to the buffer. */ 991 /** Breadcrumb of last fenced GPU access to the buffer. */
997 uint32_t last_fenced_seqno; 992 uint32_t last_fenced_seqno;
998 993
@@ -1291,7 +1286,6 @@ void i915_gem_lastclose(struct drm_device *dev);
1291int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, 1286int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
1292 gfp_t gfpmask); 1287 gfp_t gfpmask);
1293int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); 1288int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
1294int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj);
1295int i915_gem_object_sync(struct drm_i915_gem_object *obj, 1289int i915_gem_object_sync(struct drm_i915_gem_object *obj,
1296 struct intel_ring_buffer *to); 1290 struct intel_ring_buffer *to);
1297void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, 1291void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3bef7e60ddd6..6a80d6565ef2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1441,7 +1441,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
1441 list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); 1441 list_move_tail(&obj->mm_list, &dev_priv->mm.active_list);
1442 list_move_tail(&obj->ring_list, &ring->active_list); 1442 list_move_tail(&obj->ring_list, &ring->active_list);
1443 1443
1444 obj->last_rendering_seqno = seqno; 1444 obj->last_read_seqno = seqno;
1445 1445
1446 if (obj->fenced_gpu_access) { 1446 if (obj->fenced_gpu_access) {
1447 obj->last_fenced_seqno = seqno; 1447 obj->last_fenced_seqno = seqno;
@@ -1461,7 +1461,8 @@ static void
1461i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) 1461i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
1462{ 1462{
1463 list_del_init(&obj->ring_list); 1463 list_del_init(&obj->ring_list);
1464 obj->last_rendering_seqno = 0; 1464 obj->last_read_seqno = 0;
1465 obj->last_write_seqno = 0;
1465 obj->last_fenced_seqno = 0; 1466 obj->last_fenced_seqno = 0;
1466} 1467}
1467 1468
@@ -1493,7 +1494,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
1493 obj->fenced_gpu_access = false; 1494 obj->fenced_gpu_access = false;
1494 1495
1495 obj->active = 0; 1496 obj->active = 0;
1496 obj->pending_gpu_write = false;
1497 drm_gem_object_unreference(&obj->base); 1497 drm_gem_object_unreference(&obj->base);
1498 1498
1499 WARN_ON(i915_verify_lists(dev)); 1499 WARN_ON(i915_verify_lists(dev));
@@ -1812,7 +1812,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
1812 struct drm_i915_gem_object, 1812 struct drm_i915_gem_object,
1813 ring_list); 1813 ring_list);
1814 1814
1815 if (!i915_seqno_passed(seqno, obj->last_rendering_seqno)) 1815 if (!i915_seqno_passed(seqno, obj->last_read_seqno))
1816 break; 1816 break;
1817 1817
1818 if (obj->base.write_domain != 0) 1818 if (obj->base.write_domain != 0)
@@ -2036,9 +2036,11 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
2036 * Ensures that all rendering to the object has completed and the object is 2036 * Ensures that all rendering to the object has completed and the object is
2037 * safe to unbind from the GTT or access from the CPU. 2037 * safe to unbind from the GTT or access from the CPU.
2038 */ 2038 */
2039int 2039static __must_check int
2040i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) 2040i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
2041 bool readonly)
2041{ 2042{
2043 u32 seqno;
2042 int ret; 2044 int ret;
2043 2045
2044 /* This function only exists to support waiting for existing rendering, 2046 /* This function only exists to support waiting for existing rendering,
@@ -2049,13 +2051,27 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj)
2049 /* If there is rendering queued on the buffer being evicted, wait for 2051 /* If there is rendering queued on the buffer being evicted, wait for
2050 * it. 2052 * it.
2051 */ 2053 */
2052 if (obj->active) { 2054 if (readonly)
2053 ret = i915_wait_seqno(obj->ring, obj->last_rendering_seqno); 2055 seqno = obj->last_write_seqno;
2054 if (ret) 2056 else
2055 return ret; 2057 seqno = obj->last_read_seqno;
2056 i915_gem_retire_requests_ring(obj->ring); 2058 if (seqno == 0)
2059 return 0;
2060
2061 ret = i915_wait_seqno(obj->ring, seqno);
2062 if (ret)
2063 return ret;
2064
2065 /* Manually manage the write flush as we may have not yet retired
2066 * the buffer.
2067 */
2068 if (obj->last_write_seqno &&
2069 i915_seqno_passed(seqno, obj->last_write_seqno)) {
2070 obj->last_write_seqno = 0;
2071 obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
2057 } 2072 }
2058 2073
2074 i915_gem_retire_requests_ring(obj->ring);
2059 return 0; 2075 return 0;
2060} 2076}
2061 2077
@@ -2074,10 +2090,10 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
2074 if (ret) 2090 if (ret)
2075 return ret; 2091 return ret;
2076 2092
2077 ret = i915_gem_check_olr(obj->ring, 2093 ret = i915_gem_check_olr(obj->ring, obj->last_read_seqno);
2078 obj->last_rendering_seqno);
2079 if (ret) 2094 if (ret)
2080 return ret; 2095 return ret;
2096
2081 i915_gem_retire_requests_ring(obj->ring); 2097 i915_gem_retire_requests_ring(obj->ring);
2082 } 2098 }
2083 2099
@@ -2137,7 +2153,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
2137 goto out; 2153 goto out;
2138 2154
2139 if (obj->active) { 2155 if (obj->active) {
2140 seqno = obj->last_rendering_seqno; 2156 seqno = obj->last_read_seqno;
2141 ring = obj->ring; 2157 ring = obj->ring;
2142 } 2158 }
2143 2159
@@ -2192,11 +2208,11 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
2192 return 0; 2208 return 0;
2193 2209
2194 if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev)) 2210 if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev))
2195 return i915_gem_object_wait_rendering(obj); 2211 return i915_gem_object_wait_rendering(obj, false);
2196 2212
2197 idx = intel_ring_sync_index(from, to); 2213 idx = intel_ring_sync_index(from, to);
2198 2214
2199 seqno = obj->last_rendering_seqno; 2215 seqno = obj->last_read_seqno;
2200 if (seqno <= from->sync_seqno[idx]) 2216 if (seqno <= from->sync_seqno[idx])
2201 return 0; 2217 return 0;
2202 2218
@@ -2940,11 +2956,9 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
2940 if (ret) 2956 if (ret)
2941 return ret; 2957 return ret;
2942 2958
2943 if (obj->pending_gpu_write || write) { 2959 ret = i915_gem_object_wait_rendering(obj, !write);
2944 ret = i915_gem_object_wait_rendering(obj); 2960 if (ret)
2945 if (ret) 2961 return ret;
2946 return ret;
2947 }
2948 2962
2949 i915_gem_object_flush_cpu_write_domain(obj); 2963 i915_gem_object_flush_cpu_write_domain(obj);
2950 2964
@@ -3115,7 +3129,7 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj)
3115 return ret; 3129 return ret;
3116 } 3130 }
3117 3131
3118 ret = i915_gem_object_wait_rendering(obj); 3132 ret = i915_gem_object_wait_rendering(obj, false);
3119 if (ret) 3133 if (ret)
3120 return ret; 3134 return ret;
3121 3135
@@ -3143,11 +3157,9 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
3143 if (ret) 3157 if (ret)
3144 return ret; 3158 return ret;
3145 3159
3146 if (write || obj->pending_gpu_write) { 3160 ret = i915_gem_object_wait_rendering(obj, !write);
3147 ret = i915_gem_object_wait_rendering(obj); 3161 if (ret)
3148 if (ret) 3162 return ret;
3149 return ret;
3150 }
3151 3163
3152 i915_gem_object_flush_gtt_write_domain(obj); 3164 i915_gem_object_flush_gtt_write_domain(obj);
3153 3165
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f94ec574db2b..2353e6ee2f0d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -954,7 +954,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects,
954 i915_gem_object_move_to_active(obj, ring, seqno); 954 i915_gem_object_move_to_active(obj, ring, seqno);
955 if (obj->base.write_domain) { 955 if (obj->base.write_domain) {
956 obj->dirty = 1; 956 obj->dirty = 1;
957 obj->pending_gpu_write = true; 957 obj->last_write_seqno = seqno;
958 list_move_tail(&obj->gpu_write_list, 958 list_move_tail(&obj->gpu_write_list,
959 &ring->gpu_write_list); 959 &ring->gpu_write_list);
960 if (obj->pin_count) /* check for potential scanout */ 960 if (obj->pin_count) /* check for potential scanout */
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 566f61b9e47c..41ed41d70472 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -950,7 +950,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
950{ 950{
951 err->size = obj->base.size; 951 err->size = obj->base.size;
952 err->name = obj->base.name; 952 err->name = obj->base.name;
953 err->seqno = obj->last_rendering_seqno; 953 err->rseqno = obj->last_read_seqno;
954 err->wseqno = obj->last_write_seqno;
954 err->gtt_offset = obj->gtt_offset; 955 err->gtt_offset = obj->gtt_offset;
955 err->read_domains = obj->base.read_domains; 956 err->read_domains = obj->base.read_domains;
956 err->write_domain = obj->base.write_domain; 957 err->write_domain = obj->base.write_domain;
@@ -1045,7 +1046,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
1045 if (obj->ring != ring) 1046 if (obj->ring != ring)
1046 continue; 1047 continue;
1047 1048
1048 if (i915_seqno_passed(seqno, obj->last_rendering_seqno)) 1049 if (i915_seqno_passed(seqno, obj->last_read_seqno))
1049 continue; 1050 continue;
1050 1051
1051 if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) 1052 if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0)