mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
accel: ethosu: Fix job submit error clean-up refcount underflows
If the job submit fails before adding the job to the scheduler queue
such as when the GEM buffer bounds checks fail, then doing a
ethosu_job_put() results in a pm_runtime_put_autosuspend() without the
corresponding pm_runtime_resume_and_get(). The dma_fence_put()'s are
also unnecessary, but seem to be harmless.
Split the ethosu_job_cleanup() function into 2 parts for the before
and after the job is queued.
Fixes: 5a5e9c0228 ("accel: Add Arm Ethos-U NPU driver")
Reviewed-and-Tested-by: Anders Roxell <anders.roxell@linaro.org>
Link: https://patch.msgid.link/20260218-ethos-fixes-v1-1-be3fa3ea9a30@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
This commit is contained in:
parent
d5b8b0347f
commit
150bceb3e0
1 changed files with 19 additions and 9 deletions
|
|
@ -143,17 +143,10 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ethosu_job_cleanup(struct kref *ref)
|
||||
static void ethosu_job_err_cleanup(struct ethosu_job *job)
|
||||
{
|
||||
struct ethosu_job *job = container_of(ref, struct ethosu_job,
|
||||
refcount);
|
||||
unsigned int i;
|
||||
|
||||
pm_runtime_put_autosuspend(job->dev->base.dev);
|
||||
|
||||
dma_fence_put(job->done_fence);
|
||||
dma_fence_put(job->inference_done_fence);
|
||||
|
||||
for (i = 0; i < job->region_cnt; i++)
|
||||
drm_gem_object_put(job->region_bo[i]);
|
||||
|
||||
|
|
@ -162,6 +155,19 @@ static void ethosu_job_cleanup(struct kref *ref)
|
|||
kfree(job);
|
||||
}
|
||||
|
||||
static void ethosu_job_cleanup(struct kref *ref)
|
||||
{
|
||||
struct ethosu_job *job = container_of(ref, struct ethosu_job,
|
||||
refcount);
|
||||
|
||||
pm_runtime_put_autosuspend(job->dev->base.dev);
|
||||
|
||||
dma_fence_put(job->done_fence);
|
||||
dma_fence_put(job->inference_done_fence);
|
||||
|
||||
ethosu_job_err_cleanup(job);
|
||||
}
|
||||
|
||||
static void ethosu_job_put(struct ethosu_job *job)
|
||||
{
|
||||
kref_put(&job->refcount, ethosu_job_cleanup);
|
||||
|
|
@ -454,12 +460,16 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file
|
|||
}
|
||||
}
|
||||
ret = ethosu_job_push(ejob);
|
||||
if (!ret) {
|
||||
ethosu_job_put(ejob);
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_cleanup_job:
|
||||
if (ret)
|
||||
drm_sched_job_cleanup(&ejob->base);
|
||||
out_put_job:
|
||||
ethosu_job_put(ejob);
|
||||
ethosu_job_err_cleanup(ejob);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue