summaryrefslogtreecommitdiffstats
path: root/amdgpu
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--amdgpu/amdgpu-symbols.txt5
-rw-r--r--amdgpu/amdgpu.h51
-rw-r--r--amdgpu/amdgpu_cs.c15
-rw-r--r--amdgpu/amdgpu_device.c103
-rw-r--r--amdgpu/amdgpu_internal.h21
-rw-r--r--amdgpu/amdgpu_vamgr.c71
6 files changed, 201 insertions, 65 deletions
diff --git a/amdgpu/amdgpu-symbols.txt b/amdgpu/amdgpu-symbols.txt
index 530b343..594480e 100644
--- a/amdgpu/amdgpu-symbols.txt
+++ b/amdgpu/amdgpu-symbols.txt
@@ -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
@@ -71,7 +72,11 @@ amdgpu_query_info
amdgpu_query_sensor_info
amdgpu_query_video_caps_info
amdgpu_read_mm_registers
+amdgpu_va_manager_alloc
+amdgpu_va_manager_init
+amdgpu_va_manager_deinit
amdgpu_va_range_alloc
+amdgpu_va_range_alloc2
amdgpu_va_range_free
amdgpu_va_get_start_addr
amdgpu_va_range_query
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 9bdbf36..c9c1f12 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -139,6 +139,12 @@ typedef struct amdgpu_bo_list *amdgpu_bo_list_handle;
typedef struct amdgpu_va *amdgpu_va_handle;
/**
+ * Define handle dealing with VA allocation. An amdgpu_device
+ * owns one of these, but they can also be used without a device.
+ */
+typedef struct amdgpu_va_manager *amdgpu_va_manager_handle;
+
+/**
* Define handle for semaphore
*/
typedef struct amdgpu_semaphore *amdgpu_semaphore_handle;
@@ -528,6 +534,20 @@ int amdgpu_device_initialize(int fd,
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
* function must be call giving opportunity to clean up any
@@ -1411,6 +1431,37 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
uint64_t *end);
/**
+ * Allocate a amdgpu_va_manager object.
+ * The returned object has be initialized with the amdgpu_va_manager_init
+ * before use.
+ * On release, amdgpu_va_manager_deinit needs to be called, then the memory
+ * can be released using free().
+ */
+amdgpu_va_manager_handle amdgpu_va_manager_alloc(void);
+
+void amdgpu_va_manager_init(amdgpu_va_manager_handle va_mgr,
+ uint64_t low_va_offset, uint64_t low_va_max,
+ uint64_t high_va_offset, uint64_t high_va_max,
+ uint32_t virtual_address_alignment);
+
+void amdgpu_va_manager_deinit(amdgpu_va_manager_handle va_mgr);
+
+/**
+ * Similar to #amdgpu_va_range_alloc() but allocates VA
+ * directly from an amdgpu_va_manager_handle instead of using
+ * the manager from an amdgpu_device.
+ */
+
+int amdgpu_va_range_alloc2(amdgpu_va_manager_handle va_mgr,
+ enum amdgpu_gpu_va_range va_range_type,
+ uint64_t size,
+ uint64_t va_base_alignment,
+ uint64_t va_base_required,
+ uint64_t *va_base_allocated,
+ amdgpu_va_handle *va_range_handle,
+ uint64_t flags);
+
+/**
* VA mapping/unmapping for the buffer object
*
* \param bo - \c [in] BO handle
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 49fc16c..2db4967 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -598,24 +598,31 @@ drm_public int amdgpu_cs_signal_semaphore(amdgpu_context_handle ctx,
uint32_t ring,
amdgpu_semaphore_handle sem)
{
+ int ret;
+
if (!ctx || !sem)
return -EINVAL;
if (ip_type >= AMDGPU_HW_IP_NUM)
return -EINVAL;
if (ring >= AMDGPU_CS_MAX_RINGS)
return -EINVAL;
- /* sem has been signaled */
- if (sem->signal_fence.context)
- return -EINVAL;
+
pthread_mutex_lock(&ctx->sequence_mutex);
+ /* sem has been signaled */
+ if (sem->signal_fence.context) {
+ ret = -EINVAL;
+ goto unlock;
+ }
sem->signal_fence.context = ctx;
sem->signal_fence.ip_type = ip_type;
sem->signal_fence.ip_instance = ip_instance;
sem->signal_fence.ring = ring;
sem->signal_fence.fence = ctx->last_seq[ip_type][ip_instance][ring];
update_references(NULL, &sem->refcount);
+ ret = 0;
+unlock:
pthread_mutex_unlock(&ctx->sequence_mutex);
- return 0;
+ return ret;
}
drm_public int amdgpu_cs_wait_semaphore(amdgpu_context_handle ctx,
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index aeb5e3c..34463b5 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -95,22 +95,26 @@ static int amdgpu_get_auth(int fd, int *auth)
static void amdgpu_device_free_internal(amdgpu_device_handle dev)
{
- amdgpu_device_handle *node = &dev_list;
-
- pthread_mutex_lock(&dev_mutex);
- while (*node != dev && (*node)->next)
- node = &(*node)->next;
- *node = (*node)->next;
- pthread_mutex_unlock(&dev_mutex);
+ /* Remove dev from dev_list, if it was added there. */
+ if (dev == dev_list) {
+ dev_list = dev->next;
+ } else {
+ for (amdgpu_device_handle node = dev_list; node; node = node->next) {
+ if (node->next == dev) {
+ node->next = dev->next;
+ break;
+ }
+ }
+ }
close(dev->fd);
if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
close(dev->flink_fd);
- amdgpu_vamgr_deinit(&dev->vamgr_32);
- amdgpu_vamgr_deinit(&dev->vamgr);
- amdgpu_vamgr_deinit(&dev->vamgr_high_32);
- amdgpu_vamgr_deinit(&dev->vamgr_high);
+ amdgpu_vamgr_deinit(&dev->va_mgr.vamgr_32);
+ amdgpu_vamgr_deinit(&dev->va_mgr.vamgr_low);
+ amdgpu_vamgr_deinit(&dev->va_mgr.vamgr_high_32);
+ amdgpu_vamgr_deinit(&dev->va_mgr.vamgr_high);
handle_table_fini(&dev->bo_handles);
handle_table_fini(&dev->bo_flink_names);
pthread_mutex_destroy(&dev->bo_table_mutex);
@@ -140,22 +144,23 @@ 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;
int flag_authexist=0;
uint32_t accel_working = 0;
- uint64_t start, max;
*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",
@@ -164,9 +169,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);
@@ -238,35 +244,22 @@ drm_public int amdgpu_device_initialize(int fd,
goto cleanup;
}
- start = dev->dev_info.virtual_address_offset;
- max = MIN2(dev->dev_info.virtual_address_max, 0x100000000ULL);
- amdgpu_vamgr_init(&dev->vamgr_32, start, max,
- dev->dev_info.virtual_address_alignment);
-
- start = max;
- max = MAX2(dev->dev_info.virtual_address_max, 0x100000000ULL);
- amdgpu_vamgr_init(&dev->vamgr, start, max,
- dev->dev_info.virtual_address_alignment);
-
- start = dev->dev_info.high_va_offset;
- max = MIN2(dev->dev_info.high_va_max, (start & ~0xffffffffULL) +
- 0x100000000ULL);
- amdgpu_vamgr_init(&dev->vamgr_high_32, start, max,
- dev->dev_info.virtual_address_alignment);
-
- start = max;
- max = MAX2(dev->dev_info.high_va_max, (start & ~0xffffffffULL) +
- 0x100000000ULL);
- amdgpu_vamgr_init(&dev->vamgr_high, start, max,
- dev->dev_info.virtual_address_alignment);
+ amdgpu_va_manager_init(&dev->va_mgr,
+ dev->dev_info.virtual_address_offset,
+ dev->dev_info.virtual_address_max,
+ dev->dev_info.high_va_offset,
+ dev->dev_info.high_va_max,
+ dev->dev_info.virtual_address_alignment);
amdgpu_parse_asic_ids(dev);
*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;
@@ -279,9 +272,27 @@ 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);
amdgpu_device_reference(&dev, NULL);
+ pthread_mutex_unlock(&dev_mutex);
return 0;
}
@@ -306,10 +317,10 @@ drm_public int amdgpu_query_sw_info(amdgpu_device_handle dev,
switch (info) {
case amdgpu_sw_info_address32_hi:
- if (dev->vamgr_high_32.va_max)
- *val32 = (dev->vamgr_high_32.va_max - 1) >> 32;
+ if (dev->va_mgr.vamgr_high_32.va_max)
+ *val32 = (dev->va_mgr.vamgr_high_32.va_max - 1) >> 32;
else
- *val32 = (dev->vamgr_32.va_max - 1) >> 32;
+ *val32 = (dev->va_mgr.vamgr_32.va_max - 1) >> 32;
return 0;
}
return -EINVAL;
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 2834c9c..af85b84 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -63,6 +63,17 @@ struct amdgpu_va {
struct amdgpu_bo_va_mgr *vamgr;
};
+struct amdgpu_va_manager {
+ /** The VA manager for the lower virtual address space */
+ struct amdgpu_bo_va_mgr vamgr_low;
+ /** The VA manager for the 32bit address space */
+ struct amdgpu_bo_va_mgr vamgr_32;
+ /** The VA manager for the high virtual address space */
+ struct amdgpu_bo_va_mgr vamgr_high;
+ /** The VA manager for the 32bit high address space */
+ struct amdgpu_bo_va_mgr vamgr_high_32;
+};
+
struct amdgpu_device {
atomic_t refcount;
struct amdgpu_device *next;
@@ -80,14 +91,8 @@ struct amdgpu_device {
pthread_mutex_t bo_table_mutex;
struct drm_amdgpu_info_device dev_info;
struct amdgpu_gpu_info info;
- /** The VA manager for the lower virtual address space */
- struct amdgpu_bo_va_mgr vamgr;
- /** The VA manager for the 32bit address space */
- struct amdgpu_bo_va_mgr vamgr_32;
- /** The VA manager for the high virtual address space */
- struct amdgpu_bo_va_mgr vamgr_high;
- /** The VA manager for the 32bit high address space */
- struct amdgpu_bo_va_mgr vamgr_high_32;
+
+ struct amdgpu_va_manager va_mgr;
};
struct amdgpu_bo {
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 2c4c9db..29944ec 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -229,24 +229,39 @@ drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
amdgpu_va_handle *va_range_handle,
uint64_t flags)
{
+ return amdgpu_va_range_alloc2(&dev->va_mgr, va_range_type, size,
+ va_base_alignment, va_base_required,
+ va_base_allocated, va_range_handle,
+ flags);
+}
+
+drm_public int amdgpu_va_range_alloc2(amdgpu_va_manager_handle va_mgr,
+ enum amdgpu_gpu_va_range va_range_type,
+ uint64_t size,
+ uint64_t va_base_alignment,
+ uint64_t va_base_required,
+ uint64_t *va_base_allocated,
+ amdgpu_va_handle *va_range_handle,
+ uint64_t flags)
+{
struct amdgpu_bo_va_mgr *vamgr;
bool search_from_top = !!(flags & AMDGPU_VA_RANGE_REPLAYABLE);
int ret;
/* Clear the flag when the high VA manager is not initialized */
- if (flags & AMDGPU_VA_RANGE_HIGH && !dev->vamgr_high_32.va_max)
+ if (flags & AMDGPU_VA_RANGE_HIGH && !va_mgr->vamgr_high_32.va_max)
flags &= ~AMDGPU_VA_RANGE_HIGH;
if (flags & AMDGPU_VA_RANGE_HIGH) {
if (flags & AMDGPU_VA_RANGE_32_BIT)
- vamgr = &dev->vamgr_high_32;
+ vamgr = &va_mgr->vamgr_high_32;
else
- vamgr = &dev->vamgr_high;
+ vamgr = &va_mgr->vamgr_high;
} else {
if (flags & AMDGPU_VA_RANGE_32_BIT)
- vamgr = &dev->vamgr_32;
+ vamgr = &va_mgr->vamgr_32;
else
- vamgr = &dev->vamgr;
+ vamgr = &va_mgr->vamgr_low;
}
va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment);
@@ -259,9 +274,9 @@ drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
if (!(flags & AMDGPU_VA_RANGE_32_BIT) && ret) {
/* fallback to 32bit address */
if (flags & AMDGPU_VA_RANGE_HIGH)
- vamgr = &dev->vamgr_high_32;
+ vamgr = &va_mgr->vamgr_high_32;
else
- vamgr = &dev->vamgr_32;
+ vamgr = &va_mgr->vamgr_32;
ret = amdgpu_vamgr_find_va(vamgr, size,
va_base_alignment, va_base_required,
search_from_top, va_base_allocated);
@@ -300,3 +315,45 @@ drm_public uint64_t amdgpu_va_get_start_addr(amdgpu_va_handle va_handle)
{
return va_handle->address;
}
+
+drm_public amdgpu_va_manager_handle amdgpu_va_manager_alloc(void)
+{
+ amdgpu_va_manager_handle r = calloc(1, sizeof(struct amdgpu_va_manager));
+ return r;
+}
+
+drm_public void amdgpu_va_manager_init(struct amdgpu_va_manager *va_mgr,
+ uint64_t low_va_offset, uint64_t low_va_max,
+ uint64_t high_va_offset, uint64_t high_va_max,
+ uint32_t virtual_address_alignment)
+{
+ uint64_t start, max;
+
+ start = low_va_offset;
+ max = MIN2(low_va_max, 0x100000000ULL);
+ amdgpu_vamgr_init(&va_mgr->vamgr_32, start, max,
+ virtual_address_alignment);
+
+ start = max;
+ max = MAX2(low_va_max, 0x100000000ULL);
+ amdgpu_vamgr_init(&va_mgr->vamgr_low, start, max,
+ virtual_address_alignment);
+
+ start = high_va_offset;
+ max = MIN2(high_va_max, (start & ~0xffffffffULL) + 0x100000000ULL);
+ amdgpu_vamgr_init(&va_mgr->vamgr_high_32, start, max,
+ virtual_address_alignment);
+
+ start = max;
+ max = MAX2(high_va_max, (start & ~0xffffffffULL) + 0x100000000ULL);
+ amdgpu_vamgr_init(&va_mgr->vamgr_high, start, max,
+ virtual_address_alignment);
+}
+
+drm_public void amdgpu_va_manager_deinit(struct amdgpu_va_manager *va_mgr)
+{
+ amdgpu_vamgr_deinit(&va_mgr->vamgr_32);
+ amdgpu_vamgr_deinit(&va_mgr->vamgr_low);
+ amdgpu_vamgr_deinit(&va_mgr->vamgr_high_32);
+ amdgpu_vamgr_deinit(&va_mgr->vamgr_high);
+}