From: Honglei Huang <[email protected]> Add helpers to quiesce and resume KFD compute queues for xnack-off SVM restore. Use mmget_not_zero() to safely acquire a reference to svm->gpusvm.mm before calling into KFD, protecting against races with concurrent mm teardown.
Signed-off-by: Honglei Huang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userptr.c | 60 +++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userptr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userptr.c index 0b02008be..34b3b4149 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userptr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userptr.c @@ -566,6 +566,66 @@ void amdgpu_svm_restore_gc_work_func(struct work_struct *w) msecs_to_jiffies(AMDGPU_SVM_RANGE_RESTORE_DELAY_MS)); } +void amdgpu_svm_quiesce_compute(struct amdgpu_svm *svm) +{ + struct mm_struct *mm = svm->gpusvm.mm; + int ret; + + if (!mm) + return; + + if (atomic_cmpxchg(&svm->restore.quiesced, 0, 1) != 0) + return; + + if (!mmget_not_zero(mm)) { + atomic_set(&svm->restore.quiesced, 0); + return; + } + + ret = kgd2kfd_quiesce_mm(mm, KFD_QUEUE_EVICTION_TRIGGER_SVM); + mmput(mm); + if (ret == -ESRCH) { + AMDGPU_SVM_TRACE("kfd quiesce skipped no KFD process\n"); + atomic_set(&svm->restore.quiesced, 0); + return; + } + + if (ret) { + AMDGPU_SVM_TRACE("kfd quiesce failed ret=%d\n", ret); + atomic_set(&svm->restore.quiesced, 0); + return; + } + + AMDGPU_SVM_TRACE("kfd quiesce ret=%d\n", ret); +} + +void amdgpu_svm_resume_compute(struct amdgpu_svm *svm) +{ + struct mm_struct *mm = svm->gpusvm.mm; + int ret; + + if (atomic_cmpxchg(&svm->restore.quiesced, 1, 0) != 1) + return; + + if (!mm) + return; + + if (!mmget_not_zero(mm)) + return; + + ret = kgd2kfd_resume_mm(mm); + mmput(mm); + if (ret == -ESRCH) { + AMDGPU_SVM_TRACE("kfd resume skipped no KFD process\n"); + return; + } + + if (ret) + AMDGPU_SVM_TRACE("kfd resume failed ret=%d\n", ret); + else + AMDGPU_SVM_TRACE("kfd resume ret=%d\n", ret); +} + int amdgpu_svm_restore_init(struct amdgpu_svm *svm, void (*begin)(struct amdgpu_svm *), void (*end)(struct amdgpu_svm *)) -- 2.34.1
