Skip to content

Commit 487df8b

Browse files
peppsacPhilipp Stanner
authored andcommitted
drm/sched: Fix deadlock in drm_sched_entity_kill_jobs_cb
The Mesa issue referenced below pointed out a possible deadlock: [ 1231.611031] Possible interrupt unsafe locking scenario: [ 1231.611033] CPU0 CPU1 [ 1231.611034] ---- ---- [ 1231.611035] lock(&xa->xa_lock#17); [ 1231.611038] local_irq_disable(); [ 1231.611039] lock(&fence->lock); [ 1231.611041] lock(&xa->xa_lock#17); [ 1231.611044] <Interrupt> [ 1231.611045] lock(&fence->lock); [ 1231.611047] *** DEADLOCK *** In this example, CPU0 would be any function accessing job->dependencies through the xa_* functions that don't disable interrupts (eg: drm_sched_job_add_dependency(), drm_sched_entity_kill_jobs_cb()). CPU1 is executing drm_sched_entity_kill_jobs_cb() as a fence signalling callback so in an interrupt context. It will deadlock when trying to grab the xa_lock which is already held by CPU0. Replacing all xa_* usage by their xa_*_irq counterparts would fix this issue, but Christian pointed out another issue: dma_fence_signal takes fence.lock and so does dma_fence_add_callback. dma_fence_signal() // locks f1.lock -> drm_sched_entity_kill_jobs_cb() -> foreach dependencies -> dma_fence_add_callback() // locks f2.lock This will deadlock if f1 and f2 share the same spinlock. To fix both issues, the code iterating on dependencies and re-arming them is moved out to drm_sched_entity_kill_jobs_work(). Cc: [email protected] # v6.2+ Fixes: 2fdb8a8 ("drm/scheduler: rework entity flush, kill and fini") Link: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13908 Reported-by: Mikhail Gavrilov <[email protected]> Suggested-by: Christian König <[email protected]> Reviewed-by: Christian König <[email protected]> Signed-off-by: Pierre-Eric Pelloux-Prayer <[email protected]> [phasta: commit message nits] Signed-off-by: Philipp Stanner <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent b4cd8f9 commit 487df8b

1 file changed

Lines changed: 19 additions & 15 deletions

File tree

drivers/gpu/drm/scheduler/sched_entity.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -173,26 +173,15 @@ int drm_sched_entity_error(struct drm_sched_entity *entity)
173173
}
174174
EXPORT_SYMBOL(drm_sched_entity_error);
175175

176+
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
177+
struct dma_fence_cb *cb);
178+
176179
static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
177180
{
178181
struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
179-
180-
drm_sched_fence_scheduled(job->s_fence, NULL);
181-
drm_sched_fence_finished(job->s_fence, -ESRCH);
182-
WARN_ON(job->s_fence->parent);
183-
job->sched->ops->free_job(job);
184-
}
185-
186-
/* Signal the scheduler finished fence when the entity in question is killed. */
187-
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
188-
struct dma_fence_cb *cb)
189-
{
190-
struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
191-
finish_cb);
182+
struct dma_fence *f;
192183
unsigned long index;
193184

194-
dma_fence_put(f);
195-
196185
/* Wait for all dependencies to avoid data corruptions */
197186
xa_for_each(&job->dependencies, index, f) {
198187
struct drm_sched_fence *s_fence = to_drm_sched_fence(f);
@@ -220,6 +209,21 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
220209
dma_fence_put(f);
221210
}
222211

212+
drm_sched_fence_scheduled(job->s_fence, NULL);
213+
drm_sched_fence_finished(job->s_fence, -ESRCH);
214+
WARN_ON(job->s_fence->parent);
215+
job->sched->ops->free_job(job);
216+
}
217+
218+
/* Signal the scheduler finished fence when the entity in question is killed. */
219+
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
220+
struct dma_fence_cb *cb)
221+
{
222+
struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
223+
finish_cb);
224+
225+
dma_fence_put(f);
226+
223227
INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
224228
schedule_work(&job->work);
225229
}

0 commit comments

Comments
 (0)