diff --git a/docs/envvars.rst b/docs/envvars.rst index 72852ef8cf8..cfa26588538 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -1367,6 +1367,8 @@ RADV driver environment variables enable LLVM compiler backend ``allbos`` force all allocated buffers to be referenced in submissions + ``bo_history`` + dump the BO history to /tmp/radv_bo_history.log after each BO operations ``checkir`` validate the LLVM IR before LLVM compiles the shader ``dump_trap_handler`` diff --git a/src/amd/vulkan/radv_debug.h b/src/amd/vulkan/radv_debug.h index 06142f7fd60..dfd03a07009 100644 --- a/src/amd/vulkan/radv_debug.h +++ b/src/amd/vulkan/radv_debug.h @@ -74,6 +74,7 @@ enum { RADV_DEBUG_BVH4 = 1ull << 59, RADV_DEBUG_NO_VIDEO = 1ull << 60, RADV_DEBUG_VALIDATE_VAS = 1ull << 61, + RADV_DEBUG_DUMP_BO_HISTORY = 1ull << 62, RADV_DEBUG_DUMP_SHADERS = RADV_DEBUG_DUMP_VS | RADV_DEBUG_DUMP_TCS | RADV_DEBUG_DUMP_TES | RADV_DEBUG_DUMP_GS | RADV_DEBUG_DUMP_PS | RADV_DEBUG_DUMP_TASK | RADV_DEBUG_DUMP_MESH | RADV_DEBUG_DUMP_CS | RADV_DEBUG_DUMP_NIR | RADV_DEBUG_DUMP_ASM | RADV_DEBUG_DUMP_BACKEND_IR, diff --git a/src/amd/vulkan/radv_instance.c b/src/amd/vulkan/radv_instance.c index 2e5c52085a3..559393c8a34 100644 --- a/src/amd/vulkan/radv_instance.c +++ b/src/amd/vulkan/radv_instance.c @@ -89,6 +89,7 @@ static const struct debug_control radv_debug_options[] = {{"nofastclears", RADV_ {"bvh4", RADV_DEBUG_BVH4}, {"novideo", RADV_DEBUG_NO_VIDEO}, {"validatevas", RADV_DEBUG_VALIDATE_VAS}, + {"bo_history", RADV_DEBUG_DUMP_BO_HISTORY}, {NULL, 0}}; const char * diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c index 45611b0baec..ce0cccc862f 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c @@ -96,28 +96,47 @@ radv_amdgpu_winsys_rebuild_bo_list(struct radv_amdgpu_winsys_bo *bo) return VK_SUCCESS; } +static uint64_t +radv_amdgpu_canonicalize_va(uint64_t va) +{ + /* Would be less hardcoded to use addr32_hi (0xffff8000) to generate a mask, + * but there are confusing differences between page fault reports from kernel where + * it seems to report the top 48 bits, where addr32_hi has 47-bits. */ + return va & ((1ull << 48) - 1); +} + static void radv_amdgpu_log_va_op(struct radv_amdgpu_winsys *ws, struct radv_amdgpu_winsys_bo *bo, uint64_t offset, uint64_t size, uint64_t virtual_va) { - struct radv_amdgpu_winsys_bo_log *bo_log = NULL; + const uint64_t timestamp = os_time_get_nano(); + uint64_t mapped_va = bo ? (bo->base.va + offset) : 0; - if (!ws->debug_log_bos) - return; + if (ws->debug_log_bos) { + struct radv_amdgpu_winsys_bo_log *bo_log = NULL; - bo_log = calloc(1, sizeof(*bo_log)); - if (!bo_log) - return; + bo_log = calloc(1, sizeof(*bo_log)); + if (!bo_log) + return; - bo_log->va = virtual_va; - bo_log->size = size; - bo_log->timestamp = os_time_get_nano(); - bo_log->virtual_mapping = 1; - bo_log->mapped_va = bo ? (bo->base.va + offset) : 0; + bo_log->va = virtual_va; + bo_log->size = size; + bo_log->timestamp = timestamp; + bo_log->virtual_mapping = 1; + bo_log->mapped_va = mapped_va; - u_rwlock_wrlock(&ws->log_bo_list_lock); - list_addtail(&bo_log->list, &ws->log_bo_list); - u_rwlock_wrunlock(&ws->log_bo_list_lock); + u_rwlock_wrlock(&ws->log_bo_list_lock); + list_addtail(&bo_log->list, &ws->log_bo_list); + u_rwlock_wrunlock(&ws->log_bo_list_lock); + } + + if (ws->bo_history_logfile) { + fprintf(ws->bo_history_logfile, "timestamp=%llu, VA=%.16llx-%.16llx, mapped_to=%.16llx\n", (long long)timestamp, + (long long)radv_amdgpu_canonicalize_va(virtual_va), + (long long)radv_amdgpu_canonicalize_va(virtual_va + size), + (long long)radv_amdgpu_canonicalize_va(mapped_va)); + fflush(ws->bo_history_logfile); + } } static int @@ -309,24 +328,32 @@ radv_amdgpu_winsys_bo_virtual_bind(struct radeon_winsys *_ws, struct radeon_wins static void radv_amdgpu_log_bo(struct radv_amdgpu_winsys *ws, struct radv_amdgpu_winsys_bo *bo, bool destroyed) { - struct radv_amdgpu_winsys_bo_log *bo_log = NULL; + const uint64_t timestamp = os_time_get_nano(); - if (!ws->debug_log_bos) - return; + if (ws->debug_log_bos) { + struct radv_amdgpu_winsys_bo_log *bo_log = NULL; - bo_log = calloc(1, sizeof(*bo_log)); - if (!bo_log) - return; + bo_log = calloc(1, sizeof(*bo_log)); + if (!bo_log) + return; - bo_log->va = bo->base.va; - bo_log->size = bo->base.size; - bo_log->timestamp = os_time_get_nano(); - bo_log->is_virtual = bo->base.is_virtual; - bo_log->destroyed = destroyed; + bo_log->va = bo->base.va; + bo_log->size = bo->base.size; + bo_log->timestamp = timestamp; + bo_log->is_virtual = bo->base.is_virtual; + bo_log->destroyed = destroyed; - u_rwlock_wrlock(&ws->log_bo_list_lock); - list_addtail(&bo_log->list, &ws->log_bo_list); - u_rwlock_wrunlock(&ws->log_bo_list_lock); + u_rwlock_wrlock(&ws->log_bo_list_lock); + list_addtail(&bo_log->list, &ws->log_bo_list); + u_rwlock_wrunlock(&ws->log_bo_list_lock); + } + + if (ws->bo_history_logfile) { + fprintf(ws->bo_history_logfile, "timestamp=%llu, VA=%.16llx-%.16llx, destroyed=%d, is_virtual=%d\n", + (long long)timestamp, (long long)radv_amdgpu_canonicalize_va(bo->base.va), + (long long)radv_amdgpu_canonicalize_va(bo->base.va + bo->base.size), destroyed, bo->base.is_virtual); + fflush(ws->bo_history_logfile); + } } static int @@ -1202,15 +1229,6 @@ radv_amdgpu_bo_va_compare(const void *a, const void *b) return bo_a->base.va < bo_b->base.va ? -1 : bo_a->base.va > bo_b->base.va ? 1 : 0; } -static uint64_t -radv_amdgpu_canonicalize_va(uint64_t va) -{ - /* Would be less hardcoded to use addr32_hi (0xffff8000) to generate a mask, - * but there are confusing differences between page fault reports from kernel where - * it seems to report the top 48 bits, where addr32_hi has 47-bits. */ - return va & ((1ull << 48) - 1); -} - static void radv_amdgpu_dump_bo_log(struct radeon_winsys *_ws, FILE *file) { diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c index 222c96d06ec..d504213134b 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c @@ -151,6 +151,9 @@ radv_amdgpu_winsys_destroy(struct radeon_winsys *rws) if (ws->reserve_vmid) ac_drm_vm_unreserve_vmid(ws->dev, 0); + if (ws->bo_history_logfile) + fclose(ws->bo_history_logfile); + u_rwlock_destroy(&ws->log_bo_list_lock); ac_drm_device_deinitialize(ws->dev); FREE(rws); @@ -287,6 +290,12 @@ radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, if (debug_flags & RADV_DEBUG_NO_IBS) ws->use_ib_bos = false; + if (debug_flags & RADV_DEBUG_DUMP_BO_HISTORY) { + ws->bo_history_logfile = fopen("/tmp/radv_bo_history.log", "w+"); + if (!ws->bo_history_logfile) + fprintf(stderr, "radv/amdgpu: Failed to create /tmp/radv_bo_history.log.\n"); + } + ws->reserve_vmid = reserve_vmid; if (ws->reserve_vmid) { r = ac_drm_vm_reserve_vmid(ws->dev, 0); diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h index 6dd5c6ad913..b66ab253e96 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h @@ -30,6 +30,7 @@ struct radv_amdgpu_winsys { bool debug_all_bos; bool debug_log_bos; + FILE *bo_history_logfile; bool use_ib_bos; bool zero_all_vram_allocs; bool reserve_vmid;