mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 11:10:10 +01:00
virgl: fix reference counting of prime handles
The virgl reference counting of buffers is broken for prime fd buffers. Each prime fd passed into virgl_drm_winsys_resource_create_handle creates a new resource. The solution requires creating a separate hash table to track flink names separately from prime handles. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
f87330dbce
commit
2d3301e4d5
2 changed files with 35 additions and 14 deletions
|
|
@ -53,10 +53,17 @@ static void virgl_hw_res_destroy(struct virgl_drm_winsys *qdws,
|
|||
{
|
||||
struct drm_gem_close args;
|
||||
|
||||
if (res->name) {
|
||||
if (res->flinked) {
|
||||
pipe_mutex_lock(qdws->bo_handles_mutex);
|
||||
util_hash_table_remove(qdws->bo_names,
|
||||
(void *)(uintptr_t)res->flink);
|
||||
pipe_mutex_unlock(qdws->bo_handles_mutex);
|
||||
}
|
||||
|
||||
if (res->bo_handle) {
|
||||
pipe_mutex_lock(qdws->bo_handles_mutex);
|
||||
util_hash_table_remove(qdws->bo_handles,
|
||||
(void *)(uintptr_t)res->name);
|
||||
(void *)(uintptr_t)res->bo_handle);
|
||||
pipe_mutex_unlock(qdws->bo_handles_mutex);
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +119,7 @@ virgl_drm_winsys_destroy(struct virgl_winsys *qws)
|
|||
virgl_cache_flush(qdws);
|
||||
|
||||
util_hash_table_destroy(qdws->bo_handles);
|
||||
util_hash_table_destroy(qdws->bo_names);
|
||||
pipe_mutex_destroy(qdws->bo_handles_mutex);
|
||||
pipe_mutex_destroy(qdws->mutex);
|
||||
|
||||
|
|
@ -370,11 +378,12 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
|
|||
struct drm_gem_open open_arg = {};
|
||||
struct drm_virtgpu_resource_info info_arg = {};
|
||||
struct virgl_hw_res *res;
|
||||
uint32_t handle = whandle->handle;
|
||||
|
||||
pipe_mutex_lock(qdws->bo_handles_mutex);
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
|
||||
res = util_hash_table_get(qdws->bo_handles, (void*)(uintptr_t)whandle->handle);
|
||||
res = util_hash_table_get(qdws->bo_names, (void*)(uintptr_t)handle);
|
||||
if (res) {
|
||||
struct virgl_hw_res *r = NULL;
|
||||
virgl_drm_resource_reference(qdws, &r, res);
|
||||
|
|
@ -382,21 +391,31 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
|
|||
}
|
||||
}
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
|
||||
int r;
|
||||
r = drmPrimeFDToHandle(qdws->fd, whandle->handle, &handle);
|
||||
if (r) {
|
||||
res = NULL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
res = util_hash_table_get(qdws->bo_handles, (void*)(uintptr_t)handle);
|
||||
fprintf(stderr, "resource %p for handle %d, pfd=%d\n", res, handle, whandle->handle);
|
||||
if (res) {
|
||||
struct virgl_hw_res *r = NULL;
|
||||
virgl_drm_resource_reference(qdws, &r, res);
|
||||
goto done;
|
||||
}
|
||||
|
||||
res = CALLOC_STRUCT(virgl_hw_res);
|
||||
if (!res)
|
||||
goto done;
|
||||
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
|
||||
int r;
|
||||
uint32_t handle;
|
||||
r = drmPrimeFDToHandle(qdws->fd, whandle->handle, &handle);
|
||||
if (r) {
|
||||
FREE(res);
|
||||
res = NULL;
|
||||
goto done;
|
||||
}
|
||||
res->bo_handle = handle;
|
||||
} else {
|
||||
fprintf(stderr, "gem open handle %d\n", handle);
|
||||
memset(&open_arg, 0, sizeof(open_arg));
|
||||
open_arg.name = whandle->handle;
|
||||
if (drmIoctl(qdws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
|
||||
|
|
@ -406,7 +425,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
|
|||
}
|
||||
res->bo_handle = open_arg.handle;
|
||||
}
|
||||
res->name = whandle->handle;
|
||||
res->name = handle;
|
||||
|
||||
memset(&info_arg, 0, sizeof(info_arg));
|
||||
info_arg.bo_handle = res->bo_handle;
|
||||
|
|
@ -425,7 +444,7 @@ virgl_drm_winsys_resource_create_handle(struct virgl_winsys *qws,
|
|||
pipe_reference_init(&res->reference, 1);
|
||||
res->num_cs_references = 0;
|
||||
|
||||
util_hash_table_set(qdws->bo_handles, (void *)(uintptr_t)whandle->handle, res);
|
||||
util_hash_table_set(qdws->bo_handles, (void *)(uintptr_t)handle, res);
|
||||
|
||||
done:
|
||||
pipe_mutex_unlock(qdws->bo_handles_mutex);
|
||||
|
|
@ -455,7 +474,7 @@ static boolean virgl_drm_winsys_resource_get_handle(struct virgl_winsys *qws,
|
|||
res->flink = flink.name;
|
||||
|
||||
pipe_mutex_lock(qdws->bo_handles_mutex);
|
||||
util_hash_table_set(qdws->bo_handles, (void *)(uintptr_t)res->flink, res);
|
||||
util_hash_table_set(qdws->bo_names, (void *)(uintptr_t)res->flink, res);
|
||||
pipe_mutex_unlock(qdws->bo_handles_mutex);
|
||||
}
|
||||
whandle->handle = res->flink;
|
||||
|
|
@ -751,6 +770,7 @@ virgl_drm_winsys_create(int drmFD)
|
|||
pipe_mutex_init(qdws->mutex);
|
||||
pipe_mutex_init(qdws->bo_handles_mutex);
|
||||
qdws->bo_handles = util_hash_table_create(handle_hash, handle_compare);
|
||||
qdws->bo_names = util_hash_table_create(handle_hash, handle_compare);
|
||||
qdws->base.destroy = virgl_drm_winsys_destroy;
|
||||
|
||||
qdws->base.transfer_put = virgl_bo_transfer_put;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ struct virgl_drm_winsys
|
|||
pipe_mutex mutex;
|
||||
|
||||
struct util_hash_table *bo_handles;
|
||||
struct util_hash_table *bo_names;
|
||||
pipe_mutex bo_handles_mutex;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue