mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-23 15:26:50 -04:00
accel/rocket: Fix error path handling in rocket_job_run()
In rocket_job_run(), after taking an extra fence reference for
job->done_fence via dma_fence_get(), the error paths have three bugs:
- The dma_fence reference held by job->done_fence is never released,
causing a reference leak.
- pm_runtime_get_sync() increments the usage counter even on failure,
but the error path does not decrement it, leaking the runtime PM
reference and preventing the NPU from suspending.
- A valid but unsignaled fence is returned to the DRM scheduler,
which triggers WARN("Fence ... released with pending signals!")
when the scheduler drops its reference.
Fix by replacing pm_runtime_get_sync() with pm_runtime_resume_and_get()
which auto-balances the usage counter on failure, releasing both fence
references on error, and returning ERR_PTR(ret) instead of the
unsignaled fence.
Cc: stable@vger.kernel.org
Fixes: 0810d5ad88 ("accel/rocket: Add job submission IOCTL")
Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Link: https://lore.kernel.org/r/20260610071045.3414828-1-zhaojinming@uniontech.com
[tomeu: Refactored error paths to use consolidated goto labels]
Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
This commit is contained in:
committed by
Tomeu Vizoso
parent
a85402bff2
commit
9b2dedadf6
@@ -317,13 +317,13 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job)
|
||||
dma_fence_put(job->done_fence);
|
||||
job->done_fence = dma_fence_get(fence);
|
||||
|
||||
ret = pm_runtime_get_sync(core->dev);
|
||||
ret = pm_runtime_resume_and_get(core->dev);
|
||||
if (ret < 0)
|
||||
return fence;
|
||||
goto err_put_fences;
|
||||
|
||||
ret = iommu_attach_group(job->domain->domain, core->iommu_group);
|
||||
if (ret < 0)
|
||||
return fence;
|
||||
goto err_put_pm;
|
||||
|
||||
scoped_guard(mutex, &core->job_lock) {
|
||||
core->in_flight_job = job;
|
||||
@@ -331,6 +331,14 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job)
|
||||
}
|
||||
|
||||
return fence;
|
||||
|
||||
err_put_pm:
|
||||
pm_runtime_put(core->dev);
|
||||
err_put_fences:
|
||||
dma_fence_put(job->done_fence);
|
||||
job->done_fence = NULL;
|
||||
dma_fence_put(fence);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void rocket_job_handle_irq(struct rocket_core *core)
|
||||
|
||||
Reference in New Issue
Block a user