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_get_fd
amdgpu_device_initialize
amdgpu_device_initialize2
amdgpu_find_bo_by_cpu_mapping
amdgpu_get_marketing_name
amdgpu_query_buffer_size_alignment

View File

@ -533,6 +533,20 @@ int amdgpu_device_initialize(int fd,
uint32_t *minor_version,
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

View File

@ -97,9 +97,9 @@ static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{
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;
close(dev->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;
}
drm_public int amdgpu_device_initialize(int fd,
uint32_t *major_version,
uint32_t *minor_version,
amdgpu_device_handle *device_handle)
static int _amdgpu_device_initialize(int fd,
uint32_t *major_version,
uint32_t *minor_version,
amdgpu_device_handle *device_handle,
bool deduplicate_device)
{
struct amdgpu_device *dev;
struct amdgpu_device *dev = NULL;
drmVersionPtr version;
int r;
int flag_auth = 0;
@ -153,6 +154,7 @@ drm_public int amdgpu_device_initialize(int fd,
*device_handle = NULL;
pthread_mutex_lock(&dev_mutex);
r = amdgpu_get_auth(fd, &flag_auth);
if (r) {
fprintf(stderr, "%s: amdgpu_get_auth (1) failed (%i)\n",
@ -161,9 +163,10 @@ drm_public int amdgpu_device_initialize(int fd,
return r;
}
for (dev = dev_list; dev; dev = dev->next)
if (fd_compare(dev->fd, fd) == 0)
break;
if (deduplicate_device)
for (dev = dev_list; dev; dev = dev->next)
if (fd_compare(dev->fd, fd) == 0)
break;
if (dev) {
r = amdgpu_get_auth(dev->fd, &flag_authexist);
@ -247,8 +250,10 @@ drm_public int amdgpu_device_initialize(int fd,
*major_version = dev->major_version;
*minor_version = dev->minor_version;
*device_handle = dev;
dev->next = dev_list;
dev_list = dev;
if (deduplicate_device) {
dev->next = dev_list;
dev_list = dev;
}
pthread_mutex_unlock(&dev_mutex);
return 0;
@ -261,6 +266,22 @@ cleanup:
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)
{
pthread_mutex_lock(&dev_mutex);