diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c b/src/gallium/drivers/vc4/vc4_bufmgr.c index 7a366caf6a1..7c1195e3ff3 100644 --- a/src/gallium/drivers/vc4/vc4_bufmgr.c +++ b/src/gallium/drivers/vc4/vc4_bufmgr.c @@ -382,9 +382,11 @@ vc4_bo_open_handle(struct vc4_screen *screen, { struct vc4_bo *bo; - assert(size); + /* Note: the caller is responsible for locking screen->bo_handles_mutex. + * This allows the lock to cover the actual BO import, avoiding a race. + */ - mtx_lock(&screen->bo_handles_mutex); + assert(size); bo = util_hash_table_get(screen->bo_handles, (void*)(uintptr_t)handle); if (bo) { @@ -418,10 +420,14 @@ vc4_bo_open_name(struct vc4_screen *screen, uint32_t name) struct drm_gem_open o = { .name = name }; + + mtx_lock(&screen->bo_handles_mutex); + int ret = vc4_ioctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o); if (ret) { fprintf(stderr, "Failed to open bo %d: %s\n", name, strerror(errno)); + mtx_unlock(&screen->bo_handles_mutex); return NULL; } @@ -432,10 +438,14 @@ struct vc4_bo * vc4_bo_open_dmabuf(struct vc4_screen *screen, int fd) { uint32_t handle; + + mtx_lock(&screen->bo_handles_mutex); + int ret = drmPrimeFDToHandle(screen->fd, fd, &handle); int size; if (ret) { fprintf(stderr, "Failed to get vc4 handle for dmabuf %d\n", fd); + mtx_unlock(&screen->bo_handles_mutex); return NULL; } @@ -443,6 +453,7 @@ vc4_bo_open_dmabuf(struct vc4_screen *screen, int fd) size = lseek(fd, 0, SEEK_END); if (size == -1) { fprintf(stderr, "Couldn't get size of dmabuf fd %d.\n", fd); + mtx_unlock(&screen->bo_handles_mutex); return NULL; }