From 87a0eac7184ecde4ba76e62d31f742e1934f4af8 Mon Sep 17 00:00:00 2001 From: Jose Maria Casanova Crespo Date: Sat, 16 May 2026 18:24:55 +0200 Subject: [PATCH] v3dv: avoid duplicate bo_handles between cpu_job and CSD lists v3d_submit_cpu_ioctl() takes a separate ww_acquire_ctx for the cpu_job's bo_handles[] and any embedded CSD's bo_handles[]; a BO appearing in both lists makes the second lock wait on a reservation held by the first context, deadlocking the ioctl. We avoid adding a duplicate BO handle when it's already in the cpu_job's list. This collided when an app suballocates an indirect VkBuffer and a CSD bind-group VkBuffer out of one VkDeviceMemory. Fixes: e404ccba5b4 ("v3dv: use the indirect CSD user extension") Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_queue.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c index 9f14c7629c4..6c001f6e8b8 100644 --- a/src/broadcom/vulkan/v3dv_queue.c +++ b/src/broadcom/vulkan/v3dv_queue.c @@ -866,13 +866,16 @@ handle_csd_indirect_cpu_job(struct v3dv_queue *queue, submit.bo_handle_count = 1; submit.bo_handles = (uintptr_t)(void *)&bo->handle; - csd_job->csd.submit.bo_handle_count = csd_job->bo_count; uint32_t *bo_handles = (uint32_t *) malloc(sizeof(uint32_t) * csd_job->bo_count); uint32_t bo_idx = 0; set_foreach (csd_job->bos, entry) { - struct v3dv_bo *bo = (struct v3dv_bo *)entry->key; - bo_handles[bo_idx++] = bo->handle; + struct v3dv_bo *csd_bo = (struct v3dv_bo *)entry->key; + /* dedup against cpu_job bo */ + if (csd_bo->handle == bo->handle) + continue; + bo_handles[bo_idx++] = csd_bo->handle; } + csd_job->csd.submit.bo_handle_count = bo_idx; csd_job->csd.submit.bo_handles = (uintptr_t)(void *)bo_handles; struct drm_v3d_indirect_csd indirect = {0};