aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-06-15 04:14:34 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2017-06-15 05:52:58 -0400
commitd55495b4dcce2efb4656edfe211eb0bfb27c3387 (patch)
tree0c53a182e14155e32f6ef706848e920e149dd485
parent650bc63568e4218508f206c14af92b5a3f77504f (diff)
drm/i915: Use vma->exec_entry as our double-entry placeholder
This has the benefit of not requiring us to manipulate the vma->exec_link list when tearing down the execbuffer, and is a marginally cheaper test to detect the user error. 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/20170615081435.17699-2-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c17
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c77
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c1
3 files changed, 44 insertions, 51 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 51e365f70464..891247d79299 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -59,9 +59,6 @@ mark_free(struct drm_mm_scan *scan,
59 if (i915_vma_is_pinned(vma)) 59 if (i915_vma_is_pinned(vma))
60 return false; 60 return false;
61 61
62 if (WARN_ON(!list_empty(&vma->exec_list)))
63 return false;
64
65 if (flags & PIN_NONFAULT && !list_empty(&vma->obj->userfault_link)) 62 if (flags & PIN_NONFAULT && !list_empty(&vma->obj->userfault_link))
66 return false; 63 return false;
67 64
@@ -160,8 +157,6 @@ search_again:
160 list_for_each_entry_safe(vma, next, &eviction_list, exec_list) { 157 list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
161 ret = drm_mm_scan_remove_block(&scan, &vma->node); 158 ret = drm_mm_scan_remove_block(&scan, &vma->node);
162 BUG_ON(ret); 159 BUG_ON(ret);
163
164 INIT_LIST_HEAD(&vma->exec_list);
165 } 160 }
166 161
167 /* Can we unpin some objects such as idle hw contents, 162 /* Can we unpin some objects such as idle hw contents,
@@ -209,17 +204,12 @@ found:
209 if (drm_mm_scan_remove_block(&scan, &vma->node)) 204 if (drm_mm_scan_remove_block(&scan, &vma->node))
210 __i915_vma_pin(vma); 205 __i915_vma_pin(vma);
211 else 206 else
212 list_del_init(&vma->exec_list); 207 list_del(&vma->exec_list);
213 } 208 }
214 209
215 /* Unbinding will emit any required flushes */ 210 /* Unbinding will emit any required flushes */
216 ret = 0; 211 ret = 0;
217 while (!list_empty(&eviction_list)) { 212 list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
218 vma = list_first_entry(&eviction_list,
219 struct i915_vma,
220 exec_list);
221
222 list_del_init(&vma->exec_list);
223 __i915_vma_unpin(vma); 213 __i915_vma_unpin(vma);
224 if (ret == 0) 214 if (ret == 0)
225 ret = i915_vma_unbind(vma); 215 ret = i915_vma_unbind(vma);
@@ -315,7 +305,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
315 } 305 }
316 306
317 /* Overlap of objects in the same batch? */ 307 /* Overlap of objects in the same batch? */
318 if (i915_vma_is_pinned(vma) || !list_empty(&vma->exec_list)) { 308 if (i915_vma_is_pinned(vma)) {
319 ret = -ENOSPC; 309 ret = -ENOSPC;
320 if (vma->exec_entry && 310 if (vma->exec_entry &&
321 vma->exec_entry->flags & EXEC_OBJECT_PINNED) 311 vma->exec_entry->flags & EXEC_OBJECT_PINNED)
@@ -336,7 +326,6 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
336 } 326 }
337 327
338 list_for_each_entry_safe(vma, next, &eviction_list, exec_list) { 328 list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
339 list_del_init(&vma->exec_list);
340 __i915_vma_unpin(vma); 329 __i915_vma_unpin(vma);
341 if (ret == 0) 330 if (ret == 0)
342 ret = i915_vma_unbind(vma); 331 ret = i915_vma_unbind(vma);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 1c5a6a63a767..a7aa21dcc553 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -108,13 +108,40 @@ static int eb_create(struct i915_execbuffer *eb)
108 eb->and = -eb->args->buffer_count; 108 eb->and = -eb->args->buffer_count;
109 } 109 }
110 110
111 INIT_LIST_HEAD(&eb->vmas);
112 return 0; 111 return 0;
113} 112}
114 113
114static inline void
115__eb_unreserve_vma(struct i915_vma *vma,
116 const struct drm_i915_gem_exec_object2 *entry)
117{
118 if (unlikely(entry->flags & __EXEC_OBJECT_HAS_FENCE))
119 i915_vma_unpin_fence(vma);
120
121 if (entry->flags & __EXEC_OBJECT_HAS_PIN)
122 __i915_vma_unpin(vma);
123}
124
125static void
126eb_unreserve_vma(struct i915_vma *vma)
127{
128 struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
129
130 __eb_unreserve_vma(vma, entry);
131 entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
132}
133
115static void 134static void
116eb_reset(struct i915_execbuffer *eb) 135eb_reset(struct i915_execbuffer *eb)
117{ 136{
137 struct i915_vma *vma;
138
139 list_for_each_entry(vma, &eb->vmas, exec_list) {
140 eb_unreserve_vma(vma);
141 i915_vma_put(vma);
142 vma->exec_entry = NULL;
143 }
144
118 if (eb->and >= 0) 145 if (eb->and >= 0)
119 memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); 146 memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
120} 147}
@@ -146,6 +173,8 @@ eb_lookup_vmas(struct i915_execbuffer *eb)
146 struct list_head objects; 173 struct list_head objects;
147 int i, ret; 174 int i, ret;
148 175
176 INIT_LIST_HEAD(&eb->vmas);
177
149 INIT_LIST_HEAD(&objects); 178 INIT_LIST_HEAD(&objects);
150 spin_lock(&eb->file->table_lock); 179 spin_lock(&eb->file->table_lock);
151 /* Grab a reference to the object and release the lock so we can lookup 180 /* Grab a reference to the object and release the lock so we can lookup
@@ -252,40 +281,23 @@ static struct i915_vma *eb_get_vma(struct i915_execbuffer *eb, unsigned long han
252 } 281 }
253} 282}
254 283
255static void
256eb_unreserve_vma(struct i915_vma *vma)
257{
258 struct drm_i915_gem_exec_object2 *entry;
259
260 if (!drm_mm_node_allocated(&vma->node))
261 return;
262
263 entry = vma->exec_entry;
264
265 if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
266 i915_vma_unpin_fence(vma);
267
268 if (entry->flags & __EXEC_OBJECT_HAS_PIN)
269 __i915_vma_unpin(vma);
270
271 entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
272}
273
274static void eb_destroy(struct i915_execbuffer *eb) 284static void eb_destroy(struct i915_execbuffer *eb)
275{ 285{
276 i915_gem_context_put(eb->ctx); 286 struct i915_vma *vma;
277 287
278 while (!list_empty(&eb->vmas)) { 288 list_for_each_entry(vma, &eb->vmas, exec_list) {
279 struct i915_vma *vma; 289 if (!vma->exec_entry)
290 continue;
280 291
281 vma = list_first_entry(&eb->vmas, 292 __eb_unreserve_vma(vma, vma->exec_entry);
282 struct i915_vma,
283 exec_list);
284 list_del_init(&vma->exec_list);
285 eb_unreserve_vma(vma);
286 vma->exec_entry = NULL; 293 vma->exec_entry = NULL;
287 i915_vma_put(vma); 294 i915_vma_put(vma);
288 } 295 }
296
297 i915_gem_context_put(eb->ctx);
298
299 if (eb->buckets)
300 kfree(eb->buckets);
289} 301}
290 302
291static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) 303static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
@@ -985,13 +997,7 @@ eb_relocate_slow(struct i915_execbuffer *eb)
985 int i, total, ret; 997 int i, total, ret;
986 998
987 /* We may process another execbuffer during the unlock... */ 999 /* We may process another execbuffer during the unlock... */
988 while (!list_empty(&eb->vmas)) { 1000 eb_reset(eb);
989 vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
990 list_del_init(&vma->exec_list);
991 eb_unreserve_vma(vma);
992 i915_vma_put(vma);
993 }
994
995 mutex_unlock(&dev->struct_mutex); 1001 mutex_unlock(&dev->struct_mutex);
996 1002
997 total = 0; 1003 total = 0;
@@ -1052,7 +1058,6 @@ eb_relocate_slow(struct i915_execbuffer *eb)
1052 } 1058 }
1053 1059
1054 /* reacquire the objects */ 1060 /* reacquire the objects */
1055 eb_reset(eb);
1056 ret = eb_lookup_vmas(eb); 1061 ret = eb_lookup_vmas(eb);
1057 if (ret) 1062 if (ret)
1058 goto err; 1063 goto err;
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1aba47024656..6cf32da682ec 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -85,7 +85,6 @@ vma_create(struct drm_i915_gem_object *obj,
85 if (vma == NULL) 85 if (vma == NULL)
86 return ERR_PTR(-ENOMEM); 86 return ERR_PTR(-ENOMEM);
87 87
88 INIT_LIST_HEAD(&vma->exec_list);
89 for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) 88 for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
90 init_request_active(&vma->last_read[i], i915_vma_retire); 89 init_request_active(&vma->last_read[i], i915_vma_retire);
91 init_request_active(&vma->last_fence, NULL); 90 init_request_active(&vma->last_fence, NULL);