amdgpu_vm_fini() relies on vm->last_tlb_flush to wait for TLB activity
to complete before calling amdgpu_vm_pt_free_root(). Because
vm->last_tlb_flush tracks only the vm commit fence and never the TLB
fence itself, so fini() may proceed to free page tables while the TLB fence
work item is still running amdgpu_gmc_flush_gpu_tlb_pasid().

Signed-off-by: Prike Liang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 937a6dd3a4b5..53d0ac8bf98f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1093,6 +1093,13 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params 
*params,
        if (!params->unlocked && vm->need_tlb_fence) {
                amdgpu_vm_tlb_fence_create(params->adev, vm, fence);
 
+               /*
+                * Update last_tlb_flush to the TLB fence so that
+                * amdgpu_vm_fini() waits for the actual TLB flush to
+                * complete, not just its commit fence.
+                */
+               dma_fence_put(vm->last_tlb_flush);
+               vm->last_tlb_flush = dma_fence_get(*fence);
                /* Makes sure no PD/PT is freed before the flush */
                dma_resv_add_fence(vm->root.bo->tbo.base.resv, *fence,
                                   DMA_RESV_USAGE_BOOKKEEP);
-- 
2.34.1

Reply via email to