diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 401 |
1 files changed, 243 insertions, 158 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index bf345777ae9f..885d595e0e02 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -33,35 +33,35 @@ | |||
33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
34 | #include <linux/dma_remapping.h> | 34 | #include <linux/dma_remapping.h> |
35 | 35 | ||
36 | struct eb_objects { | 36 | struct eb_vmas { |
37 | struct list_head objects; | 37 | struct list_head vmas; |
38 | int and; | 38 | int and; |
39 | union { | 39 | union { |
40 | struct drm_i915_gem_object *lut[0]; | 40 | struct i915_vma *lut[0]; |
41 | struct hlist_head buckets[0]; | 41 | struct hlist_head buckets[0]; |
42 | }; | 42 | }; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct eb_objects * | 45 | static struct eb_vmas * |
46 | eb_create(struct drm_i915_gem_execbuffer2 *args) | 46 | eb_create(struct drm_i915_gem_execbuffer2 *args, struct i915_address_space *vm) |
47 | { | 47 | { |
48 | struct eb_objects *eb = NULL; | 48 | struct eb_vmas *eb = NULL; |
49 | 49 | ||
50 | if (args->flags & I915_EXEC_HANDLE_LUT) { | 50 | if (args->flags & I915_EXEC_HANDLE_LUT) { |
51 | int size = args->buffer_count; | 51 | unsigned size = args->buffer_count; |
52 | size *= sizeof(struct drm_i915_gem_object *); | 52 | size *= sizeof(struct i915_vma *); |
53 | size += sizeof(struct eb_objects); | 53 | size += sizeof(struct eb_vmas); |
54 | eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); | 54 | eb = kmalloc(size, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); |
55 | } | 55 | } |
56 | 56 | ||
57 | if (eb == NULL) { | 57 | if (eb == NULL) { |
58 | int size = args->buffer_count; | 58 | unsigned size = args->buffer_count; |
59 | int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; | 59 | unsigned count = PAGE_SIZE / sizeof(struct hlist_head) / 2; |
60 | BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); | 60 | BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); |
61 | while (count > 2*size) | 61 | while (count > 2*size) |
62 | count >>= 1; | 62 | count >>= 1; |
63 | eb = kzalloc(count*sizeof(struct hlist_head) + | 63 | eb = kzalloc(count*sizeof(struct hlist_head) + |
64 | sizeof(struct eb_objects), | 64 | sizeof(struct eb_vmas), |
65 | GFP_TEMPORARY); | 65 | GFP_TEMPORARY); |
66 | if (eb == NULL) | 66 | if (eb == NULL) |
67 | return eb; | 67 | return eb; |
@@ -70,64 +70,102 @@ eb_create(struct drm_i915_gem_execbuffer2 *args) | |||
70 | } else | 70 | } else |
71 | eb->and = -args->buffer_count; | 71 | eb->and = -args->buffer_count; |
72 | 72 | ||
73 | INIT_LIST_HEAD(&eb->objects); | 73 | INIT_LIST_HEAD(&eb->vmas); |
74 | return eb; | 74 | return eb; |
75 | } | 75 | } |
76 | 76 | ||
77 | static void | 77 | static void |
78 | eb_reset(struct eb_objects *eb) | 78 | eb_reset(struct eb_vmas *eb) |
79 | { | 79 | { |
80 | if (eb->and >= 0) | 80 | if (eb->and >= 0) |
81 | memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); | 81 | memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); |
82 | } | 82 | } |
83 | 83 | ||
84 | static int | 84 | static int |
85 | eb_lookup_objects(struct eb_objects *eb, | 85 | eb_lookup_vmas(struct eb_vmas *eb, |
86 | struct drm_i915_gem_exec_object2 *exec, | 86 | struct drm_i915_gem_exec_object2 *exec, |
87 | const struct drm_i915_gem_execbuffer2 *args, | 87 | const struct drm_i915_gem_execbuffer2 *args, |
88 | struct drm_file *file) | 88 | struct i915_address_space *vm, |
89 | struct drm_file *file) | ||
89 | { | 90 | { |
90 | int i; | 91 | struct drm_i915_gem_object *obj; |
92 | struct list_head objects; | ||
93 | int i, ret = 0; | ||
91 | 94 | ||
95 | INIT_LIST_HEAD(&objects); | ||
92 | spin_lock(&file->table_lock); | 96 | spin_lock(&file->table_lock); |
97 | /* Grab a reference to the object and release the lock so we can lookup | ||
98 | * or create the VMA without using GFP_ATOMIC */ | ||
93 | for (i = 0; i < args->buffer_count; i++) { | 99 | for (i = 0; i < args->buffer_count; i++) { |
94 | struct drm_i915_gem_object *obj; | ||
95 | |||
96 | obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle)); | 100 | obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle)); |
97 | if (obj == NULL) { | 101 | if (obj == NULL) { |
98 | spin_unlock(&file->table_lock); | 102 | spin_unlock(&file->table_lock); |
99 | DRM_DEBUG("Invalid object handle %d at index %d\n", | 103 | DRM_DEBUG("Invalid object handle %d at index %d\n", |
100 | exec[i].handle, i); | 104 | exec[i].handle, i); |
101 | return -ENOENT; | 105 | ret = -ENOENT; |
106 | goto out; | ||
102 | } | 107 | } |
103 | 108 | ||
104 | if (!list_empty(&obj->exec_list)) { | 109 | if (!list_empty(&obj->obj_exec_link)) { |
105 | spin_unlock(&file->table_lock); | 110 | spin_unlock(&file->table_lock); |
106 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", | 111 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", |
107 | obj, exec[i].handle, i); | 112 | obj, exec[i].handle, i); |
108 | return -EINVAL; | 113 | ret = -EINVAL; |
114 | goto out; | ||
109 | } | 115 | } |
110 | 116 | ||
111 | drm_gem_object_reference(&obj->base); | 117 | drm_gem_object_reference(&obj->base); |
112 | list_add_tail(&obj->exec_list, &eb->objects); | 118 | list_add_tail(&obj->obj_exec_link, &objects); |
119 | } | ||
120 | spin_unlock(&file->table_lock); | ||
113 | 121 | ||
114 | obj->exec_entry = &exec[i]; | 122 | i = 0; |
123 | list_for_each_entry(obj, &objects, obj_exec_link) { | ||
124 | struct i915_vma *vma; | ||
125 | |||
126 | /* | ||
127 | * NOTE: We can leak any vmas created here when something fails | ||
128 | * later on. But that's no issue since vma_unbind can deal with | ||
129 | * vmas which are not actually bound. And since only | ||
130 | * lookup_or_create exists as an interface to get at the vma | ||
131 | * from the (obj, vm) we don't run the risk of creating | ||
132 | * duplicated vmas for the same vm. | ||
133 | */ | ||
134 | vma = i915_gem_obj_lookup_or_create_vma(obj, vm); | ||
135 | if (IS_ERR(vma)) { | ||
136 | DRM_DEBUG("Failed to lookup VMA\n"); | ||
137 | ret = PTR_ERR(vma); | ||
138 | goto out; | ||
139 | } | ||
140 | |||
141 | list_add_tail(&vma->exec_list, &eb->vmas); | ||
142 | |||
143 | vma->exec_entry = &exec[i]; | ||
115 | if (eb->and < 0) { | 144 | if (eb->and < 0) { |
116 | eb->lut[i] = obj; | 145 | eb->lut[i] = vma; |
117 | } else { | 146 | } else { |
118 | uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle; | 147 | uint32_t handle = args->flags & I915_EXEC_HANDLE_LUT ? i : exec[i].handle; |
119 | obj->exec_handle = handle; | 148 | vma->exec_handle = handle; |
120 | hlist_add_head(&obj->exec_node, | 149 | hlist_add_head(&vma->exec_node, |
121 | &eb->buckets[handle & eb->and]); | 150 | &eb->buckets[handle & eb->and]); |
122 | } | 151 | } |
152 | ++i; | ||
123 | } | 153 | } |
124 | spin_unlock(&file->table_lock); | ||
125 | 154 | ||
126 | return 0; | 155 | |
156 | out: | ||
157 | while (!list_empty(&objects)) { | ||
158 | obj = list_first_entry(&objects, | ||
159 | struct drm_i915_gem_object, | ||
160 | obj_exec_link); | ||
161 | list_del_init(&obj->obj_exec_link); | ||
162 | if (ret) | ||
163 | drm_gem_object_unreference(&obj->base); | ||
164 | } | ||
165 | return ret; | ||
127 | } | 166 | } |
128 | 167 | ||
129 | static struct drm_i915_gem_object * | 168 | static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle) |
130 | eb_get_object(struct eb_objects *eb, unsigned long handle) | ||
131 | { | 169 | { |
132 | if (eb->and < 0) { | 170 | if (eb->and < 0) { |
133 | if (handle >= -eb->and) | 171 | if (handle >= -eb->and) |
@@ -139,34 +177,33 @@ eb_get_object(struct eb_objects *eb, unsigned long handle) | |||
139 | 177 | ||
140 | head = &eb->buckets[handle & eb->and]; | 178 | head = &eb->buckets[handle & eb->and]; |
141 | hlist_for_each(node, head) { | 179 | hlist_for_each(node, head) { |
142 | struct drm_i915_gem_object *obj; | 180 | struct i915_vma *vma; |
143 | 181 | ||
144 | obj = hlist_entry(node, struct drm_i915_gem_object, exec_node); | 182 | vma = hlist_entry(node, struct i915_vma, exec_node); |
145 | if (obj->exec_handle == handle) | 183 | if (vma->exec_handle == handle) |
146 | return obj; | 184 | return vma; |
147 | } | 185 | } |
148 | return NULL; | 186 | return NULL; |
149 | } | 187 | } |
150 | } | 188 | } |
151 | 189 | ||
152 | static void | 190 | static void eb_destroy(struct eb_vmas *eb) { |
153 | eb_destroy(struct eb_objects *eb) | 191 | while (!list_empty(&eb->vmas)) { |
154 | { | 192 | struct i915_vma *vma; |
155 | while (!list_empty(&eb->objects)) { | ||
156 | struct drm_i915_gem_object *obj; | ||
157 | 193 | ||
158 | obj = list_first_entry(&eb->objects, | 194 | vma = list_first_entry(&eb->vmas, |
159 | struct drm_i915_gem_object, | 195 | struct i915_vma, |
160 | exec_list); | 196 | exec_list); |
161 | list_del_init(&obj->exec_list); | 197 | list_del_init(&vma->exec_list); |
162 | drm_gem_object_unreference(&obj->base); | 198 | drm_gem_object_unreference(&vma->obj->base); |
163 | } | 199 | } |
164 | kfree(eb); | 200 | kfree(eb); |
165 | } | 201 | } |
166 | 202 | ||
167 | static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) | 203 | static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) |
168 | { | 204 | { |
169 | return (obj->base.write_domain == I915_GEM_DOMAIN_CPU || | 205 | return (HAS_LLC(obj->base.dev) || |
206 | obj->base.write_domain == I915_GEM_DOMAIN_CPU || | ||
170 | !obj->map_and_fenceable || | 207 | !obj->map_and_fenceable || |
171 | obj->cache_level != I915_CACHE_NONE); | 208 | obj->cache_level != I915_CACHE_NONE); |
172 | } | 209 | } |
@@ -175,17 +212,31 @@ static int | |||
175 | relocate_entry_cpu(struct drm_i915_gem_object *obj, | 212 | relocate_entry_cpu(struct drm_i915_gem_object *obj, |
176 | struct drm_i915_gem_relocation_entry *reloc) | 213 | struct drm_i915_gem_relocation_entry *reloc) |
177 | { | 214 | { |
215 | struct drm_device *dev = obj->base.dev; | ||
178 | uint32_t page_offset = offset_in_page(reloc->offset); | 216 | uint32_t page_offset = offset_in_page(reloc->offset); |
179 | char *vaddr; | 217 | char *vaddr; |
180 | int ret = -EINVAL; | 218 | int ret = -EINVAL; |
181 | 219 | ||
182 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | 220 | ret = i915_gem_object_set_to_cpu_domain(obj, true); |
183 | if (ret) | 221 | if (ret) |
184 | return ret; | 222 | return ret; |
185 | 223 | ||
186 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | 224 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, |
187 | reloc->offset >> PAGE_SHIFT)); | 225 | reloc->offset >> PAGE_SHIFT)); |
188 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; | 226 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; |
227 | |||
228 | if (INTEL_INFO(dev)->gen >= 8) { | ||
229 | page_offset = offset_in_page(page_offset + sizeof(uint32_t)); | ||
230 | |||
231 | if (page_offset == 0) { | ||
232 | kunmap_atomic(vaddr); | ||
233 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | ||
234 | (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT)); | ||
235 | } | ||
236 | |||
237 | *(uint32_t *)(vaddr + page_offset) = 0; | ||
238 | } | ||
239 | |||
189 | kunmap_atomic(vaddr); | 240 | kunmap_atomic(vaddr); |
190 | 241 | ||
191 | return 0; | 242 | return 0; |
@@ -216,6 +267,21 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, | |||
216 | reloc_entry = (uint32_t __iomem *) | 267 | reloc_entry = (uint32_t __iomem *) |
217 | (reloc_page + offset_in_page(reloc->offset)); | 268 | (reloc_page + offset_in_page(reloc->offset)); |
218 | iowrite32(reloc->delta, reloc_entry); | 269 | iowrite32(reloc->delta, reloc_entry); |
270 | |||
271 | if (INTEL_INFO(dev)->gen >= 8) { | ||
272 | reloc_entry += 1; | ||
273 | |||
274 | if (offset_in_page(reloc->offset + sizeof(uint32_t)) == 0) { | ||
275 | io_mapping_unmap_atomic(reloc_page); | ||
276 | reloc_page = io_mapping_map_atomic_wc( | ||
277 | dev_priv->gtt.mappable, | ||
278 | reloc->offset + sizeof(uint32_t)); | ||
279 | reloc_entry = reloc_page; | ||
280 | } | ||
281 | |||
282 | iowrite32(0, reloc_entry); | ||
283 | } | ||
284 | |||
219 | io_mapping_unmap_atomic(reloc_page); | 285 | io_mapping_unmap_atomic(reloc_page); |
220 | 286 | ||
221 | return 0; | 287 | return 0; |
@@ -223,22 +289,24 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, | |||
223 | 289 | ||
224 | static int | 290 | static int |
225 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | 291 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, |
226 | struct eb_objects *eb, | 292 | struct eb_vmas *eb, |
227 | struct drm_i915_gem_relocation_entry *reloc, | 293 | struct drm_i915_gem_relocation_entry *reloc, |
228 | struct i915_address_space *vm) | 294 | struct i915_address_space *vm) |
229 | { | 295 | { |
230 | struct drm_device *dev = obj->base.dev; | 296 | struct drm_device *dev = obj->base.dev; |
231 | struct drm_gem_object *target_obj; | 297 | struct drm_gem_object *target_obj; |
232 | struct drm_i915_gem_object *target_i915_obj; | 298 | struct drm_i915_gem_object *target_i915_obj; |
299 | struct i915_vma *target_vma; | ||
233 | uint32_t target_offset; | 300 | uint32_t target_offset; |
234 | int ret = -EINVAL; | 301 | int ret = -EINVAL; |
235 | 302 | ||
236 | /* we've already hold a reference to all valid objects */ | 303 | /* we've already hold a reference to all valid objects */ |
237 | target_obj = &eb_get_object(eb, reloc->target_handle)->base; | 304 | target_vma = eb_get_vma(eb, reloc->target_handle); |
238 | if (unlikely(target_obj == NULL)) | 305 | if (unlikely(target_vma == NULL)) |
239 | return -ENOENT; | 306 | return -ENOENT; |
307 | target_i915_obj = target_vma->obj; | ||
308 | target_obj = &target_vma->obj->base; | ||
240 | 309 | ||
241 | target_i915_obj = to_intel_bo(target_obj); | ||
242 | target_offset = i915_gem_obj_ggtt_offset(target_i915_obj); | 310 | target_offset = i915_gem_obj_ggtt_offset(target_i915_obj); |
243 | 311 | ||
244 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | 312 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and |
@@ -284,7 +352,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
284 | return 0; | 352 | return 0; |
285 | 353 | ||
286 | /* Check that the relocation address is valid... */ | 354 | /* Check that the relocation address is valid... */ |
287 | if (unlikely(reloc->offset > obj->base.size - 4)) { | 355 | if (unlikely(reloc->offset > |
356 | obj->base.size - (INTEL_INFO(dev)->gen >= 8 ? 8 : 4))) { | ||
288 | DRM_DEBUG("Relocation beyond object bounds: " | 357 | DRM_DEBUG("Relocation beyond object bounds: " |
289 | "obj %p target %d offset %d size %d.\n", | 358 | "obj %p target %d offset %d size %d.\n", |
290 | obj, reloc->target_handle, | 359 | obj, reloc->target_handle, |
@@ -320,14 +389,13 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
320 | } | 389 | } |
321 | 390 | ||
322 | static int | 391 | static int |
323 | i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | 392 | i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, |
324 | struct eb_objects *eb, | 393 | struct eb_vmas *eb) |
325 | struct i915_address_space *vm) | ||
326 | { | 394 | { |
327 | #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry)) | 395 | #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry)) |
328 | struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)]; | 396 | struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)]; |
329 | struct drm_i915_gem_relocation_entry __user *user_relocs; | 397 | struct drm_i915_gem_relocation_entry __user *user_relocs; |
330 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 398 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
331 | int remain, ret; | 399 | int remain, ret; |
332 | 400 | ||
333 | user_relocs = to_user_ptr(entry->relocs_ptr); | 401 | user_relocs = to_user_ptr(entry->relocs_ptr); |
@@ -346,8 +414,8 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | |||
346 | do { | 414 | do { |
347 | u64 offset = r->presumed_offset; | 415 | u64 offset = r->presumed_offset; |
348 | 416 | ||
349 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, r, | 417 | ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r, |
350 | vm); | 418 | vma->vm); |
351 | if (ret) | 419 | if (ret) |
352 | return ret; | 420 | return ret; |
353 | 421 | ||
@@ -368,17 +436,16 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | |||
368 | } | 436 | } |
369 | 437 | ||
370 | static int | 438 | static int |
371 | i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, | 439 | i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma, |
372 | struct eb_objects *eb, | 440 | struct eb_vmas *eb, |
373 | struct drm_i915_gem_relocation_entry *relocs, | 441 | struct drm_i915_gem_relocation_entry *relocs) |
374 | struct i915_address_space *vm) | ||
375 | { | 442 | { |
376 | const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 443 | const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
377 | int i, ret; | 444 | int i, ret; |
378 | 445 | ||
379 | for (i = 0; i < entry->relocation_count; i++) { | 446 | for (i = 0; i < entry->relocation_count; i++) { |
380 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i], | 447 | ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i], |
381 | vm); | 448 | vma->vm); |
382 | if (ret) | 449 | if (ret) |
383 | return ret; | 450 | return ret; |
384 | } | 451 | } |
@@ -387,10 +454,10 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, | |||
387 | } | 454 | } |
388 | 455 | ||
389 | static int | 456 | static int |
390 | i915_gem_execbuffer_relocate(struct eb_objects *eb, | 457 | i915_gem_execbuffer_relocate(struct eb_vmas *eb, |
391 | struct i915_address_space *vm) | 458 | struct i915_address_space *vm) |
392 | { | 459 | { |
393 | struct drm_i915_gem_object *obj; | 460 | struct i915_vma *vma; |
394 | int ret = 0; | 461 | int ret = 0; |
395 | 462 | ||
396 | /* This is the fast path and we cannot handle a pagefault whilst | 463 | /* This is the fast path and we cannot handle a pagefault whilst |
@@ -401,8 +468,8 @@ i915_gem_execbuffer_relocate(struct eb_objects *eb, | |||
401 | * lockdep complains vehemently. | 468 | * lockdep complains vehemently. |
402 | */ | 469 | */ |
403 | pagefault_disable(); | 470 | pagefault_disable(); |
404 | list_for_each_entry(obj, &eb->objects, exec_list) { | 471 | list_for_each_entry(vma, &eb->vmas, exec_list) { |
405 | ret = i915_gem_execbuffer_relocate_object(obj, eb, vm); | 472 | ret = i915_gem_execbuffer_relocate_vma(vma, eb); |
406 | if (ret) | 473 | if (ret) |
407 | break; | 474 | break; |
408 | } | 475 | } |
@@ -415,31 +482,32 @@ i915_gem_execbuffer_relocate(struct eb_objects *eb, | |||
415 | #define __EXEC_OBJECT_HAS_FENCE (1<<30) | 482 | #define __EXEC_OBJECT_HAS_FENCE (1<<30) |
416 | 483 | ||
417 | static int | 484 | static int |
418 | need_reloc_mappable(struct drm_i915_gem_object *obj) | 485 | need_reloc_mappable(struct i915_vma *vma) |
419 | { | 486 | { |
420 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 487 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
421 | return entry->relocation_count && !use_cpu_reloc(obj); | 488 | return entry->relocation_count && !use_cpu_reloc(vma->obj) && |
489 | i915_is_ggtt(vma->vm); | ||
422 | } | 490 | } |
423 | 491 | ||
424 | static int | 492 | static int |
425 | i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, | 493 | i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, |
426 | struct intel_ring_buffer *ring, | 494 | struct intel_ring_buffer *ring, |
427 | struct i915_address_space *vm, | 495 | bool *need_reloc) |
428 | bool *need_reloc) | ||
429 | { | 496 | { |
430 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 497 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
431 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 498 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
432 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; | 499 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; |
433 | bool need_fence, need_mappable; | 500 | bool need_fence, need_mappable; |
501 | struct drm_i915_gem_object *obj = vma->obj; | ||
434 | int ret; | 502 | int ret; |
435 | 503 | ||
436 | need_fence = | 504 | need_fence = |
437 | has_fenced_gpu_access && | 505 | has_fenced_gpu_access && |
438 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | 506 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && |
439 | obj->tiling_mode != I915_TILING_NONE; | 507 | obj->tiling_mode != I915_TILING_NONE; |
440 | need_mappable = need_fence || need_reloc_mappable(obj); | 508 | need_mappable = need_fence || need_reloc_mappable(vma); |
441 | 509 | ||
442 | ret = i915_gem_object_pin(obj, vm, entry->alignment, need_mappable, | 510 | ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, need_mappable, |
443 | false); | 511 | false); |
444 | if (ret) | 512 | if (ret) |
445 | return ret; | 513 | return ret; |
@@ -467,8 +535,8 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, | |||
467 | obj->has_aliasing_ppgtt_mapping = 1; | 535 | obj->has_aliasing_ppgtt_mapping = 1; |
468 | } | 536 | } |
469 | 537 | ||
470 | if (entry->offset != i915_gem_obj_offset(obj, vm)) { | 538 | if (entry->offset != vma->node.start) { |
471 | entry->offset = i915_gem_obj_offset(obj, vm); | 539 | entry->offset = vma->node.start; |
472 | *need_reloc = true; | 540 | *need_reloc = true; |
473 | } | 541 | } |
474 | 542 | ||
@@ -485,14 +553,15 @@ i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj, | |||
485 | } | 553 | } |
486 | 554 | ||
487 | static void | 555 | static void |
488 | i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) | 556 | i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma) |
489 | { | 557 | { |
490 | struct drm_i915_gem_exec_object2 *entry; | 558 | struct drm_i915_gem_exec_object2 *entry; |
559 | struct drm_i915_gem_object *obj = vma->obj; | ||
491 | 560 | ||
492 | if (!i915_gem_obj_bound_any(obj)) | 561 | if (!drm_mm_node_allocated(&vma->node)) |
493 | return; | 562 | return; |
494 | 563 | ||
495 | entry = obj->exec_entry; | 564 | entry = vma->exec_entry; |
496 | 565 | ||
497 | if (entry->flags & __EXEC_OBJECT_HAS_FENCE) | 566 | if (entry->flags & __EXEC_OBJECT_HAS_FENCE) |
498 | i915_gem_object_unpin_fence(obj); | 567 | i915_gem_object_unpin_fence(obj); |
@@ -505,41 +574,46 @@ i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj) | |||
505 | 574 | ||
506 | static int | 575 | static int |
507 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | 576 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, |
508 | struct list_head *objects, | 577 | struct list_head *vmas, |
509 | struct i915_address_space *vm, | ||
510 | bool *need_relocs) | 578 | bool *need_relocs) |
511 | { | 579 | { |
512 | struct drm_i915_gem_object *obj; | 580 | struct drm_i915_gem_object *obj; |
513 | struct list_head ordered_objects; | 581 | struct i915_vma *vma; |
582 | struct i915_address_space *vm; | ||
583 | struct list_head ordered_vmas; | ||
514 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; | 584 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; |
515 | int retry; | 585 | int retry; |
516 | 586 | ||
517 | INIT_LIST_HEAD(&ordered_objects); | 587 | if (list_empty(vmas)) |
518 | while (!list_empty(objects)) { | 588 | return 0; |
589 | |||
590 | vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm; | ||
591 | |||
592 | INIT_LIST_HEAD(&ordered_vmas); | ||
593 | while (!list_empty(vmas)) { | ||
519 | struct drm_i915_gem_exec_object2 *entry; | 594 | struct drm_i915_gem_exec_object2 *entry; |
520 | bool need_fence, need_mappable; | 595 | bool need_fence, need_mappable; |
521 | 596 | ||
522 | obj = list_first_entry(objects, | 597 | vma = list_first_entry(vmas, struct i915_vma, exec_list); |
523 | struct drm_i915_gem_object, | 598 | obj = vma->obj; |
524 | exec_list); | 599 | entry = vma->exec_entry; |
525 | entry = obj->exec_entry; | ||
526 | 600 | ||
527 | need_fence = | 601 | need_fence = |
528 | has_fenced_gpu_access && | 602 | has_fenced_gpu_access && |
529 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | 603 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && |
530 | obj->tiling_mode != I915_TILING_NONE; | 604 | obj->tiling_mode != I915_TILING_NONE; |
531 | need_mappable = need_fence || need_reloc_mappable(obj); | 605 | need_mappable = need_fence || need_reloc_mappable(vma); |
532 | 606 | ||
533 | if (need_mappable) | 607 | if (need_mappable) |
534 | list_move(&obj->exec_list, &ordered_objects); | 608 | list_move(&vma->exec_list, &ordered_vmas); |
535 | else | 609 | else |
536 | list_move_tail(&obj->exec_list, &ordered_objects); | 610 | list_move_tail(&vma->exec_list, &ordered_vmas); |
537 | 611 | ||
538 | obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND; | 612 | obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND; |
539 | obj->base.pending_write_domain = 0; | 613 | obj->base.pending_write_domain = 0; |
540 | obj->pending_fenced_gpu_access = false; | 614 | obj->pending_fenced_gpu_access = false; |
541 | } | 615 | } |
542 | list_splice(&ordered_objects, objects); | 616 | list_splice(&ordered_vmas, vmas); |
543 | 617 | ||
544 | /* Attempt to pin all of the buffers into the GTT. | 618 | /* Attempt to pin all of the buffers into the GTT. |
545 | * This is done in 3 phases: | 619 | * This is done in 3 phases: |
@@ -558,52 +632,52 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
558 | int ret = 0; | 632 | int ret = 0; |
559 | 633 | ||
560 | /* Unbind any ill-fitting objects or pin. */ | 634 | /* Unbind any ill-fitting objects or pin. */ |
561 | list_for_each_entry(obj, objects, exec_list) { | 635 | list_for_each_entry(vma, vmas, exec_list) { |
562 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 636 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
563 | bool need_fence, need_mappable; | 637 | bool need_fence, need_mappable; |
564 | u32 obj_offset; | ||
565 | 638 | ||
566 | if (!i915_gem_obj_bound(obj, vm)) | 639 | obj = vma->obj; |
640 | |||
641 | if (!drm_mm_node_allocated(&vma->node)) | ||
567 | continue; | 642 | continue; |
568 | 643 | ||
569 | obj_offset = i915_gem_obj_offset(obj, vm); | ||
570 | need_fence = | 644 | need_fence = |
571 | has_fenced_gpu_access && | 645 | has_fenced_gpu_access && |
572 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | 646 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && |
573 | obj->tiling_mode != I915_TILING_NONE; | 647 | obj->tiling_mode != I915_TILING_NONE; |
574 | need_mappable = need_fence || need_reloc_mappable(obj); | 648 | need_mappable = need_fence || need_reloc_mappable(vma); |
575 | 649 | ||
576 | WARN_ON((need_mappable || need_fence) && | 650 | WARN_ON((need_mappable || need_fence) && |
577 | !i915_is_ggtt(vm)); | 651 | !i915_is_ggtt(vma->vm)); |
578 | 652 | ||
579 | if ((entry->alignment && | 653 | if ((entry->alignment && |
580 | obj_offset & (entry->alignment - 1)) || | 654 | vma->node.start & (entry->alignment - 1)) || |
581 | (need_mappable && !obj->map_and_fenceable)) | 655 | (need_mappable && !obj->map_and_fenceable)) |
582 | ret = i915_vma_unbind(i915_gem_obj_to_vma(obj, vm)); | 656 | ret = i915_vma_unbind(vma); |
583 | else | 657 | else |
584 | ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); | 658 | ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); |
585 | if (ret) | 659 | if (ret) |
586 | goto err; | 660 | goto err; |
587 | } | 661 | } |
588 | 662 | ||
589 | /* Bind fresh objects */ | 663 | /* Bind fresh objects */ |
590 | list_for_each_entry(obj, objects, exec_list) { | 664 | list_for_each_entry(vma, vmas, exec_list) { |
591 | if (i915_gem_obj_bound(obj, vm)) | 665 | if (drm_mm_node_allocated(&vma->node)) |
592 | continue; | 666 | continue; |
593 | 667 | ||
594 | ret = i915_gem_execbuffer_reserve_object(obj, ring, vm, need_relocs); | 668 | ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); |
595 | if (ret) | 669 | if (ret) |
596 | goto err; | 670 | goto err; |
597 | } | 671 | } |
598 | 672 | ||
599 | err: /* Decrement pin count for bound objects */ | 673 | err: /* Decrement pin count for bound objects */ |
600 | list_for_each_entry(obj, objects, exec_list) | 674 | list_for_each_entry(vma, vmas, exec_list) |
601 | i915_gem_execbuffer_unreserve_object(obj); | 675 | i915_gem_execbuffer_unreserve_vma(vma); |
602 | 676 | ||
603 | if (ret != -ENOSPC || retry++) | 677 | if (ret != -ENOSPC || retry++) |
604 | return ret; | 678 | return ret; |
605 | 679 | ||
606 | ret = i915_gem_evict_everything(ring->dev); | 680 | ret = i915_gem_evict_vm(vm, true); |
607 | if (ret) | 681 | if (ret) |
608 | return ret; | 682 | return ret; |
609 | } while (1); | 683 | } while (1); |
@@ -614,24 +688,27 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
614 | struct drm_i915_gem_execbuffer2 *args, | 688 | struct drm_i915_gem_execbuffer2 *args, |
615 | struct drm_file *file, | 689 | struct drm_file *file, |
616 | struct intel_ring_buffer *ring, | 690 | struct intel_ring_buffer *ring, |
617 | struct eb_objects *eb, | 691 | struct eb_vmas *eb, |
618 | struct drm_i915_gem_exec_object2 *exec, | 692 | struct drm_i915_gem_exec_object2 *exec) |
619 | struct i915_address_space *vm) | ||
620 | { | 693 | { |
621 | struct drm_i915_gem_relocation_entry *reloc; | 694 | struct drm_i915_gem_relocation_entry *reloc; |
622 | struct drm_i915_gem_object *obj; | 695 | struct i915_address_space *vm; |
696 | struct i915_vma *vma; | ||
623 | bool need_relocs; | 697 | bool need_relocs; |
624 | int *reloc_offset; | 698 | int *reloc_offset; |
625 | int i, total, ret; | 699 | int i, total, ret; |
626 | int count = args->buffer_count; | 700 | unsigned count = args->buffer_count; |
701 | |||
702 | if (WARN_ON(list_empty(&eb->vmas))) | ||
703 | return 0; | ||
704 | |||
705 | vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm; | ||
627 | 706 | ||
628 | /* We may process another execbuffer during the unlock... */ | 707 | /* We may process another execbuffer during the unlock... */ |
629 | while (!list_empty(&eb->objects)) { | 708 | while (!list_empty(&eb->vmas)) { |
630 | obj = list_first_entry(&eb->objects, | 709 | vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list); |
631 | struct drm_i915_gem_object, | 710 | list_del_init(&vma->exec_list); |
632 | exec_list); | 711 | drm_gem_object_unreference(&vma->obj->base); |
633 | list_del_init(&obj->exec_list); | ||
634 | drm_gem_object_unreference(&obj->base); | ||
635 | } | 712 | } |
636 | 713 | ||
637 | mutex_unlock(&dev->struct_mutex); | 714 | mutex_unlock(&dev->struct_mutex); |
@@ -695,20 +772,19 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
695 | 772 | ||
696 | /* reacquire the objects */ | 773 | /* reacquire the objects */ |
697 | eb_reset(eb); | 774 | eb_reset(eb); |
698 | ret = eb_lookup_objects(eb, exec, args, file); | 775 | ret = eb_lookup_vmas(eb, exec, args, vm, file); |
699 | if (ret) | 776 | if (ret) |
700 | goto err; | 777 | goto err; |
701 | 778 | ||
702 | need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; | 779 | need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; |
703 | ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs); | 780 | ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs); |
704 | if (ret) | 781 | if (ret) |
705 | goto err; | 782 | goto err; |
706 | 783 | ||
707 | list_for_each_entry(obj, &eb->objects, exec_list) { | 784 | list_for_each_entry(vma, &eb->vmas, exec_list) { |
708 | int offset = obj->exec_entry - exec; | 785 | int offset = vma->exec_entry - exec; |
709 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, | 786 | ret = i915_gem_execbuffer_relocate_vma_slow(vma, eb, |
710 | reloc + reloc_offset[offset], | 787 | reloc + reloc_offset[offset]); |
711 | vm); | ||
712 | if (ret) | 788 | if (ret) |
713 | goto err; | 789 | goto err; |
714 | } | 790 | } |
@@ -727,14 +803,15 @@ err: | |||
727 | 803 | ||
728 | static int | 804 | static int |
729 | i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | 805 | i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, |
730 | struct list_head *objects) | 806 | struct list_head *vmas) |
731 | { | 807 | { |
732 | struct drm_i915_gem_object *obj; | 808 | struct i915_vma *vma; |
733 | uint32_t flush_domains = 0; | 809 | uint32_t flush_domains = 0; |
734 | bool flush_chipset = false; | 810 | bool flush_chipset = false; |
735 | int ret; | 811 | int ret; |
736 | 812 | ||
737 | list_for_each_entry(obj, objects, exec_list) { | 813 | list_for_each_entry(vma, vmas, exec_list) { |
814 | struct drm_i915_gem_object *obj = vma->obj; | ||
738 | ret = i915_gem_object_sync(obj, ring); | 815 | ret = i915_gem_object_sync(obj, ring); |
739 | if (ret) | 816 | if (ret) |
740 | return ret; | 817 | return ret; |
@@ -771,8 +848,8 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, | |||
771 | int count) | 848 | int count) |
772 | { | 849 | { |
773 | int i; | 850 | int i; |
774 | int relocs_total = 0; | 851 | unsigned relocs_total = 0; |
775 | int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry); | 852 | unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry); |
776 | 853 | ||
777 | for (i = 0; i < count; i++) { | 854 | for (i = 0; i < count; i++) { |
778 | char __user *ptr = to_user_ptr(exec[i].relocs_ptr); | 855 | char __user *ptr = to_user_ptr(exec[i].relocs_ptr); |
@@ -809,13 +886,13 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, | |||
809 | } | 886 | } |
810 | 887 | ||
811 | static void | 888 | static void |
812 | i915_gem_execbuffer_move_to_active(struct list_head *objects, | 889 | i915_gem_execbuffer_move_to_active(struct list_head *vmas, |
813 | struct i915_address_space *vm, | ||
814 | struct intel_ring_buffer *ring) | 890 | struct intel_ring_buffer *ring) |
815 | { | 891 | { |
816 | struct drm_i915_gem_object *obj; | 892 | struct i915_vma *vma; |
817 | 893 | ||
818 | list_for_each_entry(obj, objects, exec_list) { | 894 | list_for_each_entry(vma, vmas, exec_list) { |
895 | struct drm_i915_gem_object *obj = vma->obj; | ||
819 | u32 old_read = obj->base.read_domains; | 896 | u32 old_read = obj->base.read_domains; |
820 | u32 old_write = obj->base.write_domain; | 897 | u32 old_write = obj->base.write_domain; |
821 | 898 | ||
@@ -825,9 +902,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, | |||
825 | obj->base.read_domains = obj->base.pending_read_domains; | 902 | obj->base.read_domains = obj->base.pending_read_domains; |
826 | obj->fenced_gpu_access = obj->pending_fenced_gpu_access; | 903 | obj->fenced_gpu_access = obj->pending_fenced_gpu_access; |
827 | 904 | ||
828 | /* FIXME: This lookup gets fixed later <-- danvet */ | 905 | i915_vma_move_to_active(vma, ring); |
829 | list_move_tail(&i915_gem_obj_to_vma(obj, vm)->mm_list, &vm->active_list); | ||
830 | i915_gem_object_move_to_active(obj, ring); | ||
831 | if (obj->base.write_domain) { | 906 | if (obj->base.write_domain) { |
832 | obj->dirty = 1; | 907 | obj->dirty = 1; |
833 | obj->last_write_seqno = intel_ring_get_seqno(ring); | 908 | obj->last_write_seqno = intel_ring_get_seqno(ring); |
@@ -885,10 +960,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
885 | struct i915_address_space *vm) | 960 | struct i915_address_space *vm) |
886 | { | 961 | { |
887 | drm_i915_private_t *dev_priv = dev->dev_private; | 962 | drm_i915_private_t *dev_priv = dev->dev_private; |
888 | struct eb_objects *eb; | 963 | struct eb_vmas *eb; |
889 | struct drm_i915_gem_object *batch_obj; | 964 | struct drm_i915_gem_object *batch_obj; |
890 | struct drm_clip_rect *cliprects = NULL; | 965 | struct drm_clip_rect *cliprects = NULL; |
891 | struct intel_ring_buffer *ring; | 966 | struct intel_ring_buffer *ring; |
967 | struct i915_ctx_hang_stats *hs; | ||
892 | u32 ctx_id = i915_execbuffer2_get_context_id(*args); | 968 | u32 ctx_id = i915_execbuffer2_get_context_id(*args); |
893 | u32 exec_start, exec_len; | 969 | u32 exec_start, exec_len; |
894 | u32 mask, flags; | 970 | u32 mask, flags; |
@@ -1000,7 +1076,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1000 | return -EINVAL; | 1076 | return -EINVAL; |
1001 | } | 1077 | } |
1002 | 1078 | ||
1003 | cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), | 1079 | cliprects = kcalloc(args->num_cliprects, |
1080 | sizeof(*cliprects), | ||
1004 | GFP_KERNEL); | 1081 | GFP_KERNEL); |
1005 | if (cliprects == NULL) { | 1082 | if (cliprects == NULL) { |
1006 | ret = -ENOMEM; | 1083 | ret = -ENOMEM; |
@@ -1025,7 +1102,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1025 | goto pre_mutex_err; | 1102 | goto pre_mutex_err; |
1026 | } | 1103 | } |
1027 | 1104 | ||
1028 | eb = eb_create(args); | 1105 | eb = eb_create(args, vm); |
1029 | if (eb == NULL) { | 1106 | if (eb == NULL) { |
1030 | mutex_unlock(&dev->struct_mutex); | 1107 | mutex_unlock(&dev->struct_mutex); |
1031 | ret = -ENOMEM; | 1108 | ret = -ENOMEM; |
@@ -1033,18 +1110,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1033 | } | 1110 | } |
1034 | 1111 | ||
1035 | /* Look up object handles */ | 1112 | /* Look up object handles */ |
1036 | ret = eb_lookup_objects(eb, exec, args, file); | 1113 | ret = eb_lookup_vmas(eb, exec, args, vm, file); |
1037 | if (ret) | 1114 | if (ret) |
1038 | goto err; | 1115 | goto err; |
1039 | 1116 | ||
1040 | /* take note of the batch buffer before we might reorder the lists */ | 1117 | /* take note of the batch buffer before we might reorder the lists */ |
1041 | batch_obj = list_entry(eb->objects.prev, | 1118 | batch_obj = list_entry(eb->vmas.prev, struct i915_vma, exec_list)->obj; |
1042 | struct drm_i915_gem_object, | ||
1043 | exec_list); | ||
1044 | 1119 | ||
1045 | /* Move the objects en-masse into the GTT, evicting if necessary. */ | 1120 | /* Move the objects en-masse into the GTT, evicting if necessary. */ |
1046 | need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; | 1121 | need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; |
1047 | ret = i915_gem_execbuffer_reserve(ring, &eb->objects, vm, &need_relocs); | 1122 | ret = i915_gem_execbuffer_reserve(ring, &eb->vmas, &need_relocs); |
1048 | if (ret) | 1123 | if (ret) |
1049 | goto err; | 1124 | goto err; |
1050 | 1125 | ||
@@ -1054,7 +1129,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1054 | if (ret) { | 1129 | if (ret) { |
1055 | if (ret == -EFAULT) { | 1130 | if (ret == -EFAULT) { |
1056 | ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring, | 1131 | ret = i915_gem_execbuffer_relocate_slow(dev, args, file, ring, |
1057 | eb, exec, vm); | 1132 | eb, exec); |
1058 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 1133 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
1059 | } | 1134 | } |
1060 | if (ret) | 1135 | if (ret) |
@@ -1071,15 +1146,25 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1071 | 1146 | ||
1072 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure | 1147 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure |
1073 | * batch" bit. Hence we need to pin secure batches into the global gtt. | 1148 | * batch" bit. Hence we need to pin secure batches into the global gtt. |
1074 | * hsw should have this fixed, but let's be paranoid and do it | 1149 | * hsw should have this fixed, but bdw mucks it up again. */ |
1075 | * unconditionally for now. */ | ||
1076 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) | 1150 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) |
1077 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); | 1151 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); |
1078 | 1152 | ||
1079 | ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->objects); | 1153 | ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas); |
1080 | if (ret) | 1154 | if (ret) |
1081 | goto err; | 1155 | goto err; |
1082 | 1156 | ||
1157 | hs = i915_gem_context_get_hang_stats(dev, file, ctx_id); | ||
1158 | if (IS_ERR(hs)) { | ||
1159 | ret = PTR_ERR(hs); | ||
1160 | goto err; | ||
1161 | } | ||
1162 | |||
1163 | if (hs->banned) { | ||
1164 | ret = -EIO; | ||
1165 | goto err; | ||
1166 | } | ||
1167 | |||
1083 | ret = i915_switch_context(ring, file, ctx_id); | 1168 | ret = i915_switch_context(ring, file, ctx_id); |
1084 | if (ret) | 1169 | if (ret) |
1085 | goto err; | 1170 | goto err; |
@@ -1131,7 +1216,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1131 | 1216 | ||
1132 | trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); | 1217 | trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); |
1133 | 1218 | ||
1134 | i915_gem_execbuffer_move_to_active(&eb->objects, vm, ring); | 1219 | i915_gem_execbuffer_move_to_active(&eb->vmas, ring); |
1135 | i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); | 1220 | i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); |
1136 | 1221 | ||
1137 | err: | 1222 | err: |