drm/amdgpu: add vm root BO lock before accessing the vm

Add a vm root BO lock before accessing the userqueue VM.

v1:(Christian)
   - Keep the VM locked until you are done with the mapping.
   - Grab a temporary BO reference, drop the VM lock and acquire the BO.
     When you are done with everything just drop the BO lock and
     then the temporary BO reference.

Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Arunpravin Paneer Selvam 2024-10-30 10:56:57 +05:30 committed by Alex Deucher
parent fbea3d3174
commit d8675102ba

View File

@ -321,7 +321,6 @@ static const struct dma_fence_ops amdgpu_userq_fence_ops = {
/** /**
* amdgpu_userq_fence_read_wptr - Read the userq wptr value * amdgpu_userq_fence_read_wptr - Read the userq wptr value
* *
* @filp: drm file private data structure
* @queue: user mode queue structure pointer * @queue: user mode queue structure pointer
* @wptr: write pointer value * @wptr: write pointer value
* *
@ -331,25 +330,29 @@ static const struct dma_fence_ops amdgpu_userq_fence_ops = {
* *
* Returns wptr value on success, error on failure. * Returns wptr value on success, error on failure.
*/ */
static int amdgpu_userq_fence_read_wptr(struct drm_file *filp, static int amdgpu_userq_fence_read_wptr(struct amdgpu_usermode_queue *queue,
struct amdgpu_usermode_queue *queue,
u64 *wptr) u64 *wptr)
{ {
struct amdgpu_fpriv *fpriv = filp->driver_priv;
struct amdgpu_bo_va_mapping *mapping; struct amdgpu_bo_va_mapping *mapping;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
u64 addr, *ptr; u64 addr, *ptr;
int r; int r;
r = amdgpu_bo_reserve(queue->vm->root.bo, false);
if (r)
return r;
addr = queue->userq_prop->wptr_gpu_addr; addr = queue->userq_prop->wptr_gpu_addr;
addr &= AMDGPU_GMC_HOLE_MASK; addr &= AMDGPU_GMC_HOLE_MASK;
mapping = amdgpu_vm_bo_lookup_mapping(vm, addr >> PAGE_SHIFT); mapping = amdgpu_vm_bo_lookup_mapping(queue->vm, addr >> PAGE_SHIFT);
if (!mapping) if (!mapping) {
DRM_ERROR("Failed to lookup amdgpu_bo_va_mapping\n");
return -EINVAL; return -EINVAL;
}
bo = mapping->bo_va->base.bo; bo = amdgpu_bo_ref(mapping->bo_va->base.bo);
amdgpu_bo_unreserve(queue->vm->root.bo);
r = amdgpu_bo_reserve(bo, true); r = amdgpu_bo_reserve(bo, true);
if (r) { if (r) {
DRM_ERROR("Failed to reserve userqueue wptr bo"); DRM_ERROR("Failed to reserve userqueue wptr bo");
@ -366,11 +369,14 @@ static int amdgpu_userq_fence_read_wptr(struct drm_file *filp,
amdgpu_bo_kunmap(bo); amdgpu_bo_kunmap(bo);
amdgpu_bo_unreserve(bo); amdgpu_bo_unreserve(bo);
amdgpu_bo_unref(&bo);
return 0; return 0;
map_error: map_error:
amdgpu_bo_unreserve(bo); amdgpu_bo_unreserve(bo);
amdgpu_bo_unref(&bo);
return r; return r;
} }
@ -449,7 +455,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
goto exec_fini; goto exec_fini;
} }
r = amdgpu_userq_fence_read_wptr(filp, queue, &wptr); r = amdgpu_userq_fence_read_wptr(queue, &wptr);
if (r) if (r)
goto exec_fini; goto exec_fini;