aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-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)