The AMDGPU_VA_RANGE_32_BIT flag is added to request VA range in the 32bit address space for amdgpu_va_range_alloc. The 32bit address space is reserved at initialization time, and managed with a separate VAMGR as part of the global VAMGR. And if no enough VA space available in range above 4GB, this reserved range can be used as fallback. v2: add comment for AMDGPU_VA_RANGE_32_BIT, and add vamgr to va_range Signed-off-by: Jammy Zhou <Jammy.Zhou@xxxxxxx> Reviewed-by: Christian König <christian.koenig@xxxxxxx> --- amdgpu/amdgpu.h | 5 +++++ amdgpu/amdgpu_device.c | 22 ++++++++++++++++++++++ amdgpu/amdgpu_internal.h | 9 +++++++++ amdgpu/amdgpu_vamgr.c | 35 ++++++++++++++++++++++++++++------- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h index a90c1ac..1e633e3 100644 --- a/amdgpu/amdgpu.h +++ b/amdgpu/amdgpu.h @@ -1075,6 +1075,11 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset, uint32_t *values); /** + * Flag to request VA address range in the 32bit address space +*/ +#define AMDGPU_VA_RANGE_32_BIT 0x1 + +/** * Allocate virtual address range * * \param dev - [in] Device handle. See #amdgpu_device_initialize() diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c index ba75db0..067ef64 100644 --- a/amdgpu/amdgpu_device.c +++ b/amdgpu/amdgpu_device.c @@ -40,6 +40,7 @@ #include "amdgpu_drm.h" #include "amdgpu_internal.h" #include "util_hash_table.h" +#include "util_math.h" #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) #define UINT_TO_PTR(x) ((void *)((intptr_t)(x))) @@ -126,6 +127,7 @@ int amdgpu_device_initialize(int fd, int flag_auth = 0; int flag_authexist=0; uint32_t accel_working = 0; + uint64_t start, max; *device_handle = NULL; @@ -204,6 +206,19 @@ int amdgpu_device_initialize(int fd, dev->vamgr = amdgpu_vamgr_get_global(dev); + max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff); + start = amdgpu_vamgr_find_va(dev->vamgr, + max - dev->dev_info.virtual_address_offset, + dev->dev_info.virtual_address_alignment, 0); + if (start > 0xffffffff) + goto free_va; /* shouldn't get here */ + + dev->vamgr_32 = calloc(1, sizeof(struct amdgpu_bo_va_mgr)); + if (dev->vamgr_32 == NULL) + goto free_va; + amdgpu_vamgr_init(dev->vamgr_32, start, max, + dev->dev_info.virtual_address_alignment); + *major_version = dev->major_version; *minor_version = dev->minor_version; *device_handle = dev; @@ -212,6 +227,11 @@ int amdgpu_device_initialize(int fd, return 0; +free_va: + r = -ENOMEM; + amdgpu_vamgr_free_va(dev->vamgr, start, + max - dev->dev_info.virtual_address_offset); + cleanup: if (dev->fd >= 0) close(dev->fd); @@ -222,6 +242,8 @@ cleanup: void amdgpu_device_free_internal(amdgpu_device_handle dev) { + amdgpu_vamgr_deinit(dev->vamgr_32); + free(dev->vamgr_32); amdgpu_vamgr_reference(&dev->vamgr, NULL); util_hash_table_destroy(dev->bo_flink_names); util_hash_table_destroy(dev->bo_handles); diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h index 526a93f..6e65642 100644 --- a/amdgpu/amdgpu_internal.h +++ b/amdgpu/amdgpu_internal.h @@ -63,6 +63,7 @@ struct amdgpu_va { uint64_t address; uint64_t size; enum amdgpu_gpu_va_range range; + struct amdgpu_bo_va_mgr *vamgr; }; struct amdgpu_device { @@ -80,7 +81,10 @@ struct amdgpu_device { pthread_mutex_t bo_table_mutex; struct drm_amdgpu_info_device dev_info; struct amdgpu_gpu_info info; + /** The global VA manager for the whole virtual address space */ struct amdgpu_bo_va_mgr *vamgr; + /** The VA manager for the 32bit address space */ + struct amdgpu_bo_va_mgr *vamgr_32; }; struct amdgpu_bo { @@ -124,6 +128,11 @@ struct amdgpu_bo_va_mgr* amdgpu_vamgr_get_global(struct amdgpu_device *dev); void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct amdgpu_bo_va_mgr *src); +void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start, + uint64_t max, uint64_t alignment); + +void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr); + uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size, uint64_t alignment, uint64_t base_required); diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c index e044dfa..04e09e2 100644 --- a/amdgpu/amdgpu_vamgr.c +++ b/amdgpu/amdgpu_vamgr.c @@ -42,7 +42,7 @@ int amdgpu_va_range_query(amdgpu_device_handle dev, return -EINVAL; } -static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start, +void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start, uint64_t max, uint64_t alignment) { mgr->va_offset = start; @@ -53,7 +53,7 @@ static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start, pthread_mutex_init(&mgr->bo_va_mutex, NULL); } -static void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr) +void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr) { struct amdgpu_bo_va_hole *hole; LIST_FOR_EACH_ENTRY(hole, &mgr->va_holes, list) { @@ -248,23 +248,40 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev, amdgpu_va_handle *va_range_handle, uint64_t flags) { - va_base_alignment = MAX2(va_base_alignment, dev->vamgr->va_alignment); - size = ALIGN(size, vamgr.va_alignment); + struct amdgpu_bo_va_mgr *vamgr; - *va_base_allocated = amdgpu_vamgr_find_va(dev->vamgr, size, + if (flags & AMDGPU_VA_RANGE_32_BIT) + vamgr = dev->vamgr_32; + else + vamgr = dev->vamgr; + + va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment); + size = ALIGN(size, vamgr->va_alignment); + + *va_base_allocated = amdgpu_vamgr_find_va(vamgr, size, va_base_alignment, va_base_required); + if (!(flags & AMDGPU_VA_RANGE_32_BIT) && + (*va_base_allocated == AMDGPU_INVALID_VA_ADDRESS)) { + /* fallback to 32bit address */ + vamgr = dev->vamgr_32; + *va_base_allocated = amdgpu_vamgr_find_va(vamgr, size, + va_base_alignment, va_base_required); + + } + if (*va_base_allocated != AMDGPU_INVALID_VA_ADDRESS) { struct amdgpu_va* va; va = calloc(1, sizeof(struct amdgpu_va)); if(!va){ - amdgpu_vamgr_free_va(dev->vamgr, *va_base_allocated, size); + amdgpu_vamgr_free_va(vamgr, *va_base_allocated, size); return -ENOMEM; } va->dev = dev; va->address = *va_base_allocated; va->size = size; va->range = va_range_type; + va->vamgr = vamgr; *va_range_handle = va; } else { return -EINVAL; @@ -275,9 +292,13 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev, int amdgpu_va_range_free(amdgpu_va_handle va_range_handle) { + struct amdgpu_bo_va_mgr *vamgr; + if(!va_range_handle || !va_range_handle->address) return 0; - amdgpu_vamgr_free_va(va_range_handle->dev->vamgr, va_range_handle->address, + + amdgpu_vamgr_free_va(va_range_handle->vamgr, + va_range_handle->address, va_range_handle->size); free(va_range_handle); return 0; -- 1.9.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel