drm/amdgpu: Fix display freezing issue when resizing apps
authorArvind Yadav <Arvind.Yadav@amd.com>
Tue, 18 Mar 2025 13:15:40 +0000 (18:45 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 8 Apr 2025 20:48:21 +0000 (16:48 -0400)
The display is freezing because the amdgpu_userq_wait_ioctl()
is waiting for a non-user queue fence(specifically, the PT update fence).

RootCause:
The resume_work is initiated by both amdgpu_userq_suspend and
amdgpu_userqueue_ensure_ev_fence at same time. The amdgpu_userq_suspend
signals a dma-fence and subsequently triggers the resume_work, which is
intended to replace the existing fence by creating new dma-fence. However,
following this, the amdgpu_userqueue_ensure_ev_fence schedules another
resume_work that generates a new dma-fence, thereby replacing the one
created by amdgpu_userq_suspend. Consequently, the original fence will
never be signaled.

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Shashank Sharma <shashank.sharma@amd.com>
Cc: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c

index 167951aee502d223de0ec85d7ecef2a37d297139..0075469550b06abf03c5d1c2bc0e882fb47f4545 100644 (file)
@@ -52,6 +52,9 @@ amdgpu_eviction_fence_replace_fence(struct amdgpu_eviction_fence_mgr *evf_mgr,
        unsigned long index;
        int ret;
 
+       if (evf_mgr->ev_fence &&
+           !dma_fence_is_signaled(&evf_mgr->ev_fence->base))
+               return 0;
        /*
         * Steps to replace eviction fence:
         * * lock all objects in exec (caller)
index a02614cbda36e29bc8505dcaaed4316f23f72bb2..beae931152a3cdd1fd7421168a514a6972d041f6 100644 (file)
@@ -555,8 +555,11 @@ unlock_all:
 static void amdgpu_userqueue_resume_worker(struct work_struct *work)
 {
        struct amdgpu_userq_mgr *uq_mgr = work_to_uq_mgr(work, resume_work.work);
+       struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr);
        int ret;
 
+       flush_work(&fpriv->evf_mgr.suspend_work.work);
+
        mutex_lock(&uq_mgr->userq_mutex);
 
        ret = amdgpu_userqueue_validate_bos(uq_mgr);