drm/amdkfd: Improve amdgpu_vm_handle_moved
authorFelix Kuehling <Felix.Kuehling@amd.com>
Wed, 16 Mar 2022 21:21:40 +0000 (17:21 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 3 Nov 2023 16:18:32 +0000 (12:18 -0400)
Let amdgpu_vm_handle_moved update all BO VA mappings of BOs reserved by
the caller. This will be useful for handling extra BO VA mappings in
KFD VMs that are managed through the render node API.

v2: rebase against drm_exec changes (Alex)

Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

index 122472d88756f16102760698d38de9e537273763..0245de81cabdd0e911e662ee19d1dd2ba063cb49 100644 (file)
@@ -1116,6 +1116,11 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
                        return r;
        }
 
+       /* FIXME: In theory this loop shouldn't be needed any more when
+        * amdgpu_vm_handle_moved handles all moved BOs that are reserved
+        * with p->ticket. But removing it caused test regressions, so I'm
+        * leaving it here for now.
+        */
        amdgpu_bo_list_for_each_entry(e, p->bo_list) {
                bo_va = e->bo_va;
                if (bo_va == NULL)
@@ -1130,7 +1135,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
                        return r;
        }
 
-       r = amdgpu_vm_handle_moved(adev, vm);
+       r = amdgpu_vm_handle_moved(adev, vm, &p->exec.ticket);
        if (r)
                return r;
 
index b5e28fa3f4144fccfe7db3a7e21181aaf0394e31..e7e87a3b2601eb130d9eaf13d8fab0c7b5e5c4cd 100644 (file)
@@ -409,7 +409,7 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
                if (!r)
                        r = amdgpu_vm_clear_freed(adev, vm, NULL);
                if (!r)
-                       r = amdgpu_vm_handle_moved(adev, vm);
+                       r = amdgpu_vm_handle_moved(adev, vm, ticket);
 
                if (r && r != -EBUSY)
                        DRM_ERROR("Failed to invalidate VM page tables (%d))\n",
index 3cd5977c0709a66634991714a43def35b3e962d4..904252456d2582d8da3bfe5f6fad647ec24b3627 100644 (file)
@@ -1373,6 +1373,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
  *
  * @adev: amdgpu_device pointer
  * @vm: requested vm
+ * @ticket: optional reservation ticket used to reserve the VM
  *
  * Make sure all BOs which are moved are updated in the PTs.
  *
@@ -1382,11 +1383,12 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
  * PTs have to be reserved!
  */
 int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
-                          struct amdgpu_vm *vm)
+                          struct amdgpu_vm *vm,
+                          struct ww_acquire_ctx *ticket)
 {
        struct amdgpu_bo_va *bo_va;
        struct dma_resv *resv;
-       bool clear;
+       bool clear, unlock;
        int r;
 
        spin_lock(&vm->status_lock);
@@ -1409,17 +1411,24 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
                spin_unlock(&vm->status_lock);
 
                /* Try to reserve the BO to avoid clearing its ptes */
-               if (!adev->debug_vm && dma_resv_trylock(resv))
+               if (!adev->debug_vm && dma_resv_trylock(resv)) {
                        clear = false;
+                       unlock = true;
+               /* The caller is already holding the reservation lock */
+               } else if (ticket && dma_resv_locking_ctx(resv) == ticket) {
+                       clear = false;
+                       unlock = false;
                /* Somebody else is using the BO right now */
-               else
+               } else {
                        clear = true;
+                       unlock = false;
+               }
 
                r = amdgpu_vm_bo_update(adev, bo_va, clear);
                if (r)
                        return r;
 
-               if (!clear)
+               if (unlock)
                        dma_resv_unlock(resv);
                spin_lock(&vm->status_lock);
        }
index 9c7b5d33b56e9368acd3c55ce2e702400df24c9f..2cd86d2bf73f7af67fd78be273cd57fc68521e11 100644 (file)
@@ -443,7 +443,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
                          struct amdgpu_vm *vm,
                          struct dma_fence **fence);
 int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
-                          struct amdgpu_vm *vm);
+                          struct amdgpu_vm *vm,
+                          struct ww_acquire_ctx *ticket);
 void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
                            struct amdgpu_vm *vm, struct amdgpu_bo *bo);
 int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,