From ec1cdc13d5cf6026692bf3765be3aeceb511e6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Sat, 12 Nov 2022 01:51:00 +0100 Subject: [PATCH] v3dv/bo: reset bo and then call gem close After 'v3dv: fix debug dump on BO free' we changed the order, and this lead to the following test dEQP-VK.api.object_management.multithreaded_per_thread_resources.device_memory_small v2: Expanded comment just before the reset, explaining that we need to do the reset before we free the BO from the kernel (Iago) Raising this assertion: deqp-vk: ../src/broadcom/vulkan/v3dv_bo.c:281: v3dv_bo_alloc: Assertion `bo && bo->handle == 0' failed. Fixes: 2c44597181e2 ('v3dv: fix debug dump on BO free') Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_bo.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_bo.c b/src/broadcom/vulkan/v3dv_bo.c index c51b1924560..9f1bf423af1 100644 --- a/src/broadcom/vulkan/v3dv_bo.c +++ b/src/broadcom/vulkan/v3dv_bo.c @@ -135,13 +135,6 @@ bo_free(struct v3dv_device *device, assert(p_atomic_read(&bo->refcnt) == 0); assert(bo->map == NULL); - struct drm_gem_close c; - memset(&c, 0, sizeof(c)); - c.handle = bo->handle; - int ret = v3dv_ioctl(device->pdevice->render_fd, DRM_IOCTL_GEM_CLOSE, &c); - if (ret != 0) - fprintf(stderr, "close object %d: %s\n", bo->handle, strerror(errno)); - if (!bo->is_import) { device->bo_count--; device->bo_size -= bo->size; @@ -155,12 +148,24 @@ bo_free(struct v3dv_device *device, } } + uint32_t handle = bo->handle; /* Our BO structs are stored in a sparse array in the physical device, * so we don't want to free the BO pointer, instead we want to reset it * to 0, to signal that array entry as being free. + * + * We must do the reset before we actually free the BO in the kernel, since + * otherwise there is a chance the application creates another BO in a + * different thread and gets the same array entry, causing a race. */ memset(bo, 0, sizeof(*bo)); + struct drm_gem_close c; + memset(&c, 0, sizeof(c)); + c.handle = handle; + int ret = v3dv_ioctl(device->pdevice->render_fd, DRM_IOCTL_GEM_CLOSE, &c); + if (ret != 0) + fprintf(stderr, "close object %d: %s\n", handle, strerror(errno)); + return ret == 0; }