From 4171d9ff849d2d75c11111761ced049749bc9927 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Mon, 21 Aug 2023 14:49:29 +0900 Subject: [PATCH] radv/amdgpu: Use rwlock to protect access to virtual BOs. Vulkan provides no external synchronization guarantees on sparse memory objects. Use a per-BO rwlock to prevent reading data mid-update. Part-of: --- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 10 +++++++++- src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h | 2 ++ src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c index 0b13066..b71b62b 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c @@ -75,11 +75,15 @@ bo_comparator(const void *ap, const void *bp) static VkResult radv_amdgpu_winsys_rebuild_bo_list(struct radv_amdgpu_winsys_bo *bo) { + u_rwlock_wrlock(&bo->lock); + if (bo->bo_capacity < bo->range_count) { uint32_t new_count = MAX2(bo->bo_capacity * 2, bo->range_count); struct radv_amdgpu_winsys_bo **bos = realloc(bo->bos, new_count * sizeof(struct radv_amdgpu_winsys_bo *)); - if (!bos) + if (!bos) { + u_rwlock_wrunlock(&bo->lock); return VK_ERROR_OUT_OF_HOST_MEMORY; + } bo->bos = bos; bo->bo_capacity = new_count; } @@ -102,6 +106,7 @@ radv_amdgpu_winsys_rebuild_bo_list(struct radv_amdgpu_winsys_bo *bo) bo->bo_count = final_bo_count; } + u_rwlock_wrunlock(&bo->lock); return VK_SUCCESS; } @@ -337,6 +342,7 @@ radv_amdgpu_winsys_bo_destroy(struct radeon_winsys *_ws, struct radeon_winsys_bo free(bo->bos); free(bo->ranges); + u_rwlock_destroy(&bo->lock); } else { if (ws->debug_all_bos) radv_amdgpu_global_bo_list_del(ws, bo); @@ -410,6 +416,8 @@ radv_amdgpu_winsys_bo_create(struct radeon_winsys *_ws, uint64_t size, unsigned goto error_ranges_alloc; } + u_rwlock_init(&bo->lock); + bo->ranges = ranges; bo->range_count = 1; bo->range_capacity = 1; diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h index ffe4e27..f108d8b 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.h @@ -53,6 +53,8 @@ struct radv_amdgpu_winsys_bo { }; /* virtual bo */ struct { + struct u_rwlock lock; + struct radv_amdgpu_map_range *ranges; uint32_t range_count; uint32_t range_capacity; diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c index 182ea59..a98b538 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_cs.c @@ -829,6 +829,7 @@ radv_amdgpu_add_cs_to_bo_list(struct radv_amdgpu_cs *cs, struct drm_amdgpu_bo_li } for (unsigned j = 0; j < cs->num_virtual_buffers; ++j) { struct radv_amdgpu_winsys_bo *virtual_bo = radv_amdgpu_winsys_bo(cs->virtual_buffers[j]); + u_rwlock_rdlock(&virtual_bo->lock); for (unsigned k = 0; k < virtual_bo->bo_count; ++k) { struct radv_amdgpu_winsys_bo *bo = virtual_bo->bos[k]; bool found = false; @@ -844,6 +845,7 @@ radv_amdgpu_add_cs_to_bo_list(struct radv_amdgpu_cs *cs, struct drm_amdgpu_bo_li ++num_handles; } } + u_rwlock_rdunlock(&virtual_bo->lock); } return num_handles; -- 2.7.4