diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 5 |
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) | |||
121 | static void | 121 | static void |
122 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | 122 | describe_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); | |||
1291 | int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, | 1286 | int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, |
1292 | gfp_t gfpmask); | 1287 | gfp_t gfpmask); |
1293 | int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); | 1288 | int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); |
1294 | int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj); | ||
1295 | int i915_gem_object_sync(struct drm_i915_gem_object *obj, | 1289 | int i915_gem_object_sync(struct drm_i915_gem_object *obj, |
1296 | struct intel_ring_buffer *to); | 1290 | struct intel_ring_buffer *to); |
1297 | void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | 1291 | void 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 | |||
1461 | i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) | 1461 | i915_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 | */ |
2039 | int | 2039 | static __must_check int |
2040 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | 2040 | i915_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) |