On 10/12/26 11:47, Jesse Zhang wrote:
> amdgpu_gem_object_close() detaches the user queue eviction fence from
> the BO before it checks bo_va->ref_count, so closing any handle of a BO
> removes the fence, even when the file still has another handle to the
> BO and the bo_va with its GPU mappings stays. The BO can then be evicted
> without suspending the user queues of the file, which keep accessing it
> through mappings that are only marked for update.
>
> Seen on navi31 with a SDMA user queue: a BO opened twice in the same
> file (GEM_FLINK + GEM_OPEN) loses its eviction fence when the second
> handle is closed (traced attach/detach of the fence):
>
> attach bo=ffff8c78a6c84c00
> GEM_CLOSE handle=7
> detach bo=ffff8c78a6c84c00
>
> while handle 6 and the mapping are still in use.
>
> Only detach the fence when the last reference to the bo_va goes away,
> matching amdgpu_gem_object_open(), which attaches it only when the
> bo_va is created. With this the fence stays until the file is closed.
>
> Fixes: 31f7efcdca4d ("drm/amdgpu: enable eviction fence")
> Signed-off-by: Jesse Zhang <[email protected]>
Reviewed-by: Christian König <[email protected]>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index 8dbd7bb77305..0552b17d9aa8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> @@ -351,11 +351,14 @@ static void amdgpu_gem_object_close(struct
> drm_gem_object *obj,
> goto out_unlock;
> }
>
> + bo_va = amdgpu_vm_bo_find(vm, bo);
> + /* the fence is attached once per bo_va, so keep it for other handles */
> + if (bo_va && --bo_va->ref_count)
> + goto out_unlock;
> +
> if (!amdgpu_vm_is_bo_always_valid(vm, bo))
> amdgpu_evf_mgr_detach_fence(&fpriv->evf_mgr, bo);
> -
> - bo_va = amdgpu_vm_bo_find(vm, bo);
> - if (!bo_va || --bo_va->ref_count)
> + if (!bo_va)
> goto out_unlock;
>
> amdgpu_vm_bo_del(adev, bo_va);