From eb625b7a5ff501852ba7ce2a309217859d7cb791 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 3 Feb 2021 10:47:08 +0100 Subject: [PATCH] radv/winsys: use an array for the global BO list instead of a list This allows to remove one 64-bit pointer from radv_amdgpu_winsys_bo. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 88 ++++++++++++------- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h | 1 - src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 36 ++++---- .../vulkan/winsys/amdgpu/radv_amdgpu_winsys.c | 7 +- .../vulkan/winsys/amdgpu/radv_amdgpu_winsys.h | 12 ++- 5 files changed, 87 insertions(+), 57 deletions(-) diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c index 1a85bf305e9..049191873b2 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c @@ -317,6 +317,50 @@ static void radv_amdgpu_log_bo(struct radv_amdgpu_winsys_bo *bo, u_rwlock_wrunlock(&ws->log_bo_list_lock); } +static int radv_amdgpu_global_bo_list_add(struct radv_amdgpu_winsys_bo *bo) +{ + struct radv_amdgpu_winsys *ws = bo->ws; + + if (!ws->debug_all_bos) + return VK_SUCCESS; + + u_rwlock_wrlock(&ws->global_bo_list.lock); + if (ws->global_bo_list.count == ws->global_bo_list.capacity) { + unsigned capacity = MAX2(4, ws->global_bo_list.capacity * 2); + void *data = realloc(ws->global_bo_list.bos, + capacity * sizeof(struct radv_amdgpu_winsys_bo *)); + if (!data) { + u_rwlock_wrunlock(&ws->global_bo_list.lock); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + ws->global_bo_list.bos = (struct radv_amdgpu_winsys_bo **)data; + ws->global_bo_list.capacity = capacity; + } + + ws->global_bo_list.bos[ws->global_bo_list.count++] = bo; + u_rwlock_wrunlock(&ws->global_bo_list.lock); + return VK_SUCCESS; +} + +static void radv_amdgpu_global_bo_list_del(struct radv_amdgpu_winsys_bo *bo) +{ + struct radv_amdgpu_winsys *ws = bo->ws; + + if (!ws->debug_all_bos) + return; + + u_rwlock_wrlock(&ws->global_bo_list.lock); + for(unsigned i = ws->global_bo_list.count; i-- > 0;) { + if (ws->global_bo_list.bos[i] == bo) { + ws->global_bo_list.bos[i] = ws->global_bo_list.bos[ws->global_bo_list.count - 1]; + --ws->global_bo_list.count; + break; + } + } + u_rwlock_wrunlock(&ws->global_bo_list.lock); +} + static void radv_amdgpu_winsys_bo_destroy(struct radeon_winsys_bo *_bo) { struct radv_amdgpu_winsys_bo *bo = radv_amdgpu_winsys_bo(_bo); @@ -334,12 +378,7 @@ static void radv_amdgpu_winsys_bo_destroy(struct radeon_winsys_bo *_bo) free(bo->bos); free(bo->ranges); } else { - if (bo->ws->debug_all_bos) { - u_rwlock_wrlock(&bo->ws->global_bo_list_lock); - list_del(&bo->global_list_item); - bo->ws->num_buffers--; - u_rwlock_wrunlock(&bo->ws->global_bo_list_lock); - } + radv_amdgpu_global_bo_list_del(bo); radv_amdgpu_bo_va_op(bo->ws, bo->bo, 0, bo->size, bo->base.va, 0, 0, AMDGPU_VA_OP_UNMAP); amdgpu_bo_free(bo->bo); @@ -363,18 +402,6 @@ static void radv_amdgpu_winsys_bo_destroy(struct radeon_winsys_bo *_bo) FREE(bo); } -static void radv_amdgpu_add_buffer_to_global_list(struct radv_amdgpu_winsys_bo *bo) -{ - struct radv_amdgpu_winsys *ws = bo->ws; - - if (bo->ws->debug_all_bos) { - u_rwlock_wrlock(&ws->global_bo_list_lock); - list_addtail(&bo->global_list_item, &ws->global_bo_list); - ws->num_buffers++; - u_rwlock_wrunlock(&ws->global_bo_list_lock); - } -} - static struct radeon_winsys_bo * radv_amdgpu_winsys_bo_create(struct radeon_winsys *_ws, uint64_t size, @@ -532,7 +559,7 @@ radv_amdgpu_winsys_bo_create(struct radeon_winsys *_ws, p_atomic_add(&ws->allocated_gtt, align64(bo->size, ws->info.gart_page_size)); - radv_amdgpu_add_buffer_to_global_list(bo); + radv_amdgpu_global_bo_list_add(bo); radv_amdgpu_log_bo(bo, false); return (struct radeon_winsys_bo *)bo; @@ -641,7 +668,7 @@ radv_amdgpu_winsys_bo_from_ptr(struct radeon_winsys *_ws, p_atomic_add(&ws->allocated_gtt, align64(bo->size, ws->info.gart_page_size)); - radv_amdgpu_add_buffer_to_global_list(bo); + radv_amdgpu_global_bo_list_add(bo); radv_amdgpu_log_bo(bo, false); return (struct radeon_winsys_bo *)bo; @@ -723,7 +750,7 @@ radv_amdgpu_winsys_bo_from_fd(struct radeon_winsys *_ws, p_atomic_add(&ws->allocated_gtt, align64(bo->size, ws->info.gart_page_size)); - radv_amdgpu_add_buffer_to_global_list(bo); + radv_amdgpu_global_bo_list_add(bo); radv_amdgpu_log_bo(bo, false); return (struct radeon_winsys_bo *)bo; @@ -938,28 +965,29 @@ static void radv_amdgpu_dump_bo_ranges(struct radeon_winsys *_ws, FILE *file) { struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); if (ws->debug_all_bos) { - struct radv_amdgpu_winsys_bo *bo; struct radv_amdgpu_winsys_bo **bos = NULL; int i = 0; - u_rwlock_rdlock(&ws->global_bo_list_lock); - bos = malloc(sizeof(*bos) * ws->num_buffers); + u_rwlock_rdlock(&ws->global_bo_list.lock); + bos = malloc(sizeof(*bos) * ws->global_bo_list.count); if (!bos) { - u_rwlock_rdunlock(&ws->global_bo_list_lock); + u_rwlock_rdunlock(&ws->global_bo_list.lock); fprintf(file, " Failed to allocate memory to sort VA ranges for dumping\n"); return; } - LIST_FOR_EACH_ENTRY(bo, &ws->global_bo_list, global_list_item) { - bos[i++] = bo; + + for (i = 0; i < ws->global_bo_list.count; i++) { + bos[i] = ws->global_bo_list.bos[i]; } - qsort(bos, ws->num_buffers, sizeof(bos[0]), radv_amdgpu_bo_va_compare); - for (i = 0; i < ws->num_buffers; ++i) { + qsort(bos, ws->global_bo_list.count, sizeof(bos[0]), radv_amdgpu_bo_va_compare); + + for (i = 0; i < ws->global_bo_list.count; ++i) { fprintf(file, " VA=%.16llx-%.16llx, handle=%d%s\n", (long long)bos[i]->base.va, (long long)(bos[i]->base.va + bos[i]->size), bos[i]->bo_handle, bos[i]->is_virtual ? " sparse" : ""); } free(bos); - u_rwlock_rdunlock(&ws->global_bo_list_lock); + u_rwlock_rdunlock(&ws->global_bo_list.lock); } else fprintf(file, " To get BO VA ranges, please specify RADV_DEBUG=allbos\n"); } diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h index 0cced22bc56..2aa5732ecab 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h @@ -54,7 +54,6 @@ struct radv_amdgpu_winsys_bo { amdgpu_bo_handle bo; bool is_shared; uint32_t bo_handle; - struct list_head global_list_item; }; /* virtual bo */ struct { diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index 69943533e39..34f2d95febb 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -724,17 +724,14 @@ radv_amdgpu_get_bo_list(struct radv_amdgpu_winsys *ws, unsigned num_handles = 0; if (ws->debug_all_bos) { - struct radv_amdgpu_winsys_bo *bo; - - handles = malloc(sizeof(handles[0]) * ws->num_buffers); + handles = malloc(sizeof(handles[0]) * ws->global_bo_list.count); if (!handles) { return VK_ERROR_OUT_OF_HOST_MEMORY; } - LIST_FOR_EACH_ENTRY(bo, &ws->global_bo_list, global_list_item) { - assert(num_handles < ws->num_buffers); - handles[num_handles].bo_handle = bo->bo_handle; - handles[num_handles].bo_priority = bo->priority; + for (uint32_t i = 0; i < ws->global_bo_list.count; i++) { + handles[i].bo_handle = ws->global_bo_list.bos[i]->bo_handle; + handles[i].bo_priority = ws->global_bo_list.bos[i]->priority; num_handles++; } } else if (count == 1 && !num_extra_bo && !extra_cs && !radv_bo_list && @@ -919,7 +916,7 @@ radv_amdgpu_winsys_cs_submit_chained(struct radeon_winsys_ctx *_ctx, } if (aws->debug_all_bos) - u_rwlock_rdlock(&aws->global_bo_list_lock); + u_rwlock_rdlock(&aws->global_bo_list.lock); /* Get the BO list. */ result = radv_amdgpu_get_bo_list(cs0->ws, cs_array, cs_count, NULL, 0, @@ -960,7 +957,7 @@ radv_amdgpu_winsys_cs_submit_chained(struct radeon_winsys_ctx *_ctx, fail: if (aws->debug_all_bos) - u_rwlock_rdunlock(&aws->global_bo_list_lock); + u_rwlock_rdunlock(&aws->global_bo_list.lock); return result; } @@ -994,7 +991,7 @@ radv_amdgpu_winsys_cs_submit_fallback(struct radeon_winsys_ctx *_ctx, number_of_ibs = cs_count + !!initial_preamble_cs; if (aws->debug_all_bos) - u_rwlock_rdlock(&aws->global_bo_list_lock); + u_rwlock_rdlock(&aws->global_bo_list.lock); /* Get the BO list. */ result = radv_amdgpu_get_bo_list(cs0->ws, &cs_array[0], cs_count, NULL, 0, @@ -1050,7 +1047,7 @@ radv_amdgpu_winsys_cs_submit_fallback(struct radeon_winsys_ctx *_ctx, fail: if (aws->debug_all_bos) - u_rwlock_rdunlock(&aws->global_bo_list_lock); + u_rwlock_rdunlock(&aws->global_bo_list.lock); return result; } @@ -1209,7 +1206,7 @@ radv_amdgpu_winsys_cs_submit_sysmem(struct radeon_winsys_ctx *_ctx, } if (aws->debug_all_bos) - u_rwlock_rdlock(&aws->global_bo_list_lock); + u_rwlock_rdlock(&aws->global_bo_list.lock); result = radv_amdgpu_get_bo_list(cs0->ws, &cs_array[i], cnt, (struct radv_amdgpu_winsys_bo **)bos, @@ -1220,7 +1217,7 @@ radv_amdgpu_winsys_cs_submit_sysmem(struct radeon_winsys_ctx *_ctx, free(ibs); free(bos); if (aws->debug_all_bos) - u_rwlock_rdunlock(&aws->global_bo_list_lock); + u_rwlock_rdunlock(&aws->global_bo_list.lock); return result; } @@ -1239,7 +1236,7 @@ radv_amdgpu_winsys_cs_submit_sysmem(struct radeon_winsys_ctx *_ctx, free(request.handles); if (aws->debug_all_bos) - u_rwlock_rdunlock(&aws->global_bo_list_lock); + u_rwlock_rdunlock(&aws->global_bo_list.lock); for (unsigned j = 0; j < number_of_ibs; j++) { ws->buffer_destroy(bos[j]); @@ -1310,17 +1307,18 @@ static void *radv_amdgpu_winsys_get_cpu_addr(void *_cs, uint64_t addr) } } if(cs->ws->debug_all_bos) { - u_rwlock_rdlock(&cs->ws->global_bo_list_lock); - list_for_each_entry(struct radv_amdgpu_winsys_bo, bo, - &cs->ws->global_bo_list, global_list_item) { + u_rwlock_rdlock(&cs->ws->global_bo_list.lock); + for (uint32_t i = 0; i < cs->ws->global_bo_list.count; i++) { + struct radv_amdgpu_winsys_bo *bo = cs->ws->global_bo_list.bos[i]; if (addr >= bo->base.va && addr - bo->base.va < bo->size) { if (amdgpu_bo_cpu_map(bo->bo, &ret) == 0) { - u_rwlock_rdunlock(&cs->ws->global_bo_list_lock); + u_rwlock_rdunlock(&cs->ws->global_bo_list.lock); return (char *)ret + (addr - bo->base.va); } } + } - u_rwlock_rdunlock(&cs->ws->global_bo_list_lock); + u_rwlock_rdunlock(&cs->ws->global_bo_list.lock); } return ret; } diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c index cbceefb7894..743257c5489 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c @@ -166,8 +166,10 @@ static void radv_amdgpu_winsys_destroy(struct radeon_winsys *rws) amdgpu_cs_destroy_syncobj(ws->dev, ws->syncobj[i]); free(ws->syncobj); + u_rwlock_destroy(&ws->global_bo_list.lock); + free(ws->global_bo_list.bos); + pthread_mutex_destroy(&ws->syncobj_lock); - u_rwlock_destroy(&ws->global_bo_list_lock); u_rwlock_destroy(&ws->log_bo_list_lock); ac_addrlib_destroy(ws->addrlib); amdgpu_device_deinitialize(ws->dev); @@ -204,8 +206,7 @@ radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags) ws->zero_all_vram_allocs = debug_flags & RADV_DEBUG_ZERO_VRAM; ws->use_llvm = debug_flags & RADV_DEBUG_LLVM; ws->cs_bo_domain = radv_cmdbuffer_domain(&ws->info, perftest_flags); - list_inithead(&ws->global_bo_list); - u_rwlock_init(&ws->global_bo_list_lock); + u_rwlock_init(&ws->global_bo_list.lock); list_inithead(&ws->log_bo_list); u_rwlock_init(&ws->log_bo_list_lock); pthread_mutex_init(&ws->syncobj_lock, NULL); diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h index 55f932b879c..d354fe15bba 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h @@ -50,15 +50,19 @@ struct radv_amdgpu_winsys { bool zero_all_vram_allocs; bool use_local_bos; bool use_llvm; - unsigned num_buffers; - - struct u_rwlock global_bo_list_lock; - struct list_head global_bo_list; uint64_t allocated_vram; uint64_t allocated_vram_vis; uint64_t allocated_gtt; + /* Global BO list */ + struct { + struct radv_amdgpu_winsys_bo **bos; + uint32_t count; + uint32_t capacity; + struct u_rwlock lock; + } global_bo_list; + /* syncobj cache */ pthread_mutex_t syncobj_lock; uint32_t *syncobj;