From: "Christian König" <christian.koenig@amd.com>
To: moonafterrain@outlook.com,
"Alex Deucher" <alexander.deucher@amd.com>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Junwei Zhang" <Jerry.Zhang@amd.com>,
"Nicolai Hähnle" <nicolai.haehnle@amd.com>,
"Prike Liang" <Prike.Liang@amd.com>,
"Arvind Yadav" <arvind.yadav@amd.com>,
"Shashank Sharma" <shashank.sharma@amd.com>,
"Leo Liu" <leo.liu@amd.com>,
"Felix Kuehling" <Felix.Kuehling@amd.com>
Cc: amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
linaro-mm-sig@lists.linaro.org,
Yuhao Jiang <danisjiang@gmail.com>,
stable@vger.kernel.org
Subject: Re: [PATCH 3/5] drm/amdgpu/userq: bound the eviction fence rearm retry loop
Date: Mon, 10 Aug 2026 19:28:15 +0200 [thread overview]
Message-ID: <01a00d60-a3ae-44cf-a963-6baccdac32f1@amd.com> (raw)
In-Reply-To: <20260811-amdgpu-fixes-v1-3-4954a417b8ff@outlook.com>
On 8/10/26 18:13, Junrui Luo via B4 Relay wrote:
> From: Junrui Luo <moonafterrain@outlook.com>
>
> amdgpu_userq_ensure_ev_fence() loops until the eviction fence is both
> present and unsignaled. The only producer of such a fence is
> amdgpu_evf_mgr_rearm(), which runs as the very last step of
> amdgpu_userq_vm_validate(). Every failure point ahead of it - the
> kzalloc() in the rearm itself, amdgpu_hmm_range_alloc(), the
> ttm_bo_validate() calls, the GART binding of the wptr BOs - makes
> amdgpu_userq_restore_worker() give up with only a drm_file_err().
> Nothing propagates that back, so the waiting thread reschedules the
> worker and flushes it again, forever.
>
> Both flush_delayed_work() and mutex_lock() sleep in
> TASK_UNINTERRUPTIBLE, so the looping task cannot be killed and the OOM
> killer cannot reclaim it. An unprivileged render node client
> reaches this from both AMDGPU_USERQ and AMDGPU_USERQ_SIGNAL.
>
> The eviction fence sequence number is already bumped by every
> successful rearm, so use it as the loop's progress condition: if a
> completed flush of the restore worker did not move it then no rearm
> happened and retrying cannot help. Return -ENOMEM in that case and
> let both callers report it to userspace.
>
> Fixes: a242a3e4b5be ("drm/amdgpu: simplify eviction fence suspend/resume")
> Reported-by: Yuhao Jiang <danisjiang@gmail.com>
> Assisted-by: Claude:claude-opus-5
> Cc: stable@vger.kernel.org
> Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Absolutely clear NAK!
This functions needs to loop forever should the rearm worker fails to re-arm the fence.
The only thing which could potentially get out of that is to kill the process or maybe that the eviction fence is signaled with an error.
Regards,
Christian.
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 21 +++++++++++++++++++--
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 4 ++--
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 10 +++++++++-
> 3 files changed, 30 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index bec107216811..208b53ae5bd1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -448,12 +448,16 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue)
> * Ensures that a valid and not yet signaled eviction fence is attached to the
> * usermode queue before any queue operations proceed. If it is signalled, then
> * rearm a new eviction fence.
> + *
> + * Returns 0 with @uq_mgr->userq_mutex held, or -ENOMEM with the mutex released
> + * when the restore worker could not rearm the fence.
> */
> -void
> +int
> amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
> struct amdgpu_eviction_fence_mgr *evf_mgr)
> {
> struct dma_fence *ev_fence;
> + int seq, prev_seq = -1;
>
> retry:
> /* Flush any pending resume work to create ev_fence */
> @@ -463,7 +467,16 @@ amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
> ev_fence = amdgpu_evf_mgr_get_fence(evf_mgr);
> if (dma_fence_is_signaled(ev_fence)) {
> dma_fence_put(ev_fence);
> + seq = atomic_read(&evf_mgr->ev_fence_seq);
> mutex_unlock(&uq_mgr->userq_mutex);
> + /*
> + * The sequence number is only bumped by a successful rearm, so
> + * if the flush above ran the worker without moving it then the
> + * restore failed and looping again would never terminate.
> + */
> + if (seq == prev_seq)
> + return -ENOMEM;
> + prev_seq = seq;
> /*
> * Looks like there was no pending resume work,
> * add one now to create a valid eviction fence
> @@ -472,6 +485,8 @@ amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
> goto retry;
> }
> dma_fence_put(ev_fence);
> +
> + return 0;
> }
>
>
> @@ -747,7 +762,9 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
> if (r)
> goto clean_mqd;
>
> - amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
> + r = amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
> + if (r)
> + goto erase_doorbell;
>
> /* don't map the queue if scheduling is halted */
> if (!adev->userq_halt_for_enforce_isolation ||
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> index 6412a7f7b6ef..c35909bf7ceb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> @@ -164,8 +164,8 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);
>
> void amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr);
>
> -void amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *userq_mgr,
> - struct amdgpu_eviction_fence_mgr *evf_mgr);
> +int amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *userq_mgr,
> + struct amdgpu_eviction_fence_mgr *evf_mgr);
>
> u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev);
> bool amdgpu_userq_enabled(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> index 7e80442ec3e5..1c287ce59736 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> @@ -523,7 +523,15 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
> goto put_queue;
>
> /* We are here means UQ is active, make sure the eviction fence is valid */
> - amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
> + r = amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
> + if (r) {
> + /* The fence is not initialized yet, so unwind it by hand */
> + amdgpu_userq_fence_put_fence_drv_array(fence);
> + amdgpu_userq_fence_driver_put(fence->fence_drv);
> + kvfree(fence->fence_drv_array);
> + kfree(fence);
> + goto put_queue;
> + }
>
> /* Create the new fence */
> amdgpu_userq_fence_init(queue, fence, wptr);
>
next prev parent reply other threads:[~2026-08-10 17:28 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 16:13 [PATCH 0/5] drm/amdgpu: five independent fixes in the KMS, userq, UVD and CS paths Junrui Luo via B4 Relay
2026-08-10 16:13 ` Junrui Luo
2026-08-10 16:13 ` [PATCH 1/5] drm/amdgpu: free prt_va on the open_kms error path Junrui Luo via B4 Relay
2026-08-10 16:13 ` Junrui Luo
2026-08-10 16:31 ` sashiko-bot
2026-08-10 16:13 ` [PATCH 2/5] drm/amdgpu: reject PRT mappings as user queue buffer VAs Junrui Luo via B4 Relay
2026-08-10 16:13 ` Junrui Luo
2026-08-10 16:33 ` sashiko-bot
2026-08-10 16:13 ` [PATCH 3/5] drm/amdgpu/userq: bound the eviction fence rearm retry loop Junrui Luo via B4 Relay
2026-08-10 16:13 ` Junrui Luo
2026-08-10 16:35 ` sashiko-bot
2026-08-10 17:28 ` Christian König [this message]
2026-08-10 16:13 ` [PATCH 4/5] drm/amdgpu: enforce UVD handle ownership on destroy Junrui Luo via B4 Relay
2026-08-10 16:13 ` Junrui Luo
2026-08-10 16:29 ` sashiko-bot
2026-08-10 16:13 ` [PATCH 5/5] drm/amdgpu: free userptr HMM ranges on the CS error path Junrui Luo via B4 Relay
2026-08-10 16:13 ` Junrui Luo
2026-08-10 16:30 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=01a00d60-a3ae-44cf-a963-6baccdac32f1@amd.com \
--to=christian.koenig@amd.com \
--cc=Felix.Kuehling@amd.com \
--cc=Jerry.Zhang@amd.com \
--cc=Prike.Liang@amd.com \
--cc=airlied@gmail.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=arvind.yadav@amd.com \
--cc=danisjiang@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=leo.liu@amd.com \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=moonafterrain@outlook.com \
--cc=nicolai.haehnle@amd.com \
--cc=shashank.sharma@amd.com \
--cc=simona@ffwll.ch \
--cc=stable@vger.kernel.org \
--cc=sumit.semwal@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.