diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-06-15 04:14:34 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-06-15 05:52:58 -0400 |
commit | d55495b4dcce2efb4656edfe211eb0bfb27c3387 (patch) | |
tree | 0c53a182e14155e32f6ef706848e920e149dd485 | |
parent | 650bc63568e4218508f206c14af92b5a3f77504f (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.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_vma.c | 1 |
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 | ||
114 | static 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 | |||
125 | static void | ||
126 | eb_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 | |||
115 | static void | 134 | static void |
116 | eb_reset(struct i915_execbuffer *eb) | 135 | eb_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 | ||
255 | static void | ||
256 | eb_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 | |||
274 | static void eb_destroy(struct i915_execbuffer *eb) | 284 | static 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 | ||
291 | static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) | 303 | static 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); |