2 * Copyright 2003-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
38 #define DRM_DEBUG_RELOCATION (drm_debug != 0)
40 #define DRM_DEBUG_RELOCATION 0
49 struct i915_relocatee_info {
50 struct drm_buffer_object *buf;
54 struct drm_bo_kmap_obj kmap;
58 int performed_ring_relocs;
59 #ifdef DRM_KMAP_ATOMIC_PROT_PFN
65 struct drm_i915_validate_buffer {
66 struct drm_buffer_object *buffer;
67 int presumed_offset_correct;
70 enum i915_buf_idle idle;
74 * I'd like to use MI_STORE_DATA_IMM here, but I can't make
75 * it work. Seems like GART writes are broken with that
76 * instruction. Also I'm not sure that MI_FLUSH will
77 * act as a memory barrier for that instruction. It will
78 * for this single dword 2D blit.
81 static void i915_emit_ring_reloc(struct drm_device *dev, uint32_t offset,
84 struct drm_i915_private *dev_priv =
85 (struct drm_i915_private *)dev->dev_private;
88 i915_kernel_lost_context(dev);
90 OUT_RING((0x02 << 29) | (0x40 << 22) | (0x3 << 20) | (0x3));
91 OUT_RING((0x3 << 24) | (0xF0 << 16) | (0x40));
92 OUT_RING((0x1 << 16) | (0x4));
99 static void i915_dereference_buffers_locked(struct drm_i915_validate_buffer
100 *buffers, unsigned num_buffers)
102 while (num_buffers--)
103 drm_bo_usage_deref_locked(&buffers[num_buffers].buffer);
106 int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
107 struct drm_i915_validate_buffer *buffers,
108 struct i915_relocatee_info *relocatee, uint32_t * reloc)
111 unsigned long new_cmd_offset;
117 * FIXME: O(relocs * buffers) complexity.
120 for (i = 0; i <= num_buffers; i++)
121 if (buffers[i].buffer)
122 if (reloc[2] == buffers[i].buffer->base.hash.key)
125 if (buf_index == -1) {
126 DRM_ERROR("Illegal relocation buffer %08X\n", reloc[2]);
131 * Short-circuit relocations that were correctly
132 * guessed by the client
134 if (buffers[buf_index].presumed_offset_correct && !DRM_DEBUG_RELOCATION)
137 new_cmd_offset = reloc[0];
138 if (!relocatee->data_page ||
139 !drm_bo_same_page(relocatee->offset, new_cmd_offset)) {
140 struct drm_bo_mem_reg *mem = &relocatee->buf->mem;
142 drm_bo_kunmap(&relocatee->kmap);
143 relocatee->data_page = NULL;
144 relocatee->offset = new_cmd_offset;
146 if (unlikely(relocatee->idle == I915_RELOC_UNCHECKED)) {
147 ret = drm_bo_wait(relocatee->buf, 0, 1, 0, 0);
150 relocatee->idle = I915_RELOC_IDLE;
153 if (unlikely((mem->mem_type != DRM_BO_MEM_LOCAL) &&
154 (mem->flags & DRM_BO_FLAG_CACHED_MAPPED)))
155 drm_bo_evict_cached(relocatee->buf);
157 ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT,
158 1, &relocatee->kmap);
161 ("Could not map command buffer to apply relocs\n %08lx",
165 relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
166 &relocatee->is_iomem);
167 relocatee->page_offset = (relocatee->offset & PAGE_MASK);
170 val = buffers[buf_index].buffer->offset;
171 index = (reloc[0] - relocatee->page_offset) >> 2;
173 /* add in validate */
174 val = val + reloc[1];
176 if (DRM_DEBUG_RELOCATION) {
177 if (buffers[buf_index].presumed_offset_correct &&
178 relocatee->data_page[index] != val) {
180 ("Relocation mismatch source %d target %d buffer %d user %08x kernel %08x\n",
181 reloc[0], reloc[1], buf_index,
182 relocatee->data_page[index], val);
186 if (relocatee->is_iomem)
187 iowrite32(val, relocatee->data_page + index);
189 relocatee->data_page[index] = val;
193 int i915_process_relocs(struct drm_file *file_priv,
195 uint32_t __user ** reloc_user_ptr,
196 struct i915_relocatee_info *relocatee,
197 struct drm_i915_validate_buffer *buffers,
198 uint32_t num_buffers)
200 int ret, reloc_stride;
202 uint32_t reloc_count;
204 uint32_t reloc_buf_size;
205 uint32_t *reloc_buf = NULL;
208 /* do a copy from user from the user ptr */
209 ret = get_user(reloc_count, *reloc_user_ptr);
211 DRM_ERROR("Could not map relocation buffer.\n");
215 ret = get_user(reloc_type, (*reloc_user_ptr) + 1);
217 DRM_ERROR("Could not map relocation buffer.\n");
221 if (reloc_type != 0) {
222 DRM_ERROR("Unsupported relocation type requested\n");
229 (reloc_count * I915_RELOC0_STRIDE)) * sizeof(uint32_t);
230 reloc_buf = kmalloc(reloc_buf_size, GFP_KERNEL);
232 DRM_ERROR("Out of memory for reloc buffer\n");
237 if (copy_from_user(reloc_buf, *reloc_user_ptr, reloc_buf_size)) {
242 /* get next relocate buffer handle */
243 *reloc_user_ptr = (uint32_t *) * (unsigned long *)&reloc_buf[2];
245 reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */
247 DRM_DEBUG("num relocs is %d, next is %p\n", reloc_count,
250 for (i = 0; i < reloc_count; i++) {
251 cur_offset = I915_RELOC_HEADER + (i * I915_RELOC0_STRIDE);
253 ret = i915_apply_reloc(file_priv, num_buffers, buffers,
254 relocatee, reloc_buf + cur_offset);
263 if (relocatee->data_page) {
264 drm_bo_kunmap(&relocatee->kmap);
265 relocatee->data_page = NULL;
271 static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
272 uint32_t __user * reloc_user_ptr,
273 struct drm_i915_validate_buffer *buffers,
276 struct drm_device *dev = file_priv->minor->dev;
277 struct i915_relocatee_info relocatee;
282 * Short circuit relocations when all previous
283 * buffers offsets were correctly guessed by
286 if (!DRM_DEBUG_RELOCATION) {
287 for (b = 0; b < buf_count; b++)
288 if (!buffers[b].presumed_offset_correct)
295 memset(&relocatee, 0, sizeof(relocatee));
296 relocatee.idle = I915_RELOC_UNCHECKED;
298 mutex_lock(&dev->struct_mutex);
299 relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1);
300 mutex_unlock(&dev->struct_mutex);
301 if (!relocatee.buf) {
302 DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle);
307 mutex_lock(&relocatee.buf->mutex);
308 while (reloc_user_ptr) {
310 i915_process_relocs(file_priv, buf_handle, &reloc_user_ptr,
311 &relocatee, buffers, buf_count);
313 DRM_ERROR("process relocs failed\n");
319 mutex_unlock(&relocatee.buf->mutex);
320 drm_bo_usage_deref_unlocked(&relocatee.buf);
325 static void i915_clear_relocatee(struct i915_relocatee_info *relocatee)
327 if (relocatee->data_page) {
328 #ifndef DRM_KMAP_ATOMIC_PROT_PFN
329 drm_bo_kunmap(&relocatee->kmap);
331 kunmap_atomic(relocatee->data_page, KM_USER0);
333 relocatee->data_page = NULL;
335 relocatee->buf = NULL;
339 static int i915_update_relocatee(struct i915_relocatee_info *relocatee,
340 struct drm_i915_validate_buffer *buffers,
341 unsigned int dst, unsigned long dst_offset)
345 if (unlikely(dst != relocatee->dst || NULL == relocatee->buf)) {
346 i915_clear_relocatee(relocatee);
347 relocatee->dst = dst;
348 relocatee->buf = buffers[dst].buffer;
349 relocatee->idle = buffers[dst].idle;
352 * Check for buffer idle. If the buffer is busy, revert to
356 if (relocatee->idle == I915_RELOC_UNCHECKED) {
358 mutex_lock(&relocatee->buf->mutex);
360 ret = drm_bo_wait(relocatee->buf, 0, 1, 1, 0);
362 relocatee->idle = I915_RELOC_IDLE;
364 relocatee->idle = I915_RELOC_BUSY;
365 relocatee->performed_ring_relocs = 1;
367 mutex_unlock(&relocatee->buf->mutex);
369 buffers[dst].idle = relocatee->idle;
373 if (relocatee->idle == I915_RELOC_BUSY)
376 if (unlikely(dst_offset > relocatee->buf->num_pages * PAGE_SIZE)) {
377 DRM_ERROR("Relocation destination out of bounds.\n");
380 if (unlikely(!drm_bo_same_page(relocatee->page_offset, dst_offset) ||
381 NULL == relocatee->data_page)) {
382 #ifdef DRM_KMAP_ATOMIC_PROT_PFN
383 if (NULL != relocatee->data_page) {
384 kunmap_atomic(relocatee->data_page, KM_USER0);
385 relocatee->data_page = NULL;
387 ret = drm_bo_pfn_prot(relocatee->buf, dst_offset,
388 &relocatee->pfn, &relocatee->pg_prot);
390 DRM_ERROR("Can't map relocation destination.\n");
393 relocatee->data_page =
394 kmap_atomic_prot_pfn(relocatee->pfn, KM_USER0,
397 if (NULL != relocatee->data_page) {
398 drm_bo_kunmap(&relocatee->kmap);
399 relocatee->data_page = NULL;
402 ret = drm_bo_kmap(relocatee->buf, dst_offset >> PAGE_SHIFT,
403 1, &relocatee->kmap);
405 DRM_ERROR("Can't map relocation destination.\n");
409 relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
410 &relocatee->is_iomem);
412 relocatee->page_offset = dst_offset & PAGE_MASK;
417 static int i915_apply_post_reloc(uint32_t reloc[],
418 struct drm_i915_validate_buffer *buffers,
419 uint32_t num_buffers,
420 struct i915_relocatee_info *relocatee)
422 uint32_t reloc_buffer = reloc[2];
423 uint32_t dst_buffer = reloc[3];
428 if (likely(buffers[reloc_buffer].presumed_offset_correct))
430 if (unlikely(reloc_buffer >= num_buffers)) {
431 DRM_ERROR("Invalid reloc buffer index.\n");
434 if (unlikely(dst_buffer >= num_buffers)) {
435 DRM_ERROR("Invalid dest buffer index.\n");
439 ret = i915_update_relocatee(relocatee, buffers, dst_buffer, reloc[0]);
443 val = buffers[reloc_buffer].buffer->offset;
444 index = (reloc[0] - relocatee->page_offset) >> 2;
445 val = val + reloc[1];
447 if (relocatee->idle == I915_RELOC_BUSY) {
448 i915_emit_ring_reloc(relocatee->buf->dev,
449 relocatee->buf->offset + reloc[0], val);
452 #ifdef DRM_KMAP_ATOMIC_PROT_PFN
453 relocatee->data_page[index] = val;
455 if (likely(relocatee->is_iomem))
456 iowrite32(val, relocatee->data_page + index);
458 relocatee->data_page[index] = val;
464 static int i915_post_relocs(struct drm_file *file_priv,
465 uint32_t __user * new_reloc_ptr,
466 struct drm_i915_validate_buffer *buffers,
467 unsigned int num_buffers)
470 uint32_t reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t);
471 uint32_t header_size = I915_RELOC_HEADER * sizeof(uint32_t);
472 struct i915_relocatee_info relocatee;
478 int short_circuit = 1;
479 uint32_t __user *reloc_ptr;
480 uint64_t new_reloc_data;
481 uint32_t reloc_buf_size;
484 for (i = 0; i < num_buffers; ++i) {
485 if (unlikely(!buffers[i].presumed_offset_correct)) {
491 if (likely(short_circuit))
494 memset(&relocatee, 0, sizeof(relocatee));
496 while (new_reloc_ptr) {
497 reloc_ptr = new_reloc_ptr;
499 ret = get_user(num_relocs, reloc_ptr);
502 if (unlikely(!access_ok(VERIFY_READ, reloc_ptr,
504 num_relocs * reloc_stride)))
507 ret = __get_user(reloc_type, reloc_ptr + 1);
511 if (unlikely(reloc_type != 1)) {
512 DRM_ERROR("Unsupported relocation type requested.\n");
517 ret = __get_user(new_reloc_data, reloc_ptr + 2);
518 new_reloc_ptr = (uint32_t __user *) (unsigned long)
521 reloc_ptr += I915_RELOC_HEADER;
527 (num_relocs * I915_RELOC0_STRIDE) * sizeof(uint32_t);
528 reloc_buf = kmalloc(reloc_buf_size, GFP_KERNEL);
530 DRM_ERROR("Out of memory for reloc buffer\n");
535 if (__copy_from_user(reloc_buf, reloc_ptr, reloc_buf_size)) {
541 for (count = 0; count < num_relocs; ++count) {
542 ret = i915_apply_post_reloc(reloc, buffers,
543 num_buffers, &relocatee);
548 reloc += I915_RELOC0_STRIDE;
556 i915_clear_relocatee(&relocatee);
561 * Flush ring relocs so the command parser will pick them up.
564 if (relocatee.performed_ring_relocs)
565 (void)i915_emit_mi_flush(file_priv->minor->dev, 0);
567 i915_clear_relocatee(&relocatee);
576 static int i915_check_presumed(struct drm_i915_op_arg *arg,
577 struct drm_buffer_object *bo,
578 uint32_t __user * data, int *presumed_ok)
580 struct drm_bo_op_req *req = &arg->d.req;
581 uint32_t hint_offset;
582 uint32_t hint = req->bo_req.hint;
586 if (!(hint & DRM_BO_HINT_PRESUMED_OFFSET))
588 if (bo->offset == req->bo_req.presumed_offset) {
594 * We need to turn off the HINT_PRESUMED_OFFSET for this buffer in
595 * the user-space IOCTL argument list, since the buffer has moved,
596 * we're about to apply relocations and we might subsequently
597 * hit an -EAGAIN. In that case the argument list will be reused by
598 * user-space, but the presumed offset is no longer valid.
600 * Needless to say, this is a bit ugly.
603 hint_offset = (uint32_t *) & req->bo_req.hint - (uint32_t *) arg;
604 hint &= ~DRM_BO_HINT_PRESUMED_OFFSET;
605 return __put_user(hint, data + hint_offset);
609 * Validate, add fence and relocate a block of bos from a userspace list
611 int i915_validate_buffer_list(struct drm_file *file_priv,
612 unsigned int fence_class, uint64_t data,
613 struct drm_i915_validate_buffer *buffers,
614 uint32_t * num_buffers,
615 uint32_t __user ** post_relocs)
617 struct drm_i915_op_arg arg;
618 struct drm_bo_op_req *req = &arg.d.req;
620 unsigned buf_count = 0;
622 uint32_t __user *reloc_user_ptr;
623 struct drm_i915_validate_buffer *item = buffers;
627 if (buf_count >= *num_buffers) {
628 DRM_ERROR("Buffer count exceeded %d\n.", *num_buffers);
632 item = buffers + buf_count;
634 item->presumed_offset_correct = 0;
635 item->idle = I915_RELOC_UNCHECKED;
638 (&arg, (void __user *)(unsigned long)data, sizeof(arg))) {
644 if (req->op != drm_bo_validate) {
646 ("Buffer object operation wasn't \"validate\".\n");
651 item->data = (void __user *)(unsigned long)data;
653 buf_handle = req->bo_req.handle;
654 reloc_user_ptr = (uint32_t *) (unsigned long)arg.reloc_ptr;
657 * Switch mode to post-validation relocations?
660 if (unlikely((buf_count == 0) && (*post_relocs == NULL) &&
661 (reloc_user_ptr != NULL))) {
664 ret = get_user(reloc_type, reloc_user_ptr + 1);
669 *post_relocs = reloc_user_ptr;
673 if ((*post_relocs == NULL) && (reloc_user_ptr != NULL)) {
675 i915_exec_reloc(file_priv, buf_handle,
676 reloc_user_ptr, buffers, buf_count);
682 ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
684 req->bo_req.mask, req->bo_req.hint,
685 req->bo_req.fence_class,
686 NULL, &item->buffer);
688 DRM_ERROR("error on handle validate %d\n", ret);
694 ret = i915_check_presumed(&arg, item->buffer,
697 &item->presumed_offset_correct);
704 *num_buffers = buf_count;
705 item->ret = (ret != -EAGAIN) ? ret : 0;
710 * Remove all buffers from the unfenced list.
711 * If the execbuffer operation was aborted, for example due to a signal,
712 * this also make sure that buffers retain their original state and
714 * Copy back buffer information to user-space unless we were interrupted
715 * by a signal. In which case the IOCTL must be rerun.
718 static int i915_handle_copyback(struct drm_device *dev,
719 struct drm_i915_validate_buffer *buffers,
720 unsigned int num_buffers, int ret)
724 struct drm_i915_op_arg arg;
725 struct drm_buffer_object *bo;
728 drm_putback_buffer_objects(dev);
730 if (ret != -EAGAIN) {
731 for (i = 0; i < num_buffers; ++i) {
733 arg.d.rep.ret = buffers->ret;
734 bo = buffers->buffer;
735 mutex_lock(&bo->mutex);
736 drm_bo_fill_rep_arg(bo, &arg.d.rep.bo_info);
737 mutex_unlock(&bo->mutex);
738 if (__copy_to_user(buffers->data, &arg, sizeof(arg)))
748 * Create a fence object, and if that fails, pretend that everything is
749 * OK and just idle the GPU.
752 void i915_fence_or_sync(struct drm_file *file_priv,
753 uint32_t fence_flags,
754 struct drm_fence_arg *fence_arg,
755 struct drm_fence_object **fence_p)
757 struct drm_device *dev = file_priv->minor->dev;
759 struct drm_fence_object *fence;
761 ret = drm_fence_buffer_objects(dev, NULL, fence_flags, NULL, &fence);
766 * Fence creation failed.
767 * Fall back to synchronous operation and idle the engine.
770 (void)i915_emit_mi_flush(dev, MI_READ_FLUSH);
771 (void)i915_quiescent(dev);
773 if (!(fence_flags & DRM_FENCE_FLAG_NO_USER)) {
776 * Communicate to user-space that
777 * fence creation has failed and that
778 * the engine is idle.
781 fence_arg->handle = ~0;
782 fence_arg->error = ret;
784 drm_putback_buffer_objects(dev);
790 if (!(fence_flags & DRM_FENCE_FLAG_NO_USER)) {
792 ret = drm_fence_add_user_object(file_priv, fence,
794 DRM_FENCE_FLAG_SHAREABLE);
796 drm_fence_fill_arg(fence, fence_arg);
799 * Fence user object creation failed.
800 * We must idle the engine here as well, as user-
801 * space expects a fence object to wait on. Since we
802 * have a fence object we wait for it to signal
803 * to indicate engine "sufficiently" idle.
806 (void)drm_fence_object_wait(fence, 0, 1, fence->type);
807 drm_fence_usage_deref_unlocked(&fence);
808 fence_arg->handle = ~0;
809 fence_arg->error = ret;
816 drm_fence_usage_deref_unlocked(&fence);
819 int i915_execbuffer(struct drm_device *dev, void *data,
820 struct drm_file *file_priv)
822 struct drm_i915_private *dev_priv = (struct drm_i915_private *)
824 struct drm_i915_master_private *master_priv =
825 (struct drm_i915_master_private *)
826 dev->primary->master->driver_priv;
827 struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)
828 master_priv->sarea_priv;
829 struct drm_i915_execbuffer *exec_buf = data;
830 struct drm_i915_batchbuffer *batch = &exec_buf->batch;
831 struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;
834 uint32_t __user *post_relocs;
836 if (!dev_priv->allow_batchbuffer) {
837 DRM_ERROR("Batchbuffer ioctl disabled\n");
841 if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
842 batch->num_cliprects *
847 if (exec_buf->num_buffers > dev_priv->max_validate_buffers)
850 ret = drm_bo_read_lock(&dev->bm.bm_lock, 1);
855 * The cmdbuf_mutex makes sure the validate-submit-fence
856 * operation is atomic.
859 ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
861 drm_bo_read_unlock(&dev->bm.bm_lock);
865 num_buffers = exec_buf->num_buffers;
867 if (!dev_priv->val_bufs) {
869 vmalloc(sizeof(struct drm_i915_validate_buffer) *
870 dev_priv->max_validate_buffers);
872 if (!dev_priv->val_bufs) {
873 drm_bo_read_unlock(&dev->bm.bm_lock);
874 mutex_unlock(&dev_priv->cmdbuf_mutex);
878 /* validate buffer list + fixup relocations */
879 ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list,
880 dev_priv->val_bufs, &num_buffers,
886 ret = i915_post_relocs(file_priv, post_relocs,
887 dev_priv->val_bufs, num_buffers);
892 /* make sure all previous memory operations have passed */
896 drm_agp_chipset_flush(dev);
898 dev_priv->val_bufs[num_buffers - 1].buffer->offset;
900 batch->start += dev_priv->val_bufs[0].buffer->offset;
903 DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n",
904 batch->start, batch->used, batch->num_cliprects);
906 ret = i915_dispatch_batchbuffer(dev, batch);
910 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
911 i915_fence_or_sync(file_priv, fence_arg->flags, fence_arg, NULL);
914 ret = i915_handle_copyback(dev, dev_priv->val_bufs, num_buffers, ret);
915 mutex_lock(&dev->struct_mutex);
916 i915_dereference_buffers_locked(dev_priv->val_bufs, num_buffers);
917 mutex_unlock(&dev->struct_mutex);
918 mutex_unlock(&dev_priv->cmdbuf_mutex);
919 drm_bo_read_unlock(&dev->bm.bm_lock);