From a7a4abc8d87a05279197ed5d8271656197399a98 Mon Sep 17 00:00:00 2001 From: Natalie Vock Date: Mon, 1 Dec 2025 15:41:32 +0100 Subject: [PATCH] radv: Move VMID reservation to vkCreateDevice DXVK's DXGI implementation can create extra instances used for enumerating physical devices besides the games' instance. When reserving VMIDs for SPM, the DXGI instances may snatch the VMID reservation early, making VMID reservation for the instance that actually needs it fail. This starts being a problem on kernels 6.18+ where only one user may reserve a VMID at a time. Move reserving VMIDs to SQTT initialization inside vkCreateDevice so that only the instances that actually create logical devices try reserving VMIDs. Cc: mesa-stable Part-of: --- src/amd/vulkan/radv_physical_device.c | 5 +--- src/amd/vulkan/radv_radeon_winsys.h | 2 ++ src/amd/vulkan/radv_sqtt.c | 8 +++++ .../vulkan/winsys/amdgpu/radv_amdgpu_winsys.c | 30 +++++++++++-------- .../vulkan/winsys/amdgpu/radv_amdgpu_winsys.h | 1 - .../winsys/amdgpu/radv_amdgpu_winsys_public.h | 4 +-- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/amd/vulkan/radv_physical_device.c b/src/amd/vulkan/radv_physical_device.c index 11b9452a548..b4e5c46b37c 100644 --- a/src/amd/vulkan/radv_physical_device.c +++ b/src/amd/vulkan/radv_physical_device.c @@ -2338,10 +2338,7 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm } if (drm_device) { - bool reserve_vmid = instance->vk.trace_mode & RADV_TRACE_MODE_RGP; - - result = radv_amdgpu_winsys_create(fd, instance->debug_flags, instance->perftest_flags, reserve_vmid, is_virtio, - &pdev->ws); + result = radv_amdgpu_winsys_create(fd, instance->debug_flags, instance->perftest_flags, is_virtio, &pdev->ws); if (result != VK_SUCCESS) { result = vk_errorf(instance, result, "failed to initialize winsys"); diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index 6a2f396b989..70126064be6 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -323,6 +323,8 @@ struct radeon_winsys { uint32_t signal_count, const struct vk_sync_signal *signals); + int (*reserve_vmid)(struct radeon_winsys *ws); + void (*unreserve_vmid)(struct radeon_winsys *ws); }; static inline uint64_t diff --git a/src/amd/vulkan/radv_sqtt.c b/src/amd/vulkan/radv_sqtt.c index ceda774eee8..b78c41d483b 100644 --- a/src/amd/vulkan/radv_sqtt.c +++ b/src/amd/vulkan/radv_sqtt.c @@ -392,6 +392,11 @@ radv_sqtt_init(struct radv_device *device) device->sqtt.buffer_size = (uint32_t)debug_get_num_option("RADV_THREAD_TRACE_BUFFER_SIZE", 32 * 1024 * 1024); device->sqtt.instruction_timing_enabled = radv_is_instruction_timing_enabled(); + if (device->ws->reserve_vmid(device->ws) < 0) { + fprintf(stderr, "radv: Failed to reserve VMID for SQTT tracing.\n"); + return false; + } + if (!radv_sqtt_init_bo(device)) return false; @@ -427,6 +432,9 @@ radv_sqtt_finish(struct radv_device *device) radv_unregister_queues(device, sqtt); ac_sqtt_finish(sqtt); + + if (device->ws) + device->ws->unreserve_vmid(device->ws); } static bool diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c index 6f9d0147129..b67671bbef2 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.c @@ -143,9 +143,6 @@ radv_amdgpu_winsys_destroy(struct radeon_winsys *rws) ac_drm_cs_destroy_syncobj(ws->dev, ws->vm_timeline_syncobj); simple_mtx_destroy(&ws->vm_ioctl_lock); - if (ws->reserve_vmid) - ac_drm_vm_unreserve_vmid(ws->dev, 0); - if (ws->bo_history_logfile) fclose(ws->bo_history_logfile); @@ -177,6 +174,20 @@ radv_amdgpu_winsys_get_sync_provider(struct radeon_winsys *rws) return p->clone(p); } +static int +radv_amdgpu_winsys_reserve_vmid(struct radeon_winsys *rws) +{ + struct radv_amdgpu_winsys *ws = (struct radv_amdgpu_winsys *)rws; + return ac_drm_vm_reserve_vmid(ws->dev, 0); +} + +static void +radv_amdgpu_winsys_unreserve_vmid(struct radeon_winsys *rws) +{ + struct radv_amdgpu_winsys *ws = (struct radv_amdgpu_winsys *)rws; + ac_drm_vm_unreserve_vmid(ws->dev, 0); +} + static uint64_t radv_amdgpu_winsys_filter_perftest_flags(uint64_t perftest_flags) { @@ -185,7 +196,7 @@ radv_amdgpu_winsys_filter_perftest_flags(uint64_t perftest_flags) } VkResult -radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, bool reserve_vmid, bool is_virtio, +radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, bool is_virtio, struct radeon_winsys **winsys) { VkResult result = VK_SUCCESS; @@ -289,15 +300,6 @@ radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, 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); - if (r) { - fprintf(stderr, "radv/amdgpu: failed to reserve vmid.\n"); - result = VK_ERROR_INITIALIZATION_FAILED; - goto winsys_fail; - } - } int num_sync_types = 0; ws->syncobj_sync_type = vk_drm_syncobj_get_type_from_provider(ac_drm_device_get_sync_provider(dev)); @@ -338,6 +340,8 @@ radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, ws->base.get_sync_types = radv_amdgpu_winsys_get_sync_types; ws->base.get_sync_provider = radv_amdgpu_winsys_get_sync_provider; ws->base.copy_sync_payloads = vk_drm_syncobj_copy_payloads; + ws->base.reserve_vmid = radv_amdgpu_winsys_reserve_vmid; + ws->base.unreserve_vmid = radv_amdgpu_winsys_unreserve_vmid; radv_amdgpu_bo_init_functions(ws); radv_amdgpu_cs_init_functions(ws); diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h index b68afe8d4d9..cce30ca7f93 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys.h @@ -35,7 +35,6 @@ struct radv_amdgpu_winsys { FILE *bo_history_logfile; bool chain_ib; bool zero_all_vram_allocs; - bool reserve_vmid; uint64_t perftest; alignas(8) uint64_t allocated_vram; diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys_public.h b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys_public.h index 438d9285b65..fabd1604e60 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys_public.h +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_winsys_public.h @@ -12,8 +12,8 @@ #ifndef RADV_AMDGPU_WINSYS_PUBLIC_H #define RADV_AMDGPU_WINSYS_PUBLIC_H -VkResult radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, bool reserve_vmid, - bool is_virtio, struct radeon_winsys **winsys); +VkResult radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, bool is_virtio, + struct radeon_winsys **winsys); struct radeon_winsys *radv_dummy_winsys_create(void);