[PATCH 37/44] drm/amdkfd: Fix svm_bo_list locking in eviction worker

Felix Kuehling Felix.Kuehling at amd.com
Mon Mar 22 10:58:53 UTC 2021


Take the svm_bo_list spin lock when iterating of the range list during
eviction.

Change-Id: I979d959e06c32e114cea8d151933b8ee7455627e
Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 49aca4664411..3a7030d9f331 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -2494,7 +2494,6 @@ int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
 static void svm_range_evict_svm_bo_worker(struct work_struct *work)
 {
 	struct svm_range_bo *svm_bo;
-	struct svm_range *prange;
 	struct kfd_process *p;
 	struct mm_struct *mm;
 
@@ -2511,13 +2510,29 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
 		return;
 
 	mmap_read_lock(mm);
-	list_for_each_entry(prange, &svm_bo->range_list, svm_bo_list) {
+	spin_lock(&svm_bo->list_lock);
+	while (!list_empty(&svm_bo->range_list)) {
+		struct svm_range *prange =
+				list_first_entry(&svm_bo->range_list,
+						struct svm_range, svm_bo_list);
+		list_del_init(&prange->svm_bo_list);
+		spin_unlock(&svm_bo->list_lock);
+
 		pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms,
 			 prange->start, prange->last);
+
 		mutex_lock(&prange->migrate_mutex);
 		svm_migrate_vram_to_ram(prange, svm_bo->eviction_fence->mm);
+
+		mutex_lock(&prange->lock);
+		prange->svm_bo = NULL;
+		mutex_unlock(&prange->lock);
+
 		mutex_unlock(&prange->migrate_mutex);
+
+		spin_lock(&svm_bo->list_lock);
 	}
+	spin_unlock(&svm_bo->list_lock);
 	mmap_read_unlock(mm);
 
 	dma_fence_signal(&svm_bo->eviction_fence->base);
-- 
2.31.0



More information about the amd-gfx mailing list