Add separate tracking of last cleared of freed mappings and use this as
dependency when freeing GEM handles.

Still heavily oversyncing, but better than undersyncing.

Signed-off-by: Christian König <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c |  4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 14 +++++++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  3 ++-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 2e16484bf606..4509a59d499a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -232,12 +232,12 @@ static void amdgpu_gem_object_close(struct drm_gem_object 
*obj,
                fence = NULL;
        }
 
-       r = amdgpu_vm_clear_freed(adev, vm, &fence);
+       r = amdgpu_vm_clear_freed(adev, vm, NULL);
+       fence = vm->last_clear;
        if (r || !fence)
                goto out_unlock;
 
        amdgpu_bo_fence(bo, fence, true);
-       dma_fence_put(fence);
 
 out_unlock:
        if (unlikely(r < 0))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 11ebfef6962f..3f73e6097e6c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1286,15 +1286,17 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
                }
        }
 
-       if (fence && f) {
+       if (!f)
+               return 0;
+
+       if (fence) {
                dma_fence_put(*fence);
-               *fence = f;
-       } else {
-               dma_fence_put(f);
+               *fence = dma_fence_get(f);
        }
 
+       swap(vm->last_clear, f);
+       dma_fence_put(f);
        return 0;
-
 }
 
 /**
@@ -2084,6 +2086,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct 
amdgpu_vm *vm)
        else
                vm->update_funcs = &amdgpu_vm_sdma_funcs;
        vm->last_update = NULL;
+       vm->last_clear = NULL;
        vm->last_unlocked = dma_fence_get_stub();
 
        mutex_init(&vm->eviction_lock);
@@ -2198,6 +2201,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, 
struct amdgpu_vm *vm)
                vm->update_funcs = &amdgpu_vm_sdma_funcs;
        }
        dma_fence_put(vm->last_update);
+       dma_fence_put(vm->last_clear);
        vm->last_update = NULL;
        vm->is_compute_context = true;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 1a814fbffff8..be82ef170926 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -272,12 +272,13 @@ struct amdgpu_vm {
 
        /* BO mappings freed, but not yet updated in the PT */
        struct list_head        freed;
+       struct dma_fence        *last_clear;
 
        /* BOs which are invalidated, has been updated in the PTs */
        struct list_head        done;
 
        /* contains the page directory */
-       struct amdgpu_vm_bo_base     root;
+       struct amdgpu_vm_bo_base root;
        struct dma_fence        *last_update;
 
        /* Scheduler entities for page table updates */
-- 
2.25.1

Reply via email to