From: "Christian König" <ckoenig.leichtzumerken@gmail.com>
To: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>,
amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
Hawking Zhang <Hawking.Zhang@amd.com>,
Alex Deucher <alexander.deucher@amd.com>
Cc: kernel-dev@igalia.com,
"Christian König" <christian.koenig@amd.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Danilo Krummrich" <dakr@kernel.org>,
"Philipp Stanner" <phasta@kernel.org>
Subject: Re: [PATCH 5/7] drm/amdgpu: Rework the amdgpu_job_stop_all_jobs_on_sched() hack
Date: Mon, 9 Nov 2026 15:54:15 +0100 [thread overview]
Message-ID: <52d41d99-90f0-40d1-828e-0456dad433b6@gmail.com> (raw)
In-Reply-To: <20261106145702.61640-6-tvrtko.ursulin@igalia.com>
On 11/6/26 15:57, Tvrtko Ursulin wrote:
> amdgpu_job_stop_all_jobs_on_sched is a semi broken hack used on only one
> platform which suffers from several problems as mentioned in
> https://lore.kernel.org/amd-gfx/44edde63-7181-44fb-a4f7-94e50514f539@amd.com/.
>
> Until it can be fully removed, given that it directly acceses DRM scheduler
> internals which want to be changed, we need to rework it to allow for
> replacing the SPSC queue with a standard spin locked list.
>
> Problem at hand is the lock inversion between the run-queue and entity
> lock which becomes apparent once locking is added to the job queue
> amdgpu_job_stop_all_jobs_on_sched().
>
> To work around it we change the approach of how queued jobs are drained by
> using trylock and restarting on locked entities until all queued jobs from
> all active entities are removed.
>
> This slightly widens the existing scope for a live lock in case of
> userspace actively submitting new jobs. Whereas the current code can keep
> processing the single busy entity, this new implementation can retry on the
> entities which it previously processed.
>
> Since userspace submitting jobs so rapidly the GPU reset cannot finish and
> the problem already exists, plus the plan is to remove this code
> altogether, we can say this is acceptable in order to unblock the DRM
> scheduler rework.
>
> While at it we add the assert scheduler workqueue has been stopped by the
> caller and also correct the wrong order of signalling already submitted
> and queued fences.
I think that is generally the wrong approach.
See function amdgpu_ras_need_emergency_restart() who triggers the behavior when returning true:
if (adev->asic_type == CHIP_VEGA20 &&
adev->pm.fw_version <= 0x283400) {
return !(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) &&
amdgpu_ras_intr_triggered();
}
return false;
So only on Vega 20 with an outdated power management FW version we use this hack to clean up the DRM scheduler jobs.
My educated guess is the code wasn't used in at least the last 5-6 years :)
I think we should rather completely remove the amdgpu_job_stop_all_jobs_on_sched() hack and just print a big warning in the system log when we detect an outdated firmware.
Hawking and Alex any objections to that?
Regards,
Christian.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
> References: https://lore.kernel.org/amd-gfx/44edde63-7181-44fb-a4f7-94e50514f539@amd.com/
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Hawking Zhang <Hawking.Zhang@amd.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Danilo Krummrich <dakr@kernel.org>
> Cc: Philipp Stanner <phasta@kernel.org>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 86 ++++++++++++++++++++-----
> 1 file changed, 69 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> index 8689a3c933b2..1f4a4a5a978d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> @@ -457,13 +457,6 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
> return fence;
> }
>
> -/*
> - * This is a duplicate function from DRM scheduler sched_internal.h.
> - * Plan is to remove it when amdgpu_job_stop_all_jobs_on_sched is removed, due
> - * latter being incorrect and racy.
> - *
> - * See https://lore.kernel.org/amd-gfx/44edde63-7181-44fb-a4f7-94e50514f539@amd.com/
> - */
> static struct drm_sched_job *
> drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
> {
> @@ -476,28 +469,66 @@ drm_sched_entity_queue_pop(struct drm_sched_entity *entity)
> return container_of(node, struct drm_sched_job, queue_node);
> }
>
> -void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
> +static struct drm_sched_entity *
> +get_entity_with_jobs(struct drm_gpu_scheduler *sched) __acquires(&entity->lock)
> {
> - struct drm_sched_job *s_job;
> - struct drm_sched_entity *s_entity = NULL;
> + struct drm_sched_entity *entity;
> int i;
>
> - /* Signal all jobs not yet scheduled */
> +retry:
> for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) {
> struct drm_sched_rq *rq = sched->sched_rq[i];
> +
> spin_lock(&rq->lock);
> - list_for_each_entry(s_entity, &rq->entities, list) {
> - while ((s_job = drm_sched_entity_queue_pop(s_entity))) {
> - struct drm_sched_fence *s_fence = s_job->s_fence;
> + list_for_each_entry(entity, &rq->entities, list) {
> + /*
> + * This can false negative, but so could the previous
> + * approach of scanning the run-queues once when
> + * nothing prevents userspace to queue more jobs.
> + */
> + if (!spsc_queue_count(&entity->job_queue))
> + continue;
>
> - dma_fence_signal(&s_fence->scheduled);
> - dma_fence_set_error(&s_fence->finished, -EHWPOISON);
> - dma_fence_signal(&s_fence->finished);
> + /*
> + * We must trylock because normal locking order is
> + * entity then rq and here we already have rq locked
> + * in order to be able to walk the entities.
> + */
> + if (spin_trylock(&entity->lock)) {
> + /* Returns with a locked entity. */
> + spin_unlock(&rq->lock);
> + return entity;
> + } else {
> + /*
> + * Busy entity - we will try again looking for a
> + * window where trylock will succeed.
> + */
> + spin_unlock(&rq->lock);
> + goto retry;
> }
> }
> spin_unlock(&rq->lock);
> }
>
> + return NULL;
> +}
> +
> +/*
> + * amdgpu_job_stop_all_jobs_on_sched has a single purpose which is an
> + * unreliable and racy, as described in:
> + * https://lore.kernel.org/amd-gfx/44edde63-7181-44fb-a4f7-94e50514f539@amd.com/.
> + *
> + * Plan is to remove it, together with the above open coded DRM scheduler
> + * helpers, and replace with a proper solution.
> + */
> +void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
> +{
> + struct drm_sched_job *s_job, *next;
> + struct drm_sched_entity *s_entity;
> + LIST_HEAD(queued);
> +
> + WARN_ON_ONCE(!sched->pause_submit);
> +
> /* Signal all jobs already scheduled to HW */
> list_for_each_entry(s_job, &sched->pending_list, list) {
> struct drm_sched_fence *s_fence = s_job->s_fence;
> @@ -505,6 +536,27 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
> dma_fence_set_error(&s_fence->finished, -EHWPOISON);
> dma_fence_signal(&s_fence->finished);
> }
> +
> + /*
> + * Signal all jobs not yet scheduled - note that the entity trylock loop
> + * can in theory livelock if userspace keeps submitting new jobs more
> + * rapidly than the loop can do a full pass over all run-queues and
> + * entities.
> + */
> + while ((s_entity = get_entity_with_jobs(sched)) != NULL) {
> + while ((s_job = drm_sched_entity_queue_pop(s_entity)))
> + list_add_tail(&s_job->list, &queued);
> + spin_unlock(&s_entity->lock);
> + }
> +
> + list_for_each_entry_safe(s_job, next, &queued, list) {
> + struct drm_sched_fence *s_fence = s_job->s_fence;
> +
> + list_del(&s_job->list);
> + dma_fence_signal(&s_fence->scheduled);
> + dma_fence_set_error(&s_fence->finished, -EHWPOISON);
> + dma_fence_signal(&s_fence->finished);
> + }
> }
>
> const struct drm_sched_backend_ops amdgpu_sched_ops = {
next prev parent reply other threads:[~2026-11-09 14:54 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 14:56 [PATCH 0/7] drm/sched: Replace SPSC queue with a list and spinlock Tvrtko Ursulin
2026-11-06 14:56 ` [PATCH 1/7] drm/sched: Disallow initializing entities with un-initialized schedulers Tvrtko Ursulin
2026-11-06 14:56 ` [PATCH 2/7] drm/sched: Ignore stopped entity attempt to change its run-queue Tvrtko Ursulin
2026-11-06 14:56 ` [PATCH 3/7] drm/sched: Replace completion with a flush Tvrtko Ursulin
2026-11-06 14:56 ` [PATCH 4/7] drm/sched: Remove the single scheduler special case Tvrtko Ursulin
2026-11-08 9:12 ` Sidong Yang
2026-11-09 1:49 ` Sidong Yang
2026-11-06 14:57 ` [PATCH 5/7] drm/amdgpu: Rework the amdgpu_job_stop_all_jobs_on_sched() hack Tvrtko Ursulin
2026-11-09 12:46 ` Philipp Stanner
2026-11-09 14:45 ` Tvrtko Ursulin
2026-11-09 14:54 ` Christian König [this message]
2026-11-06 14:57 ` [PATCH 6/7] drm/sched: Replace the SPSC queue with a list and a spinlock Tvrtko Ursulin
2026-11-10 15:49 ` Philipp Stanner
2026-11-12 12:59 ` Tvrtko Ursulin
2026-11-12 14:09 ` Philipp Stanner
2026-11-12 15:37 ` Tvrtko Ursulin
2026-11-06 14:57 ` [PATCH 7/7] drm/sched: Address the fence_seq fixme Tvrtko Ursulin
2026-11-09 10:21 ` [PATCH 0/7] drm/sched: Replace SPSC queue with a list and spinlock Philipp Stanner
2026-11-09 11:14 ` Tvrtko Ursulin
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=52d41d99-90f0-40d1-828e-0456dad433b6@gmail.com \
--to=ckoenig.leichtzumerken@gmail.com \
--cc=Hawking.Zhang@amd.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=christian.koenig@amd.com \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=kernel-dev@igalia.com \
--cc=matthew.brost@intel.com \
--cc=phasta@kernel.org \
--cc=simona@ffwll.ch \
--cc=tvrtko.ursulin@igalia.com \
/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.