]> git.itanic.dy.fi Git - linux-stable/commitdiff
drm/xe: Rework rebinding
authorThomas Hellström <thomas.hellstrom@linux.intel.com>
Wed, 27 Mar 2024 09:11:34 +0000 (10:11 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Apr 2024 14:38:22 +0000 (16:38 +0200)
commit a00e7e3fb4b9b30a9f2286a6f892b6e781e560a8 upstream.

Instead of handling the vm's rebind fence separately,
which is error prone if they are not strictly ordered,
attach rebind fences as kernel fences to the vm's resv.

Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <stable@vger.kernel.org> # v6.8+
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240327091136.3271-3-thomas.hellstrom@linux.intel.com
(cherry picked from commit 5a091aff50b780ae29c7faf70a7a6c21c98a54c4)
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/xe/xe_exec.c
drivers/gpu/drm/xe/xe_pt.c
drivers/gpu/drm/xe/xe_vm.c
drivers/gpu/drm/xe/xe_vm.h
drivers/gpu/drm/xe/xe_vm_types.h

index 222209b0d6904d78089750af82829f69c29e9e43..2cd4ad2fcffa1c9fa19ad0e93b1b039e8cb148e6 100644 (file)
@@ -113,7 +113,6 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
        struct drm_exec *exec = &vm_exec.exec;
        u32 i, num_syncs = 0, num_ufence = 0;
        struct xe_sched_job *job;
-       struct dma_fence *rebind_fence;
        struct xe_vm *vm;
        bool write_locked, skip_retry = false;
        ktime_t end = 0;
@@ -256,35 +255,11 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
         * Rebind any invalidated userptr or evicted BOs in the VM, non-compute
         * VM mode only.
         */
-       rebind_fence = xe_vm_rebind(vm, false);
-       if (IS_ERR(rebind_fence)) {
-               err = PTR_ERR(rebind_fence);
+       err = xe_vm_rebind(vm, false);
+       if (err)
                goto err_put_job;
-       }
-
-       /*
-        * We store the rebind_fence in the VM so subsequent execs don't get
-        * scheduled before the rebinds of userptrs / evicted BOs is complete.
-        */
-       if (rebind_fence) {
-               dma_fence_put(vm->rebind_fence);
-               vm->rebind_fence = rebind_fence;
-       }
-       if (vm->rebind_fence) {
-               if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
-                            &vm->rebind_fence->flags)) {
-                       dma_fence_put(vm->rebind_fence);
-                       vm->rebind_fence = NULL;
-               } else {
-                       dma_fence_get(vm->rebind_fence);
-                       err = drm_sched_job_add_dependency(&job->drm,
-                                                          vm->rebind_fence);
-                       if (err)
-                               goto err_put_job;
-               }
-       }
 
-       /* Wait behind munmap style rebinds */
+       /* Wait behind rebinds */
        if (!xe_vm_in_lr_mode(vm)) {
                err = drm_sched_job_add_resv_dependencies(&job->drm,
                                                          xe_vm_resv(vm),
index 9fdff84f2d42dc0ee4a9c29a8cd11f44984abdc6..c1a833b1cb3d3ad10ea5da38b5db1966bc2d1af9 100644 (file)
@@ -1300,7 +1300,7 @@ __xe_pt_bind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queue
                }
 
                /* add shared fence now for pagetable delayed destroy */
-               dma_resv_add_fence(xe_vm_resv(vm), fence, !rebind &&
+               dma_resv_add_fence(xe_vm_resv(vm), fence, rebind ||
                                   last_munmap_rebind ?
                                   DMA_RESV_USAGE_KERNEL :
                                   DMA_RESV_USAGE_BOOKKEEP);
index a2397f232efc6d000b78f6b2adaa4806923294bf..a2024247bec1ad85b43875c941aaed97b82cd098 100644 (file)
@@ -520,7 +520,6 @@ static void preempt_rebind_work_func(struct work_struct *w)
 {
        struct xe_vm *vm = container_of(w, struct xe_vm, preempt.rebind_work);
        struct drm_exec exec;
-       struct dma_fence *rebind_fence;
        unsigned int fence_count = 0;
        LIST_HEAD(preempt_fences);
        ktime_t end = 0;
@@ -566,18 +565,11 @@ static void preempt_rebind_work_func(struct work_struct *w)
        if (err)
                goto out_unlock;
 
-       rebind_fence = xe_vm_rebind(vm, true);
-       if (IS_ERR(rebind_fence)) {
-               err = PTR_ERR(rebind_fence);
+       err = xe_vm_rebind(vm, true);
+       if (err)
                goto out_unlock;
-       }
-
-       if (rebind_fence) {
-               dma_fence_wait(rebind_fence, false);
-               dma_fence_put(rebind_fence);
-       }
 
-       /* Wait on munmap style VM unbinds */
+       /* Wait on rebinds and munmap style VM unbinds */
        wait = dma_resv_wait_timeout(xe_vm_resv(vm),
                                     DMA_RESV_USAGE_KERNEL,
                                     false, MAX_SCHEDULE_TIMEOUT);
@@ -771,14 +763,14 @@ xe_vm_bind_vma(struct xe_vma *vma, struct xe_exec_queue *q,
               struct xe_sync_entry *syncs, u32 num_syncs,
               bool first_op, bool last_op);
 
-struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
+int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
 {
-       struct dma_fence *fence = NULL;
+       struct dma_fence *fence;
        struct xe_vma *vma, *next;
 
        lockdep_assert_held(&vm->lock);
        if (xe_vm_in_lr_mode(vm) && !rebind_worker)
-               return NULL;
+               return 0;
 
        xe_vm_assert_held(vm);
        list_for_each_entry_safe(vma, next, &vm->rebind_list,
@@ -786,17 +778,17 @@ struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
                xe_assert(vm->xe, vma->tile_present);
 
                list_del_init(&vma->combined_links.rebind);
-               dma_fence_put(fence);
                if (rebind_worker)
                        trace_xe_vma_rebind_worker(vma);
                else
                        trace_xe_vma_rebind_exec(vma);
                fence = xe_vm_bind_vma(vma, NULL, NULL, 0, false, false);
                if (IS_ERR(fence))
-                       return fence;
+                       return PTR_ERR(fence);
+               dma_fence_put(fence);
        }
 
-       return fence;
+       return 0;
 }
 
 static void xe_vma_free(struct xe_vma *vma)
@@ -1575,7 +1567,6 @@ static void vm_destroy_work_func(struct work_struct *w)
                XE_WARN_ON(vm->pt_root[id]);
 
        trace_xe_vm_free(vm);
-       dma_fence_put(vm->rebind_fence);
        kfree(vm);
 }
 
index 9654a0612fc258d0ba7395ba7c7fd87899caf904..40188a28c5471fb0ea6a51f72ebaab6daea6e64b 100644 (file)
@@ -207,7 +207,7 @@ int __xe_vm_userptr_needs_repin(struct xe_vm *vm);
 
 int xe_vm_userptr_check_repin(struct xe_vm *vm);
 
-struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker);
+int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker);
 
 int xe_vm_invalidate_vma(struct xe_vma *vma);
 
index a44048e297f7dcb42fd5ec450dda90c2e31e8cca..4027da3a10b3a17dead6157d0ff858b8955cf09d 100644 (file)
@@ -171,9 +171,6 @@ struct xe_vm {
         */
        struct list_head rebind_list;
 
-       /** @rebind_fence: rebind fence from execbuf */
-       struct dma_fence *rebind_fence;
-
        /**
         * @destroy_work: worker to destroy VM, needed as a dma_fence signaling
         * from an irq context can be last put and the destroy needs to be able