Skip to content

Commit

Permalink
drm/scheduler: Clean up jobs when the scheduler is torn down.
Browse files Browse the repository at this point in the history
drm_sched_fini() currently leaves any pending jobs dangling, which
causes segfaults and other badness when job completion fences are
signaled after the scheduler is torn down.

Explicitly detach all jobs from their completion callbacks and free
them. This makes it possible to write a sensible safe abstraction for
drm_sched, without having to externally duplicate the tracking of
in-flight jobs.

This shouldn't regress any existing drivers, since calling
drm_sched_fini() with any pending jobs is broken and this change should
be a no-op if there are no pending jobs.

Signed-off-by: Asahi Lina <[email protected]>
  • Loading branch information
asahilina committed May 10, 2024
1 parent 2c8cad7 commit 3ad18c1
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions drivers/gpu/drm/scheduler/sched_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,8 +1336,33 @@ EXPORT_SYMBOL(drm_sched_init);
void drm_sched_fini(struct drm_gpu_scheduler *sched)
{
struct drm_sched_entity *s_entity;
struct drm_sched_job *s_job, *tmp;
int i;

/*
* Stop the scheduler, detaching all jobs from their hardware callbacks
* and cleaning up complete jobs.
*/
drm_sched_stop(sched, NULL);

/*
* Iterate through the pending job list and free all jobs.
* This assumes the driver has either guaranteed jobs are already stopped, or that
* otherwise it is responsible for keeping any necessary data structures for
* in-progress jobs alive even when the free_job() callback is called early (e.g. by
* putting them in its own queue or doing its own refcounting).
*/
list_for_each_entry_safe(s_job, tmp, &sched->pending_list, list) {
spin_lock(&sched->job_list_lock);
list_del_init(&s_job->list);
spin_unlock(&sched->job_list_lock);

drm_sched_fence_finished(s_job->s_fence, -ESRCH);

WARN_ON(s_job->s_fence->parent);
sched->ops->free_job(s_job);
}

drm_sched_wqueue_stop(sched);

for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) {
Expand Down

0 comments on commit 3ad18c1

Please sign in to comment.