Skip to content

Commit

Permalink
drm/panthor: Fix race when converting group handle to group object
Browse files Browse the repository at this point in the history
XArray provides it's own internal lock which protects the internal array
when entries are being simultaneously added and removed. However there
is still a race between retrieving the pointer from the XArray and
incrementing the reference count.

To avoid this race simply hold the internal XArray lock when
incrementing the reference count, this ensures there cannot be a racing
call to xa_erase().

Fixes: de85488 ("drm/panthor: Add the scheduler logical block")
Signed-off-by: Steven Price <steven.price@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240923103406.2509906-1-steven.price@arm.com
  • Loading branch information
Steven Price committed Sep 23, 2024
1 parent d92b90f commit cac0757
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions drivers/gpu/drm/panthor/panthor_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -3242,6 +3242,18 @@ int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle)
return 0;
}

static struct panthor_group *group_from_handle(struct panthor_group_pool *pool,
u32 group_handle)
{
struct panthor_group *group;

xa_lock(&pool->xa);
group = group_get(xa_load(&pool->xa, group_handle));
xa_unlock(&pool->xa);

return group;
}

int panthor_group_get_state(struct panthor_file *pfile,
struct drm_panthor_group_get_state *get_state)
{
Expand All @@ -3253,7 +3265,7 @@ int panthor_group_get_state(struct panthor_file *pfile,
if (get_state->pad)
return -EINVAL;

group = group_get(xa_load(&gpool->xa, get_state->group_handle));
group = group_from_handle(gpool, get_state->group_handle);
if (!group)
return -EINVAL;

Expand Down Expand Up @@ -3384,7 +3396,7 @@ panthor_job_create(struct panthor_file *pfile,
job->call_info.latest_flush = qsubmit->latest_flush;
INIT_LIST_HEAD(&job->node);

job->group = group_get(xa_load(&gpool->xa, group_handle));
job->group = group_from_handle(gpool, group_handle);
if (!job->group) {
ret = -EINVAL;
goto err_put_job;
Expand Down

0 comments on commit cac0757

Please sign in to comment.