summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiaogang Chen <xiaogang.chen@amd.com>2023-09-20 11:02:51 -0500
committerAlex Deucher <alexander.deucher@amd.com>2023-09-26 17:00:02 -0400
commit7bfaa160caed8192f8262c4638f552cad94bcf5a (patch)
treeb11419d98ad8c54a5770aa286ca3c8b759399e4b
parent101b8104307eac734f2dfa4d3511430b0b631c73 (diff)
downloadlinux-stable-7bfaa160caed8192f8262c4638f552cad94bcf5a.tar.gz
linux-stable-7bfaa160caed8192f8262c4638f552cad94bcf5a.tar.bz2
linux-stable-7bfaa160caed8192f8262c4638f552cad94bcf5a.zip
drm/amdkfd: fix some race conditions in vram buffer alloc/free of svm code
This patch fixes: 1: ref number of prange's svm_bo got decreased by an async call from hmm. When wait svm_bo of prange got released we shoul also wait prang->svm_bo become NULL, otherwise prange->svm_bo may be set to null after allocate new vram buffer. 2: During waiting svm_bo of prange got released in a while loop should reschedule current task to give other tasks oppotunity to run, specially the the workque task that handles svm_bo ref release, otherwise we may enter to softlock. Signed-off-by: Xiaogang.Chen <xiaogang.chen@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 136a7a969d48..56a2afdfd3d4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -504,11 +504,11 @@ svm_range_validate_svm_bo(struct kfd_node *node, struct svm_range *prange)
/* We need a new svm_bo. Spin-loop to wait for concurrent
* svm_range_bo_release to finish removing this range from
- * its range list. After this, it is safe to reuse the
- * svm_bo pointer and svm_bo_list head.
+ * its range list and set prange->svm_bo to null. After this,
+ * it is safe to reuse the svm_bo pointer and svm_bo_list head.
*/
- while (!list_empty_careful(&prange->svm_bo_list))
- ;
+ while (!list_empty_careful(&prange->svm_bo_list) || prange->svm_bo)
+ cond_resched();
return false;
}