drm/amdgpu: Use vm status_lock to protect vm evicted list
authorPhilip Yang <Philip.Yang@amd.com>
Fri, 16 Sep 2022 03:21:15 +0000 (23:21 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 21 Sep 2022 19:25:40 +0000 (15:25 -0400)
Use vm_status_lock to protect all vm_status state transitions to allow
them to happen without a reservation lock in unlocked page table
updates.

Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Acked-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_vm.c

index 1688751..b2e9668 100644 (file)
@@ -183,10 +183,12 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
        struct amdgpu_bo *bo = vm_bo->bo;
 
        vm_bo->moved = true;
+       spin_lock(&vm_bo->vm->status_lock);
        if (bo->tbo.type == ttm_bo_type_kernel)
                list_move(&vm_bo->vm_status, &vm->evicted);
        else
                list_move_tail(&vm_bo->vm_status, &vm->evicted);
+       spin_unlock(&vm_bo->vm->status_lock);
 }
 /**
  * amdgpu_vm_bo_moved - vm_bo is moved
@@ -370,12 +372,20 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                              int (*validate)(void *p, struct amdgpu_bo *bo),
                              void *param)
 {
-       struct amdgpu_vm_bo_base *bo_base, *tmp;
+       struct amdgpu_vm_bo_base *bo_base;
+       struct amdgpu_bo *shadow;
+       struct amdgpu_bo *bo;
        int r;
 
-       list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) {
-               struct amdgpu_bo *bo = bo_base->bo;
-               struct amdgpu_bo *shadow = amdgpu_bo_shadowed(bo);
+       spin_lock(&vm->status_lock);
+       while (!list_empty(&vm->evicted)) {
+               bo_base = list_first_entry(&vm->evicted,
+                                          struct amdgpu_vm_bo_base,
+                                          vm_status);
+               spin_unlock(&vm->status_lock);
+
+               bo = bo_base->bo;
+               shadow = amdgpu_bo_shadowed(bo);
 
                r = validate(param, bo);
                if (r)
@@ -392,7 +402,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                        vm->update_funcs->map_table(to_amdgpu_bo_vm(bo));
                        amdgpu_vm_bo_relocated(bo_base);
                }
+               spin_lock(&vm->status_lock);
        }
+       spin_unlock(&vm->status_lock);
 
        amdgpu_vm_eviction_lock(vm);
        vm->evicting = false;
@@ -413,13 +425,18 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
  */
 bool amdgpu_vm_ready(struct amdgpu_vm *vm)
 {
+       bool empty;
        bool ret;
 
        amdgpu_vm_eviction_lock(vm);
        ret = !vm->evicting;
        amdgpu_vm_eviction_unlock(vm);
 
-       return ret && list_empty(&vm->evicted);
+       spin_lock(&vm->status_lock);
+       empty = list_empty(&vm->evicted);
+       spin_unlock(&vm->status_lock);
+
+       return ret && empty;
 }
 
 /**