1 // SPDX-License-Identifier: MIT
3 * Copyright © 2021 Intel Corporation
8 #include <linux/dma-fence-array.h>
10 #include <drm/ttm/ttm_execbuf_util.h>
11 #include <drm/ttm/ttm_tt.h>
12 #include <drm/xe_drm.h>
13 #include <linux/kthread.h>
15 #include <linux/swap.h>
18 #include "xe_device.h"
19 #include "xe_engine.h"
21 #include "xe_gt_pagefault.h"
22 #include "xe_gt_tlb_invalidation.h"
23 #include "xe_migrate.h"
25 #include "xe_preempt_fence.h"
27 #include "xe_res_cursor.h"
31 #define TEST_VM_ASYNC_OPS_ERROR
34 * xe_vma_userptr_check_repin() - Advisory check for repin needed
35 * @vma: The userptr vma
37 * Check if the userptr vma has been invalidated since last successful
38 * repin. The check is advisory only and can the function can be called
39 * without the vm->userptr.notifier_lock held. There is no guarantee that the
40 * vma userptr will remain valid after a lockless check, so typically
41 * the call needs to be followed by a proper check under the notifier_lock.
43 * Return: 0 if userptr vma is valid, -EAGAIN otherwise; repin recommended.
45 int xe_vma_userptr_check_repin(struct xe_vma *vma)
47 return mmu_interval_check_retry(&vma->userptr.notifier,
48 vma->userptr.notifier_seq) ?
52 int xe_vma_userptr_pin_pages(struct xe_vma *vma)
54 struct xe_vm *vm = vma->vm;
55 struct xe_device *xe = vm->xe;
56 const unsigned long num_pages =
57 (vma->end - vma->start + 1) >> PAGE_SHIFT;
59 bool in_kthread = !current->mm;
60 unsigned long notifier_seq;
62 bool read_only = vma->pte_flags & XE_PTE_READ_ONLY;
64 lockdep_assert_held(&vm->lock);
65 XE_BUG_ON(!xe_vma_is_userptr(vma));
70 notifier_seq = mmu_interval_read_begin(&vma->userptr.notifier);
71 if (notifier_seq == vma->userptr.notifier_seq)
74 pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL);
78 if (vma->userptr.sg) {
79 dma_unmap_sgtable(xe->drm.dev,
81 read_only ? DMA_TO_DEVICE :
82 DMA_BIDIRECTIONAL, 0);
83 sg_free_table(vma->userptr.sg);
84 vma->userptr.sg = NULL;
89 if (!mmget_not_zero(vma->userptr.notifier.mm)) {
93 kthread_use_mm(vma->userptr.notifier.mm);
96 while (pinned < num_pages) {
97 ret = get_user_pages_fast(vma->userptr.ptr + pinned * PAGE_SIZE,
99 read_only ? 0 : FOLL_WRITE,
112 kthread_unuse_mm(vma->userptr.notifier.mm);
113 mmput(vma->userptr.notifier.mm);
119 ret = sg_alloc_table_from_pages(&vma->userptr.sgt, pages, pinned,
120 0, (u64)pinned << PAGE_SHIFT,
123 vma->userptr.sg = NULL;
126 vma->userptr.sg = &vma->userptr.sgt;
128 ret = dma_map_sgtable(xe->drm.dev, vma->userptr.sg,
129 read_only ? DMA_TO_DEVICE :
131 DMA_ATTR_SKIP_CPU_SYNC |
132 DMA_ATTR_NO_KERNEL_MAPPING);
134 sg_free_table(vma->userptr.sg);
135 vma->userptr.sg = NULL;
139 for (i = 0; i < pinned; ++i) {
142 set_page_dirty(pages[i]);
143 unlock_page(pages[i]);
146 mark_page_accessed(pages[i]);
150 release_pages(pages, pinned);
154 vma->userptr.notifier_seq = notifier_seq;
155 if (xe_vma_userptr_check_repin(vma) == -EAGAIN)
159 return ret < 0 ? ret : 0;
162 static bool preempt_fences_waiting(struct xe_vm *vm)
166 lockdep_assert_held(&vm->lock);
167 xe_vm_assert_held(vm);
169 list_for_each_entry(e, &vm->preempt.engines, compute.link) {
170 if (!e->compute.pfence || (e->compute.pfence &&
171 test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
172 &e->compute.pfence->flags))) {
180 static void free_preempt_fences(struct list_head *list)
182 struct list_head *link, *next;
184 list_for_each_safe(link, next, list)
185 xe_preempt_fence_free(to_preempt_fence_from_link(link));
188 static int alloc_preempt_fences(struct xe_vm *vm, struct list_head *list,
191 lockdep_assert_held(&vm->lock);
192 xe_vm_assert_held(vm);
194 if (*count >= vm->preempt.num_engines)
197 for (; *count < vm->preempt.num_engines; ++(*count)) {
198 struct xe_preempt_fence *pfence = xe_preempt_fence_alloc();
201 return PTR_ERR(pfence);
203 list_move_tail(xe_preempt_fence_link(pfence), list);
209 static int wait_for_existing_preempt_fences(struct xe_vm *vm)
213 xe_vm_assert_held(vm);
215 list_for_each_entry(e, &vm->preempt.engines, compute.link) {
216 if (e->compute.pfence) {
217 long timeout = dma_fence_wait(e->compute.pfence, false);
221 dma_fence_put(e->compute.pfence);
222 e->compute.pfence = NULL;
229 static bool xe_vm_is_idle(struct xe_vm *vm)
233 xe_vm_assert_held(vm);
234 list_for_each_entry(e, &vm->preempt.engines, compute.link) {
235 if (!xe_engine_is_idle(e))
242 static void arm_preempt_fences(struct xe_vm *vm, struct list_head *list)
244 struct list_head *link;
247 list_for_each_entry(e, &vm->preempt.engines, compute.link) {
248 struct dma_fence *fence;
251 XE_BUG_ON(link == list);
253 fence = xe_preempt_fence_arm(to_preempt_fence_from_link(link),
254 e, e->compute.context,
256 dma_fence_put(e->compute.pfence);
257 e->compute.pfence = fence;
261 static int add_preempt_fences(struct xe_vm *vm, struct xe_bo *bo)
264 struct ww_acquire_ctx ww;
267 err = xe_bo_lock(bo, &ww, vm->preempt.num_engines, true);
271 list_for_each_entry(e, &vm->preempt.engines, compute.link)
272 if (e->compute.pfence) {
273 dma_resv_add_fence(bo->ttm.base.resv,
275 DMA_RESV_USAGE_BOOKKEEP);
278 xe_bo_unlock(bo, &ww);
283 * xe_vm_fence_all_extobjs() - Add a fence to vm's external objects' resv
285 * @fence: The fence to add.
286 * @usage: The resv usage for the fence.
288 * Loops over all of the vm's external object bindings and adds a @fence
289 * with the given @usage to all of the external object's reservation
292 void xe_vm_fence_all_extobjs(struct xe_vm *vm, struct dma_fence *fence,
293 enum dma_resv_usage usage)
297 list_for_each_entry(vma, &vm->extobj.list, extobj.link)
298 dma_resv_add_fence(vma->bo->ttm.base.resv, fence, usage);
301 static void resume_and_reinstall_preempt_fences(struct xe_vm *vm)
305 lockdep_assert_held(&vm->lock);
306 xe_vm_assert_held(vm);
308 list_for_each_entry(e, &vm->preempt.engines, compute.link) {
311 dma_resv_add_fence(&vm->resv, e->compute.pfence,
312 DMA_RESV_USAGE_BOOKKEEP);
313 xe_vm_fence_all_extobjs(vm, e->compute.pfence,
314 DMA_RESV_USAGE_BOOKKEEP);
318 int xe_vm_add_compute_engine(struct xe_vm *vm, struct xe_engine *e)
320 struct ttm_validate_buffer tv_onstack[XE_ONSTACK_TV];
321 struct ttm_validate_buffer *tv;
322 struct ww_acquire_ctx ww;
323 struct list_head objs;
324 struct dma_fence *pfence;
328 XE_BUG_ON(!xe_vm_in_compute_mode(vm));
330 down_write(&vm->lock);
332 err = xe_vm_lock_dma_resv(vm, &ww, tv_onstack, &tv, &objs, true, 1);
334 goto out_unlock_outer;
336 pfence = xe_preempt_fence_create(e, e->compute.context,
343 list_add(&e->compute.link, &vm->preempt.engines);
344 ++vm->preempt.num_engines;
345 e->compute.pfence = pfence;
347 down_read(&vm->userptr.notifier_lock);
349 dma_resv_add_fence(&vm->resv, pfence,
350 DMA_RESV_USAGE_BOOKKEEP);
352 xe_vm_fence_all_extobjs(vm, pfence, DMA_RESV_USAGE_BOOKKEEP);
355 * Check to see if a preemption on VM is in flight or userptr
356 * invalidation, if so trigger this preempt fence to sync state with
357 * other preempt fences on the VM.
359 wait = __xe_vm_userptr_needs_repin(vm) || preempt_fences_waiting(vm);
361 dma_fence_enable_sw_signaling(pfence);
363 up_read(&vm->userptr.notifier_lock);
366 xe_vm_unlock_dma_resv(vm, tv_onstack, tv, &ww, &objs);
374 * __xe_vm_userptr_needs_repin() - Check whether the VM does have userptrs
375 * that need repinning.
378 * This function checks for whether the VM has userptrs that need repinning,
379 * and provides a release-type barrier on the userptr.notifier_lock after
382 * Return: 0 if there are no userptrs needing repinning, -EAGAIN if there are.
384 int __xe_vm_userptr_needs_repin(struct xe_vm *vm)
386 lockdep_assert_held_read(&vm->userptr.notifier_lock);
388 return (list_empty(&vm->userptr.repin_list) &&
389 list_empty(&vm->userptr.invalidated)) ? 0 : -EAGAIN;
393 * xe_vm_lock_dma_resv() - Lock the vm dma_resv object and the dma_resv
394 * objects of the vm's external buffer objects.
396 * @ww: Pointer to a struct ww_acquire_ctx locking context.
397 * @tv_onstack: Array size XE_ONSTACK_TV of storage for the struct
398 * ttm_validate_buffers used for locking.
399 * @tv: Pointer to a pointer that on output contains the actual storage used.
400 * @objs: List head for the buffer objects locked.
401 * @intr: Whether to lock interruptible.
402 * @num_shared: Number of dma-fence slots to reserve in the locked objects.
404 * Locks the vm dma-resv objects and all the dma-resv objects of the
405 * buffer objects on the vm external object list. The TTM utilities require
406 * a list of struct ttm_validate_buffers pointing to the actual buffer
407 * objects to lock. Storage for those struct ttm_validate_buffers should
408 * be provided in @tv_onstack, and is typically reserved on the stack
409 * of the caller. If the size of @tv_onstack isn't sufficient, then
410 * storage will be allocated internally using kvmalloc().
412 * The function performs deadlock handling internally, and after a
413 * successful return the ww locking transaction should be considered
416 * Return: 0 on success, Negative error code on error. In particular if
417 * @intr is set to true, -EINTR or -ERESTARTSYS may be returned. In case
418 * of error, any locking performed has been reverted.
420 int xe_vm_lock_dma_resv(struct xe_vm *vm, struct ww_acquire_ctx *ww,
421 struct ttm_validate_buffer *tv_onstack,
422 struct ttm_validate_buffer **tv,
423 struct list_head *objs,
425 unsigned int num_shared)
427 struct ttm_validate_buffer *tv_vm, *tv_bo;
428 struct xe_vma *vma, *next;
432 lockdep_assert_held(&vm->lock);
434 if (vm->extobj.entries < XE_ONSTACK_TV) {
437 tv_vm = kvmalloc_array(vm->extobj.entries + 1, sizeof(*tv_vm),
444 INIT_LIST_HEAD(objs);
445 list_for_each_entry(vma, &vm->extobj.list, extobj.link) {
446 tv_bo->num_shared = num_shared;
447 tv_bo->bo = &vma->bo->ttm;
449 list_add_tail(&tv_bo->head, objs);
452 tv_vm->num_shared = num_shared;
453 tv_vm->bo = xe_vm_ttm_bo(vm);
454 list_add_tail(&tv_vm->head, objs);
455 err = ttm_eu_reserve_buffers(ww, objs, intr, &dups);
459 spin_lock(&vm->notifier.list_lock);
460 list_for_each_entry_safe(vma, next, &vm->notifier.rebind_list,
461 notifier.rebind_link) {
462 xe_bo_assert_held(vma->bo);
464 list_del_init(&vma->notifier.rebind_link);
465 if (vma->gt_present && !vma->destroyed)
466 list_move_tail(&vma->rebind_link, &vm->rebind_list);
468 spin_unlock(&vm->notifier.list_lock);
474 if (tv_vm != tv_onstack)
481 * xe_vm_unlock_dma_resv() - Unlock reservation objects locked by
482 * xe_vm_lock_dma_resv()
484 * @tv_onstack: The @tv_onstack array given to xe_vm_lock_dma_resv().
485 * @tv: The value of *@tv given by xe_vm_lock_dma_resv().
486 * @ww: The ww_acquire_context used for locking.
487 * @objs: The list returned from xe_vm_lock_dma_resv().
489 * Unlocks the reservation objects and frees any memory allocated by
490 * xe_vm_lock_dma_resv().
492 void xe_vm_unlock_dma_resv(struct xe_vm *vm,
493 struct ttm_validate_buffer *tv_onstack,
494 struct ttm_validate_buffer *tv,
495 struct ww_acquire_ctx *ww,
496 struct list_head *objs)
499 * Nothing should've been able to enter the list while we were locked,
500 * since we've held the dma-resvs of all the vm's external objects,
501 * and holding the dma_resv of an object is required for list
502 * addition, and we shouldn't add ourselves.
504 XE_WARN_ON(!list_empty(&vm->notifier.rebind_list));
506 ttm_eu_backoff_reservation(ww, objs);
507 if (tv && tv != tv_onstack)
511 static void preempt_rebind_work_func(struct work_struct *w)
513 struct xe_vm *vm = container_of(w, struct xe_vm, preempt.rebind_work);
515 struct ttm_validate_buffer tv_onstack[XE_ONSTACK_TV];
516 struct ttm_validate_buffer *tv;
517 struct ww_acquire_ctx ww;
518 struct list_head objs;
519 struct dma_fence *rebind_fence;
520 unsigned int fence_count = 0;
521 LIST_HEAD(preempt_fences);
524 int __maybe_unused tries = 0;
526 XE_BUG_ON(!xe_vm_in_compute_mode(vm));
527 trace_xe_vm_rebind_worker_enter(vm);
529 if (xe_vm_is_closed(vm)) {
530 trace_xe_vm_rebind_worker_exit(vm);
534 down_write(&vm->lock);
537 if (vm->async_ops.error)
538 goto out_unlock_outer;
541 * Extreme corner where we exit a VM error state with a munmap style VM
542 * unbind inflight which requires a rebind. In this case the rebind
543 * needs to install some fences into the dma-resv slots. The worker to
544 * do this queued, let that worker make progress by dropping vm->lock
545 * and trying this again.
547 if (vm->async_ops.munmap_rebind_inflight) {
549 flush_work(&vm->async_ops.work);
553 if (xe_vm_userptr_check_repin(vm)) {
554 err = xe_vm_userptr_pin(vm);
556 goto out_unlock_outer;
559 err = xe_vm_lock_dma_resv(vm, &ww, tv_onstack, &tv, &objs,
560 false, vm->preempt.num_engines);
562 goto out_unlock_outer;
564 if (xe_vm_is_idle(vm)) {
565 vm->preempt.rebind_deactivated = true;
569 /* Fresh preempt fences already installed. Everyting is running. */
570 if (!preempt_fences_waiting(vm))
574 * This makes sure vm is completely suspended and also balances
575 * xe_engine suspend- and resume; we resume *all* vm engines below.
577 err = wait_for_existing_preempt_fences(vm);
581 err = alloc_preempt_fences(vm, &preempt_fences, &fence_count);
585 list_for_each_entry(vma, &vm->rebind_list, rebind_link) {
586 if (xe_vma_is_userptr(vma) || vma->destroyed)
589 err = xe_bo_validate(vma->bo, vm, false);
594 rebind_fence = xe_vm_rebind(vm, true);
595 if (IS_ERR(rebind_fence)) {
596 err = PTR_ERR(rebind_fence);
601 dma_fence_wait(rebind_fence, false);
602 dma_fence_put(rebind_fence);
605 /* Wait on munmap style VM unbinds */
606 wait = dma_resv_wait_timeout(&vm->resv,
607 DMA_RESV_USAGE_KERNEL,
608 false, MAX_SCHEDULE_TIMEOUT);
614 #define retry_required(__tries, __vm) \
615 (IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT) ? \
616 (!(__tries)++ || __xe_vm_userptr_needs_repin(__vm)) : \
617 __xe_vm_userptr_needs_repin(__vm))
619 down_read(&vm->userptr.notifier_lock);
620 if (retry_required(tries, vm)) {
621 up_read(&vm->userptr.notifier_lock);
626 #undef retry_required
628 /* Point of no return. */
629 arm_preempt_fences(vm, &preempt_fences);
630 resume_and_reinstall_preempt_fences(vm);
631 up_read(&vm->userptr.notifier_lock);
634 xe_vm_unlock_dma_resv(vm, tv_onstack, tv, &ww, &objs);
636 if (err == -EAGAIN) {
637 trace_xe_vm_rebind_worker_retry(vm);
642 free_preempt_fences(&preempt_fences);
644 XE_WARN_ON(err < 0); /* TODO: Kill VM or put in error state */
645 trace_xe_vm_rebind_worker_exit(vm);
648 struct async_op_fence;
649 static int __xe_vm_bind(struct xe_vm *vm, struct xe_vma *vma,
650 struct xe_engine *e, struct xe_sync_entry *syncs,
651 u32 num_syncs, struct async_op_fence *afence);
653 static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
654 const struct mmu_notifier_range *range,
655 unsigned long cur_seq)
657 struct xe_vma *vma = container_of(mni, struct xe_vma, userptr.notifier);
658 struct xe_vm *vm = vma->vm;
659 struct dma_resv_iter cursor;
660 struct dma_fence *fence;
663 XE_BUG_ON(!xe_vma_is_userptr(vma));
664 trace_xe_vma_userptr_invalidate(vma);
666 if (!mmu_notifier_range_blockable(range))
669 down_write(&vm->userptr.notifier_lock);
670 mmu_interval_set_seq(mni, cur_seq);
672 /* No need to stop gpu access if the userptr is not yet bound. */
673 if (!vma->userptr.initial_bind) {
674 up_write(&vm->userptr.notifier_lock);
679 * Tell exec and rebind worker they need to repin and rebind this
682 if (!xe_vm_in_fault_mode(vm) && !vma->destroyed && vma->gt_present) {
683 spin_lock(&vm->userptr.invalidated_lock);
684 list_move_tail(&vma->userptr.invalidate_link,
685 &vm->userptr.invalidated);
686 spin_unlock(&vm->userptr.invalidated_lock);
689 up_write(&vm->userptr.notifier_lock);
692 * Preempt fences turn into schedule disables, pipeline these.
693 * Note that even in fault mode, we need to wait for binds and
694 * unbinds to complete, and those are attached as BOOKMARK fences
697 dma_resv_iter_begin(&cursor, &vm->resv,
698 DMA_RESV_USAGE_BOOKKEEP);
699 dma_resv_for_each_fence_unlocked(&cursor, fence)
700 dma_fence_enable_sw_signaling(fence);
701 dma_resv_iter_end(&cursor);
703 err = dma_resv_wait_timeout(&vm->resv,
704 DMA_RESV_USAGE_BOOKKEEP,
705 false, MAX_SCHEDULE_TIMEOUT);
706 XE_WARN_ON(err <= 0);
708 if (xe_vm_in_fault_mode(vm)) {
709 err = xe_vm_invalidate_vma(vma);
713 trace_xe_vma_userptr_invalidate_complete(vma);
718 static const struct mmu_interval_notifier_ops vma_userptr_notifier_ops = {
719 .invalidate = vma_userptr_invalidate,
722 int xe_vm_userptr_pin(struct xe_vm *vm)
724 struct xe_vma *vma, *next;
726 LIST_HEAD(tmp_evict);
728 lockdep_assert_held_write(&vm->lock);
730 /* Collect invalidated userptrs */
731 spin_lock(&vm->userptr.invalidated_lock);
732 list_for_each_entry_safe(vma, next, &vm->userptr.invalidated,
733 userptr.invalidate_link) {
734 list_del_init(&vma->userptr.invalidate_link);
735 list_move_tail(&vma->userptr_link, &vm->userptr.repin_list);
737 spin_unlock(&vm->userptr.invalidated_lock);
739 /* Pin and move to temporary list */
740 list_for_each_entry_safe(vma, next, &vm->userptr.repin_list, userptr_link) {
741 err = xe_vma_userptr_pin_pages(vma);
745 list_move_tail(&vma->userptr_link, &tmp_evict);
748 /* Take lock and move to rebind_list for rebinding. */
749 err = dma_resv_lock_interruptible(&vm->resv, NULL);
753 list_for_each_entry_safe(vma, next, &tmp_evict, userptr_link) {
754 list_del_init(&vma->userptr_link);
755 list_move_tail(&vma->rebind_link, &vm->rebind_list);
758 dma_resv_unlock(&vm->resv);
763 list_splice_tail(&tmp_evict, &vm->userptr.repin_list);
769 * xe_vm_userptr_check_repin() - Check whether the VM might have userptrs
770 * that need repinning.
773 * This function does an advisory check for whether the VM has userptrs that
776 * Return: 0 if there are no indications of userptrs needing repinning,
777 * -EAGAIN if there are.
779 int xe_vm_userptr_check_repin(struct xe_vm *vm)
781 return (list_empty_careful(&vm->userptr.repin_list) &&
782 list_empty_careful(&vm->userptr.invalidated)) ? 0 : -EAGAIN;
785 static struct dma_fence *
786 xe_vm_bind_vma(struct xe_vma *vma, struct xe_engine *e,
787 struct xe_sync_entry *syncs, u32 num_syncs);
789 struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
791 struct dma_fence *fence = NULL;
792 struct xe_vma *vma, *next;
794 lockdep_assert_held(&vm->lock);
795 if (xe_vm_no_dma_fences(vm) && !rebind_worker)
798 xe_vm_assert_held(vm);
799 list_for_each_entry_safe(vma, next, &vm->rebind_list, rebind_link) {
800 XE_WARN_ON(!vma->gt_present);
802 list_del_init(&vma->rebind_link);
803 dma_fence_put(fence);
805 trace_xe_vma_rebind_worker(vma);
807 trace_xe_vma_rebind_exec(vma);
808 fence = xe_vm_bind_vma(vma, NULL, NULL, 0);
816 static struct xe_vma *xe_vma_create(struct xe_vm *vm,
818 u64 bo_offset_or_userptr,
827 XE_BUG_ON(start >= end);
828 XE_BUG_ON(end >= vm->size);
830 vma = kzalloc(sizeof(*vma), GFP_KERNEL);
832 vma = ERR_PTR(-ENOMEM);
836 INIT_LIST_HEAD(&vma->rebind_link);
837 INIT_LIST_HEAD(&vma->unbind_link);
838 INIT_LIST_HEAD(&vma->userptr_link);
839 INIT_LIST_HEAD(&vma->userptr.invalidate_link);
840 INIT_LIST_HEAD(&vma->notifier.rebind_link);
841 INIT_LIST_HEAD(&vma->extobj.link);
847 vma->pte_flags = XE_PTE_READ_ONLY;
850 vma->gt_mask = gt_mask;
852 for_each_gt(gt, vm->xe, id)
853 if (!xe_gt_is_media_type(gt))
854 vma->gt_mask |= 0x1 << id;
857 if (vm->xe->info.platform == XE_PVC)
858 vma->use_atomic_access_pte_bit = true;
861 xe_bo_assert_held(bo);
862 vma->bo_offset = bo_offset_or_userptr;
863 vma->bo = xe_bo_get(bo);
864 list_add_tail(&vma->bo_link, &bo->vmas);
865 } else /* userptr */ {
866 u64 size = end - start + 1;
869 vma->userptr.ptr = bo_offset_or_userptr;
871 err = mmu_interval_notifier_insert(&vma->userptr.notifier,
873 vma->userptr.ptr, size,
874 &vma_userptr_notifier_ops);
881 vma->userptr.notifier_seq = LONG_MAX;
888 static bool vm_remove_extobj(struct xe_vma *vma)
890 if (!list_empty(&vma->extobj.link)) {
891 vma->vm->extobj.entries--;
892 list_del_init(&vma->extobj.link);
898 static void xe_vma_destroy_late(struct xe_vma *vma)
900 struct xe_vm *vm = vma->vm;
901 struct xe_device *xe = vm->xe;
902 bool read_only = vma->pte_flags & XE_PTE_READ_ONLY;
904 if (xe_vma_is_userptr(vma)) {
905 if (vma->userptr.sg) {
906 dma_unmap_sgtable(xe->drm.dev,
908 read_only ? DMA_TO_DEVICE :
909 DMA_BIDIRECTIONAL, 0);
910 sg_free_table(vma->userptr.sg);
911 vma->userptr.sg = NULL;
915 * Since userptr pages are not pinned, we can't remove
916 * the notifer until we're sure the GPU is not accessing
919 mmu_interval_notifier_remove(&vma->userptr.notifier);
928 static void vma_destroy_work_func(struct work_struct *w)
931 container_of(w, struct xe_vma, destroy_work);
933 xe_vma_destroy_late(vma);
936 static struct xe_vma *
937 bo_has_vm_references_locked(struct xe_bo *bo, struct xe_vm *vm,
938 struct xe_vma *ignore)
942 list_for_each_entry(vma, &bo->vmas, bo_link) {
943 if (vma != ignore && vma->vm == vm && !vma->destroyed)
950 static bool bo_has_vm_references(struct xe_bo *bo, struct xe_vm *vm,
951 struct xe_vma *ignore)
953 struct ww_acquire_ctx ww;
956 xe_bo_lock(bo, &ww, 0, false);
957 ret = !!bo_has_vm_references_locked(bo, vm, ignore);
958 xe_bo_unlock(bo, &ww);
963 static void __vm_insert_extobj(struct xe_vm *vm, struct xe_vma *vma)
965 list_add(&vma->extobj.link, &vm->extobj.list);
966 vm->extobj.entries++;
969 static void vm_insert_extobj(struct xe_vm *vm, struct xe_vma *vma)
971 struct xe_bo *bo = vma->bo;
973 lockdep_assert_held_write(&vm->lock);
975 if (bo_has_vm_references(bo, vm, vma))
978 __vm_insert_extobj(vm, vma);
981 static void vma_destroy_cb(struct dma_fence *fence,
982 struct dma_fence_cb *cb)
984 struct xe_vma *vma = container_of(cb, struct xe_vma, destroy_cb);
986 INIT_WORK(&vma->destroy_work, vma_destroy_work_func);
987 queue_work(system_unbound_wq, &vma->destroy_work);
990 static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
992 struct xe_vm *vm = vma->vm;
994 lockdep_assert_held_write(&vm->lock);
995 XE_BUG_ON(!list_empty(&vma->unbind_link));
997 if (xe_vma_is_userptr(vma)) {
998 XE_WARN_ON(!vma->destroyed);
999 spin_lock(&vm->userptr.invalidated_lock);
1000 list_del_init(&vma->userptr.invalidate_link);
1001 spin_unlock(&vm->userptr.invalidated_lock);
1002 list_del(&vma->userptr_link);
1004 xe_bo_assert_held(vma->bo);
1005 list_del(&vma->bo_link);
1007 spin_lock(&vm->notifier.list_lock);
1008 list_del(&vma->notifier.rebind_link);
1009 spin_unlock(&vm->notifier.list_lock);
1011 if (!vma->bo->vm && vm_remove_extobj(vma)) {
1012 struct xe_vma *other;
1014 other = bo_has_vm_references_locked(vma->bo, vm, NULL);
1017 __vm_insert_extobj(vm, other);
1021 xe_vm_assert_held(vm);
1022 if (!list_empty(&vma->rebind_link))
1023 list_del(&vma->rebind_link);
1026 int ret = dma_fence_add_callback(fence, &vma->destroy_cb,
1030 XE_WARN_ON(ret != -ENOENT);
1031 xe_vma_destroy_late(vma);
1034 xe_vma_destroy_late(vma);
1038 static void xe_vma_destroy_unlocked(struct xe_vma *vma)
1040 struct ttm_validate_buffer tv[2];
1041 struct ww_acquire_ctx ww;
1042 struct xe_bo *bo = vma->bo;
1047 memset(tv, 0, sizeof(tv));
1048 tv[0].bo = xe_vm_ttm_bo(vma->vm);
1049 list_add(&tv[0].head, &objs);
1052 tv[1].bo = &xe_bo_get(bo)->ttm;
1053 list_add(&tv[1].head, &objs);
1055 err = ttm_eu_reserve_buffers(&ww, &objs, false, &dups);
1058 xe_vma_destroy(vma, NULL);
1060 ttm_eu_backoff_reservation(&ww, &objs);
1065 static struct xe_vma *to_xe_vma(const struct rb_node *node)
1067 BUILD_BUG_ON(offsetof(struct xe_vma, vm_node) != 0);
1068 return (struct xe_vma *)node;
1071 static int xe_vma_cmp(const struct xe_vma *a, const struct xe_vma *b)
1073 if (a->end < b->start) {
1075 } else if (b->end < a->start) {
1082 static bool xe_vma_less_cb(struct rb_node *a, const struct rb_node *b)
1084 return xe_vma_cmp(to_xe_vma(a), to_xe_vma(b)) < 0;
1087 int xe_vma_cmp_vma_cb(const void *key, const struct rb_node *node)
1089 struct xe_vma *cmp = to_xe_vma(node);
1090 const struct xe_vma *own = key;
1092 if (own->start > cmp->end)
1095 if (own->end < cmp->start)
1102 xe_vm_find_overlapping_vma(struct xe_vm *vm, const struct xe_vma *vma)
1104 struct rb_node *node;
1106 if (xe_vm_is_closed(vm))
1109 XE_BUG_ON(vma->end >= vm->size);
1110 lockdep_assert_held(&vm->lock);
1112 node = rb_find(vma, &vm->vmas, xe_vma_cmp_vma_cb);
1114 return node ? to_xe_vma(node) : NULL;
1117 static void xe_vm_insert_vma(struct xe_vm *vm, struct xe_vma *vma)
1119 XE_BUG_ON(vma->vm != vm);
1120 lockdep_assert_held(&vm->lock);
1122 rb_add(&vma->vm_node, &vm->vmas, xe_vma_less_cb);
1125 static void xe_vm_remove_vma(struct xe_vm *vm, struct xe_vma *vma)
1127 XE_BUG_ON(vma->vm != vm);
1128 lockdep_assert_held(&vm->lock);
1130 rb_erase(&vma->vm_node, &vm->vmas);
1131 if (vm->usm.last_fault_vma == vma)
1132 vm->usm.last_fault_vma = NULL;
1135 static void async_op_work_func(struct work_struct *w);
1136 static void vm_destroy_work_func(struct work_struct *w);
1138 struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
1141 int err, i = 0, number_gts = 0;
1145 vm = kzalloc(sizeof(*vm), GFP_KERNEL);
1147 return ERR_PTR(-ENOMEM);
1150 kref_init(&vm->refcount);
1151 dma_resv_init(&vm->resv);
1153 vm->size = 1ull << xe_pt_shift(xe->info.vm_max_level + 1);
1158 init_rwsem(&vm->lock);
1160 INIT_LIST_HEAD(&vm->rebind_list);
1162 INIT_LIST_HEAD(&vm->userptr.repin_list);
1163 INIT_LIST_HEAD(&vm->userptr.invalidated);
1164 init_rwsem(&vm->userptr.notifier_lock);
1165 spin_lock_init(&vm->userptr.invalidated_lock);
1167 INIT_LIST_HEAD(&vm->notifier.rebind_list);
1168 spin_lock_init(&vm->notifier.list_lock);
1170 INIT_LIST_HEAD(&vm->async_ops.pending);
1171 INIT_WORK(&vm->async_ops.work, async_op_work_func);
1172 spin_lock_init(&vm->async_ops.lock);
1174 INIT_WORK(&vm->destroy_work, vm_destroy_work_func);
1176 INIT_LIST_HEAD(&vm->preempt.engines);
1177 vm->preempt.min_run_period_ms = 10; /* FIXME: Wire up to uAPI */
1179 INIT_LIST_HEAD(&vm->extobj.list);
1181 if (!(flags & XE_VM_FLAG_MIGRATION)) {
1182 /* We need to immeditatelly exit from any D3 state */
1183 xe_pm_runtime_get(xe);
1184 xe_device_mem_access_get(xe);
1187 err = dma_resv_lock_interruptible(&vm->resv, NULL);
1191 if (IS_DGFX(xe) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
1192 vm->flags |= XE_VM_FLAGS_64K;
1194 for_each_gt(gt, xe, id) {
1195 if (xe_gt_is_media_type(gt))
1198 if (flags & XE_VM_FLAG_MIGRATION &&
1199 gt->info.id != XE_VM_FLAG_GT_ID(flags))
1202 vm->pt_root[id] = xe_pt_create(vm, gt, xe->info.vm_max_level);
1203 if (IS_ERR(vm->pt_root[id])) {
1204 err = PTR_ERR(vm->pt_root[id]);
1205 vm->pt_root[id] = NULL;
1206 goto err_destroy_root;
1210 if (flags & XE_VM_FLAG_SCRATCH_PAGE) {
1211 for_each_gt(gt, xe, id) {
1212 if (!vm->pt_root[id])
1215 err = xe_pt_create_scratch(xe, gt, vm);
1217 goto err_scratch_pt;
1221 if (flags & DRM_XE_VM_CREATE_COMPUTE_MODE) {
1222 INIT_WORK(&vm->preempt.rebind_work, preempt_rebind_work_func);
1223 vm->flags |= XE_VM_FLAG_COMPUTE_MODE;
1226 if (flags & DRM_XE_VM_CREATE_ASYNC_BIND_OPS) {
1227 vm->async_ops.fence.context = dma_fence_context_alloc(1);
1228 vm->flags |= XE_VM_FLAG_ASYNC_BIND_OPS;
1231 /* Fill pt_root after allocating scratch tables */
1232 for_each_gt(gt, xe, id) {
1233 if (!vm->pt_root[id])
1236 xe_pt_populate_empty(gt, vm, vm->pt_root[id]);
1238 dma_resv_unlock(&vm->resv);
1240 /* Kernel migration VM shouldn't have a circular loop.. */
1241 if (!(flags & XE_VM_FLAG_MIGRATION)) {
1242 for_each_gt(gt, xe, id) {
1243 struct xe_vm *migrate_vm;
1244 struct xe_engine *eng;
1246 if (!vm->pt_root[id])
1249 migrate_vm = xe_migrate_get_vm(gt->migrate);
1250 eng = xe_engine_create_class(xe, gt, migrate_vm,
1251 XE_ENGINE_CLASS_COPY,
1253 xe_vm_put(migrate_vm);
1255 xe_vm_close_and_put(vm);
1256 return ERR_CAST(eng);
1264 vm->composite_fence_ctx = dma_fence_context_alloc(1);
1266 mutex_lock(&xe->usm.lock);
1267 if (flags & XE_VM_FLAG_FAULT_MODE)
1268 xe->usm.num_vm_in_fault_mode++;
1269 else if (!(flags & XE_VM_FLAG_MIGRATION))
1270 xe->usm.num_vm_in_non_fault_mode++;
1271 mutex_unlock(&xe->usm.lock);
1273 trace_xe_vm_create(vm);
1278 for_each_gt(gt, xe, id) {
1279 if (!vm->pt_root[id])
1282 i = vm->pt_root[id]->level;
1284 if (vm->scratch_pt[id][--i])
1285 xe_pt_destroy(vm->scratch_pt[id][i],
1287 xe_bo_unpin(vm->scratch_bo[id]);
1288 xe_bo_put(vm->scratch_bo[id]);
1291 for_each_gt(gt, xe, id) {
1292 if (vm->pt_root[id])
1293 xe_pt_destroy(vm->pt_root[id], vm->flags, NULL);
1295 dma_resv_unlock(&vm->resv);
1297 dma_resv_fini(&vm->resv);
1299 if (!(flags & XE_VM_FLAG_MIGRATION)) {
1300 xe_device_mem_access_put(xe);
1301 xe_pm_runtime_put(xe);
1303 return ERR_PTR(err);
1306 static void flush_async_ops(struct xe_vm *vm)
1308 queue_work(system_unbound_wq, &vm->async_ops.work);
1309 flush_work(&vm->async_ops.work);
1312 static void vm_error_capture(struct xe_vm *vm, int err,
1313 u32 op, u64 addr, u64 size)
1315 struct drm_xe_vm_bind_op_error_capture capture;
1316 u64 __user *address =
1317 u64_to_user_ptr(vm->async_ops.error_capture.addr);
1318 bool in_kthread = !current->mm;
1320 capture.error = err;
1322 capture.addr = addr;
1323 capture.size = size;
1326 if (!mmget_not_zero(vm->async_ops.error_capture.mm))
1328 kthread_use_mm(vm->async_ops.error_capture.mm);
1331 if (copy_to_user(address, &capture, sizeof(capture)))
1332 XE_WARN_ON("Copy to user failed");
1335 kthread_unuse_mm(vm->async_ops.error_capture.mm);
1336 mmput(vm->async_ops.error_capture.mm);
1340 wake_up_all(&vm->async_ops.error_capture.wq);
1343 void xe_vm_close_and_put(struct xe_vm *vm)
1345 struct rb_root contested = RB_ROOT;
1346 struct ww_acquire_ctx ww;
1347 struct xe_device *xe = vm->xe;
1351 XE_BUG_ON(vm->preempt.num_engines);
1355 flush_async_ops(vm);
1356 if (xe_vm_in_compute_mode(vm))
1357 flush_work(&vm->preempt.rebind_work);
1359 for_each_gt(gt, xe, id) {
1361 xe_engine_kill(vm->eng[id]);
1362 xe_engine_put(vm->eng[id]);
1367 down_write(&vm->lock);
1368 xe_vm_lock(vm, &ww, 0, false);
1369 while (vm->vmas.rb_node) {
1370 struct xe_vma *vma = to_xe_vma(vm->vmas.rb_node);
1372 if (xe_vma_is_userptr(vma)) {
1373 down_read(&vm->userptr.notifier_lock);
1374 vma->destroyed = true;
1375 up_read(&vm->userptr.notifier_lock);
1378 rb_erase(&vma->vm_node, &vm->vmas);
1380 /* easy case, remove from VMA? */
1381 if (xe_vma_is_userptr(vma) || vma->bo->vm) {
1382 xe_vma_destroy(vma, NULL);
1386 rb_add(&vma->vm_node, &contested, xe_vma_less_cb);
1390 * All vm operations will add shared fences to resv.
1391 * The only exception is eviction for a shared object,
1392 * but even so, the unbind when evicted would still
1393 * install a fence to resv. Hence it's safe to
1394 * destroy the pagetables immediately.
1396 for_each_gt(gt, xe, id) {
1397 if (vm->scratch_bo[id]) {
1400 xe_bo_unpin(vm->scratch_bo[id]);
1401 xe_bo_put(vm->scratch_bo[id]);
1402 for (i = 0; i < vm->pt_root[id]->level; i++)
1403 xe_pt_destroy(vm->scratch_pt[id][i], vm->flags,
1407 xe_vm_unlock(vm, &ww);
1409 if (contested.rb_node) {
1412 * VM is now dead, cannot re-add nodes to vm->vmas if it's NULL
1413 * Since we hold a refcount to the bo, we can remove and free
1414 * the members safely without locking.
1416 while (contested.rb_node) {
1417 struct xe_vma *vma = to_xe_vma(contested.rb_node);
1419 rb_erase(&vma->vm_node, &contested);
1420 xe_vma_destroy_unlocked(vma);
1424 if (vm->async_ops.error_capture.addr)
1425 wake_up_all(&vm->async_ops.error_capture.wq);
1427 XE_WARN_ON(!list_empty(&vm->extobj.list));
1428 up_write(&vm->lock);
1430 mutex_lock(&xe->usm.lock);
1431 if (vm->flags & XE_VM_FLAG_FAULT_MODE)
1432 xe->usm.num_vm_in_fault_mode--;
1433 else if (!(vm->flags & XE_VM_FLAG_MIGRATION))
1434 xe->usm.num_vm_in_non_fault_mode--;
1435 mutex_unlock(&xe->usm.lock);
1440 static void vm_destroy_work_func(struct work_struct *w)
1443 container_of(w, struct xe_vm, destroy_work);
1444 struct ww_acquire_ctx ww;
1445 struct xe_device *xe = vm->xe;
1450 /* xe_vm_close_and_put was not called? */
1451 XE_WARN_ON(vm->size);
1453 if (!(vm->flags & XE_VM_FLAG_MIGRATION)) {
1454 xe_device_mem_access_put(xe);
1455 xe_pm_runtime_put(xe);
1457 if (xe->info.has_asid) {
1458 mutex_lock(&xe->usm.lock);
1459 lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
1460 XE_WARN_ON(lookup != vm);
1461 mutex_unlock(&xe->usm.lock);
1466 * XXX: We delay destroying the PT root until the VM if freed as PT root
1467 * is needed for xe_vm_lock to work. If we remove that dependency this
1468 * can be moved to xe_vm_close_and_put.
1470 xe_vm_lock(vm, &ww, 0, false);
1471 for_each_gt(gt, xe, id) {
1472 if (vm->pt_root[id]) {
1473 xe_pt_destroy(vm->pt_root[id], vm->flags, NULL);
1474 vm->pt_root[id] = NULL;
1477 xe_vm_unlock(vm, &ww);
1479 trace_xe_vm_free(vm);
1480 dma_fence_put(vm->rebind_fence);
1481 dma_resv_fini(&vm->resv);
1485 void xe_vm_free(struct kref *ref)
1487 struct xe_vm *vm = container_of(ref, struct xe_vm, refcount);
1489 /* To destroy the VM we need to be able to sleep */
1490 queue_work(system_unbound_wq, &vm->destroy_work);
1493 struct xe_vm *xe_vm_lookup(struct xe_file *xef, u32 id)
1497 mutex_lock(&xef->vm.lock);
1498 vm = xa_load(&xef->vm.xa, id);
1499 mutex_unlock(&xef->vm.lock);
1507 u64 xe_vm_pdp4_descriptor(struct xe_vm *vm, struct xe_gt *full_gt)
1509 XE_BUG_ON(xe_gt_is_media_type(full_gt));
1511 return gen8_pde_encode(vm->pt_root[full_gt->info.id]->bo, 0,
1515 static struct dma_fence *
1516 xe_vm_unbind_vma(struct xe_vma *vma, struct xe_engine *e,
1517 struct xe_sync_entry *syncs, u32 num_syncs)
1520 struct dma_fence *fence = NULL;
1521 struct dma_fence **fences = NULL;
1522 struct dma_fence_array *cf = NULL;
1523 struct xe_vm *vm = vma->vm;
1524 int cur_fence = 0, i;
1525 int number_gts = hweight_long(vma->gt_present);
1529 trace_xe_vma_unbind(vma);
1531 if (number_gts > 1) {
1532 fences = kmalloc_array(number_gts, sizeof(*fences),
1535 return ERR_PTR(-ENOMEM);
1538 for_each_gt(gt, vm->xe, id) {
1539 if (!(vma->gt_present & BIT(id)))
1542 XE_BUG_ON(xe_gt_is_media_type(gt));
1544 fence = __xe_pt_unbind_vma(gt, vma, e, syncs, num_syncs);
1545 if (IS_ERR(fence)) {
1546 err = PTR_ERR(fence);
1551 fences[cur_fence++] = fence;
1554 if (e && vm->pt_root[id] && !list_empty(&e->multi_gt_list))
1555 e = list_next_entry(e, multi_gt_list);
1559 cf = dma_fence_array_create(number_gts, fences,
1560 vm->composite_fence_ctx,
1561 vm->composite_fence_seqno++,
1564 --vm->composite_fence_seqno;
1570 for (i = 0; i < num_syncs; i++)
1571 xe_sync_entry_signal(&syncs[i], NULL, cf ? &cf->base : fence);
1573 return cf ? &cf->base : !fence ? dma_fence_get_stub() : fence;
1578 /* FIXME: Rewind the previous binds? */
1579 dma_fence_put(fences[--cur_fence]);
1584 return ERR_PTR(err);
1587 static struct dma_fence *
1588 xe_vm_bind_vma(struct xe_vma *vma, struct xe_engine *e,
1589 struct xe_sync_entry *syncs, u32 num_syncs)
1592 struct dma_fence *fence;
1593 struct dma_fence **fences = NULL;
1594 struct dma_fence_array *cf = NULL;
1595 struct xe_vm *vm = vma->vm;
1596 int cur_fence = 0, i;
1597 int number_gts = hweight_long(vma->gt_mask);
1601 trace_xe_vma_bind(vma);
1603 if (number_gts > 1) {
1604 fences = kmalloc_array(number_gts, sizeof(*fences),
1607 return ERR_PTR(-ENOMEM);
1610 for_each_gt(gt, vm->xe, id) {
1611 if (!(vma->gt_mask & BIT(id)))
1614 XE_BUG_ON(xe_gt_is_media_type(gt));
1615 fence = __xe_pt_bind_vma(gt, vma, e, syncs, num_syncs,
1616 vma->gt_present & BIT(id));
1617 if (IS_ERR(fence)) {
1618 err = PTR_ERR(fence);
1623 fences[cur_fence++] = fence;
1626 if (e && vm->pt_root[id] && !list_empty(&e->multi_gt_list))
1627 e = list_next_entry(e, multi_gt_list);
1631 cf = dma_fence_array_create(number_gts, fences,
1632 vm->composite_fence_ctx,
1633 vm->composite_fence_seqno++,
1636 --vm->composite_fence_seqno;
1642 for (i = 0; i < num_syncs; i++)
1643 xe_sync_entry_signal(&syncs[i], NULL, cf ? &cf->base : fence);
1645 return cf ? &cf->base : fence;
1650 /* FIXME: Rewind the previous binds? */
1651 dma_fence_put(fences[--cur_fence]);
1656 return ERR_PTR(err);
1659 struct async_op_fence {
1660 struct dma_fence fence;
1661 struct dma_fence *wait_fence;
1662 struct dma_fence_cb cb;
1664 wait_queue_head_t wq;
1668 static const char *async_op_fence_get_driver_name(struct dma_fence *dma_fence)
1674 async_op_fence_get_timeline_name(struct dma_fence *dma_fence)
1676 return "async_op_fence";
1679 static const struct dma_fence_ops async_op_fence_ops = {
1680 .get_driver_name = async_op_fence_get_driver_name,
1681 .get_timeline_name = async_op_fence_get_timeline_name,
1684 static void async_op_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
1686 struct async_op_fence *afence =
1687 container_of(cb, struct async_op_fence, cb);
1689 afence->fence.error = afence->wait_fence->error;
1690 dma_fence_signal(&afence->fence);
1691 xe_vm_put(afence->vm);
1692 dma_fence_put(afence->wait_fence);
1693 dma_fence_put(&afence->fence);
1696 static void add_async_op_fence_cb(struct xe_vm *vm,
1697 struct dma_fence *fence,
1698 struct async_op_fence *afence)
1702 if (!xe_vm_no_dma_fences(vm)) {
1703 afence->started = true;
1705 wake_up_all(&afence->wq);
1708 afence->wait_fence = dma_fence_get(fence);
1709 afence->vm = xe_vm_get(vm);
1710 dma_fence_get(&afence->fence);
1711 ret = dma_fence_add_callback(fence, &afence->cb, async_op_fence_cb);
1712 if (ret == -ENOENT) {
1713 afence->fence.error = afence->wait_fence->error;
1714 dma_fence_signal(&afence->fence);
1718 dma_fence_put(afence->wait_fence);
1719 dma_fence_put(&afence->fence);
1721 XE_WARN_ON(ret && ret != -ENOENT);
1724 int xe_vm_async_fence_wait_start(struct dma_fence *fence)
1726 if (fence->ops == &async_op_fence_ops) {
1727 struct async_op_fence *afence =
1728 container_of(fence, struct async_op_fence, fence);
1730 XE_BUG_ON(xe_vm_no_dma_fences(afence->vm));
1733 return wait_event_interruptible(afence->wq, afence->started);
1739 static int __xe_vm_bind(struct xe_vm *vm, struct xe_vma *vma,
1740 struct xe_engine *e, struct xe_sync_entry *syncs,
1741 u32 num_syncs, struct async_op_fence *afence)
1743 struct dma_fence *fence;
1745 xe_vm_assert_held(vm);
1747 fence = xe_vm_bind_vma(vma, e, syncs, num_syncs);
1749 return PTR_ERR(fence);
1751 add_async_op_fence_cb(vm, fence, afence);
1753 dma_fence_put(fence);
1757 static int xe_vm_bind(struct xe_vm *vm, struct xe_vma *vma, struct xe_engine *e,
1758 struct xe_bo *bo, struct xe_sync_entry *syncs,
1759 u32 num_syncs, struct async_op_fence *afence)
1763 xe_vm_assert_held(vm);
1764 xe_bo_assert_held(bo);
1767 err = xe_bo_validate(bo, vm, true);
1772 return __xe_vm_bind(vm, vma, e, syncs, num_syncs, afence);
1775 static int xe_vm_unbind(struct xe_vm *vm, struct xe_vma *vma,
1776 struct xe_engine *e, struct xe_sync_entry *syncs,
1777 u32 num_syncs, struct async_op_fence *afence)
1779 struct dma_fence *fence;
1781 xe_vm_assert_held(vm);
1782 xe_bo_assert_held(vma->bo);
1784 fence = xe_vm_unbind_vma(vma, e, syncs, num_syncs);
1786 return PTR_ERR(fence);
1788 add_async_op_fence_cb(vm, fence, afence);
1790 xe_vma_destroy(vma, fence);
1791 dma_fence_put(fence);
1796 static int vm_set_error_capture_address(struct xe_device *xe, struct xe_vm *vm,
1799 if (XE_IOCTL_ERR(xe, !value))
1802 if (XE_IOCTL_ERR(xe, !(vm->flags & XE_VM_FLAG_ASYNC_BIND_OPS)))
1805 if (XE_IOCTL_ERR(xe, vm->async_ops.error_capture.addr))
1808 vm->async_ops.error_capture.mm = current->mm;
1809 vm->async_ops.error_capture.addr = value;
1810 init_waitqueue_head(&vm->async_ops.error_capture.wq);
1815 typedef int (*xe_vm_set_property_fn)(struct xe_device *xe, struct xe_vm *vm,
1818 static const xe_vm_set_property_fn vm_set_property_funcs[] = {
1819 [XE_VM_PROPERTY_BIND_OP_ERROR_CAPTURE_ADDRESS] =
1820 vm_set_error_capture_address,
1823 static int vm_user_ext_set_property(struct xe_device *xe, struct xe_vm *vm,
1826 u64 __user *address = u64_to_user_ptr(extension);
1827 struct drm_xe_ext_vm_set_property ext;
1830 err = __copy_from_user(&ext, address, sizeof(ext));
1831 if (XE_IOCTL_ERR(xe, err))
1834 if (XE_IOCTL_ERR(xe, ext.property >=
1835 ARRAY_SIZE(vm_set_property_funcs)))
1838 return vm_set_property_funcs[ext.property](xe, vm, ext.value);
1841 typedef int (*xe_vm_user_extension_fn)(struct xe_device *xe, struct xe_vm *vm,
1844 static const xe_vm_set_property_fn vm_user_extension_funcs[] = {
1845 [XE_VM_EXTENSION_SET_PROPERTY] = vm_user_ext_set_property,
1848 #define MAX_USER_EXTENSIONS 16
1849 static int vm_user_extensions(struct xe_device *xe, struct xe_vm *vm,
1850 u64 extensions, int ext_number)
1852 u64 __user *address = u64_to_user_ptr(extensions);
1853 struct xe_user_extension ext;
1856 if (XE_IOCTL_ERR(xe, ext_number >= MAX_USER_EXTENSIONS))
1859 err = __copy_from_user(&ext, address, sizeof(ext));
1860 if (XE_IOCTL_ERR(xe, err))
1863 if (XE_IOCTL_ERR(xe, ext.name >=
1864 ARRAY_SIZE(vm_user_extension_funcs)))
1867 err = vm_user_extension_funcs[ext.name](xe, vm, extensions);
1868 if (XE_IOCTL_ERR(xe, err))
1871 if (ext.next_extension)
1872 return vm_user_extensions(xe, vm, ext.next_extension,
1878 #define ALL_DRM_XE_VM_CREATE_FLAGS (DRM_XE_VM_CREATE_SCRATCH_PAGE | \
1879 DRM_XE_VM_CREATE_COMPUTE_MODE | \
1880 DRM_XE_VM_CREATE_ASYNC_BIND_OPS | \
1881 DRM_XE_VM_CREATE_FAULT_MODE)
1883 int xe_vm_create_ioctl(struct drm_device *dev, void *data,
1884 struct drm_file *file)
1886 struct xe_device *xe = to_xe_device(dev);
1887 struct xe_file *xef = to_xe_file(file);
1888 struct drm_xe_vm_create *args = data;
1894 if (XE_IOCTL_ERR(xe, args->flags & ~ALL_DRM_XE_VM_CREATE_FLAGS))
1897 if (XE_IOCTL_ERR(xe, args->flags & DRM_XE_VM_CREATE_SCRATCH_PAGE &&
1898 args->flags & DRM_XE_VM_CREATE_FAULT_MODE))
1901 if (XE_IOCTL_ERR(xe, args->flags & DRM_XE_VM_CREATE_COMPUTE_MODE &&
1902 args->flags & DRM_XE_VM_CREATE_FAULT_MODE))
1905 if (XE_IOCTL_ERR(xe, args->flags & DRM_XE_VM_CREATE_FAULT_MODE &&
1906 xe_device_in_non_fault_mode(xe)))
1909 if (XE_IOCTL_ERR(xe, !(args->flags & DRM_XE_VM_CREATE_FAULT_MODE) &&
1910 xe_device_in_fault_mode(xe)))
1913 if (XE_IOCTL_ERR(xe, args->flags & DRM_XE_VM_CREATE_FAULT_MODE &&
1914 !xe->info.supports_usm))
1917 if (args->flags & DRM_XE_VM_CREATE_SCRATCH_PAGE)
1918 flags |= XE_VM_FLAG_SCRATCH_PAGE;
1919 if (args->flags & DRM_XE_VM_CREATE_COMPUTE_MODE)
1920 flags |= XE_VM_FLAG_COMPUTE_MODE;
1921 if (args->flags & DRM_XE_VM_CREATE_ASYNC_BIND_OPS)
1922 flags |= XE_VM_FLAG_ASYNC_BIND_OPS;
1923 if (args->flags & DRM_XE_VM_CREATE_FAULT_MODE)
1924 flags |= XE_VM_FLAG_FAULT_MODE;
1926 vm = xe_vm_create(xe, flags);
1930 if (args->extensions) {
1931 err = vm_user_extensions(xe, vm, args->extensions, 0);
1932 if (XE_IOCTL_ERR(xe, err)) {
1933 xe_vm_close_and_put(vm);
1938 mutex_lock(&xef->vm.lock);
1939 err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
1940 mutex_unlock(&xef->vm.lock);
1942 xe_vm_close_and_put(vm);
1946 if (xe->info.has_asid) {
1947 mutex_lock(&xe->usm.lock);
1948 err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm,
1949 XA_LIMIT(0, XE_MAX_ASID - 1),
1950 &xe->usm.next_asid, GFP_KERNEL);
1951 mutex_unlock(&xe->usm.lock);
1953 xe_vm_close_and_put(vm);
1956 vm->usm.asid = asid;
1961 #if IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEM)
1962 /* Warning: Security issue - never enable by default */
1963 args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE);
1969 int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
1970 struct drm_file *file)
1972 struct xe_device *xe = to_xe_device(dev);
1973 struct xe_file *xef = to_xe_file(file);
1974 struct drm_xe_vm_destroy *args = data;
1977 if (XE_IOCTL_ERR(xe, args->pad))
1980 vm = xe_vm_lookup(xef, args->vm_id);
1981 if (XE_IOCTL_ERR(xe, !vm))
1985 /* FIXME: Extend this check to non-compute mode VMs */
1986 if (XE_IOCTL_ERR(xe, vm->preempt.num_engines))
1989 mutex_lock(&xef->vm.lock);
1990 xa_erase(&xef->vm.xa, args->vm_id);
1991 mutex_unlock(&xef->vm.lock);
1993 xe_vm_close_and_put(vm);
1998 static const u32 region_to_mem_type[] = {
2004 static int xe_vm_prefetch(struct xe_vm *vm, struct xe_vma *vma,
2005 struct xe_engine *e, u32 region,
2006 struct xe_sync_entry *syncs, u32 num_syncs,
2007 struct async_op_fence *afence)
2011 XE_BUG_ON(region > ARRAY_SIZE(region_to_mem_type));
2013 if (!xe_vma_is_userptr(vma)) {
2014 err = xe_bo_migrate(vma->bo, region_to_mem_type[region]);
2019 if (vma->gt_mask != (vma->gt_present & ~vma->usm.gt_invalidated)) {
2020 return xe_vm_bind(vm, vma, e, vma->bo, syncs, num_syncs,
2025 /* Nothing to do, signal fences now */
2026 for (i = 0; i < num_syncs; i++)
2027 xe_sync_entry_signal(&syncs[i], NULL,
2028 dma_fence_get_stub());
2030 dma_fence_signal(&afence->fence);
2035 #define VM_BIND_OP(op) (op & 0xffff)
2037 static int __vm_bind_ioctl(struct xe_vm *vm, struct xe_vma *vma,
2038 struct xe_engine *e, struct xe_bo *bo, u32 op,
2039 u32 region, struct xe_sync_entry *syncs,
2040 u32 num_syncs, struct async_op_fence *afence)
2042 switch (VM_BIND_OP(op)) {
2043 case XE_VM_BIND_OP_MAP:
2044 return xe_vm_bind(vm, vma, e, bo, syncs, num_syncs, afence);
2045 case XE_VM_BIND_OP_UNMAP:
2046 case XE_VM_BIND_OP_UNMAP_ALL:
2047 return xe_vm_unbind(vm, vma, e, syncs, num_syncs, afence);
2048 case XE_VM_BIND_OP_MAP_USERPTR:
2049 return xe_vm_bind(vm, vma, e, NULL, syncs, num_syncs, afence);
2050 case XE_VM_BIND_OP_PREFETCH:
2051 return xe_vm_prefetch(vm, vma, e, region, syncs, num_syncs,
2055 XE_BUG_ON("NOT POSSIBLE");
2060 struct ttm_buffer_object *xe_vm_ttm_bo(struct xe_vm *vm)
2062 int idx = vm->flags & XE_VM_FLAG_MIGRATION ?
2063 XE_VM_FLAG_GT_ID(vm->flags) : 0;
2065 /* Safe to use index 0 as all BO in the VM share a single dma-resv lock */
2066 return &vm->pt_root[idx]->bo->ttm;
2069 static void xe_vm_tv_populate(struct xe_vm *vm, struct ttm_validate_buffer *tv)
2072 tv->bo = xe_vm_ttm_bo(vm);
2075 static bool is_map_op(u32 op)
2077 return VM_BIND_OP(op) == XE_VM_BIND_OP_MAP ||
2078 VM_BIND_OP(op) == XE_VM_BIND_OP_MAP_USERPTR;
2081 static bool is_unmap_op(u32 op)
2083 return VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP ||
2084 VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP_ALL;
2087 static int vm_bind_ioctl(struct xe_vm *vm, struct xe_vma *vma,
2088 struct xe_engine *e, struct xe_bo *bo,
2089 struct drm_xe_vm_bind_op *bind_op,
2090 struct xe_sync_entry *syncs, u32 num_syncs,
2091 struct async_op_fence *afence)
2095 struct ttm_validate_buffer tv_bo, tv_vm;
2096 struct ww_acquire_ctx ww;
2100 lockdep_assert_held(&vm->lock);
2101 XE_BUG_ON(!list_empty(&vma->unbind_link));
2103 /* Binds deferred to faults, signal fences now */
2104 if (xe_vm_in_fault_mode(vm) && is_map_op(bind_op->op) &&
2105 !(bind_op->op & XE_VM_BIND_FLAG_IMMEDIATE)) {
2106 for (i = 0; i < num_syncs; i++)
2107 xe_sync_entry_signal(&syncs[i], NULL,
2108 dma_fence_get_stub());
2110 dma_fence_signal(&afence->fence);
2114 xe_vm_tv_populate(vm, &tv_vm);
2115 list_add_tail(&tv_vm.head, &objs);
2119 * An unbind can drop the last reference to the BO and
2120 * the BO is needed for ttm_eu_backoff_reservation so
2121 * take a reference here.
2125 tv_bo.bo = &vbo->ttm;
2126 tv_bo.num_shared = 1;
2127 list_add(&tv_bo.head, &objs);
2131 err = ttm_eu_reserve_buffers(&ww, &objs, true, &dups);
2133 err = __vm_bind_ioctl(vm, vma, e, bo,
2134 bind_op->op, bind_op->region, syncs,
2136 ttm_eu_backoff_reservation(&ww, &objs);
2137 if (err == -EAGAIN && xe_vma_is_userptr(vma)) {
2138 lockdep_assert_held_write(&vm->lock);
2139 err = xe_vma_userptr_pin_pages(vma);
2151 struct xe_engine *engine;
2153 struct drm_xe_vm_bind_op bind_op;
2154 struct xe_sync_entry *syncs;
2156 struct list_head link;
2157 struct async_op_fence *fence;
2160 static void async_op_cleanup(struct xe_vm *vm, struct async_op *op)
2162 while (op->num_syncs--)
2163 xe_sync_entry_cleanup(&op->syncs[op->num_syncs]);
2167 xe_engine_put(op->engine);
2170 dma_fence_put(&op->fence->fence);
2174 static struct async_op *next_async_op(struct xe_vm *vm)
2176 return list_first_entry_or_null(&vm->async_ops.pending,
2177 struct async_op, link);
2180 static void vm_set_async_error(struct xe_vm *vm, int err)
2182 lockdep_assert_held(&vm->lock);
2183 vm->async_ops.error = err;
2186 static void async_op_work_func(struct work_struct *w)
2188 struct xe_vm *vm = container_of(w, struct xe_vm, async_ops.work);
2191 struct async_op *op;
2194 if (vm->async_ops.error && !xe_vm_is_closed(vm))
2197 spin_lock_irq(&vm->async_ops.lock);
2198 op = next_async_op(vm);
2200 list_del_init(&op->link);
2201 spin_unlock_irq(&vm->async_ops.lock);
2206 if (!xe_vm_is_closed(vm)) {
2209 down_write(&vm->lock);
2211 first = op->vma->first_munmap_rebind;
2212 last = op->vma->last_munmap_rebind;
2213 #ifdef TEST_VM_ASYNC_OPS_ERROR
2214 #define FORCE_ASYNC_OP_ERROR BIT(31)
2215 if (!(op->bind_op.op & FORCE_ASYNC_OP_ERROR)) {
2216 err = vm_bind_ioctl(vm, op->vma, op->engine,
2217 op->bo, &op->bind_op,
2218 op->syncs, op->num_syncs,
2222 op->bind_op.op &= ~FORCE_ASYNC_OP_ERROR;
2225 err = vm_bind_ioctl(vm, op->vma, op->engine, op->bo,
2226 &op->bind_op, op->syncs,
2227 op->num_syncs, op->fence);
2230 * In order for the fencing to work (stall behind
2231 * existing jobs / prevent new jobs from running) all
2232 * the dma-resv slots need to be programmed in a batch
2233 * relative to execs / the rebind worker. The vm->lock
2236 if (!err && ((first && VM_BIND_OP(op->bind_op.op) ==
2237 XE_VM_BIND_OP_UNMAP) ||
2238 vm->async_ops.munmap_rebind_inflight)) {
2240 op->vma->last_munmap_rebind = false;
2241 vm->async_ops.munmap_rebind_inflight =
2244 vm->async_ops.munmap_rebind_inflight =
2247 async_op_cleanup(vm, op);
2249 spin_lock_irq(&vm->async_ops.lock);
2250 op = next_async_op(vm);
2252 list_del_init(&op->link);
2253 spin_unlock_irq(&vm->async_ops.lock);
2259 trace_xe_vma_fail(op->vma);
2260 drm_warn(&vm->xe->drm, "Async VM op(%d) failed with %d",
2261 VM_BIND_OP(op->bind_op.op),
2264 spin_lock_irq(&vm->async_ops.lock);
2265 list_add(&op->link, &vm->async_ops.pending);
2266 spin_unlock_irq(&vm->async_ops.lock);
2268 vm_set_async_error(vm, err);
2269 up_write(&vm->lock);
2271 if (vm->async_ops.error_capture.addr)
2272 vm_error_capture(vm, err,
2278 up_write(&vm->lock);
2280 trace_xe_vma_flush(op->vma);
2282 if (is_unmap_op(op->bind_op.op)) {
2283 down_write(&vm->lock);
2284 xe_vma_destroy_unlocked(op->vma);
2285 up_write(&vm->lock);
2288 if (op->fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
2289 &op->fence->fence.flags)) {
2290 if (!xe_vm_no_dma_fences(vm)) {
2291 op->fence->started = true;
2293 wake_up_all(&op->fence->wq);
2295 dma_fence_signal(&op->fence->fence);
2299 async_op_cleanup(vm, op);
2303 static int __vm_bind_ioctl_async(struct xe_vm *vm, struct xe_vma *vma,
2304 struct xe_engine *e, struct xe_bo *bo,
2305 struct drm_xe_vm_bind_op *bind_op,
2306 struct xe_sync_entry *syncs, u32 num_syncs)
2308 struct async_op *op;
2309 bool installed = false;
2313 lockdep_assert_held(&vm->lock);
2315 op = kmalloc(sizeof(*op), GFP_KERNEL);
2321 op->fence = kmalloc(sizeof(*op->fence), GFP_KERNEL);
2327 seqno = e ? ++e->bind.fence_seqno : ++vm->async_ops.fence.seqno;
2328 dma_fence_init(&op->fence->fence, &async_op_fence_ops,
2329 &vm->async_ops.lock, e ? e->bind.fence_ctx :
2330 vm->async_ops.fence.context, seqno);
2332 if (!xe_vm_no_dma_fences(vm)) {
2334 op->fence->started = false;
2335 init_waitqueue_head(&op->fence->wq);
2343 op->bind_op = *bind_op;
2345 op->num_syncs = num_syncs;
2346 INIT_LIST_HEAD(&op->link);
2348 for (i = 0; i < num_syncs; i++)
2349 installed |= xe_sync_entry_signal(&syncs[i], NULL,
2352 if (!installed && op->fence)
2353 dma_fence_signal(&op->fence->fence);
2355 spin_lock_irq(&vm->async_ops.lock);
2356 list_add_tail(&op->link, &vm->async_ops.pending);
2357 spin_unlock_irq(&vm->async_ops.lock);
2359 if (!vm->async_ops.error)
2360 queue_work(system_unbound_wq, &vm->async_ops.work);
2365 static int vm_bind_ioctl_async(struct xe_vm *vm, struct xe_vma *vma,
2366 struct xe_engine *e, struct xe_bo *bo,
2367 struct drm_xe_vm_bind_op *bind_op,
2368 struct xe_sync_entry *syncs, u32 num_syncs)
2370 struct xe_vma *__vma, *next;
2371 struct list_head rebind_list;
2372 struct xe_sync_entry *in_syncs = NULL, *out_syncs = NULL;
2373 u32 num_in_syncs = 0, num_out_syncs = 0;
2374 bool first = true, last;
2378 lockdep_assert_held(&vm->lock);
2380 /* Not a linked list of unbinds + rebinds, easy */
2381 if (list_empty(&vma->unbind_link))
2382 return __vm_bind_ioctl_async(vm, vma, e, bo, bind_op,
2386 * Linked list of unbinds + rebinds, decompose syncs into 'in / out'
2387 * passing the 'in' to the first operation and 'out' to the last. Also
2388 * the reference counting is a little tricky, increment the VM / bind
2389 * engine ref count on all but the last operation and increment the BOs
2390 * ref count on each rebind.
2393 XE_BUG_ON(VM_BIND_OP(bind_op->op) != XE_VM_BIND_OP_UNMAP &&
2394 VM_BIND_OP(bind_op->op) != XE_VM_BIND_OP_UNMAP_ALL &&
2395 VM_BIND_OP(bind_op->op) != XE_VM_BIND_OP_PREFETCH);
2397 /* Decompose syncs */
2399 in_syncs = kmalloc(sizeof(*in_syncs) * num_syncs, GFP_KERNEL);
2400 out_syncs = kmalloc(sizeof(*out_syncs) * num_syncs, GFP_KERNEL);
2401 if (!in_syncs || !out_syncs) {
2406 for (i = 0; i < num_syncs; ++i) {
2407 bool signal = syncs[i].flags & DRM_XE_SYNC_SIGNAL;
2410 out_syncs[num_out_syncs++] = syncs[i];
2412 in_syncs[num_in_syncs++] = syncs[i];
2416 /* Do unbinds + move rebinds to new list */
2417 INIT_LIST_HEAD(&rebind_list);
2418 list_for_each_entry_safe(__vma, next, &vma->unbind_link, unbind_link) {
2419 if (__vma->destroyed ||
2420 VM_BIND_OP(bind_op->op) == XE_VM_BIND_OP_PREFETCH) {
2421 list_del_init(&__vma->unbind_link);
2423 err = __vm_bind_ioctl_async(xe_vm_get(vm), __vma,
2424 e ? xe_engine_get(e) : NULL,
2425 bo, bind_op, first ?
2427 first ? num_in_syncs : 0);
2438 list_move_tail(&__vma->unbind_link, &rebind_list);
2441 last = list_empty(&rebind_list);
2447 err = __vm_bind_ioctl_async(vm, vma, e,
2450 last ? out_syncs : NULL,
2451 first ? num_in_syncs :
2452 last ? num_out_syncs : 0);
2464 list_for_each_entry_safe(__vma, next, &rebind_list, unbind_link) {
2465 list_del_init(&__vma->unbind_link);
2466 last = list_empty(&rebind_list);
2468 if (xe_vma_is_userptr(__vma)) {
2469 bind_op->op = XE_VM_BIND_FLAG_ASYNC |
2470 XE_VM_BIND_OP_MAP_USERPTR;
2472 bind_op->op = XE_VM_BIND_FLAG_ASYNC |
2474 xe_bo_get(__vma->bo);
2483 err = __vm_bind_ioctl_async(vm, __vma, e,
2484 __vma->bo, bind_op, last ?
2486 last ? num_out_syncs : 0);
2508 static int __vm_bind_ioctl_lookup_vma(struct xe_vm *vm, struct xe_bo *bo,
2509 u64 addr, u64 range, u32 op)
2511 struct xe_device *xe = vm->xe;
2512 struct xe_vma *vma, lookup;
2513 bool async = !!(op & XE_VM_BIND_FLAG_ASYNC);
2515 lockdep_assert_held(&vm->lock);
2517 lookup.start = addr;
2518 lookup.end = addr + range - 1;
2520 switch (VM_BIND_OP(op)) {
2521 case XE_VM_BIND_OP_MAP:
2522 case XE_VM_BIND_OP_MAP_USERPTR:
2523 vma = xe_vm_find_overlapping_vma(vm, &lookup);
2524 if (XE_IOCTL_ERR(xe, vma))
2527 case XE_VM_BIND_OP_UNMAP:
2528 case XE_VM_BIND_OP_PREFETCH:
2529 vma = xe_vm_find_overlapping_vma(vm, &lookup);
2530 if (XE_IOCTL_ERR(xe, !vma) ||
2531 XE_IOCTL_ERR(xe, (vma->start != addr ||
2532 vma->end != addr + range - 1) && !async))
2535 case XE_VM_BIND_OP_UNMAP_ALL:
2538 XE_BUG_ON("NOT POSSIBLE");
2545 static void prep_vma_destroy(struct xe_vm *vm, struct xe_vma *vma)
2547 down_read(&vm->userptr.notifier_lock);
2548 vma->destroyed = true;
2549 up_read(&vm->userptr.notifier_lock);
2550 xe_vm_remove_vma(vm, vma);
2553 static int prep_replacement_vma(struct xe_vm *vm, struct xe_vma *vma)
2557 if (vma->bo && !vma->bo->vm) {
2558 vm_insert_extobj(vm, vma);
2559 err = add_preempt_fences(vm, vma->bo);
2568 * Find all overlapping VMAs in lookup range and add to a list in the returned
2569 * VMA, all of VMAs found will be unbound. Also possibly add 2 new VMAs that
2570 * need to be bound if first / last VMAs are not fully unbound. This is akin to
2573 static struct xe_vma *vm_unbind_lookup_vmas(struct xe_vm *vm,
2574 struct xe_vma *lookup)
2576 struct xe_vma *vma = xe_vm_find_overlapping_vma(vm, lookup);
2577 struct rb_node *node;
2578 struct xe_vma *first = vma, *last = vma, *new_first = NULL,
2579 *new_last = NULL, *__vma, *next;
2581 bool first_munmap_rebind = false;
2583 lockdep_assert_held(&vm->lock);
2586 node = &vma->vm_node;
2587 while ((node = rb_next(node))) {
2588 if (!xe_vma_cmp_vma_cb(lookup, node)) {
2589 __vma = to_xe_vma(node);
2590 list_add_tail(&__vma->unbind_link, &vma->unbind_link);
2597 node = &vma->vm_node;
2598 while ((node = rb_prev(node))) {
2599 if (!xe_vma_cmp_vma_cb(lookup, node)) {
2600 __vma = to_xe_vma(node);
2601 list_add(&__vma->unbind_link, &vma->unbind_link);
2608 if (first->start != lookup->start) {
2609 struct ww_acquire_ctx ww;
2612 err = xe_bo_lock(first->bo, &ww, 0, true);
2615 new_first = xe_vma_create(first->vm, first->bo,
2616 first->bo ? first->bo_offset :
2620 (first->pte_flags & XE_PTE_READ_ONLY),
2623 xe_bo_unlock(first->bo, &ww);
2629 err = xe_vma_userptr_pin_pages(new_first);
2633 err = prep_replacement_vma(vm, new_first);
2638 if (last->end != lookup->end) {
2639 struct ww_acquire_ctx ww;
2640 u64 chunk = lookup->end + 1 - last->start;
2643 err = xe_bo_lock(last->bo, &ww, 0, true);
2646 new_last = xe_vma_create(last->vm, last->bo,
2647 last->bo ? last->bo_offset + chunk :
2648 last->userptr.ptr + chunk,
2649 last->start + chunk,
2651 (last->pte_flags & XE_PTE_READ_ONLY),
2654 xe_bo_unlock(last->bo, &ww);
2660 err = xe_vma_userptr_pin_pages(new_last);
2664 err = prep_replacement_vma(vm, new_last);
2669 prep_vma_destroy(vm, vma);
2670 if (list_empty(&vma->unbind_link) && (new_first || new_last))
2671 vma->first_munmap_rebind = true;
2672 list_for_each_entry(__vma, &vma->unbind_link, unbind_link) {
2673 if ((new_first || new_last) && !first_munmap_rebind) {
2674 __vma->first_munmap_rebind = true;
2675 first_munmap_rebind = true;
2677 prep_vma_destroy(vm, __vma);
2680 xe_vm_insert_vma(vm, new_first);
2681 list_add_tail(&new_first->unbind_link, &vma->unbind_link);
2683 new_first->last_munmap_rebind = true;
2686 xe_vm_insert_vma(vm, new_last);
2687 list_add_tail(&new_last->unbind_link, &vma->unbind_link);
2688 new_last->last_munmap_rebind = true;
2694 list_for_each_entry_safe(__vma, next, &vma->unbind_link, unbind_link)
2695 list_del_init(&__vma->unbind_link);
2697 prep_vma_destroy(vm, new_last);
2698 xe_vma_destroy_unlocked(new_last);
2701 prep_vma_destroy(vm, new_first);
2702 xe_vma_destroy_unlocked(new_first);
2705 return ERR_PTR(err);
2709 * Similar to vm_unbind_lookup_vmas, find all VMAs in lookup range to prefetch
2711 static struct xe_vma *vm_prefetch_lookup_vmas(struct xe_vm *vm,
2712 struct xe_vma *lookup,
2715 struct xe_vma *vma = xe_vm_find_overlapping_vma(vm, lookup), *__vma,
2717 struct rb_node *node;
2719 if (!xe_vma_is_userptr(vma)) {
2720 if (!xe_bo_can_migrate(vma->bo, region_to_mem_type[region]))
2721 return ERR_PTR(-EINVAL);
2724 node = &vma->vm_node;
2725 while ((node = rb_next(node))) {
2726 if (!xe_vma_cmp_vma_cb(lookup, node)) {
2727 __vma = to_xe_vma(node);
2728 if (!xe_vma_is_userptr(__vma)) {
2729 if (!xe_bo_can_migrate(__vma->bo, region_to_mem_type[region]))
2732 list_add_tail(&__vma->unbind_link, &vma->unbind_link);
2738 node = &vma->vm_node;
2739 while ((node = rb_prev(node))) {
2740 if (!xe_vma_cmp_vma_cb(lookup, node)) {
2741 __vma = to_xe_vma(node);
2742 if (!xe_vma_is_userptr(__vma)) {
2743 if (!xe_bo_can_migrate(__vma->bo, region_to_mem_type[region]))
2746 list_add(&__vma->unbind_link, &vma->unbind_link);
2755 list_for_each_entry_safe(__vma, next, &vma->unbind_link,
2757 list_del_init(&__vma->unbind_link);
2759 return ERR_PTR(-EINVAL);
2762 static struct xe_vma *vm_unbind_all_lookup_vmas(struct xe_vm *vm,
2765 struct xe_vma *first = NULL, *vma;
2767 lockdep_assert_held(&vm->lock);
2768 xe_bo_assert_held(bo);
2770 list_for_each_entry(vma, &bo->vmas, bo_link) {
2774 prep_vma_destroy(vm, vma);
2778 list_add_tail(&vma->unbind_link, &first->unbind_link);
2784 static struct xe_vma *vm_bind_ioctl_lookup_vma(struct xe_vm *vm,
2786 u64 bo_offset_or_userptr,
2787 u64 addr, u64 range, u32 op,
2788 u64 gt_mask, u32 region)
2790 struct ww_acquire_ctx ww;
2791 struct xe_vma *vma, lookup;
2794 lockdep_assert_held(&vm->lock);
2796 lookup.start = addr;
2797 lookup.end = addr + range - 1;
2799 switch (VM_BIND_OP(op)) {
2800 case XE_VM_BIND_OP_MAP:
2803 err = xe_bo_lock(bo, &ww, 0, true);
2805 return ERR_PTR(err);
2806 vma = xe_vma_create(vm, bo, bo_offset_or_userptr, addr,
2808 op & XE_VM_BIND_FLAG_READONLY,
2810 xe_bo_unlock(bo, &ww);
2812 return ERR_PTR(-ENOMEM);
2814 xe_vm_insert_vma(vm, vma);
2816 vm_insert_extobj(vm, vma);
2817 err = add_preempt_fences(vm, bo);
2819 prep_vma_destroy(vm, vma);
2820 xe_vma_destroy_unlocked(vma);
2822 return ERR_PTR(err);
2826 case XE_VM_BIND_OP_UNMAP:
2827 vma = vm_unbind_lookup_vmas(vm, &lookup);
2829 case XE_VM_BIND_OP_PREFETCH:
2830 vma = vm_prefetch_lookup_vmas(vm, &lookup, region);
2832 case XE_VM_BIND_OP_UNMAP_ALL:
2835 err = xe_bo_lock(bo, &ww, 0, true);
2837 return ERR_PTR(err);
2838 vma = vm_unbind_all_lookup_vmas(vm, bo);
2840 vma = ERR_PTR(-EINVAL);
2841 xe_bo_unlock(bo, &ww);
2843 case XE_VM_BIND_OP_MAP_USERPTR:
2846 vma = xe_vma_create(vm, NULL, bo_offset_or_userptr, addr,
2848 op & XE_VM_BIND_FLAG_READONLY,
2851 return ERR_PTR(-ENOMEM);
2853 err = xe_vma_userptr_pin_pages(vma);
2855 prep_vma_destroy(vm, vma);
2856 xe_vma_destroy_unlocked(vma);
2858 return ERR_PTR(err);
2860 xe_vm_insert_vma(vm, vma);
2864 XE_BUG_ON("NOT POSSIBLE");
2865 vma = ERR_PTR(-EINVAL);
2871 #ifdef TEST_VM_ASYNC_OPS_ERROR
2872 #define SUPPORTED_FLAGS \
2873 (FORCE_ASYNC_OP_ERROR | XE_VM_BIND_FLAG_ASYNC | \
2874 XE_VM_BIND_FLAG_READONLY | XE_VM_BIND_FLAG_IMMEDIATE | 0xffff)
2876 #define SUPPORTED_FLAGS \
2877 (XE_VM_BIND_FLAG_ASYNC | XE_VM_BIND_FLAG_READONLY | \
2878 XE_VM_BIND_FLAG_IMMEDIATE | 0xffff)
2880 #define XE_64K_PAGE_MASK 0xffffull
2882 #define MAX_BINDS 512 /* FIXME: Picking random upper limit */
2884 static int vm_bind_ioctl_check_args(struct xe_device *xe,
2885 struct drm_xe_vm_bind *args,
2886 struct drm_xe_vm_bind_op **bind_ops,
2892 if (XE_IOCTL_ERR(xe, args->extensions) ||
2893 XE_IOCTL_ERR(xe, !args->num_binds) ||
2894 XE_IOCTL_ERR(xe, args->num_binds > MAX_BINDS))
2897 if (args->num_binds > 1) {
2898 u64 __user *bind_user =
2899 u64_to_user_ptr(args->vector_of_binds);
2901 *bind_ops = kmalloc(sizeof(struct drm_xe_vm_bind_op) *
2902 args->num_binds, GFP_KERNEL);
2906 err = __copy_from_user(*bind_ops, bind_user,
2907 sizeof(struct drm_xe_vm_bind_op) *
2909 if (XE_IOCTL_ERR(xe, err)) {
2914 *bind_ops = &args->bind;
2917 for (i = 0; i < args->num_binds; ++i) {
2918 u64 range = (*bind_ops)[i].range;
2919 u64 addr = (*bind_ops)[i].addr;
2920 u32 op = (*bind_ops)[i].op;
2921 u32 obj = (*bind_ops)[i].obj;
2922 u64 obj_offset = (*bind_ops)[i].obj_offset;
2923 u32 region = (*bind_ops)[i].region;
2926 *async = !!(op & XE_VM_BIND_FLAG_ASYNC);
2927 } else if (XE_IOCTL_ERR(xe, !*async) ||
2928 XE_IOCTL_ERR(xe, !(op & XE_VM_BIND_FLAG_ASYNC)) ||
2929 XE_IOCTL_ERR(xe, VM_BIND_OP(op) ==
2930 XE_VM_BIND_OP_RESTART)) {
2935 if (XE_IOCTL_ERR(xe, !*async &&
2936 VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP_ALL)) {
2941 if (XE_IOCTL_ERR(xe, !*async &&
2942 VM_BIND_OP(op) == XE_VM_BIND_OP_PREFETCH)) {
2947 if (XE_IOCTL_ERR(xe, VM_BIND_OP(op) >
2948 XE_VM_BIND_OP_PREFETCH) ||
2949 XE_IOCTL_ERR(xe, op & ~SUPPORTED_FLAGS) ||
2950 XE_IOCTL_ERR(xe, !obj &&
2951 VM_BIND_OP(op) == XE_VM_BIND_OP_MAP) ||
2952 XE_IOCTL_ERR(xe, !obj &&
2953 VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP_ALL) ||
2954 XE_IOCTL_ERR(xe, addr &&
2955 VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP_ALL) ||
2956 XE_IOCTL_ERR(xe, range &&
2957 VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP_ALL) ||
2958 XE_IOCTL_ERR(xe, obj &&
2959 VM_BIND_OP(op) == XE_VM_BIND_OP_MAP_USERPTR) ||
2960 XE_IOCTL_ERR(xe, obj &&
2961 VM_BIND_OP(op) == XE_VM_BIND_OP_PREFETCH) ||
2962 XE_IOCTL_ERR(xe, region &&
2963 VM_BIND_OP(op) != XE_VM_BIND_OP_PREFETCH) ||
2964 XE_IOCTL_ERR(xe, !(BIT(region) &
2965 xe->info.mem_region_mask)) ||
2966 XE_IOCTL_ERR(xe, obj &&
2967 VM_BIND_OP(op) == XE_VM_BIND_OP_UNMAP)) {
2972 if (XE_IOCTL_ERR(xe, obj_offset & ~PAGE_MASK) ||
2973 XE_IOCTL_ERR(xe, addr & ~PAGE_MASK) ||
2974 XE_IOCTL_ERR(xe, range & ~PAGE_MASK) ||
2975 XE_IOCTL_ERR(xe, !range && VM_BIND_OP(op) !=
2976 XE_VM_BIND_OP_RESTART &&
2977 VM_BIND_OP(op) != XE_VM_BIND_OP_UNMAP_ALL)) {
2986 if (args->num_binds > 1)
2991 int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
2993 struct xe_device *xe = to_xe_device(dev);
2994 struct xe_file *xef = to_xe_file(file);
2995 struct drm_xe_vm_bind *args = data;
2996 struct drm_xe_sync __user *syncs_user;
2997 struct xe_bo **bos = NULL;
2998 struct xe_vma **vmas = NULL;
3000 struct xe_engine *e = NULL;
3002 struct xe_sync_entry *syncs = NULL;
3003 struct drm_xe_vm_bind_op *bind_ops;
3008 err = vm_bind_ioctl_check_args(xe, args, &bind_ops, &async);
3012 vm = xe_vm_lookup(xef, args->vm_id);
3013 if (XE_IOCTL_ERR(xe, !vm)) {
3018 if (XE_IOCTL_ERR(xe, xe_vm_is_closed(vm))) {
3019 DRM_ERROR("VM closed while we began looking up?\n");
3024 if (args->engine_id) {
3025 e = xe_engine_lookup(xef, args->engine_id);
3026 if (XE_IOCTL_ERR(xe, !e)) {
3030 if (XE_IOCTL_ERR(xe, !(e->flags & ENGINE_FLAG_VM))) {
3036 if (VM_BIND_OP(bind_ops[0].op) == XE_VM_BIND_OP_RESTART) {
3037 if (XE_IOCTL_ERR(xe, !(vm->flags & XE_VM_FLAG_ASYNC_BIND_OPS)))
3039 if (XE_IOCTL_ERR(xe, !err && args->num_syncs))
3041 if (XE_IOCTL_ERR(xe, !err && !vm->async_ops.error))
3045 down_write(&vm->lock);
3046 trace_xe_vm_restart(vm);
3047 vm_set_async_error(vm, 0);
3048 up_write(&vm->lock);
3050 queue_work(system_unbound_wq, &vm->async_ops.work);
3052 /* Rebinds may have been blocked, give worker a kick */
3053 if (xe_vm_in_compute_mode(vm))
3054 queue_work(vm->xe->ordered_wq,
3055 &vm->preempt.rebind_work);
3061 if (XE_IOCTL_ERR(xe, !vm->async_ops.error &&
3062 async != !!(vm->flags & XE_VM_FLAG_ASYNC_BIND_OPS))) {
3067 for (i = 0; i < args->num_binds; ++i) {
3068 u64 range = bind_ops[i].range;
3069 u64 addr = bind_ops[i].addr;
3071 if (XE_IOCTL_ERR(xe, range > vm->size) ||
3072 XE_IOCTL_ERR(xe, addr > vm->size - range)) {
3077 if (bind_ops[i].gt_mask) {
3078 u64 valid_gts = BIT(xe->info.tile_count) - 1;
3080 if (XE_IOCTL_ERR(xe, bind_ops[i].gt_mask &
3088 bos = kzalloc(sizeof(*bos) * args->num_binds, GFP_KERNEL);
3094 vmas = kzalloc(sizeof(*vmas) * args->num_binds, GFP_KERNEL);
3100 for (i = 0; i < args->num_binds; ++i) {
3101 struct drm_gem_object *gem_obj;
3102 u64 range = bind_ops[i].range;
3103 u64 addr = bind_ops[i].addr;
3104 u32 obj = bind_ops[i].obj;
3105 u64 obj_offset = bind_ops[i].obj_offset;
3110 gem_obj = drm_gem_object_lookup(file, obj);
3111 if (XE_IOCTL_ERR(xe, !gem_obj)) {
3115 bos[i] = gem_to_xe_bo(gem_obj);
3117 if (XE_IOCTL_ERR(xe, range > bos[i]->size) ||
3118 XE_IOCTL_ERR(xe, obj_offset >
3119 bos[i]->size - range)) {
3124 if (bos[i]->flags & XE_BO_INTERNAL_64K) {
3125 if (XE_IOCTL_ERR(xe, obj_offset &
3126 XE_64K_PAGE_MASK) ||
3127 XE_IOCTL_ERR(xe, addr & XE_64K_PAGE_MASK) ||
3128 XE_IOCTL_ERR(xe, range & XE_64K_PAGE_MASK)) {
3135 if (args->num_syncs) {
3136 syncs = kcalloc(args->num_syncs, sizeof(*syncs), GFP_KERNEL);
3143 syncs_user = u64_to_user_ptr(args->syncs);
3144 for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
3145 err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
3146 &syncs_user[num_syncs], false,
3147 xe_vm_no_dma_fences(vm));
3152 err = down_write_killable(&vm->lock);
3156 /* Do some error checking first to make the unwind easier */
3157 for (i = 0; i < args->num_binds; ++i) {
3158 u64 range = bind_ops[i].range;
3159 u64 addr = bind_ops[i].addr;
3160 u32 op = bind_ops[i].op;
3162 err = __vm_bind_ioctl_lookup_vma(vm, bos[i], addr, range, op);
3164 goto release_vm_lock;
3167 for (i = 0; i < args->num_binds; ++i) {
3168 u64 range = bind_ops[i].range;
3169 u64 addr = bind_ops[i].addr;
3170 u32 op = bind_ops[i].op;
3171 u64 obj_offset = bind_ops[i].obj_offset;
3172 u64 gt_mask = bind_ops[i].gt_mask;
3173 u32 region = bind_ops[i].region;
3175 vmas[i] = vm_bind_ioctl_lookup_vma(vm, bos[i], obj_offset,
3176 addr, range, op, gt_mask,
3178 if (IS_ERR(vmas[i])) {
3179 err = PTR_ERR(vmas[i]);
3185 for (j = 0; j < args->num_binds; ++j) {
3186 struct xe_sync_entry *__syncs;
3187 u32 __num_syncs = 0;
3188 bool first_or_last = j == 0 || j == args->num_binds - 1;
3190 if (args->num_binds == 1) {
3191 __num_syncs = num_syncs;
3193 } else if (first_or_last && num_syncs) {
3194 bool first = j == 0;
3196 __syncs = kmalloc(sizeof(*__syncs) * num_syncs,
3203 /* in-syncs on first bind, out-syncs on last bind */
3204 for (i = 0; i < num_syncs; ++i) {
3205 bool signal = syncs[i].flags &
3208 if ((first && !signal) || (!first && signal))
3209 __syncs[__num_syncs++] = syncs[i];
3217 bool last = j == args->num_binds - 1;
3220 * Each pass of async worker drops the ref, take a ref
3221 * here, 1 set of refs taken above
3229 err = vm_bind_ioctl_async(vm, vmas[j], e, bos[j],
3230 bind_ops + j, __syncs,
3240 XE_BUG_ON(j != 0); /* Not supported */
3241 err = vm_bind_ioctl(vm, vmas[j], e, bos[j],
3242 bind_ops + j, __syncs,
3244 break; /* Needed so cleanup loops work */
3248 /* Most of cleanup owned by the async bind worker */
3249 if (async && !err) {
3250 up_write(&vm->lock);
3251 if (args->num_binds > 1)
3257 for (i = j; err && i < args->num_binds; ++i) {
3258 u32 op = bind_ops[i].op;
3259 struct xe_vma *vma, *next;
3264 list_for_each_entry_safe(vma, next, &vma->unbind_link,
3266 list_del_init(&vma->unbind_link);
3267 if (!vma->destroyed) {
3268 prep_vma_destroy(vm, vma);
3269 xe_vma_destroy_unlocked(vma);
3273 switch (VM_BIND_OP(op)) {
3274 case XE_VM_BIND_OP_MAP:
3275 prep_vma_destroy(vm, vmas[i]);
3276 xe_vma_destroy_unlocked(vmas[i]);
3278 case XE_VM_BIND_OP_MAP_USERPTR:
3279 prep_vma_destroy(vm, vmas[i]);
3280 xe_vma_destroy_unlocked(vmas[i]);
3285 up_write(&vm->lock);
3287 while (num_syncs--) {
3289 !(syncs[num_syncs].flags & DRM_XE_SYNC_SIGNAL))
3290 continue; /* Still in async worker */
3291 xe_sync_entry_cleanup(&syncs[num_syncs]);
3296 for (i = j; i < args->num_binds; ++i)
3306 if (args->num_binds > 1)
3312 * XXX: Using the TTM wrappers for now, likely can call into dma-resv code
3313 * directly to optimize. Also this likely should be an inline function.
3315 int xe_vm_lock(struct xe_vm *vm, struct ww_acquire_ctx *ww,
3316 int num_resv, bool intr)
3318 struct ttm_validate_buffer tv_vm;
3324 tv_vm.num_shared = num_resv;
3325 tv_vm.bo = xe_vm_ttm_bo(vm);;
3326 list_add_tail(&tv_vm.head, &objs);
3328 return ttm_eu_reserve_buffers(ww, &objs, intr, &dups);
3331 void xe_vm_unlock(struct xe_vm *vm, struct ww_acquire_ctx *ww)
3333 dma_resv_unlock(&vm->resv);
3334 ww_acquire_fini(ww);
3338 * xe_vm_invalidate_vma - invalidate GPU mappings for VMA without a lock
3339 * @vma: VMA to invalidate
3341 * Walks a list of page tables leaves which it memset the entries owned by this
3342 * VMA to zero, invalidates the TLBs, and block until TLBs invalidation is
3345 * Returns 0 for success, negative error code otherwise.
3347 int xe_vm_invalidate_vma(struct xe_vma *vma)
3349 struct xe_device *xe = vma->vm->xe;
3351 u32 gt_needs_invalidate = 0;
3352 int seqno[XE_MAX_GT];
3356 XE_BUG_ON(!xe_vm_in_fault_mode(vma->vm));
3357 trace_xe_vma_usm_invalidate(vma);
3359 /* Check that we don't race with page-table updates */
3360 if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
3361 if (xe_vma_is_userptr(vma)) {
3362 WARN_ON_ONCE(!mmu_interval_check_retry
3363 (&vma->userptr.notifier,
3364 vma->userptr.notifier_seq));
3365 WARN_ON_ONCE(!dma_resv_test_signaled(&vma->vm->resv,
3366 DMA_RESV_USAGE_BOOKKEEP));
3369 xe_bo_assert_held(vma->bo);
3373 for_each_gt(gt, xe, id) {
3374 if (xe_pt_zap_ptes(gt, vma)) {
3375 gt_needs_invalidate |= BIT(id);
3377 seqno[id] = xe_gt_tlb_invalidation_vma(gt, NULL, vma);
3383 for_each_gt(gt, xe, id) {
3384 if (gt_needs_invalidate & BIT(id)) {
3385 ret = xe_gt_tlb_invalidation_wait(gt, seqno[id]);
3391 vma->usm.gt_invalidated = vma->gt_mask;
3396 #if IS_ENABLED(CONFIG_DRM_XE_SIMPLE_ERROR_CAPTURE)
3397 int xe_analyze_vm(struct drm_printer *p, struct xe_vm *vm, int gt_id)
3399 struct rb_node *node;
3403 if (!down_read_trylock(&vm->lock)) {
3404 drm_printf(p, " Failed to acquire VM lock to dump capture");
3407 if (vm->pt_root[gt_id]) {
3408 addr = xe_bo_addr(vm->pt_root[gt_id]->bo, 0, XE_PAGE_SIZE,
3410 drm_printf(p, " VM root: A:0x%llx %s\n", addr, is_vram ? "VRAM" : "SYS");
3413 for (node = rb_first(&vm->vmas); node; node = rb_next(node)) {
3414 struct xe_vma *vma = to_xe_vma(node);
3415 bool is_userptr = xe_vma_is_userptr(vma);
3418 struct xe_res_cursor cur;
3420 xe_res_first_sg(vma->userptr.sg, 0, XE_PAGE_SIZE,
3422 addr = xe_res_dma(&cur);
3424 addr = __xe_bo_addr(vma->bo, 0, XE_PAGE_SIZE, &is_vram);
3426 drm_printf(p, " [%016llx-%016llx] S:0x%016llx A:%016llx %s\n",
3427 vma->start, vma->end, vma->end - vma->start + 1ull,
3428 addr, is_userptr ? "USR" : is_vram ? "VRAM" : "SYS");
3435 int xe_analyze_vm(struct drm_printer *p, struct xe_vm *vm, int gt_id)