diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2024-02-06 03:52:00 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2024-02-06 03:52:00 +0000 |
commit | 5b4fe0e732bd214bd170aefd21846e6014e4dcbb (patch) | |
tree | 54ce806e38af6996a2ea17bc423efb973ba858b0 /sys/dev/pci/drm/amd/amdkfd/kfd_svm.c | |
parent | 50f9a0ce35773b5c989b19c9ce9070977823d8d0 (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.c | 26 |
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; |