drm/amdkfd: Fix lock dependency warning
authorjsg <jsg@openbsd.org>
Tue, 6 Feb 2024 03:51:59 +0000 (03:51 +0000)
committerjsg <jsg@openbsd.org>
Tue, 6 Feb 2024 03:51:59 +0000 (03:51 +0000)
From Felix Kuehling
28d2d623d2fbddcca5c24600474e92f16ebb3a05 in linux-6.6.y/6.6.16
47bf0f83fc86df1bf42b385a91aadb910137c5c9 in mainline linux

sys/dev/pci/drm/amd/amdkfd/kfd_svm.c

index 8e368e4..a4c911f 100644 (file)
@@ -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;