During kfd_criu_resume_svm(), the driver puts in place every
checkpointed svm range, including explicitly setting
KFD_IOCTL_SVM_ATTR_NO_ACCESS on every range where that was previously true.

This leads to an unmap without the vm lock held. This isn't an error
but it does trip an assert.

Make an alternate amdgpu_vm_ready for svm_unmap that lacks the assert.

Signed-off-by: David Francis <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 32 ++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  1 +
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c   |  2 +-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index f07b7fb0c5db..ee68ffb0dc8f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -696,6 +696,38 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
        return ret;
 }
 
+/**
+ * amdgpu_vm_ready_for_unmap - check VM is ready for unmap
+ *
+ * @vm: VM to check
+ *
+ * Check if all VM PDs/PTs are ready for unmap
+ * Doesn't require the vm be locked
+ *
+ * Returns:
+ * True if VM is not evicting and all VM entities are not stopped
+ */
+bool amdgpu_vm_ready_for_unmap(struct amdgpu_vm *vm)
+{
+       bool ret;
+
+       amdgpu_vm_eviction_lock(vm);
+       ret = !vm->evicting;
+       amdgpu_vm_eviction_unlock(vm);
+
+       ret &= list_empty(&vm->kernel.evicted);
+
+       spin_lock(&vm->immediate.lock);
+       ret &= !vm->immediate.stopped;
+       spin_unlock(&vm->immediate.lock);
+
+       spin_lock(&vm->delayed.lock);
+       ret &= !vm->delayed.stopped;
+       spin_unlock(&vm->delayed.lock);
+
+       return ret;
+}
+
 /**
  * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug
  *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 0f6634b74974..8a2639be28fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -438,6 +438,7 @@ int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec 
*exec,
 int amdgpu_vm_lock_individual(struct amdgpu_vm *vm, struct drm_exec *exec,
                              unsigned int num_fences);
 bool amdgpu_vm_ready(struct amdgpu_vm *vm);
+bool amdgpu_vm_ready_for_unmap(struct amdgpu_vm *vm);
 uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm 
*vm);
 int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                       struct ww_acquire_ctx *ticket,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index c521ec07bf3c..68e51367e714 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -1406,7 +1406,7 @@ svm_range_unmap_from_gpu(struct amdgpu_device *adev, 
struct amdgpu_vm *vm,
        pr_debug("CPU[0x%llx 0x%llx] -> GPU[0x%llx 0x%llx]\n", start, last,
                gpu_start, gpu_end);
 
-       if (!amdgpu_vm_ready(vm)) {
+       if (!amdgpu_vm_ready_for_unmap(vm)) {
                pr_debug("VM not ready, canceling unmap\n");
                return -EINVAL;
        }
-- 
2.34.1

Reply via email to