Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Arunpravin Paneer Selvam and committed by
Alex Deucher
d8675102 fbea3d31

+15 -9
+15 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
··· 321 321 /** 322 322 * amdgpu_userq_fence_read_wptr - Read the userq wptr value 323 323 * 324 - * @filp: drm file private data structure 325 324 * @queue: user mode queue structure pointer 326 325 * @wptr: write pointer value 327 326 * ··· 330 331 * 331 332 * Returns wptr value on success, error on failure. 332 333 */ 333 - static int amdgpu_userq_fence_read_wptr(struct drm_file *filp, 334 - struct amdgpu_usermode_queue *queue, 334 + static int amdgpu_userq_fence_read_wptr(struct amdgpu_usermode_queue *queue, 335 335 u64 *wptr) 336 336 { 337 - struct amdgpu_fpriv *fpriv = filp->driver_priv; 338 337 struct amdgpu_bo_va_mapping *mapping; 339 - struct amdgpu_vm *vm = &fpriv->vm; 340 338 struct amdgpu_bo *bo; 341 339 u64 addr, *ptr; 342 340 int r; 343 341 342 + r = amdgpu_bo_reserve(queue->vm->root.bo, false); 343 + if (r) 344 + return r; 345 + 344 346 addr = queue->userq_prop->wptr_gpu_addr; 345 347 addr &= AMDGPU_GMC_HOLE_MASK; 346 348 347 - mapping = amdgpu_vm_bo_lookup_mapping(vm, addr >> PAGE_SHIFT); 348 - if (!mapping) 349 + mapping = amdgpu_vm_bo_lookup_mapping(queue->vm, addr >> PAGE_SHIFT); 350 + if (!mapping) { 351 + DRM_ERROR("Failed to lookup amdgpu_bo_va_mapping\n"); 349 352 return -EINVAL; 353 + } 350 354 351 - bo = mapping->bo_va->base.bo; 355 + bo = amdgpu_bo_ref(mapping->bo_va->base.bo); 356 + amdgpu_bo_unreserve(queue->vm->root.bo); 352 357 r = amdgpu_bo_reserve(bo, true); 353 358 if (r) { 354 359 DRM_ERROR("Failed to reserve userqueue wptr bo"); ··· 369 366 370 367 amdgpu_bo_kunmap(bo); 371 368 amdgpu_bo_unreserve(bo); 369 + amdgpu_bo_unref(&bo); 372 370 373 371 return 0; 374 372 375 373 map_error: 376 374 amdgpu_bo_unreserve(bo); 375 + amdgpu_bo_unref(&bo); 376 + 377 377 return r; 378 378 } 379 379 ··· 455 449 goto exec_fini; 456 450 } 457 451 458 - r = amdgpu_userq_fence_read_wptr(filp, queue, &wptr); 452 + r = amdgpu_userq_fence_read_wptr(queue, &wptr); 459 453 if (r) 460 454 goto exec_fini; 461 455