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

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu: Fix circular locking in userq creation

A circular locking dependency was detected between the global
`adev->userq_mutex` and per-file `userq_mgr->userq_mutex` when
creating user queues. The issue occurs because:

1. `amdgpu_userq_suspend()` and `amdgpu_userq_resume` take `adev->userq_mutex` first, then
`userq_mgr->userq_mutex`
2. While `amdgpu_userq_create()` takes them in reverse order

This patch resolves the issue by:
1. Moving the `adev->userq_mutex` lock earlier in `amdgpu_userq_create()`
to cover the `amdgpu_userq_ensure_ev_fence()` call
2. Releasing it after we're done with both queue creation and the
scheduling halt check

v2: remove unused adev->userq_mutex lock (Prike)

Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: Prike Liang <Prike.Liang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Jesse.Zhang and committed by
Alex Deucher
96a86dcb 07c9db09

+2 -3
+2 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 394 394 * 395 395 * This will also make sure we have a valid eviction fence ready to be used. 396 396 */ 397 + mutex_lock(&adev->userq_mutex); 397 398 amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); 398 399 399 400 uq_funcs = adev->userq_funcs[args->in.ip_type]; ··· 457 456 } 458 457 459 458 /* don't map the queue if scheduling is halted */ 460 - mutex_lock(&adev->userq_mutex); 461 459 if (adev->userq_halt_for_enforce_isolation && 462 460 ((queue->queue_type == AMDGPU_HW_IP_GFX) || 463 461 (queue->queue_type == AMDGPU_HW_IP_COMPUTE))) ··· 466 466 if (!skip_map_queue) { 467 467 r = amdgpu_userq_map_helper(uq_mgr, queue); 468 468 if (r) { 469 - mutex_unlock(&adev->userq_mutex); 470 469 drm_file_err(uq_mgr->file, "Failed to map Queue\n"); 471 470 idr_remove(&uq_mgr->userq_idr, qid); 472 471 amdgpu_userq_fence_driver_free(queue); ··· 474 475 goto unlock; 475 476 } 476 477 } 477 - mutex_unlock(&adev->userq_mutex); 478 478 479 479 480 480 args->out.queue_id = qid; 481 481 482 482 unlock: 483 483 mutex_unlock(&uq_mgr->userq_mutex); 484 + mutex_unlock(&adev->userq_mutex); 484 485 485 486 return r; 486 487 }