diff options
| author | Tvrtko Ursulin <tvrtko.ursulin@igalia.com> | 2024-07-11 14:53:32 +0100 |
|---|---|---|
| committer | Maíra Canal <mcanal@igalia.com> | 2024-07-13 11:00:31 -0300 |
| commit | 484de39fa5f5b7bd0c5f2e2c5265167250ef7501 (patch) | |
| tree | 95704fa17ac5703dcbe658bbe629ebcb7ac5159d /drivers/gpu/drm/v3d/v3d_sched.c | |
| parent | 753ce4fea62182c77e1691ab4f9022008f25b62e (diff) | |
drm/v3d: Fix potential memory leak in the performance extension
If fetching of userspace memory fails during the main loop, all drm sync
objs looked up until that point will be leaked because of the missing
drm_syncobj_put.
Fix it by exporting and using a common cleanup helper.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Fixes: bae7cb5d6800 ("drm/v3d: Create a CPU job extension for the reset performance query job")
Cc: Maíra Canal <mcanal@igalia.com>
Cc: Iago Toral Quiroga <itoral@igalia.com>
Cc: stable@vger.kernel.org # v6.8+
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240711135340.84617-4-tursulin@igalia.com
Diffstat (limited to 'drivers/gpu/drm/v3d/v3d_sched.c')
| -rw-r--r-- | drivers/gpu/drm/v3d/v3d_sched.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 59dc0287dab9..5fbbee47c6b7 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -87,20 +87,30 @@ v3d_timestamp_query_info_free(struct v3d_timestamp_query_info *query_info, } } +void +v3d_performance_query_info_free(struct v3d_performance_query_info *query_info, + unsigned int count) +{ + if (query_info->queries) { + unsigned int i; + + for (i = 0; i < count; i++) + drm_syncobj_put(query_info->queries[i].syncobj); + + kvfree(query_info->queries); + } +} + static void v3d_cpu_job_free(struct drm_sched_job *sched_job) { struct v3d_cpu_job *job = to_cpu_job(sched_job); - struct v3d_performance_query_info *performance_query = &job->performance_query; v3d_timestamp_query_info_free(&job->timestamp_query, job->timestamp_query.count); - if (performance_query->queries) { - for (int i = 0; i < performance_query->count; i++) - drm_syncobj_put(performance_query->queries[i].syncobj); - kvfree(performance_query->queries); - } + v3d_performance_query_info_free(&job->performance_query, + job->performance_query.count); v3d_job_cleanup(&job->base); } |