amdgpu: Make amdgpu_device_deinitialize thread-safe

Device will be removed from dev_list when refcount reaches 0, so the
dev_mutex must be locked before decreasing reference otherwise there's
a race where this device is still in dev_list with refcount 0 which will
assert or crash in amdgpu_device_initialize trying to use this device
instead of creating new one.

Fixes issue reported in https://gitlab.freedesktop.org/drm/amd/-/issues/2156#note_2268110

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
main
David Rosca 2024-02-25 16:53:29 +01:00 committed by Marek Olšák
parent 1b4e04ba68
commit c8f327ce9c
1 changed files with 2 additions and 2 deletions

View File

@ -97,11 +97,9 @@ static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{ {
amdgpu_device_handle *node = &dev_list; amdgpu_device_handle *node = &dev_list;
pthread_mutex_lock(&dev_mutex);
while (*node != dev && (*node)->next) while (*node != dev && (*node)->next)
node = &(*node)->next; node = &(*node)->next;
*node = (*node)->next; *node = (*node)->next;
pthread_mutex_unlock(&dev_mutex);
close(dev->fd); close(dev->fd);
if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd)) if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
@ -281,7 +279,9 @@ cleanup:
drm_public int amdgpu_device_deinitialize(amdgpu_device_handle dev) drm_public int amdgpu_device_deinitialize(amdgpu_device_handle dev)
{ {
pthread_mutex_lock(&dev_mutex);
amdgpu_device_reference(&dev, NULL); amdgpu_device_reference(&dev, NULL);
pthread_mutex_unlock(&dev_mutex);
return 0; return 0;
} }