AMD General
Regards,
Prike
> -----Original Message-----
> From: Koenig, Christian <[email protected]>
> Sent: Friday, September 11, 2026 5:45 PM
> To: Liang, Prike <[email protected]>; [email protected]
> Cc: Deucher, Alexander <[email protected]>; Pelloux-Prayer, Pierre-
> Eric <[email protected]>
> Subject: Re: [PATCH 5/5] drm/amdgpu: mark queue and process as guilty on
> resetting userq fault
>
> On 9/11/26 10:22, Prike Liang wrote:
> > When a queue encounters a reset error and fallback to device reset,
> > mark both the queue and its owning process as guilty so that userspace
> > is notified that the offending queue is no longer usable and should
> > recreate the context before resubmitting work.
> >
> > Signed-off-by: Prike Liang <[email protected]>
> > ---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 4 +++-
> > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 24
> > ++++++++++++++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h |
> > 5 ++++-
> > 3 files changed, 28 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> > index b15ed4a534f1..038d18faf344 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> > @@ -589,7 +589,9 @@ static int amdgpu_ctx_query2(struct amdgpu_device
> *adev,
> > if (ctx->generation != amdgpu_vm_generation(adev, &fpriv->vm))
> > out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
> >
> > - if (amdgpu_ctx_guilty(ctx))
> > + if (amdgpu_ctx_guilty(ctx) ||
> > + ((out->state.flags & AMDGPU_CTX_QUERY2_FLAGS_RESET) &&
> > + fpriv->userq_mgr.guilty))
> > out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
> >
> > if (amdgpu_in_reset(adev))
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > index 6c92575213c1..7098d550c0ee 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > @@ -173,8 +173,12 @@ static void amdgpu_userq_hang_detect_work(struct
> work_struct *work)
> > * Don't schedule the work here! Scheduling or queue work from one reset
> > * handler to another is illegal if you don't take extra precautions!
> > */
> > - if (gpu_reset)
> > + if (gpu_reset) {
> > + /* Block re-map until userspace recreates the queue. */
> > + queue->guilty = true;
> > + queue->userq_mgr->guilty = true;
>
> Clear NAK to having a global guilty flag in the userq_mgr. Each queue should
> be
> handled completely separated.
Yes, if a hung user queue can be successfully recovered via per-queue reset,
the kernel should handle each affected user queue independently and resume
normal execution.
But, if the guilty user queue cannot be recovered through per-queue reset, the
driver will fall back to a device-level reset (i.e., Mode-1 reset). In this
case, all user queue contexts will be lost, and this patch is to mark the
guilty queue's process accordingly and report the fault to user space so it can
recreate and resubmit the affected user queues for the context lost cases.
Thanks,
Prike
> The only case where that makes sense would be gang submitted queues, but we
> haven't implemented those.
>
> Regards,
> Christian.
>
> > amdgpu_userq_mgr_reset_work(&queue->userq_mgr->reset_work);
> > + }
> > }
> >
> > /*
> > @@ -389,8 +393,17 @@ static int amdgpu_userq_map_helper(struct
> amdgpu_usermode_queue *queue)
> > int r;
> >
> > if (queue->state == AMDGPU_USERQ_STATE_UNMAPPED) {
> > - trace_amdgpu_userq_state_start(queue);
> >
> > + if (queue->guilty) {
> > + /*
> > + * A queue that was reset for hanging must not be
> > + * re-mapped: replaying its command stream faults
> > + * again. Leave it unmapped for userspace to recreate.
> > + */
> > + return 0;
> > + }
> > +
> > + trace_amdgpu_userq_state_start(queue);
> > r = userq_funcs->map(queue);
> > if (r) {
> > trace_amdgpu_userq_state_changed(queue,
> AMDGPU_USERQ_STATE_HUNG);
> > @@ -833,7 +846,8 @@ amdgpu_userq_query_status(struct drm_file *filp, union
> drm_amdgpu_userq *args)
> > args->out_qs.flags = 0;
> > if (queue->state == AMDGPU_USERQ_STATE_HUNG)
> > args->out_qs.flags |=
> AMDGPU_USERQ_QUERY_STATUS_FLAGS_HUNG;
> > - if (queue->generation != amdgpu_vm_generation(adev, &fpriv->vm))
> > + if (queue->generation != amdgpu_vm_generation(adev, &fpriv->vm) ||
> > + fpriv->userq_mgr.guilty)
> > args->out_qs.flags |=
> AMDGPU_USERQ_QUERY_STATUS_FLAGS_VRAMLOST;
> > if (queue->state == AMDGPU_USERQ_STATE_INVALID_VA)
> > args->out_qs.flags |=
> AMDGPU_USERQ_QUERY_STATUS_FLAGS_INVALID_VA;
> > @@ -1594,6 +1608,10 @@ int amdgpu_userq_post_reset(struct amdgpu_device
> *adev, bool vram_lost)
> > int ret = 0, r;
> >
> > xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) {
> > + /* Guilty queues are not restored; userspace recreates them. */
> > + if (queue->guilty)
> > + continue;
> > +
> > if (queue->state == AMDGPU_USERQ_STATE_HUNG
> && !vram_lost) {
> > trace_amdgpu_userq_state_start(queue);
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > index 40228c60a1ea..f2eca744a3c5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> > @@ -51,6 +51,8 @@ struct amdgpu_userq_obj { struct
> > amdgpu_usermode_queue {
> > int queue_type;
> > enum amdgpu_userq_state state;
> > + /* Reset due to a hang; must not be re-mapped, userspace recreates. */
> > + bool guilty;
> > uint64_t doorbell_handle;
> > uint64_t doorbell_index;
> > u32 doorbell_offset;
> > @@ -132,7 +134,8 @@ struct amdgpu_userq_mgr {
> > struct drm_file *file;
> > struct mutex proc_ctx_lock;
> > struct amdgpu_userq_obj proc_ctx_obj;
> > -
> > + /* Set when any queue owned by this process is reset guilty */
> > + bool guilty;
> > bool proc_ctx_allocated;
> > uint32_t proc_ctx_array_index;
> > /**