summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Zhang <Jesse.Zhang@amd.com>2026-10-15 22:59:25 +0800
committerAlex Deucher <alexander.deucher@amd.com>2026-10-27 14:09:01 -0400
commitdf4d6d404d44bbc8fc850bc7f9f136a25dabf180 (patch)
treeb1eea0dfd67aec5eac82981ec5a4b749d5be4354
parent55ca06a52a0913c4baed24346b2e9ca57071c10b (diff)
downloadlinux-next-df4d6d404d44bbc8fc850bc7f9f136a25dabf180.tar.gz
linux-next-df4d6d404d44bbc8fc850bc7f9f136a25dabf180.zip
drm/amdgpu: drop the gang leader reference when freeing gang jobs
Every job of a gang except the leader holds a reference to the scheduled fence of the leader in job->gang_submit. Only amdgpu_job_free(), used for jobs which never ran, drops it, so for every gang submission which completes the scheduler fence of the leader, and with it its hardware fence, is leaked. amdgpu_job_free() in turn checks for the leader only after drm_sched_job_cleanup() cleared the scheduler fence, so a leader freed there drops a reference it never took. On navi31, 100 submissions of a GFX + COMPUTE gang grow the slab cache drm_sched_fence is merged into by 60 to 180 objects each time, while 100 GFX only submissions don't. Use amdgpu_job_free() for the jobs the scheduler frees too, and check for the gang leader there before drm_sched_job_cleanup() clears the scheduler fence. As the scheduler clears the entity of the jobs it picked up, check for the scheduler fence instead to tell whether the job needs cleaning up. Keep freeing the remaining IBs with amdgpu_job_free_resources() after drm_sched_job_cleanup(), so that it frees them with the hardware fence or right away and not with the scheduler fence, which nobody signals for jobs aborted after drm_sched_job_arm(), like a CS returning -EAGAIN. v2: unify amdgpu_job_free() and amdgpu_job_free_cb() (Christian), don't free the remaining IBs with the scheduler fence v3: drop the comments (Christian) v4: free the IBs with amdgpu_job_free_resources() again (Christian) Fixes: 68ce8b242242 ("drm/amdgpu: add gang submit backend v2") Fixes: f7d66fb2ea43 ("drm/amdgpu: cleanup scheduler job initialization v2") Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c24
1 files changed, 5 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 9cc210198fa4..8689a3c933b2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -313,22 +313,7 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
{
- struct amdgpu_job *job = to_amdgpu_job(s_job);
-
- drm_sched_job_cleanup(s_job);
-
- amdgpu_sync_free(&job->explicit_sync);
-
- if (dma_fence_was_initialized(&job->hw_fence->base))
- dma_fence_put(&job->hw_fence->base);
- else
- kfree(job->hw_fence);
- if (dma_fence_was_initialized(&job->hw_vm_fence->base))
- dma_fence_put(&job->hw_vm_fence->base);
- else
- kfree(job->hw_vm_fence);
-
- kfree(job);
+ amdgpu_job_free(to_amdgpu_job(s_job));
}
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
@@ -349,13 +334,14 @@ void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
void amdgpu_job_free(struct amdgpu_job *job)
{
- if (job->base.entity)
+ if (job->gang_submit != &job->base.s_fence->scheduled)
+ dma_fence_put(job->gang_submit);
+
+ if (job->base.s_fence)
drm_sched_job_cleanup(&job->base);
amdgpu_job_free_resources(job);
amdgpu_sync_free(&job->explicit_sync);
- if (job->gang_submit != &job->base.s_fence->scheduled)
- dma_fence_put(job->gang_submit);
if (dma_fence_was_initialized(&job->hw_fence->base))
dma_fence_put(&job->hw_fence->base);