radv: Move VMID reservation to vkCreateDevice
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38746>
This commit is contained in:
Natalie Vock 2025-12-01 15:41:32 +01:00 committed by Marge Bot
parent fa1fd2413f
commit a7a4abc8d8
6 changed files with 30 additions and 20 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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