| From stable+bounces-165106-greg=kroah.com@vger.kernel.org Tue Jul 29 19:15:19 2025 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 29 Jul 2025 13:14:55 -0400 |
| Subject: drm/sched: Remove optimization that causes hang when killing dependent jobs |
| To: stable@vger.kernel.org |
| Cc: "Lin.Cao" <lincao12@amd.com>, "Christian König" <christian.koenig@amd.com>, "Philipp Stanner" <phasta@kernel.org>, "Sasha Levin" <sashal@kernel.org> |
| Message-ID: <20250729171455.2825719-1-sashal@kernel.org> |
| |
| From: "Lin.Cao" <lincao12@amd.com> |
| |
| [ Upstream commit 15f77764e90a713ee3916ca424757688e4f565b9 ] |
| |
| When application A submits jobs and application B submits a job with a |
| dependency on A's fence, the normal flow wakes up the scheduler after |
| processing each job. However, the optimization in |
| drm_sched_entity_add_dependency_cb() uses a callback that only clears |
| dependencies without waking up the scheduler. |
| |
| When application A is killed before its jobs can run, the callback gets |
| triggered but only clears the dependency without waking up the scheduler, |
| causing the scheduler to enter sleep state and application B to hang. |
| |
| Remove the optimization by deleting drm_sched_entity_clear_dep() and its |
| usage, ensuring the scheduler is always woken up when dependencies are |
| cleared. |
| |
| Fixes: 777dbd458c89 ("drm/amdgpu: drop a dummy wakeup scheduler") |
| Cc: stable@vger.kernel.org # v4.6+ |
| Signed-off-by: Lin.Cao <lincao12@amd.com> |
| Reviewed-by: Christian König <christian.koenig@amd.com> |
| Signed-off-by: Philipp Stanner <phasta@kernel.org> |
| Link: https://lore.kernel.org/r/20250717084453.921097-1-lincao12@amd.com |
| [ adjusted context ] |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/scheduler/sched_entity.c | 23 ++--------------------- |
| 1 file changed, 2 insertions(+), 21 deletions(-) |
| |
| --- a/drivers/gpu/drm/scheduler/sched_entity.c |
| +++ b/drivers/gpu/drm/scheduler/sched_entity.c |
| @@ -328,19 +328,6 @@ void drm_sched_entity_destroy(struct drm |
| EXPORT_SYMBOL(drm_sched_entity_destroy); |
| |
| /** |
| - * drm_sched_entity_clear_dep - callback to clear the entities dependency |
| - */ |
| -static void drm_sched_entity_clear_dep(struct dma_fence *f, |
| - struct dma_fence_cb *cb) |
| -{ |
| - struct drm_sched_entity *entity = |
| - container_of(cb, struct drm_sched_entity, cb); |
| - |
| - entity->dependency = NULL; |
| - dma_fence_put(f); |
| -} |
| - |
| -/** |
| * drm_sched_entity_clear_dep - callback to clear the entities dependency and |
| * wake up scheduler |
| */ |
| @@ -350,7 +337,8 @@ static void drm_sched_entity_wakeup(stru |
| struct drm_sched_entity *entity = |
| container_of(cb, struct drm_sched_entity, cb); |
| |
| - drm_sched_entity_clear_dep(f, cb); |
| + entity->dependency = NULL; |
| + dma_fence_put(f); |
| drm_sched_wakeup(entity->rq->sched); |
| } |
| |
| @@ -426,13 +414,6 @@ static bool drm_sched_entity_add_depende |
| fence = dma_fence_get(&s_fence->scheduled); |
| dma_fence_put(entity->dependency); |
| entity->dependency = fence; |
| - if (!dma_fence_add_callback(fence, &entity->cb, |
| - drm_sched_entity_clear_dep)) |
| - return true; |
| - |
| - /* Ignore it when it is already scheduled */ |
| - dma_fence_put(fence); |
| - return false; |
| } |
| |
| if (!dma_fence_add_callback(entity->dependency, &entity->cb, |