From 9acce36652b4c56948a5333c729d3b5646190b3d Mon Sep 17 00:00:00 2001 From: Mel Henning Date: Wed, 12 Nov 2025 17:44:36 -0500 Subject: [PATCH] zink: Create one queue lock per device We currently only create one queue per queue family on the device. The device can be shared between multiple zink_screens, so having one lock per screen can still lead to multiple locks per queue. Fix this by allocating queue_lock along with the device. This fixes an issue that was causing crashes with nvk+zink and QtWebEngine with QTWEBENGINE_FORCE_USE_GBM=1 This can be reproduced by resizing the window in either: * anki - https://apps.ankiweb.net/ or * Qt's simplebrowser example https://doc.qt.io/qt-6/qtwebengine-webenginewidgets-simplebrowser-example.html which would then cause this dmesg error: nouveau 0000:01:00.0: anki[92007]: Failed to find syncobj (-> in): handle=40 along with a context loss. With VK_LOADER_LAYERS_ENABLE=VK_LAYER_KHRONOS_validation we would additionally get warnings like: Validation Error: [ UNASSIGNED-Threading-MultipleThreads-Write ] | MessageID = 0xa05b236e vkQueueSubmit(): THREADING ERROR : object of type VkQueue is simultaneously used in current thread 139824449189568 and thread 139823901816512 Objects: 1 [0] VkQueue 0x557a666783e0 Fixes: 015eda4a4186c ("zink: deduplicate VkDevice and VkInstance") Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_screen.c | 10 ++++++---- src/gallium/drivers/zink/zink_types.h | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index fef111c5dd5..f6a0f28f800 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -145,6 +145,7 @@ struct zink_device { VkPhysicalDevice pdev; VkDevice dev; struct zink_device_info *info; + simple_mtx_t queue_lock; }; static simple_mtx_t device_lock = SIMPLE_MTX_INITIALIZER; @@ -1832,8 +1833,6 @@ update_queue_props(struct zink_screen *screen) static void init_queue(struct zink_screen *screen) { - simple_mtx_init(&screen->queue_lock_storage, mtx_plain); - screen->queue_lock = &screen->queue_lock_storage; VKSCR(GetDeviceQueue)(screen->dev, screen->gfx_queue, 0, &screen->queue); if (screen->sparse_queue != screen->gfx_queue) VKSCR(GetDeviceQueue)(screen->dev, screen->sparse_queue, 0, &screen->queue_sparse); @@ -2760,6 +2759,7 @@ get_device(struct zink_screen *screen, VkDeviceCreateInfo *dci) zdev->refcount = 1; zdev->pdev = screen->pdev; zdev->dev = dev; + simple_mtx_init(&zdev->queue_lock, mtx_plain); _mesa_set_add(&device_table, zdev); simple_mtx_unlock(&device_lock); return zdev; @@ -3523,9 +3523,11 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev init_driver_workarounds(screen); disable_features(screen); - screen->dev = zink_create_logical_device(screen)->dev; - if (!screen->dev) + struct zink_device *zdev = zink_create_logical_device(screen); + if (!zdev->dev) goto fail; + screen->dev = zdev->dev; + screen->queue_lock = &zdev->queue_lock; vk_device_uncompacted_dispatch_table_load(&screen->vk.device, screen->vk_GetDeviceProcAddr, diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index f2a03ed90c4..c174930e83b 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1481,7 +1481,6 @@ struct zink_screen { VkQueue queue; //gfx+compute VkQueue queue_sparse; simple_mtx_t *queue_lock; - simple_mtx_t queue_lock_storage; VkDebugUtilsMessengerEXT debugUtilsCallbackHandle; uint32_t cur_custom_border_color_samplers;