drm/amdgpu: fix error handling in amdgpu_vm_init
authorChristian König <christian.koenig@amd.com>
Tue, 31 Oct 2023 14:35:27 +0000 (15:35 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 Nov 2023 17:20:17 +0000 (17:20 +0000)
commit 8473bfdcb5b1a32fd05629c4535ccacd73bc5567 upstream.

When clearing the root PD fails we need to properly release it again.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

index 82f25996ff5ef63f1528e5353d495703a7922a32..9ab87a55c8da2de92e9716dbf1aa2de2d2ea9fff 100644 (file)
@@ -2125,7 +2125,8 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
  * Returns:
  * 0 for success, error for failure.
  */
-int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id)
+int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+                  int32_t xcp_id)
 {
        struct amdgpu_bo *root_bo;
        struct amdgpu_bo_vm *root;
@@ -2144,6 +2145,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp
        INIT_LIST_HEAD(&vm->done);
        INIT_LIST_HEAD(&vm->pt_freed);
        INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
+       INIT_KFIFO(vm->faults);
 
        r = amdgpu_vm_init_entities(adev, vm);
        if (r)
@@ -2178,34 +2180,33 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp
                                false, &root, xcp_id);
        if (r)
                goto error_free_delayed;
-       root_bo = &root->bo;
+
+       root_bo = amdgpu_bo_ref(&root->bo);
        r = amdgpu_bo_reserve(root_bo, true);
-       if (r)
-               goto error_free_root;
+       if (r) {
+               amdgpu_bo_unref(&root->shadow);
+               amdgpu_bo_unref(&root_bo);
+               goto error_free_delayed;
+       }
 
+       amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
        r = dma_resv_reserve_fences(root_bo->tbo.base.resv, 1);
        if (r)
-               goto error_unreserve;
-
-       amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
+               goto error_free_root;
 
        r = amdgpu_vm_pt_clear(adev, vm, root, false);
        if (r)
-               goto error_unreserve;
+               goto error_free_root;
 
        amdgpu_bo_unreserve(vm->root.bo);
-
-       INIT_KFIFO(vm->faults);
+       amdgpu_bo_unref(&root_bo);
 
        return 0;
 
-error_unreserve:
-       amdgpu_bo_unreserve(vm->root.bo);
-
 error_free_root:
-       amdgpu_bo_unref(&root->shadow);
+       amdgpu_vm_pt_free_root(adev, vm);
+       amdgpu_bo_unreserve(vm->root.bo);
        amdgpu_bo_unref(&root_bo);
-       vm->root.bo = NULL;
 
 error_free_delayed:
        dma_fence_put(vm->last_tlb_flush);