diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-06-22 09:46:21 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2020-06-22 09:46:21 +0000 |
commit | d934dc33fac35d22b06d5dbfc75aa6eb2ca37438 (patch) | |
tree | 4fb1ee6a9eb41e03501293cbe5a6b4fcdd19af5b | |
parent | b4d8cdd046c883169c1a97088e689e7b6b6b2f31 (diff) |
drm/amdgpu: fix and cleanup amdgpu_gem_object_close v4
From Christian Koenig
ba90bed3ea632a6cff527dea080336666f36ab2b in linux 5.7.y/5.7.5
82c416b13cb7d22b96ec0888b296a48dff8a09eb in mainline linux
-rw-r--r-- | sys/dev/pci/drm/amd/amdgpu/amdgpu_gem.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_gem.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_gem.c index 7e302644316..80324595e87 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_gem.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_gem.c @@ -168,16 +168,17 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, struct amdgpu_bo_list_entry vm_pd; struct list_head list, duplicates; + struct dma_fence *fence = NULL; struct ttm_validate_buffer tv; struct ww_acquire_ctx ticket; struct amdgpu_bo_va *bo_va; - int r; + long r; INIT_LIST_HEAD(&list); INIT_LIST_HEAD(&duplicates); tv.bo = &bo->tbo; - tv.num_shared = 1; + tv.num_shared = 2; list_add(&tv.head, &list); amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); @@ -185,28 +186,34 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates); if (r) { dev_err(adev->dev, "leaking bo va because " - "we fail to reserve bo (%d)\n", r); + "we fail to reserve bo (%ld)\n", r); return; } bo_va = amdgpu_vm_bo_find(vm, bo); - if (bo_va && --bo_va->ref_count == 0) { - amdgpu_vm_bo_rmv(adev, bo_va); - - if (amdgpu_vm_ready(vm)) { - struct dma_fence *fence = NULL; + if (!bo_va || --bo_va->ref_count) + goto out_unlock; - r = amdgpu_vm_clear_freed(adev, vm, &fence); - if (unlikely(r)) { - dev_err(adev->dev, "failed to clear page " - "tables on GEM object close (%d)\n", r); - } + amdgpu_vm_bo_rmv(adev, bo_va); + if (!amdgpu_vm_ready(vm)) + goto out_unlock; - if (fence) { - amdgpu_bo_fence(bo, fence, true); - dma_fence_put(fence); - } - } + fence = dma_resv_get_excl(bo->tbo.base.resv); + if (fence) { + amdgpu_bo_fence(bo, fence, true); + fence = NULL; } + + r = amdgpu_vm_clear_freed(adev, vm, &fence); + if (r || !fence) + goto out_unlock; + + amdgpu_bo_fence(bo, fence, true); + dma_fence_put(fence); + +out_unlock: + if (unlikely(r < 0)) + dev_err(adev->dev, "failed to clear page " + "tables on GEM object close (%ld)\n", r); ttm_eu_backoff_reservation(&ticket, &list); } |