blob: 97d5fbd8ea137735a0bf3f1b4387fd6e88f43c1b [file] [log] [blame]
Chris Wilson54cf91d2010-11-25 18:00:26 +00001/*
2 * Copyright © 2008,2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 * Chris Wilson <chris@chris-wilson.co.uk>
26 *
27 */
28
29#include "drmP.h"
30#include "drm.h"
31#include "i915_drm.h"
32#include "i915_drv.h"
33#include "i915_trace.h"
34#include "intel_drv.h"
35
36struct change_domains {
37 uint32_t invalidate_domains;
38 uint32_t flush_domains;
39 uint32_t flush_rings;
40};
41
42/*
43 * Set the next domain for the specified object. This
44 * may not actually perform the necessary flushing/invaliding though,
45 * as that may want to be batched with other set_domain operations
46 *
47 * This is (we hope) the only really tricky part of gem. The goal
48 * is fairly simple -- track which caches hold bits of the object
49 * and make sure they remain coherent. A few concrete examples may
50 * help to explain how it works. For shorthand, we use the notation
51 * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
52 * a pair of read and write domain masks.
53 *
54 * Case 1: the batch buffer
55 *
56 * 1. Allocated
57 * 2. Written by CPU
58 * 3. Mapped to GTT
59 * 4. Read by GPU
60 * 5. Unmapped from GTT
61 * 6. Freed
62 *
63 * Let's take these a step at a time
64 *
65 * 1. Allocated
66 * Pages allocated from the kernel may still have
67 * cache contents, so we set them to (CPU, CPU) always.
68 * 2. Written by CPU (using pwrite)
69 * The pwrite function calls set_domain (CPU, CPU) and
70 * this function does nothing (as nothing changes)
71 * 3. Mapped by GTT
72 * This function asserts that the object is not
73 * currently in any GPU-based read or write domains
74 * 4. Read by GPU
75 * i915_gem_execbuffer calls set_domain (COMMAND, 0).
76 * As write_domain is zero, this function adds in the
77 * current read domains (CPU+COMMAND, 0).
78 * flush_domains is set to CPU.
79 * invalidate_domains is set to COMMAND
80 * clflush is run to get data out of the CPU caches
81 * then i915_dev_set_domain calls i915_gem_flush to
82 * emit an MI_FLUSH and drm_agp_chipset_flush
83 * 5. Unmapped from GTT
84 * i915_gem_object_unbind calls set_domain (CPU, CPU)
85 * flush_domains and invalidate_domains end up both zero
86 * so no flushing/invalidating happens
87 * 6. Freed
88 * yay, done
89 *
90 * Case 2: The shared render buffer
91 *
92 * 1. Allocated
93 * 2. Mapped to GTT
94 * 3. Read/written by GPU
95 * 4. set_domain to (CPU,CPU)
96 * 5. Read/written by CPU
97 * 6. Read/written by GPU
98 *
99 * 1. Allocated
100 * Same as last example, (CPU, CPU)
101 * 2. Mapped to GTT
102 * Nothing changes (assertions find that it is not in the GPU)
103 * 3. Read/written by GPU
104 * execbuffer calls set_domain (RENDER, RENDER)
105 * flush_domains gets CPU
106 * invalidate_domains gets GPU
107 * clflush (obj)
108 * MI_FLUSH and drm_agp_chipset_flush
109 * 4. set_domain (CPU, CPU)
110 * flush_domains gets GPU
111 * invalidate_domains gets CPU
112 * wait_rendering (obj) to make sure all drawing is complete.
113 * This will include an MI_FLUSH to get the data from GPU
114 * to memory
115 * clflush (obj) to invalidate the CPU cache
116 * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
117 * 5. Read/written by CPU
118 * cache lines are loaded and dirtied
119 * 6. Read written by GPU
120 * Same as last GPU access
121 *
122 * Case 3: The constant buffer
123 *
124 * 1. Allocated
125 * 2. Written by CPU
126 * 3. Read by GPU
127 * 4. Updated (written) by CPU again
128 * 5. Read by GPU
129 *
130 * 1. Allocated
131 * (CPU, CPU)
132 * 2. Written by CPU
133 * (CPU, CPU)
134 * 3. Read by GPU
135 * (CPU+RENDER, 0)
136 * flush_domains = CPU
137 * invalidate_domains = RENDER
138 * clflush (obj)
139 * MI_FLUSH
140 * drm_agp_chipset_flush
141 * 4. Updated (written) by CPU again
142 * (CPU, CPU)
143 * flush_domains = 0 (no previous write domain)
144 * invalidate_domains = 0 (no new read domains)
145 * 5. Read by GPU
146 * (CPU+RENDER, 0)
147 * flush_domains = CPU
148 * invalidate_domains = RENDER
149 * clflush (obj)
150 * MI_FLUSH
151 * drm_agp_chipset_flush
152 */
153static void
154i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj,
155 struct intel_ring_buffer *ring,
156 struct change_domains *cd)
157{
158 uint32_t invalidate_domains = 0, flush_domains = 0;
159
160 /*
161 * If the object isn't moving to a new write domain,
162 * let the object stay in multiple read domains
163 */
164 if (obj->base.pending_write_domain == 0)
165 obj->base.pending_read_domains |= obj->base.read_domains;
166
167 /*
168 * Flush the current write domain if
169 * the new read domains don't match. Invalidate
170 * any read domains which differ from the old
171 * write domain
172 */
173 if (obj->base.write_domain &&
174 (((obj->base.write_domain != obj->base.pending_read_domains ||
175 obj->ring != ring)) ||
176 (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) {
177 flush_domains |= obj->base.write_domain;
178 invalidate_domains |=
179 obj->base.pending_read_domains & ~obj->base.write_domain;
180 }
181 /*
182 * Invalidate any read caches which may have
183 * stale data. That is, any new read domains.
184 */
185 invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains;
186 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU)
187 i915_gem_clflush_object(obj);
188
189 /* blow away mappings if mapped through GTT */
190 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT)
191 i915_gem_release_mmap(obj);
192
193 /* The actual obj->write_domain will be updated with
194 * pending_write_domain after we emit the accumulated flush for all
195 * of our domain changes in execbuffers (which clears objects'
196 * write_domains). So if we have a current write domain that we
197 * aren't changing, set pending_write_domain to that.
198 */
199 if (flush_domains == 0 && obj->base.pending_write_domain == 0)
200 obj->base.pending_write_domain = obj->base.write_domain;
201
202 cd->invalidate_domains |= invalidate_domains;
203 cd->flush_domains |= flush_domains;
204 if (flush_domains & I915_GEM_GPU_DOMAINS)
205 cd->flush_rings |= obj->ring->id;
206 if (invalidate_domains & I915_GEM_GPU_DOMAINS)
207 cd->flush_rings |= ring->id;
208}
209
Chris Wilson67731b82010-12-08 10:38:14 +0000210struct eb_objects {
211 int and;
212 struct hlist_head buckets[0];
213};
214
215static struct eb_objects *
216eb_create(int size)
217{
218 struct eb_objects *eb;
219 int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
220 while (count > size)
221 count >>= 1;
222 eb = kzalloc(count*sizeof(struct hlist_head) +
223 sizeof(struct eb_objects),
224 GFP_KERNEL);
225 if (eb == NULL)
226 return eb;
227
228 eb->and = count - 1;
229 return eb;
230}
231
232static void
233eb_reset(struct eb_objects *eb)
234{
235 memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
236}
237
238static void
239eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj)
240{
241 hlist_add_head(&obj->exec_node,
242 &eb->buckets[obj->exec_handle & eb->and]);
243}
244
245static struct drm_i915_gem_object *
246eb_get_object(struct eb_objects *eb, unsigned long handle)
247{
248 struct hlist_head *head;
249 struct hlist_node *node;
250 struct drm_i915_gem_object *obj;
251
252 head = &eb->buckets[handle & eb->and];
253 hlist_for_each(node, head) {
254 obj = hlist_entry(node, struct drm_i915_gem_object, exec_node);
255 if (obj->exec_handle == handle)
256 return obj;
257 }
258
259 return NULL;
260}
261
262static void
263eb_destroy(struct eb_objects *eb)
264{
265 kfree(eb);
266}
267
Chris Wilson54cf91d2010-11-25 18:00:26 +0000268static int
269i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
Chris Wilson67731b82010-12-08 10:38:14 +0000270 struct eb_objects *eb,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000271 struct drm_i915_gem_exec_object2 *entry,
272 struct drm_i915_gem_relocation_entry *reloc)
273{
274 struct drm_device *dev = obj->base.dev;
275 struct drm_gem_object *target_obj;
276 uint32_t target_offset;
277 int ret = -EINVAL;
278
Chris Wilson67731b82010-12-08 10:38:14 +0000279 /* we've already hold a reference to all valid objects */
280 target_obj = &eb_get_object(eb, reloc->target_handle)->base;
281 if (unlikely(target_obj == NULL))
Chris Wilson54cf91d2010-11-25 18:00:26 +0000282 return -ENOENT;
283
284 target_offset = to_intel_bo(target_obj)->gtt_offset;
285
286#if WATCH_RELOC
287 DRM_INFO("%s: obj %p offset %08x target %d "
288 "read %08x write %08x gtt %08x "
289 "presumed %08x delta %08x\n",
290 __func__,
291 obj,
292 (int) reloc->offset,
293 (int) reloc->target_handle,
294 (int) reloc->read_domains,
295 (int) reloc->write_domain,
296 (int) target_offset,
297 (int) reloc->presumed_offset,
298 reloc->delta);
299#endif
300
301 /* The target buffer should have appeared before us in the
302 * exec_object list, so it should have a GTT space bound by now.
303 */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000304 if (unlikely(target_offset == 0)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000305 DRM_ERROR("No GTT space found for object %d\n",
306 reloc->target_handle);
Chris Wilson67731b82010-12-08 10:38:14 +0000307 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000308 }
309
310 /* Validate that the target is in a valid r/w GPU domain */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000311 if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000312 DRM_ERROR("reloc with multiple write domains: "
313 "obj %p target %d offset %d "
314 "read %08x write %08x",
315 obj, reloc->target_handle,
316 (int) reloc->offset,
317 reloc->read_domains,
318 reloc->write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000319 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000320 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000321 if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000322 DRM_ERROR("reloc with read/write CPU domains: "
323 "obj %p target %d offset %d "
324 "read %08x write %08x",
325 obj, reloc->target_handle,
326 (int) reloc->offset,
327 reloc->read_domains,
328 reloc->write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000329 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000330 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000331 if (unlikely(reloc->write_domain && target_obj->pending_write_domain &&
332 reloc->write_domain != target_obj->pending_write_domain)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000333 DRM_ERROR("Write domain conflict: "
334 "obj %p target %d offset %d "
335 "new %08x old %08x\n",
336 obj, reloc->target_handle,
337 (int) reloc->offset,
338 reloc->write_domain,
339 target_obj->pending_write_domain);
Chris Wilson67731b82010-12-08 10:38:14 +0000340 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000341 }
342
343 target_obj->pending_read_domains |= reloc->read_domains;
344 target_obj->pending_write_domain |= reloc->write_domain;
345
346 /* If the relocation already has the right value in it, no
347 * more work needs to be done.
348 */
349 if (target_offset == reloc->presumed_offset)
Chris Wilson67731b82010-12-08 10:38:14 +0000350 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000351
352 /* Check that the relocation address is valid... */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000353 if (unlikely(reloc->offset > obj->base.size - 4)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000354 DRM_ERROR("Relocation beyond object bounds: "
355 "obj %p target %d offset %d size %d.\n",
356 obj, reloc->target_handle,
357 (int) reloc->offset,
358 (int) obj->base.size);
Chris Wilson67731b82010-12-08 10:38:14 +0000359 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000360 }
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000361 if (unlikely(reloc->offset & 3)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000362 DRM_ERROR("Relocation not 4-byte aligned: "
363 "obj %p target %d offset %d.\n",
364 obj, reloc->target_handle,
365 (int) reloc->offset);
Chris Wilson67731b82010-12-08 10:38:14 +0000366 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000367 }
368
369 /* and points to somewhere within the target object. */
Chris Wilsonb8f7ab12010-12-08 10:43:06 +0000370 if (unlikely(reloc->delta >= target_obj->size)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000371 DRM_ERROR("Relocation beyond target object bounds: "
372 "obj %p target %d delta %d size %d.\n",
373 obj, reloc->target_handle,
374 (int) reloc->delta,
375 (int) target_obj->size);
Chris Wilson67731b82010-12-08 10:38:14 +0000376 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000377 }
378
379 reloc->delta += target_offset;
380 if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
381 uint32_t page_offset = reloc->offset & ~PAGE_MASK;
382 char *vaddr;
383
384 vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
385 *(uint32_t *)(vaddr + page_offset) = reloc->delta;
386 kunmap_atomic(vaddr);
387 } else {
388 struct drm_i915_private *dev_priv = dev->dev_private;
389 uint32_t __iomem *reloc_entry;
390 void __iomem *reloc_page;
391
392 ret = i915_gem_object_set_to_gtt_domain(obj, 1);
393 if (ret)
Chris Wilson67731b82010-12-08 10:38:14 +0000394 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000395
396 /* Map the page containing the relocation we're going to perform. */
397 reloc->offset += obj->gtt_offset;
398 reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
399 reloc->offset & PAGE_MASK);
400 reloc_entry = (uint32_t __iomem *)
401 (reloc_page + (reloc->offset & ~PAGE_MASK));
402 iowrite32(reloc->delta, reloc_entry);
403 io_mapping_unmap_atomic(reloc_page);
404 }
405
406 /* and update the user's relocation entry */
407 reloc->presumed_offset = target_offset;
408
Chris Wilson67731b82010-12-08 10:38:14 +0000409 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000410}
411
412static int
413i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
Chris Wilson67731b82010-12-08 10:38:14 +0000414 struct eb_objects *eb,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000415 struct drm_i915_gem_exec_object2 *entry)
416{
417 struct drm_i915_gem_relocation_entry __user *user_relocs;
418 int i, ret;
419
420 user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
421 for (i = 0; i < entry->relocation_count; i++) {
422 struct drm_i915_gem_relocation_entry reloc;
423
424 if (__copy_from_user_inatomic(&reloc,
425 user_relocs+i,
426 sizeof(reloc)))
427 return -EFAULT;
428
Chris Wilson67731b82010-12-08 10:38:14 +0000429 ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &reloc);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000430 if (ret)
431 return ret;
432
433 if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset,
434 &reloc.presumed_offset,
435 sizeof(reloc.presumed_offset)))
436 return -EFAULT;
437 }
438
439 return 0;
440}
441
442static int
443i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
Chris Wilson67731b82010-12-08 10:38:14 +0000444 struct eb_objects *eb,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000445 struct drm_i915_gem_exec_object2 *entry,
446 struct drm_i915_gem_relocation_entry *relocs)
447{
448 int i, ret;
449
450 for (i = 0; i < entry->relocation_count; i++) {
Chris Wilson67731b82010-12-08 10:38:14 +0000451 ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &relocs[i]);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000452 if (ret)
453 return ret;
454 }
455
456 return 0;
457}
458
459static int
460i915_gem_execbuffer_relocate(struct drm_device *dev,
Chris Wilson67731b82010-12-08 10:38:14 +0000461 struct eb_objects *eb,
Chris Wilson432e58e2010-11-25 19:32:06 +0000462 struct list_head *objects,
463 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000464{
Chris Wilson432e58e2010-11-25 19:32:06 +0000465 struct drm_i915_gem_object *obj;
466 int ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000467
Chris Wilson432e58e2010-11-25 19:32:06 +0000468 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000469 obj->base.pending_read_domains = 0;
470 obj->base.pending_write_domain = 0;
Chris Wilson67731b82010-12-08 10:38:14 +0000471 ret = i915_gem_execbuffer_relocate_object(obj, eb, exec++);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000472 if (ret)
473 return ret;
474 }
475
476 return 0;
477}
478
479static int
Chris Wilsond9e86c02010-11-10 16:40:20 +0000480i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000481 struct drm_file *file,
Chris Wilson432e58e2010-11-25 19:32:06 +0000482 struct list_head *objects,
483 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000484{
Chris Wilson432e58e2010-11-25 19:32:06 +0000485 struct drm_i915_gem_object *obj;
486 struct drm_i915_gem_exec_object2 *entry;
487 int ret, retry;
Chris Wilson9b3826b2010-12-05 17:11:54 +0000488 bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000489
490 /* Attempt to pin all of the buffers into the GTT.
491 * This is done in 3 phases:
492 *
493 * 1a. Unbind all objects that do not match the GTT constraints for
494 * the execbuffer (fenceable, mappable, alignment etc).
495 * 1b. Increment pin count for already bound objects.
496 * 2. Bind new objects.
497 * 3. Decrement pin count.
498 *
499 * This avoid unnecessary unbinding of later objects in order to makr
500 * room for the earlier objects *unless* we need to defragment.
501 */
502 retry = 0;
503 do {
504 ret = 0;
505
506 /* Unbind any ill-fitting objects or pin. */
Chris Wilson432e58e2010-11-25 19:32:06 +0000507 entry = exec;
508 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000509 bool need_fence, need_mappable;
510
Chris Wilson432e58e2010-11-25 19:32:06 +0000511 if (!obj->gtt_space) {
512 entry++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000513 continue;
Chris Wilson432e58e2010-11-25 19:32:06 +0000514 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000515
516 need_fence =
Chris Wilson9b3826b2010-12-05 17:11:54 +0000517 has_fenced_gpu_access &&
Chris Wilson54cf91d2010-11-25 18:00:26 +0000518 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
519 obj->tiling_mode != I915_TILING_NONE;
520 need_mappable =
521 entry->relocation_count ? true : need_fence;
522
523 if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) ||
524 (need_mappable && !obj->map_and_fenceable))
525 ret = i915_gem_object_unbind(obj);
526 else
527 ret = i915_gem_object_pin(obj,
528 entry->alignment,
529 need_mappable);
Chris Wilson432e58e2010-11-25 19:32:06 +0000530 if (ret)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000531 goto err;
Chris Wilson432e58e2010-11-25 19:32:06 +0000532
533 entry++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000534 }
535
536 /* Bind fresh objects */
Chris Wilson432e58e2010-11-25 19:32:06 +0000537 entry = exec;
538 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000539 bool need_fence;
540
541 need_fence =
Chris Wilson9b3826b2010-12-05 17:11:54 +0000542 has_fenced_gpu_access &&
Chris Wilson54cf91d2010-11-25 18:00:26 +0000543 entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
544 obj->tiling_mode != I915_TILING_NONE;
545
546 if (!obj->gtt_space) {
547 bool need_mappable =
548 entry->relocation_count ? true : need_fence;
549
550 ret = i915_gem_object_pin(obj,
551 entry->alignment,
552 need_mappable);
553 if (ret)
554 break;
555 }
556
Chris Wilson9b3826b2010-12-05 17:11:54 +0000557 if (has_fenced_gpu_access) {
558 if (need_fence) {
559 ret = i915_gem_object_get_fence(obj, ring, 1);
560 if (ret)
561 break;
562 } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
563 obj->tiling_mode == I915_TILING_NONE) {
564 /* XXX pipelined! */
565 ret = i915_gem_object_put_fence(obj);
566 if (ret)
567 break;
568 }
569 obj->pending_fenced_gpu_access = need_fence;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000570 }
571
572 entry->offset = obj->gtt_offset;
Chris Wilson432e58e2010-11-25 19:32:06 +0000573 entry++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000574 }
575
Chris Wilson432e58e2010-11-25 19:32:06 +0000576 /* Decrement pin count for bound objects */
577 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000578 if (obj->gtt_space)
579 i915_gem_object_unpin(obj);
580 }
581
582 if (ret != -ENOSPC || retry > 1)
583 return ret;
584
585 /* First attempt, just clear anything that is purgeable.
586 * Second attempt, clear the entire GTT.
587 */
Chris Wilsond9e86c02010-11-10 16:40:20 +0000588 ret = i915_gem_evict_everything(ring->dev, retry == 0);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000589 if (ret)
590 return ret;
591
592 retry++;
593 } while (1);
Chris Wilson432e58e2010-11-25 19:32:06 +0000594
595err:
Chris Wilson602606a2010-11-28 15:31:02 +0000596 obj = list_entry(obj->exec_list.prev,
597 struct drm_i915_gem_object,
598 exec_list);
Chris Wilson432e58e2010-11-25 19:32:06 +0000599 while (objects != &obj->exec_list) {
600 if (obj->gtt_space)
601 i915_gem_object_unpin(obj);
602
603 obj = list_entry(obj->exec_list.prev,
604 struct drm_i915_gem_object,
605 exec_list);
606 }
607
608 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000609}
610
611static int
612i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
613 struct drm_file *file,
Chris Wilsond9e86c02010-11-10 16:40:20 +0000614 struct intel_ring_buffer *ring,
Chris Wilson432e58e2010-11-25 19:32:06 +0000615 struct list_head *objects,
Chris Wilson67731b82010-12-08 10:38:14 +0000616 struct eb_objects *eb,
Chris Wilson432e58e2010-11-25 19:32:06 +0000617 struct drm_i915_gem_exec_object2 *exec,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000618 int count)
619{
620 struct drm_i915_gem_relocation_entry *reloc;
Chris Wilson432e58e2010-11-25 19:32:06 +0000621 struct drm_i915_gem_object *obj;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000622 int i, total, ret;
623
Chris Wilson67731b82010-12-08 10:38:14 +0000624 /* We may process another execbuffer during the unlock... */
625 while (list_empty(objects)) {
626 obj = list_first_entry(objects,
627 struct drm_i915_gem_object,
628 exec_list);
629 list_del_init(&obj->exec_list);
630 drm_gem_object_unreference(&obj->base);
631 }
632
Chris Wilson54cf91d2010-11-25 18:00:26 +0000633 mutex_unlock(&dev->struct_mutex);
634
635 total = 0;
636 for (i = 0; i < count; i++)
Chris Wilson432e58e2010-11-25 19:32:06 +0000637 total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000638
639 reloc = drm_malloc_ab(total, sizeof(*reloc));
640 if (reloc == NULL) {
641 mutex_lock(&dev->struct_mutex);
642 return -ENOMEM;
643 }
644
645 total = 0;
646 for (i = 0; i < count; i++) {
647 struct drm_i915_gem_relocation_entry __user *user_relocs;
648
Chris Wilson432e58e2010-11-25 19:32:06 +0000649 user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000650
651 if (copy_from_user(reloc+total, user_relocs,
Chris Wilson432e58e2010-11-25 19:32:06 +0000652 exec[i].relocation_count * sizeof(*reloc))) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000653 ret = -EFAULT;
654 mutex_lock(&dev->struct_mutex);
655 goto err;
656 }
657
Chris Wilson432e58e2010-11-25 19:32:06 +0000658 total += exec[i].relocation_count;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000659 }
660
661 ret = i915_mutex_lock_interruptible(dev);
662 if (ret) {
663 mutex_lock(&dev->struct_mutex);
664 goto err;
665 }
666
Chris Wilson67731b82010-12-08 10:38:14 +0000667 /* reacquire the objects */
668 INIT_LIST_HEAD(objects);
669 eb_reset(eb);
670 for (i = 0; i < count; i++) {
671 struct drm_i915_gem_object *obj;
672
673 obj = to_intel_bo(drm_gem_object_lookup(dev, file,
674 exec[i].handle));
675 if (obj == NULL) {
676 DRM_ERROR("Invalid object handle %d at index %d\n",
677 exec[i].handle, i);
678 ret = -ENOENT;
679 goto err;
680 }
681
682 list_add_tail(&obj->exec_list, objects);
683 obj->exec_handle = exec[i].handle;
684 eb_add_object(eb, obj);
685 }
686
Chris Wilsond9e86c02010-11-10 16:40:20 +0000687 ret = i915_gem_execbuffer_reserve(ring, file, objects, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000688 if (ret)
689 goto err;
690
691 total = 0;
Chris Wilson432e58e2010-11-25 19:32:06 +0000692 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson54cf91d2010-11-25 18:00:26 +0000693 obj->base.pending_read_domains = 0;
694 obj->base.pending_write_domain = 0;
Chris Wilson67731b82010-12-08 10:38:14 +0000695 ret = i915_gem_execbuffer_relocate_object_slow(obj, eb,
Chris Wilson432e58e2010-11-25 19:32:06 +0000696 exec,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000697 reloc + total);
698 if (ret)
699 goto err;
700
Chris Wilson432e58e2010-11-25 19:32:06 +0000701 total += exec->relocation_count;
702 exec++;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000703 }
704
705 /* Leave the user relocations as are, this is the painfully slow path,
706 * and we want to avoid the complication of dropping the lock whilst
707 * having buffers reserved in the aperture and so causing spurious
708 * ENOSPC for random operations.
709 */
710
711err:
712 drm_free_large(reloc);
713 return ret;
714}
715
Chris Wilson88241782011-01-07 17:09:48 +0000716static int
Chris Wilson54cf91d2010-11-25 18:00:26 +0000717i915_gem_execbuffer_flush(struct drm_device *dev,
718 uint32_t invalidate_domains,
719 uint32_t flush_domains,
720 uint32_t flush_rings)
721{
722 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilson88241782011-01-07 17:09:48 +0000723 int i, ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000724
725 if (flush_domains & I915_GEM_DOMAIN_CPU)
726 intel_gtt_chipset_flush();
727
Chris Wilson63256ec2011-01-04 18:42:07 +0000728 if (flush_domains & I915_GEM_DOMAIN_GTT)
729 wmb();
730
Chris Wilson54cf91d2010-11-25 18:00:26 +0000731 if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000732 for (i = 0; i < I915_NUM_RINGS; i++)
Chris Wilson88241782011-01-07 17:09:48 +0000733 if (flush_rings & (1 << i)) {
734 ret = i915_gem_flush_ring(dev,
735 &dev_priv->ring[i],
736 invalidate_domains,
737 flush_domains);
738 if (ret)
739 return ret;
740 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000741 }
Chris Wilson88241782011-01-07 17:09:48 +0000742
743 return 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000744}
745
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000746static int
747i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj,
748 struct intel_ring_buffer *to)
749{
750 struct intel_ring_buffer *from = obj->ring;
751 u32 seqno;
752 int ret, idx;
753
754 if (from == NULL || to == from)
755 return 0;
756
757 if (INTEL_INFO(obj->base.dev)->gen < 6)
758 return i915_gem_object_wait_rendering(obj, true);
759
760 idx = intel_ring_sync_index(from, to);
761
762 seqno = obj->last_rendering_seqno;
763 if (seqno <= from->sync_seqno[idx])
764 return 0;
765
766 if (seqno == from->outstanding_lazy_request) {
767 struct drm_i915_gem_request *request;
768
769 request = kzalloc(sizeof(*request), GFP_KERNEL);
770 if (request == NULL)
771 return -ENOMEM;
772
773 ret = i915_add_request(obj->base.dev, NULL, request, from);
774 if (ret) {
775 kfree(request);
776 return ret;
777 }
778
779 seqno = request->seqno;
780 }
781
782 from->sync_seqno[idx] = seqno;
783 return intel_ring_sync(to, from, seqno - 1);
784}
Chris Wilson54cf91d2010-11-25 18:00:26 +0000785
786static int
Chris Wilson432e58e2010-11-25 19:32:06 +0000787i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring,
788 struct list_head *objects)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000789{
Chris Wilson432e58e2010-11-25 19:32:06 +0000790 struct drm_i915_gem_object *obj;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000791 struct change_domains cd;
Chris Wilson432e58e2010-11-25 19:32:06 +0000792 int ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000793
794 cd.invalidate_domains = 0;
795 cd.flush_domains = 0;
796 cd.flush_rings = 0;
Chris Wilson432e58e2010-11-25 19:32:06 +0000797 list_for_each_entry(obj, objects, exec_list)
798 i915_gem_object_set_to_gpu_domain(obj, ring, &cd);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000799
800 if (cd.invalidate_domains | cd.flush_domains) {
801#if WATCH_EXEC
802 DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
803 __func__,
804 cd.invalidate_domains,
805 cd.flush_domains);
806#endif
Chris Wilson88241782011-01-07 17:09:48 +0000807 ret = i915_gem_execbuffer_flush(ring->dev,
808 cd.invalidate_domains,
809 cd.flush_domains,
810 cd.flush_rings);
811 if (ret)
812 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000813 }
814
Chris Wilson432e58e2010-11-25 19:32:06 +0000815 list_for_each_entry(obj, objects, exec_list) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000816 ret = i915_gem_execbuffer_sync_rings(obj, ring);
817 if (ret)
818 return ret;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000819 }
820
821 return 0;
822}
823
Chris Wilson432e58e2010-11-25 19:32:06 +0000824static bool
825i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000826{
Chris Wilson432e58e2010-11-25 19:32:06 +0000827 return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000828}
829
830static int
831validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
832 int count)
833{
834 int i;
835
836 for (i = 0; i < count; i++) {
837 char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
838 int length; /* limited by fault_in_pages_readable() */
839
840 /* First check for malicious input causing overflow */
841 if (exec[i].relocation_count >
842 INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
843 return -EINVAL;
844
845 length = exec[i].relocation_count *
846 sizeof(struct drm_i915_gem_relocation_entry);
847 if (!access_ok(VERIFY_READ, ptr, length))
848 return -EFAULT;
849
850 /* we may also need to update the presumed offsets */
851 if (!access_ok(VERIFY_WRITE, ptr, length))
852 return -EFAULT;
853
854 if (fault_in_pages_readable(ptr, length))
855 return -EFAULT;
856 }
857
858 return 0;
859}
860
Chris Wilson432e58e2010-11-25 19:32:06 +0000861static int
862i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring,
863 struct list_head *objects)
864{
865 struct drm_i915_gem_object *obj;
866 int flips;
867
868 /* Check for any pending flips. As we only maintain a flip queue depth
869 * of 1, we can simply insert a WAIT for the next display flip prior
870 * to executing the batch and avoid stalling the CPU.
871 */
872 flips = 0;
873 list_for_each_entry(obj, objects, exec_list) {
874 if (obj->base.write_domain)
875 flips |= atomic_read(&obj->pending_flip);
876 }
877 if (flips) {
878 int plane, flip_mask, ret;
879
880 for (plane = 0; flips >> plane; plane++) {
881 if (((flips >> plane) & 1) == 0)
882 continue;
883
884 if (plane)
885 flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
886 else
887 flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
888
889 ret = intel_ring_begin(ring, 2);
890 if (ret)
891 return ret;
892
893 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask);
894 intel_ring_emit(ring, MI_NOOP);
895 intel_ring_advance(ring);
896 }
897 }
898
899 return 0;
900}
901
902static void
903i915_gem_execbuffer_move_to_active(struct list_head *objects,
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000904 struct intel_ring_buffer *ring,
905 u32 seqno)
Chris Wilson432e58e2010-11-25 19:32:06 +0000906{
907 struct drm_i915_gem_object *obj;
908
909 list_for_each_entry(obj, objects, exec_list) {
910 obj->base.read_domains = obj->base.pending_read_domains;
911 obj->base.write_domain = obj->base.pending_write_domain;
912 obj->fenced_gpu_access = obj->pending_fenced_gpu_access;
913
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000914 i915_gem_object_move_to_active(obj, ring, seqno);
Chris Wilson432e58e2010-11-25 19:32:06 +0000915 if (obj->base.write_domain) {
916 obj->dirty = 1;
Chris Wilson87ca9c82010-12-02 09:42:56 +0000917 obj->pending_gpu_write = true;
Chris Wilson432e58e2010-11-25 19:32:06 +0000918 list_move_tail(&obj->gpu_write_list,
919 &ring->gpu_write_list);
920 intel_mark_busy(ring->dev, obj);
921 }
922
923 trace_i915_gem_object_change_domain(obj,
924 obj->base.read_domains,
925 obj->base.write_domain);
926 }
927}
928
Chris Wilson54cf91d2010-11-25 18:00:26 +0000929static void
930i915_gem_execbuffer_retire_commands(struct drm_device *dev,
Chris Wilson432e58e2010-11-25 19:32:06 +0000931 struct drm_file *file,
Chris Wilson54cf91d2010-11-25 18:00:26 +0000932 struct intel_ring_buffer *ring)
933{
Chris Wilson432e58e2010-11-25 19:32:06 +0000934 struct drm_i915_gem_request *request;
Chris Wilsonb72f3ac2011-01-04 17:34:02 +0000935 u32 invalidate;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000936
Chris Wilson432e58e2010-11-25 19:32:06 +0000937 /*
938 * Ensure that the commands in the batch buffer are
939 * finished before the interrupt fires.
940 *
941 * The sampler always gets flushed on i965 (sigh).
942 */
Chris Wilsonb72f3ac2011-01-04 17:34:02 +0000943 invalidate = I915_GEM_DOMAIN_COMMAND;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000944 if (INTEL_INFO(dev)->gen >= 4)
Chris Wilsonb72f3ac2011-01-04 17:34:02 +0000945 invalidate |= I915_GEM_DOMAIN_SAMPLER;
946 if (ring->flush(ring, invalidate, 0)) {
947 i915_gem_next_request_seqno(dev, ring);
948 return;
949 }
Chris Wilson54cf91d2010-11-25 18:00:26 +0000950
Chris Wilson432e58e2010-11-25 19:32:06 +0000951 /* Add a breadcrumb for the completion of the batch buffer */
952 request = kzalloc(sizeof(*request), GFP_KERNEL);
953 if (request == NULL || i915_add_request(dev, file, request, ring)) {
954 i915_gem_next_request_seqno(dev, ring);
955 kfree(request);
956 }
957}
Chris Wilson54cf91d2010-11-25 18:00:26 +0000958
959static int
960i915_gem_do_execbuffer(struct drm_device *dev, void *data,
961 struct drm_file *file,
962 struct drm_i915_gem_execbuffer2 *args,
Chris Wilson432e58e2010-11-25 19:32:06 +0000963 struct drm_i915_gem_exec_object2 *exec)
Chris Wilson54cf91d2010-11-25 18:00:26 +0000964{
965 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilson432e58e2010-11-25 19:32:06 +0000966 struct list_head objects;
Chris Wilson67731b82010-12-08 10:38:14 +0000967 struct eb_objects *eb;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000968 struct drm_i915_gem_object *batch_obj;
969 struct drm_clip_rect *cliprects = NULL;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000970 struct intel_ring_buffer *ring;
Chris Wilsonc4e7a412010-11-30 14:10:25 +0000971 u32 exec_start, exec_len;
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000972 u32 seqno;
Chris Wilson72bfa192010-12-19 11:42:05 +0000973 int ret, mode, i;
Chris Wilson54cf91d2010-11-25 18:00:26 +0000974
Chris Wilson432e58e2010-11-25 19:32:06 +0000975 if (!i915_gem_check_execbuffer(args)) {
976 DRM_ERROR("execbuf with invalid offset/length\n");
977 return -EINVAL;
978 }
979
980 ret = validate_exec_list(exec, args->buffer_count);
Chris Wilson54cf91d2010-11-25 18:00:26 +0000981 if (ret)
982 return ret;
983
984#if WATCH_EXEC
985 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
986 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
987#endif
988 switch (args->flags & I915_EXEC_RING_MASK) {
989 case I915_EXEC_DEFAULT:
990 case I915_EXEC_RENDER:
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000991 ring = &dev_priv->ring[RCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000992 break;
993 case I915_EXEC_BSD:
994 if (!HAS_BSD(dev)) {
995 DRM_ERROR("execbuf with invalid ring (BSD)\n");
996 return -EINVAL;
997 }
Chris Wilson1ec14ad2010-12-04 11:30:53 +0000998 ring = &dev_priv->ring[VCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +0000999 break;
1000 case I915_EXEC_BLT:
1001 if (!HAS_BLT(dev)) {
1002 DRM_ERROR("execbuf with invalid ring (BLT)\n");
1003 return -EINVAL;
1004 }
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001005 ring = &dev_priv->ring[BCS];
Chris Wilson54cf91d2010-11-25 18:00:26 +00001006 break;
1007 default:
1008 DRM_ERROR("execbuf with unknown ring: %d\n",
1009 (int)(args->flags & I915_EXEC_RING_MASK));
1010 return -EINVAL;
1011 }
1012
Chris Wilson72bfa192010-12-19 11:42:05 +00001013 mode = args->flags & I915_EXEC_CONSTANTS_MASK;
1014 switch (mode) {
1015 case I915_EXEC_CONSTANTS_REL_GENERAL:
1016 case I915_EXEC_CONSTANTS_ABSOLUTE:
1017 case I915_EXEC_CONSTANTS_REL_SURFACE:
1018 if (ring == &dev_priv->ring[RCS] &&
1019 mode != dev_priv->relative_constants_mode) {
1020 if (INTEL_INFO(dev)->gen < 4)
1021 return -EINVAL;
1022
1023 if (INTEL_INFO(dev)->gen > 5 &&
1024 mode == I915_EXEC_CONSTANTS_REL_SURFACE)
1025 return -EINVAL;
1026
1027 ret = intel_ring_begin(ring, 4);
1028 if (ret)
1029 return ret;
1030
1031 intel_ring_emit(ring, MI_NOOP);
1032 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
1033 intel_ring_emit(ring, INSTPM);
1034 intel_ring_emit(ring,
1035 I915_EXEC_CONSTANTS_MASK << 16 | mode);
1036 intel_ring_advance(ring);
1037
1038 dev_priv->relative_constants_mode = mode;
1039 }
1040 break;
1041 default:
1042 DRM_ERROR("execbuf with unknown constants: %d\n", mode);
1043 return -EINVAL;
1044 }
1045
Chris Wilson54cf91d2010-11-25 18:00:26 +00001046 if (args->buffer_count < 1) {
1047 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
1048 return -EINVAL;
1049 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001050
1051 if (args->num_cliprects != 0) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001052 if (ring != &dev_priv->ring[RCS]) {
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001053 DRM_ERROR("clip rectangles are only valid with the render ring\n");
1054 return -EINVAL;
1055 }
1056
Chris Wilson432e58e2010-11-25 19:32:06 +00001057 cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
Chris Wilson54cf91d2010-11-25 18:00:26 +00001058 GFP_KERNEL);
1059 if (cliprects == NULL) {
1060 ret = -ENOMEM;
1061 goto pre_mutex_err;
1062 }
1063
Chris Wilson432e58e2010-11-25 19:32:06 +00001064 if (copy_from_user(cliprects,
1065 (struct drm_clip_rect __user *)(uintptr_t)
1066 args->cliprects_ptr,
1067 sizeof(*cliprects)*args->num_cliprects)) {
Chris Wilson54cf91d2010-11-25 18:00:26 +00001068 ret = -EFAULT;
1069 goto pre_mutex_err;
1070 }
1071 }
1072
Chris Wilson54cf91d2010-11-25 18:00:26 +00001073 ret = i915_mutex_lock_interruptible(dev);
1074 if (ret)
1075 goto pre_mutex_err;
1076
1077 if (dev_priv->mm.suspended) {
1078 mutex_unlock(&dev->struct_mutex);
1079 ret = -EBUSY;
1080 goto pre_mutex_err;
1081 }
1082
Chris Wilson67731b82010-12-08 10:38:14 +00001083 eb = eb_create(args->buffer_count);
1084 if (eb == NULL) {
1085 mutex_unlock(&dev->struct_mutex);
1086 ret = -ENOMEM;
1087 goto pre_mutex_err;
1088 }
1089
Chris Wilson54cf91d2010-11-25 18:00:26 +00001090 /* Look up object handles */
Chris Wilson432e58e2010-11-25 19:32:06 +00001091 INIT_LIST_HEAD(&objects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001092 for (i = 0; i < args->buffer_count; i++) {
1093 struct drm_i915_gem_object *obj;
1094
Chris Wilson432e58e2010-11-25 19:32:06 +00001095 obj = to_intel_bo(drm_gem_object_lookup(dev, file,
1096 exec[i].handle));
Chris Wilson54cf91d2010-11-25 18:00:26 +00001097 if (obj == NULL) {
1098 DRM_ERROR("Invalid object handle %d at index %d\n",
Chris Wilson432e58e2010-11-25 19:32:06 +00001099 exec[i].handle, i);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001100 /* prevent error path from reading uninitialized data */
Chris Wilson54cf91d2010-11-25 18:00:26 +00001101 ret = -ENOENT;
1102 goto err;
1103 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001104
Chris Wilson432e58e2010-11-25 19:32:06 +00001105 if (!list_empty(&obj->exec_list)) {
1106 DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n",
1107 obj, exec[i].handle, i);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001108 ret = -EINVAL;
1109 goto err;
1110 }
Chris Wilson432e58e2010-11-25 19:32:06 +00001111
1112 list_add_tail(&obj->exec_list, &objects);
Chris Wilson67731b82010-12-08 10:38:14 +00001113 obj->exec_handle = exec[i].handle;
1114 eb_add_object(eb, obj);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001115 }
1116
1117 /* Move the objects en-masse into the GTT, evicting if necessary. */
Chris Wilsond9e86c02010-11-10 16:40:20 +00001118 ret = i915_gem_execbuffer_reserve(ring, file, &objects, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001119 if (ret)
1120 goto err;
1121
1122 /* The objects are in their final locations, apply the relocations. */
Chris Wilson67731b82010-12-08 10:38:14 +00001123 ret = i915_gem_execbuffer_relocate(dev, eb, &objects, exec);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001124 if (ret) {
1125 if (ret == -EFAULT) {
Chris Wilsond9e86c02010-11-10 16:40:20 +00001126 ret = i915_gem_execbuffer_relocate_slow(dev, file, ring,
Chris Wilson67731b82010-12-08 10:38:14 +00001127 &objects, eb,
1128 exec,
Chris Wilson54cf91d2010-11-25 18:00:26 +00001129 args->buffer_count);
1130 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
1131 }
1132 if (ret)
1133 goto err;
1134 }
1135
1136 /* Set the pending read domains for the batch buffer to COMMAND */
Chris Wilson432e58e2010-11-25 19:32:06 +00001137 batch_obj = list_entry(objects.prev,
1138 struct drm_i915_gem_object,
1139 exec_list);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001140 if (batch_obj->base.pending_write_domain) {
1141 DRM_ERROR("Attempting to use self-modifying batch buffer\n");
1142 ret = -EINVAL;
1143 goto err;
1144 }
1145 batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
1146
Chris Wilson432e58e2010-11-25 19:32:06 +00001147 ret = i915_gem_execbuffer_move_to_gpu(ring, &objects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001148 if (ret)
1149 goto err;
1150
Chris Wilson432e58e2010-11-25 19:32:06 +00001151 ret = i915_gem_execbuffer_wait_for_flips(ring, &objects);
1152 if (ret)
Chris Wilson54cf91d2010-11-25 18:00:26 +00001153 goto err;
Chris Wilson54cf91d2010-11-25 18:00:26 +00001154
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001155 seqno = i915_gem_next_request_seqno(dev, ring);
1156 for (i = 0; i < I915_NUM_RINGS-1; i++) {
1157 if (seqno < ring->sync_seqno[i]) {
1158 /* The GPU can not handle its semaphore value wrapping,
1159 * so every billion or so execbuffers, we need to stall
1160 * the GPU in order to reset the counters.
1161 */
1162 ret = i915_gpu_idle(dev);
1163 if (ret)
1164 goto err;
1165
1166 BUG_ON(ring->sync_seqno[i]);
1167 }
1168 }
1169
Chris Wilsonc4e7a412010-11-30 14:10:25 +00001170 exec_start = batch_obj->gtt_offset + args->batch_start_offset;
1171 exec_len = args->batch_len;
1172 if (cliprects) {
1173 for (i = 0; i < args->num_cliprects; i++) {
1174 ret = i915_emit_box(dev, &cliprects[i],
1175 args->DR1, args->DR4);
1176 if (ret)
1177 goto err;
1178
1179 ret = ring->dispatch_execbuffer(ring,
1180 exec_start, exec_len);
1181 if (ret)
1182 goto err;
1183 }
1184 } else {
1185 ret = ring->dispatch_execbuffer(ring, exec_start, exec_len);
1186 if (ret)
1187 goto err;
1188 }
Chris Wilson54cf91d2010-11-25 18:00:26 +00001189
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001190 i915_gem_execbuffer_move_to_active(&objects, ring, seqno);
Chris Wilson432e58e2010-11-25 19:32:06 +00001191 i915_gem_execbuffer_retire_commands(dev, file, ring);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001192
1193err:
Chris Wilson67731b82010-12-08 10:38:14 +00001194 eb_destroy(eb);
Chris Wilson432e58e2010-11-25 19:32:06 +00001195 while (!list_empty(&objects)) {
1196 struct drm_i915_gem_object *obj;
1197
1198 obj = list_first_entry(&objects,
1199 struct drm_i915_gem_object,
1200 exec_list);
1201 list_del_init(&obj->exec_list);
1202 drm_gem_object_unreference(&obj->base);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001203 }
1204
1205 mutex_unlock(&dev->struct_mutex);
1206
1207pre_mutex_err:
Chris Wilson54cf91d2010-11-25 18:00:26 +00001208 kfree(cliprects);
Chris Wilson54cf91d2010-11-25 18:00:26 +00001209 return ret;
1210}
1211
1212/*
1213 * Legacy execbuffer just creates an exec2 list from the original exec object
1214 * list array and passes it to the real function.
1215 */
1216int
1217i915_gem_execbuffer(struct drm_device *dev, void *data,
1218 struct drm_file *file)
1219{
1220 struct drm_i915_gem_execbuffer *args = data;
1221 struct drm_i915_gem_execbuffer2 exec2;
1222 struct drm_i915_gem_exec_object *exec_list = NULL;
1223 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
1224 int ret, i;
1225
1226#if WATCH_EXEC
1227 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
1228 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
1229#endif
1230
1231 if (args->buffer_count < 1) {
1232 DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
1233 return -EINVAL;
1234 }
1235
1236 /* Copy in the exec list from userland */
1237 exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
1238 exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
1239 if (exec_list == NULL || exec2_list == NULL) {
1240 DRM_ERROR("Failed to allocate exec list for %d buffers\n",
1241 args->buffer_count);
1242 drm_free_large(exec_list);
1243 drm_free_large(exec2_list);
1244 return -ENOMEM;
1245 }
1246 ret = copy_from_user(exec_list,
1247 (struct drm_i915_relocation_entry __user *)
1248 (uintptr_t) args->buffers_ptr,
1249 sizeof(*exec_list) * args->buffer_count);
1250 if (ret != 0) {
1251 DRM_ERROR("copy %d exec entries failed %d\n",
1252 args->buffer_count, ret);
1253 drm_free_large(exec_list);
1254 drm_free_large(exec2_list);
1255 return -EFAULT;
1256 }
1257
1258 for (i = 0; i < args->buffer_count; i++) {
1259 exec2_list[i].handle = exec_list[i].handle;
1260 exec2_list[i].relocation_count = exec_list[i].relocation_count;
1261 exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr;
1262 exec2_list[i].alignment = exec_list[i].alignment;
1263 exec2_list[i].offset = exec_list[i].offset;
1264 if (INTEL_INFO(dev)->gen < 4)
1265 exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE;
1266 else
1267 exec2_list[i].flags = 0;
1268 }
1269
1270 exec2.buffers_ptr = args->buffers_ptr;
1271 exec2.buffer_count = args->buffer_count;
1272 exec2.batch_start_offset = args->batch_start_offset;
1273 exec2.batch_len = args->batch_len;
1274 exec2.DR1 = args->DR1;
1275 exec2.DR4 = args->DR4;
1276 exec2.num_cliprects = args->num_cliprects;
1277 exec2.cliprects_ptr = args->cliprects_ptr;
1278 exec2.flags = I915_EXEC_RENDER;
1279
1280 ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
1281 if (!ret) {
1282 /* Copy the new buffer offsets back to the user's exec list. */
1283 for (i = 0; i < args->buffer_count; i++)
1284 exec_list[i].offset = exec2_list[i].offset;
1285 /* ... and back out to userspace */
1286 ret = copy_to_user((struct drm_i915_relocation_entry __user *)
1287 (uintptr_t) args->buffers_ptr,
1288 exec_list,
1289 sizeof(*exec_list) * args->buffer_count);
1290 if (ret) {
1291 ret = -EFAULT;
1292 DRM_ERROR("failed to copy %d exec entries "
1293 "back to user (%d)\n",
1294 args->buffer_count, ret);
1295 }
1296 }
1297
1298 drm_free_large(exec_list);
1299 drm_free_large(exec2_list);
1300 return ret;
1301}
1302
1303int
1304i915_gem_execbuffer2(struct drm_device *dev, void *data,
1305 struct drm_file *file)
1306{
1307 struct drm_i915_gem_execbuffer2 *args = data;
1308 struct drm_i915_gem_exec_object2 *exec2_list = NULL;
1309 int ret;
1310
1311#if WATCH_EXEC
1312 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
1313 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
1314#endif
1315
1316 if (args->buffer_count < 1) {
1317 DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count);
1318 return -EINVAL;
1319 }
1320
1321 exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
1322 if (exec2_list == NULL) {
1323 DRM_ERROR("Failed to allocate exec list for %d buffers\n",
1324 args->buffer_count);
1325 return -ENOMEM;
1326 }
1327 ret = copy_from_user(exec2_list,
1328 (struct drm_i915_relocation_entry __user *)
1329 (uintptr_t) args->buffers_ptr,
1330 sizeof(*exec2_list) * args->buffer_count);
1331 if (ret != 0) {
1332 DRM_ERROR("copy %d exec entries failed %d\n",
1333 args->buffer_count, ret);
1334 drm_free_large(exec2_list);
1335 return -EFAULT;
1336 }
1337
1338 ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
1339 if (!ret) {
1340 /* Copy the new buffer offsets back to the user's exec list. */
1341 ret = copy_to_user((struct drm_i915_relocation_entry __user *)
1342 (uintptr_t) args->buffers_ptr,
1343 exec2_list,
1344 sizeof(*exec2_list) * args->buffer_count);
1345 if (ret) {
1346 ret = -EFAULT;
1347 DRM_ERROR("failed to copy %d exec entries "
1348 "back to user (%d)\n",
1349 args->buffer_count, ret);
1350 }
1351 }
1352
1353 drm_free_large(exec2_list);
1354 return ret;
1355}
1356