drm/amdgpu: fix clearing mappings for BOs that are always valid in VM
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 16 Jun 2023 13:14:07 +0000 (15:14 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 23 Jun 2023 19:35:51 +0000 (15:35 -0400)
Per VM BOs must be marked as moved or otherwise their ranges are not
updated on use which might be necessary when the replace operation
splits mappings.

This fixes random GPU hangs when replacing sparse mappings from the
userspace, while OP_MAP/OP_UNMAP works fine because always valid BOs
are correctly handled there.

Cc: stable@vger.kernel.org
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.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_vm.c

index 143d11afe0e5a97836e0566adea626e80742f07d..eff73c428b123c2beb0c8c3048d9ac5310c1232a 100644 (file)
@@ -1771,18 +1771,30 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
 
        /* Insert partial mapping before the range */
        if (!list_empty(&before->list)) {
+               struct amdgpu_bo *bo = before->bo_va->base.bo;
+
                amdgpu_vm_it_insert(before, &vm->va);
                if (before->flags & AMDGPU_PTE_PRT)
                        amdgpu_vm_prt_get(adev);
+
+               if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv &&
+                   !before->bo_va->base.moved)
+                       amdgpu_vm_bo_moved(&before->bo_va->base);
        } else {
                kfree(before);
        }
 
        /* Insert partial mapping after the range */
        if (!list_empty(&after->list)) {
+               struct amdgpu_bo *bo = after->bo_va->base.bo;
+
                amdgpu_vm_it_insert(after, &vm->va);
                if (after->flags & AMDGPU_PTE_PRT)
                        amdgpu_vm_prt_get(adev);
+
+               if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv &&
+                   !after->bo_va->base.moved)
+                       amdgpu_vm_bo_moved(&after->bo_va->base);
        } else {
                kfree(after);
        }