mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-02 19:40:26 +01:00
turnip: virtio: fix iova leak upon found already imported dmabuf
There's a success path on found dmabuf while the iova won't be cleaned up. This change defers iova alloc till lookup miss and also to prepare for later racy dmabuf re-import fix. Also documented a potential leak on error path due to unable to tell whether a gem handle should be closed or not without refcounting. Fixes:f17c5297d7("tu: Add virtgpu support") Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29093> (cherry picked from commit6ca192f586)
This commit is contained in:
parent
8013c8fe3e
commit
bf9cd27575
2 changed files with 16 additions and 14 deletions
|
|
@ -664,7 +664,7 @@
|
|||
"description": "turnip: virtio: fix iova leak upon found already imported dmabuf",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "f17c5297d7a01eb37815f96bbf3a87667a2f3261",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -675,11 +675,6 @@ virtio_bo_init_dmabuf(struct tu_device *dev,
|
|||
/* iova allocation needs to consider the object's *real* size: */
|
||||
size = real_size;
|
||||
|
||||
uint64_t iova;
|
||||
result = virtio_allocate_userspace_iova(dev, size, 0, TU_BO_ALLOC_NO_FLAGS, &iova);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
/* Importing the same dmabuf several times would yield the same
|
||||
* gem_handle. Thus there could be a race when destroying
|
||||
* BO and importing the same dmabuf from different threads.
|
||||
|
|
@ -689,6 +684,7 @@ virtio_bo_init_dmabuf(struct tu_device *dev,
|
|||
u_rwlock_wrlock(&dev->dma_bo_lock);
|
||||
|
||||
uint32_t handle, res_id;
|
||||
uint64_t iova;
|
||||
|
||||
handle = vdrm_dmabuf_to_handle(vdrm, prime_fd);
|
||||
if (!handle) {
|
||||
|
|
@ -698,6 +694,7 @@ virtio_bo_init_dmabuf(struct tu_device *dev,
|
|||
|
||||
res_id = vdrm_handle_to_res_id(vdrm, handle);
|
||||
if (!res_id) {
|
||||
/* XXX gem_handle potentially leaked here since no refcnt */
|
||||
result = vk_error(dev, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
@ -714,21 +711,26 @@ virtio_bo_init_dmabuf(struct tu_device *dev,
|
|||
|
||||
bo->res_id = res_id;
|
||||
|
||||
result = tu_bo_init(dev, bo, handle, size, iova,
|
||||
TU_BO_ALLOC_NO_FLAGS, "dmabuf");
|
||||
if (result != VK_SUCCESS)
|
||||
memset(bo, 0, sizeof(*bo));
|
||||
else
|
||||
*out_bo = bo;
|
||||
result = virtio_allocate_userspace_iova(dev, size, 0, TU_BO_ALLOC_NO_FLAGS,
|
||||
&iova);
|
||||
if (result != VK_SUCCESS) {
|
||||
vdrm_bo_close(dev->vdev->vdrm, handle);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
u_rwlock_wrunlock(&dev->dma_bo_lock);
|
||||
result =
|
||||
tu_bo_init(dev, bo, handle, size, iova, TU_BO_ALLOC_NO_FLAGS, "dmabuf");
|
||||
if (result != VK_SUCCESS) {
|
||||
mtx_lock(&dev->vma_mutex);
|
||||
util_vma_heap_free(&dev->vma, iova, size);
|
||||
mtx_unlock(&dev->vma_mutex);
|
||||
memset(bo, 0, sizeof(*bo));
|
||||
} else {
|
||||
*out_bo = bo;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
u_rwlock_wrunlock(&dev->dma_bo_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue