amdgpu: add amdgpu_device_initialize2

Allows to opt-out from the device deduplication logic. This is not the
recommended way of using dev handles, but it's necessary for native context:
in this situation one process (eg: Qemu) will init many devices and we
want independent devices to make sure guest applications are isolated from
each other.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
main
Pierre-Eric Pelloux-Prayer 2023-02-17 14:41:48 +01:00
parent 6978f999ea
commit 7275ef8eba
3 changed files with 48 additions and 12 deletions

View File

@ -56,6 +56,7 @@ amdgpu_cs_wait_semaphore
amdgpu_device_deinitialize amdgpu_device_deinitialize
amdgpu_device_get_fd amdgpu_device_get_fd
amdgpu_device_initialize amdgpu_device_initialize
amdgpu_device_initialize2
amdgpu_find_bo_by_cpu_mapping amdgpu_find_bo_by_cpu_mapping
amdgpu_get_marketing_name amdgpu_get_marketing_name
amdgpu_query_buffer_size_alignment amdgpu_query_buffer_size_alignment

View File

@ -533,6 +533,20 @@ int amdgpu_device_initialize(int fd,
uint32_t *minor_version, uint32_t *minor_version,
amdgpu_device_handle *device_handle); amdgpu_device_handle *device_handle);
/**
* Same as amdgpu_device_initialize() except when deduplicate_device
* is false *and* fd points to a device that was already initialized.
* In this case, amdgpu_device_initialize would return the same
* amdgpu_device_handle while here amdgpu_device_initialize2 would
* return a new handle.
* amdgpu_device_initialize() should be preferred in most situations;
* the only use-case where not-deduplicating devices make sense is
* when one wants to have isolated device handles in the same process.
*/
int amdgpu_device_initialize2(int fd, bool deduplicate_device,
uint32_t *major_version,
uint32_t *minor_version,
amdgpu_device_handle *device_handle);
/** /**
* *
* When access to such library does not needed any more the special * When access to such library does not needed any more the special

View File

@ -97,9 +97,9 @@ static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{ {
amdgpu_device_handle *node = &dev_list; amdgpu_device_handle *node = &dev_list;
while (*node != dev && (*node)->next) /* Remove dev from dev_list, if it was added there. */
while (*node != dev && *node && (*node)->next)
node = &(*node)->next; node = &(*node)->next;
*node = (*node)->next;
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))
@ -138,12 +138,13 @@ static void amdgpu_device_reference(struct amdgpu_device **dst,
*dst = src; *dst = src;
} }
drm_public int amdgpu_device_initialize(int fd, static int _amdgpu_device_initialize(int fd,
uint32_t *major_version, uint32_t *major_version,
uint32_t *minor_version, uint32_t *minor_version,
amdgpu_device_handle *device_handle) amdgpu_device_handle *device_handle,
bool deduplicate_device)
{ {
struct amdgpu_device *dev; struct amdgpu_device *dev = NULL;
drmVersionPtr version; drmVersionPtr version;
int r; int r;
int flag_auth = 0; int flag_auth = 0;
@ -153,6 +154,7 @@ drm_public int amdgpu_device_initialize(int fd,
*device_handle = NULL; *device_handle = NULL;
pthread_mutex_lock(&dev_mutex); pthread_mutex_lock(&dev_mutex);
r = amdgpu_get_auth(fd, &flag_auth); r = amdgpu_get_auth(fd, &flag_auth);
if (r) { if (r) {
fprintf(stderr, "%s: amdgpu_get_auth (1) failed (%i)\n", fprintf(stderr, "%s: amdgpu_get_auth (1) failed (%i)\n",
@ -161,6 +163,7 @@ drm_public int amdgpu_device_initialize(int fd,
return r; return r;
} }
if (deduplicate_device)
for (dev = dev_list; dev; dev = dev->next) for (dev = dev_list; dev; dev = dev->next)
if (fd_compare(dev->fd, fd) == 0) if (fd_compare(dev->fd, fd) == 0)
break; break;
@ -247,8 +250,10 @@ drm_public int amdgpu_device_initialize(int fd,
*major_version = dev->major_version; *major_version = dev->major_version;
*minor_version = dev->minor_version; *minor_version = dev->minor_version;
*device_handle = dev; *device_handle = dev;
if (deduplicate_device) {
dev->next = dev_list; dev->next = dev_list;
dev_list = dev; dev_list = dev;
}
pthread_mutex_unlock(&dev_mutex); pthread_mutex_unlock(&dev_mutex);
return 0; return 0;
@ -261,6 +266,22 @@ cleanup:
return r; return r;
} }
drm_public int amdgpu_device_initialize(int fd,
uint32_t *major_version,
uint32_t *minor_version,
amdgpu_device_handle *device_handle)
{
return _amdgpu_device_initialize(fd, major_version, minor_version, device_handle, true);
}
drm_public int amdgpu_device_initialize2(int fd, bool deduplicate_device,
uint32_t *major_version,
uint32_t *minor_version,
amdgpu_device_handle *device_handle)
{
return _amdgpu_device_initialize(fd, major_version, minor_version, device_handle, deduplicate_device);
}
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); pthread_mutex_lock(&dev_mutex);