diff options
author | Matthew Brost <[email protected]> | 2024-01-24 13:08:11 -0800 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2024-01-26 12:46:36 +1000 |
commit | 66dbd9004a55073c5931f5f65f5fe2bbd414bdaa (patch) | |
tree | 6306cc89d266527151966ddba653ece11379b1f3 | |
parent | 77fe8f195737056e26b84a4d7fbe693587ab887e (diff) |
drm/sched: Drain all entities in DRM sched run job worker
All entities must be drained in the DRM scheduler run job worker to
avoid the following case. An entity found that is ready, no job found
ready on entity, and run job worker goes idle with other entities + jobs
ready. Draining all ready entities (i.e. loop over all ready entities)
in the run job worker ensures all job that are ready will be scheduled.
Cc: Thorsten Leemhuis <[email protected]>
Reported-by: Mikhail Gavrilov <[email protected]>
Closes: https://lore.kernel.org/all/CABXGCsM2VLs489CH-vF-1539-s3in37=bwuOWtoeeE+q26zE+Q@mail.gmail.com/
Reported-and-tested-by: Mario Limonciello <[email protected]>
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3124
Link: https://lore.kernel.org/all/[email protected]/
Reported-and-tested-by: Vlastimil Babka <[email protected]>
Closes: https://lore.kernel.org/dri-devel/[email protected]/T/#m0c31d4d1b9ae9995bb880974c4f1dbaddc33a48a
Signed-off-by: Matthew Brost <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
-rw-r--r-- | drivers/gpu/drm/scheduler/sched_main.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 550492a7a031..85f082396d42 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -1178,21 +1178,20 @@ static void drm_sched_run_job_work(struct work_struct *w) struct drm_sched_entity *entity; struct dma_fence *fence; struct drm_sched_fence *s_fence; - struct drm_sched_job *sched_job; + struct drm_sched_job *sched_job = NULL; int r; if (READ_ONCE(sched->pause_submit)) return; - entity = drm_sched_select_entity(sched); + /* Find entity with a ready job */ + while (!sched_job && (entity = drm_sched_select_entity(sched))) { + sched_job = drm_sched_entity_pop_job(entity); + if (!sched_job) + complete_all(&entity->entity_idle); + } if (!entity) - return; - - sched_job = drm_sched_entity_pop_job(entity); - if (!sched_job) { - complete_all(&entity->entity_idle); return; /* No more work */ - } s_fence = sched_job->s_fence; |