Skip to content

Commit c50b2e2

Browse files
ArvindYadavAMDlutzbichler
authored andcommitted
drm/amdgpu: Fix display freeze lockup error
A deadlock situation has arised between the userq signal ioctl and the eviction fence. In this scenario, the function amdgpu_userq_signal_ioctl() has acquired a reservation lock on the read/write buffer object (BO) through drm_exec. Subsequently, it calls amdgpu_userqueue_ensure_ev_fence(), which is in a waiting for the userq resume work. Meanwhile, the userq suspend worker has initiated the userq resume work(amdgpu_userqueue_resume_worker). This userq resume work attempts to validate the vm->done BO, leading to amdgpu_userqueue_validate_bos also attempting to reservation lock the same write BO that is already locked by amdgpu_userq_signal_ioctl. As a result, the resume work becomes stalled, causing amdgpu_userqueue_ensure_ev_fence to remain in a waiting state. Call Trace: [ 242.836469] INFO: task gnome-shel:cs0:1288 blocked for more than 120 seconds. [ 242.836486] Tainted: G OE 6.12.0-rc2rebased-oct-24+ freebsd#4 [ 242.836491] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 242.836494] task:gnome-shel:cs0 state:D stack:0 pid:1288 tgid:1282 ppid:1180 flags:0x00000002 [ 242.836503] Call Trace: [ 242.836508] <TASK> [ 242.836517] __schedule+0x3e0/0xb10 [ 242.836530] ? srso_return_thunk+0x5/0x5f [ 242.836541] schedule+0x31/0x120 [ 242.836546] schedule_timeout+0x150/0x160 [ 242.836551] ? srso_return_thunk+0x5/0x5f [ 242.836555] ? sysvec_call_function+0x69/0xd0 [ 242.836562] ? srso_return_thunk+0x5/0x5f [ 242.836567] ? preempt_count_add+0x7f/0xd0 [ 242.836577] __wait_for_common+0x91/0x180 [ 242.836582] ? __pfx_schedule_timeout+0x10/0x10 [ 242.836590] wait_for_completion+0x28/0x30 [ 242.836595] __flush_work+0x16c/0x290 [ 242.836602] ? __pfx_wq_barrier_func+0x10/0x10 [ 242.836611] flush_delayed_work+0x3a/0x60 [ 242.836621] amdgpu_userqueue_ensure_ev_fence+0x2d/0xb0 [amdgpu] [ 242.836966] amdgpu_userq_signal_ioctl+0x959/0xec0 [amdgpu] [ 242.837171] ? __pfx_amdgpu_userq_signal_ioctl+0x10/0x10 [amdgpu] [ 242.837365] drm_ioctl_kernel+0xae/0x100 [drm] [ 242.837398] drm_ioctl+0x2a1/0x500 [drm] [ 242.837420] ? __pfx_amdgpu_userq_signal_ioctl+0x10/0x10 [amdgpu] [ 242.837622] ? srso_return_thunk+0x5/0x5f [ 242.837627] ? srso_return_thunk+0x5/0x5f [ 242.837630] ? _raw_spin_unlock_irqrestore+0x2b/0x50 [ 242.837635] amdgpu_drm_ioctl+0x4f/0x90 [amdgpu] [ 242.837811] __x64_sys_ioctl+0x99/0xd0 [ 242.837820] x64_sys_call+0x1209/0x20d0 [ 242.837825] do_syscall_64+0x51/0x120 [ 242.837830] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 242.837835] RIP: 0033:0x7f2f33f1a94f [ 242.837838] RSP: 002b:00007f2f24ffea30 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 242.837842] RAX: ffffffffffffffda RBX: 00007f2f24ffebd0 RCX: 00007f2f33f1a94f [ 242.837845] RDX: 00007f2f24ffebd0 RSI: 00000000c0306457 RDI: 000000000000000d [ 242.837847] RBP: 00007f2f24ffeab0 R08: 0000000000000000 R09: 0000000000000000 [ 242.837849] R10: 00007f2f24ffecd0 R11: 0000000000000246 R12: 00007f2f25000640 [ 242.837851] R13: 00000000c0306457 R14: 000000000000000d R15: 00007fff3b39c1e0 [ 242.837858] </TASK> [ 242.837865] INFO: task Xwayland:cs0:1517 blocked for more than 120 seconds. [ 242.837869] Tainted: G OE 6.12.0-rc2rebased-oct-24+ freebsd#4 [ 242.837872] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 242.837874] task:Xwayland:cs0 state:D stack:0 pid:1517 tgid:1338 ppid:1282 flags:0x00004002 [ 242.837878] Call Trace: [ 242.837880] <TASK> [ 242.837883] __schedule+0x3e0/0xb10 [ 242.837890] schedule+0x31/0x120 [ 242.837894] schedule_preempt_disabled+0x1c/0x30 [ 242.837897] __mutex_lock.constprop.0+0x386/0x6e0 [ 242.837902] ? srso_return_thunk+0x5/0x5f [ 242.837905] ? __timer_delete_sync+0x81/0xe0 [ 242.837911] __mutex_lock_slowpath+0x13/0x20 [ 242.837915] mutex_lock+0x3b/0x50 [ 242.837919] amdgpu_userqueue_ensure_ev_fence+0x35/0xb0 [amdgpu] [ 242.838138] amdgpu_userq_signal_ioctl+0x959/0xec0 [amdgpu] [ 242.838340] ? __pfx_amdgpu_userq_signal_ioctl+0x10/0x10 [amdgpu] [ 242.838531] drm_ioctl_kernel+0xae/0x100 [drm] [ 242.838559] drm_ioctl+0x2a1/0x500 [drm] [ 242.838580] ? __pfx_amdgpu_userq_signal_ioctl+0x10/0x10 [amdgpu] [ 242.838778] ? srso_return_thunk+0x5/0x5f [ 242.838783] ? srso_return_thunk+0x5/0x5f [ 242.838786] ? _raw_spin_unlock_irqrestore+0x2b/0x50 [ 242.838791] amdgpu_drm_ioctl+0x4f/0x90 [amdgpu] [ 242.838967] __x64_sys_ioctl+0x99/0xd0 [ 242.838972] x64_sys_call+0x1209/0x20d0 [ 242.838975] do_syscall_64+0x51/0x120 [ 242.838979] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 242.838982] RIP: 0033:0x7f9118b1a94f [ 242.838985] RSP: 002b:00007f910cdff760 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 242.838989] RAX: ffffffffffffffda RBX: 00007f910cdff910 RCX: 00007f9118b1a94f [ 242.838991] RDX: 00007f910cdff910 RSI: 00000000c0306457 RDI: 000000000000000c [ 242.838993] RBP: 00007f910cdff7e0 R08: 0000000000000000 R09: 0000000000000001 [ 242.838995] R10: 00007f910cdff9d4 R11: 0000000000000246 R12: 00007f910ce00640 [ 242.838997] R13: 00000000c0306457 R14: 000000000000000c R15: 00007fff9dd11d10 [ 242.839004] </TASK> v2: Addressed review comemnts from Christian. v3/v4: Addressed review comemnts from Christian. - Move drm_exec drm_exec loop after userq fence create. - cleanup the newly created userq fence in case of error. v5 - Addressed review comemnts from Christian. - Create a new amdgpu_userq_fence_alloc() function for allocation. - Calling dma_fence_put for cleanup procedure. - make amdgpu_userq_fence_create() function static. - drm_exec_init is called after mutex_unlock. Cc: Alex Deucher <[email protected]> Cc: Christian König <[email protected]> Cc: Shashank Sharma <[email protected]> Reviewed-by: Christian König <[email protected]> Signed-off-by: Arvind Yadav <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 0494a5a commit c50b2e2

File tree

3 files changed

+48
-28
lines changed

3 files changed

+48
-28
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -197,22 +197,25 @@ void amdgpu_userq_fence_driver_put(struct amdgpu_userq_fence_driver *fence_drv)
197197
kref_put(&fence_drv->refcount, amdgpu_userq_fence_driver_destroy);
198198
}
199199

200-
int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq,
201-
u64 seq, struct dma_fence **f)
200+
#ifdef CONFIG_DRM_AMDGPU_NAVI3X_USERQ
201+
static int amdgpu_userq_fence_alloc(struct amdgpu_userq_fence **userq_fence)
202+
{
203+
*userq_fence = kmem_cache_alloc(amdgpu_userq_fence_slab, GFP_ATOMIC);
204+
return *userq_fence ? 0 : -ENOMEM;
205+
}
206+
207+
static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq,
208+
struct amdgpu_userq_fence *userq_fence,
209+
u64 seq, struct dma_fence **f)
202210
{
203211
struct amdgpu_userq_fence_driver *fence_drv;
204-
struct amdgpu_userq_fence *userq_fence;
205212
struct dma_fence *fence;
206213
unsigned long flags;
207214

208215
fence_drv = userq->fence_drv;
209216
if (!fence_drv)
210217
return -EINVAL;
211218

212-
userq_fence = kmem_cache_alloc(amdgpu_userq_fence_slab, GFP_ATOMIC);
213-
if (!userq_fence)
214-
return -ENOMEM;
215-
216219
spin_lock_init(&userq_fence->lock);
217220
INIT_LIST_HEAD(&userq_fence->link);
218221
fence = &userq_fence->base;
@@ -266,6 +269,7 @@ int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq,
266269

267270
return 0;
268271
}
272+
#endif
269273

270274
static const char *amdgpu_userq_fence_get_driver_name(struct dma_fence *f)
271275
{
@@ -383,6 +387,11 @@ static int amdgpu_userq_fence_read_wptr(struct amdgpu_usermode_queue *queue,
383387
return r;
384388
}
385389

390+
static void amdgpu_userq_fence_cleanup(struct dma_fence *fence)
391+
{
392+
dma_fence_put(fence);
393+
}
394+
386395
int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
387396
struct drm_file *filp)
388397
{
@@ -392,6 +401,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
392401
struct drm_gem_object **gobj_write = NULL;
393402
struct drm_gem_object **gobj_read = NULL;
394403
struct amdgpu_usermode_queue *queue;
404+
struct amdgpu_userq_fence *userq_fence;
395405
struct drm_syncobj **syncobj = NULL;
396406
u32 *bo_handles_write, num_write_bo_handles;
397407
u32 *syncobj_handles, num_syncobj_handles;
@@ -475,38 +485,49 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
475485
goto put_gobj_write;
476486
}
477487

488+
r = amdgpu_userq_fence_read_wptr(queue, &wptr);
489+
if (r)
490+
goto put_gobj_write;
491+
492+
r = amdgpu_userq_fence_alloc(&userq_fence);
493+
if (r)
494+
goto put_gobj_write;
495+
496+
/* We are here means UQ is active, make sure the eviction fence is valid */
497+
amdgpu_userqueue_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
498+
499+
/* Create a new fence */
500+
r = amdgpu_userq_fence_create(queue, userq_fence, wptr, &fence);
501+
if (r) {
502+
mutex_unlock(&userq_mgr->userq_mutex);
503+
kmem_cache_free(amdgpu_userq_fence_slab, userq_fence);
504+
goto put_gobj_write;
505+
}
506+
507+
dma_fence_put(queue->last_fence);
508+
queue->last_fence = dma_fence_get(fence);
509+
mutex_unlock(&userq_mgr->userq_mutex);
510+
478511
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT,
479512
(num_read_bo_handles + num_write_bo_handles));
480513

481514
/* Lock all BOs with retry handling */
482515
drm_exec_until_all_locked(&exec) {
483516
r = drm_exec_prepare_array(&exec, gobj_read, num_read_bo_handles, 1);
484517
drm_exec_retry_on_contention(&exec);
485-
if (r)
518+
if (r) {
519+
amdgpu_userq_fence_cleanup(fence);
486520
goto exec_fini;
521+
}
487522

488523
r = drm_exec_prepare_array(&exec, gobj_write, num_write_bo_handles, 1);
489524
drm_exec_retry_on_contention(&exec);
490-
if (r)
525+
if (r) {
526+
amdgpu_userq_fence_cleanup(fence);
491527
goto exec_fini;
528+
}
492529
}
493530

494-
r = amdgpu_userq_fence_read_wptr(queue, &wptr);
495-
if (r)
496-
goto exec_fini;
497-
498-
/* Create a new fence */
499-
r = amdgpu_userq_fence_create(queue, wptr, &fence);
500-
if (r)
501-
goto exec_fini;
502-
503-
/* We are here means UQ is active, make sure the eviction fence is valid */
504-
amdgpu_userqueue_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
505-
506-
dma_fence_put(queue->last_fence);
507-
queue->last_fence = dma_fence_get(fence);
508-
mutex_unlock(&userq_mgr->userq_mutex);
509-
510531
for (i = 0; i < num_read_bo_handles; i++) {
511532
if (!gobj_read || !gobj_read[i]->resv)
512533
continue;

drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ struct amdgpu_userq_fence_driver {
6161

6262
int amdgpu_userq_fence_slab_init(void);
6363
void amdgpu_userq_fence_slab_fini(void);
64-
int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq,
65-
u64 seq, struct dma_fence **f);
64+
6665
void amdgpu_userq_fence_driver_get(struct amdgpu_userq_fence_driver *fence_drv);
6766
void amdgpu_userq_fence_driver_put(struct amdgpu_userq_fence_driver *fence_drv);
6867
int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,

drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ amdgpu_userqueue_validate_bos(struct amdgpu_userq_mgr *uq_mgr)
455455
bool clear, unlock;
456456
int ret = 0;
457457

458-
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES | DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
458+
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
459459
drm_exec_until_all_locked(&exec) {
460460
ret = amdgpu_vm_lock_pd(vm, &exec, 2);
461461
drm_exec_retry_on_contention(&exec);

0 commit comments

Comments
 (0)