summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/amd/amdkfd/kfd_svm.c
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2024-02-06 03:52:00 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2024-02-06 03:52:00 +0000
commit5b4fe0e732bd214bd170aefd21846e6014e4dcbb (patch)
tree54ce806e38af6996a2ea17bc423efb973ba858b0 /sys/dev/pci/drm/amd/amdkfd/kfd_svm.c
parent50f9a0ce35773b5c989b19c9ce9070977823d8d0 (diff)
drm/amdkfd: Fix lock dependency warning
From Felix Kuehling 28d2d623d2fbddcca5c24600474e92f16ebb3a05 in linux-6.6.y/6.6.16 47bf0f83fc86df1bf42b385a91aadb910137c5c9 in mainline linux
Diffstat (limited to 'sys/dev/pci/drm/amd/amdkfd/kfd_svm.c')
-rw-r--r--sys/dev/pci/drm/amd/amdkfd/kfd_svm.c26
1 files changed, 10 insertions, 16 deletions
diff --git a/sys/dev/pci/drm/amd/amdkfd/kfd_svm.c b/sys/dev/pci/drm/amd/amdkfd/kfd_svm.c
index 8e368e4659f..a4c911fa167 100644
--- a/sys/dev/pci/drm/amd/amdkfd/kfd_svm.c
+++ b/sys/dev/pci/drm/amd/amdkfd/kfd_svm.c
@@ -391,14 +391,9 @@ static void svm_range_bo_release(struct kref *kref)
spin_lock(&svm_bo->list_lock);
}
spin_unlock(&svm_bo->list_lock);
- if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) {
- /* We're not in the eviction worker.
- * Signal the fence and synchronize with any
- * pending eviction work.
- */
+ if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
+ /* We're not in the eviction worker. Signal the fence. */
dma_fence_signal(&svm_bo->eviction_fence->base);
- cancel_work_sync(&svm_bo->eviction_work);
- }
dma_fence_put(&svm_bo->eviction_fence->base);
amdgpu_bo_unref(&svm_bo->bo);
kfree(svm_bo);
@@ -3424,13 +3419,14 @@ svm_range_trigger_migration(struct mm_struct *mm, struct svm_range *prange,
int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
{
- if (!fence)
- return -EINVAL;
-
- if (dma_fence_is_signaled(&fence->base))
- return 0;
-
- if (fence->svm_bo) {
+ /* Dereferencing fence->svm_bo is safe here because the fence hasn't
+ * signaled yet and we're under the protection of the fence->lock.
+ * After the fence is signaled in svm_range_bo_release, we cannot get
+ * here any more.
+ *
+ * Reference is dropped in svm_range_evict_svm_bo_worker.
+ */
+ if (svm_bo_ref_unless_zero(fence->svm_bo)) {
WRITE_ONCE(fence->svm_bo->evicting, 1);
schedule_work(&fence->svm_bo->eviction_work);
}
@@ -3445,8 +3441,6 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
int r = 0;
svm_bo = container_of(work, struct svm_range_bo, eviction_work);
- if (!svm_bo_ref_unless_zero(svm_bo))
- return; /* svm_bo was freed while eviction was pending */
if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
mm = svm_bo->eviction_fence->mm;