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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24806>
This commit is contained in:
Tatsuyuki Ishi 2023-08-21 14:49:29 +09:00 committed by Marge Bot
parent eb0c197090
commit 4171d9ff84
3 changed files with 13 additions and 1 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;