summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChangyeon Lee <cyeon.lee@samsung.com>2021-04-08 17:47:03 +0900
committerChangyeon Lee <cyeon.lee@samsung.com>2021-04-08 17:53:24 +0900
commitc9deb29166723207883c78750e4cc928df4271bf (patch)
tree0c83d0628d4f863751acb26f2a27b8db1b2c876e
parent0ff413cbd14305a63bbe3f8758d7a2d91fd1aecf (diff)
downloadlibtbm-vigs-c9deb29166723207883c78750e4cc928df4271bf.tar.gz
libtbm-vigs-c9deb29166723207883c78750e4cc928df4271bf.tar.bz2
libtbm-vigs-c9deb29166723207883c78750e4cc928df4271bf.zip
Add hash of bos using gem name
when one bo is may times imported by fd in process, vigs_drm_prime_import_fd create vigs_drm_surface but gem handle is always the same. it causes a problem that gem handle is closed even if another tbm_bo uses it. Change-Id: I9663ff18422166dd3fefe37a0b35b44ebad83dbc
-rw-r--r--src/libhal-backend-tbm-vigs/tbm_backend_vigs.c135
-rwxr-xr-xsrc/libtbm-vigs/tbm_bufmgr_vigs.c134
2 files changed, 269 insertions, 0 deletions
diff --git a/src/libhal-backend-tbm-vigs/tbm_backend_vigs.c b/src/libhal-backend-tbm-vigs/tbm_backend_vigs.c
index 4a9aeb6..011a4fe 100644
--- a/src/libhal-backend-tbm-vigs/tbm_backend_vigs.c
+++ b/src/libhal-backend-tbm-vigs/tbm_backend_vigs.c
@@ -79,6 +79,8 @@ struct _tbm_vigs_bo {
/* tbm bufmgr private for vigs */
struct _tbm_vigs_bufmgr {
int fd;
+ void *hash_bos;
+
struct vigs_drm_device *drm_dev;
};
@@ -96,6 +98,20 @@ _tbm_vigs_open_drm(void)
return fd;
}
+static unsigned int
+_get_name(int fd, unsigned int gem)
+{
+ struct drm_gem_flink arg = {0,};
+
+ arg.handle = gem;
+ if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
+ TBM_BACKEND_ERR("fail to DRM_IOCTL_GEM_FLINK gem:%d", gem);
+ return 0;
+ }
+
+ return (unsigned int)arg.name;
+}
+
static hal_tbm_bo_handle
get_tbm_bo_handle(struct vigs_drm_surface *sfc, int device)
{
@@ -297,6 +313,19 @@ tbm_vigs_bufmgr_alloc_bo(hal_tbm_bufmgr *bufmgr, unsigned int size,
bo_data->bufmgr_data = bufmgr_data;
bo_data->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_data);
+ if (error)
+ *error = HAL_TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
+ TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
+
TBM_BACKEND_DBG("size = %d, flags = 0x%X", size, flags);
if (error)
@@ -378,6 +407,19 @@ tbm_vigs_bufmgr_alloc_bo_with_format(hal_tbm_bufmgr *bufmgr, int format, int bo
bo_data->bufmgr_data = bufmgr_data;
bo_data->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_data);
+ if (error)
+ *error = HAL_TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
+ TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
+
TBM_BACKEND_DBG("width = %d, height = %d, format = %x, flags = 0x%X bo_idx = %d",
width, height, format, flags, bo_idx);
@@ -396,6 +438,9 @@ tbm_vigs_bufmgr_import_fd(hal_tbm_bufmgr *bufmgr, hal_tbm_fd key, hal_tbm_error
struct vigs_drm_surface *sfc;
int ret;
char buf[STRERR_BUFSIZE];
+ struct drm_prime_handle arg = {0, };
+ unsigned int gem;
+ unsigned int name;
if (bufmgr_data == NULL || bufmgr_data->drm_dev == NULL) {
TBM_BACKEND_ERR("bufmgr_data is null\n");
@@ -406,6 +451,34 @@ tbm_vigs_bufmgr_import_fd(hal_tbm_bufmgr *bufmgr, hal_tbm_fd key, hal_tbm_error
drm_dev = bufmgr_data->drm_dev;
+ arg.fd = key;
+ if (drmIoctl(bufmgr_data->drm_dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
+ TBM_BACKEND_ERR("Cannot get gem handle from fd:%d (%s)\n",
+ arg.fd, strerror_r(errno, buf, STRERR_BUFSIZE));
+ if (error)
+ *error = HAL_TBM_ERROR_INVALID_OPERATION;
+ return NULL;
+ }
+ gem = arg.handle;
+
+ name = _get_name(bufmgr_data->drm_dev->fd, gem);
+ if (!name) {
+ TBM_BACKEND_ERR("Cannot get name from gem:%d, fd:%d (%s)\n",
+ gem, key, strerror_r(errno, buf, STRERR_BUFSIZE));
+ if (error)
+ *error = HAL_TBM_ERROR_INVALID_OPERATION;
+ return NULL;
+ }
+
+ ret = drmHashLookup(bufmgr_data->hash_bos, name, (void **)&bo_data);
+ if (ret == 0) {
+ if (gem == bo_data->sfc->gem.handle) {
+ if (error)
+ *error = HAL_TBM_ERROR_NONE;
+ return (hal_tbm_bo *)bo_data;
+ }
+ }
+
ret = vigs_drm_prime_import_fd(drm_dev, key, &sfc);
if (ret != 0) {
TBM_BACKEND_ERR("vigs_drm_prime_import_fd failed for key %d: %s",
@@ -426,6 +499,19 @@ tbm_vigs_bufmgr_import_fd(hal_tbm_bufmgr *bufmgr, hal_tbm_fd key, hal_tbm_error
bo_data->bufmgr_data = bufmgr_data;
bo_data->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_data);
+ if (error)
+ *error = HAL_TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
+ TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
+
TBM_BACKEND_DBG("bo_data = %p, key = %u handle = %u", bo_data, key, sfc->gem.handle);
if (error)
@@ -453,6 +539,13 @@ tbm_vigs_bufmgr_import_key(hal_tbm_bufmgr *bufmgr, hal_tbm_key key, hal_tbm_erro
drm_dev = bufmgr_data->drm_dev;
+ ret = drmHashLookup(bufmgr_data->hash_bos, key, (void **)&bo_data);
+ if (ret == 0) {
+ if (error)
+ *error = HAL_TBM_ERROR_NONE;
+ return (hal_tbm_bo *)bo_data;
+ }
+
ret = vigs_drm_surface_open(drm_dev, key, &sfc);
if (ret != 0) {
TBM_BACKEND_ERR("vigs_drm_surface_open failed for key %u: %s",
@@ -473,6 +566,19 @@ tbm_vigs_bufmgr_import_key(hal_tbm_bufmgr *bufmgr, hal_tbm_key key, hal_tbm_erro
bo_data->bufmgr_data = bufmgr_data;
bo_data->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_BACKEND_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_data);
+ if (error)
+ *error = HAL_TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_data->hash_bos, bo_data->sfc->gem.name, (void *)bo_data) < 0)
+ TBM_BACKEND_ERR("Cannot insert bo_data to Hash(%d)\n", bo_data->sfc->gem.name);
+
TBM_BACKEND_DBG("bo_data = %p, key = %u handle = %u", bo_data, key, sfc->gem.handle);
if (error)
@@ -485,15 +591,30 @@ static void
tbm_vigs_bo_free(hal_tbm_bo *bo)
{
tbm_vigs_bo *bo_data = (tbm_vigs_bo *)bo;
+ tbm_vigs_bo *temp;
struct vigs_drm_surface *sfc;
+ tbm_vigs_bufmgr *bufmgr_data;
+ int ret;
if (!bo_data)
return;
+ bufmgr_data = bo_data->bufmgr_data;
+ if (!bufmgr_data)
+ return;
+
TBM_BACKEND_DBG("bo_data = %p", bo_data);
sfc = bo_data->sfc;
+ /* delete bo from hash */
+ ret = drmHashLookup(bufmgr_data->hash_bos, bo_data->sfc->gem.name,
+ (void **)&temp);
+ if (ret == 0)
+ drmHashDelete(bufmgr_data->hash_bos, bo_data->sfc->gem.name);
+ else
+ TBM_BACKEND_ERR("Cannot find bo_data to Hash(%d), ret=%d\n", bo_data->sfc->gem.name, ret);
+
vigs_drm_gem_unref(&sfc->gem);
}
@@ -779,6 +900,8 @@ hal_backend_tbm_vigs_exit(void *data)
{
hal_tbm_backend_data *backend_data = (hal_tbm_backend_data *)data;
tbm_vigs_bufmgr *bufmgr_data;
+ unsigned long key;
+ void *value;
TBM_BACKEND_DBG("enter");
@@ -787,6 +910,16 @@ hal_backend_tbm_vigs_exit(void *data)
bufmgr_data = (tbm_vigs_bufmgr *)backend_data->bufmgr;
TBM_BACKEND_RETURN_VAL_IF_FAIL(bufmgr_data != NULL, -1);
+ if (bufmgr_data->hash_bos) {
+ while (drmHashFirst(bufmgr_data->hash_bos, &key, &value) > 0) {
+ free(value);
+ drmHashDelete(bufmgr_data->hash_bos, key);
+ }
+
+ drmHashDestroy(bufmgr_data->hash_bos);
+ bufmgr_data->hash_bos = NULL;
+ }
+
if (backend_data->bufmgr_funcs)
free(backend_data->bufmgr_funcs);
if (backend_data->bo_funcs)
@@ -870,6 +1003,8 @@ hal_backend_tbm_vigs_init(void **data)
TBM_BACKEND_INFO("A backend requests an authenticated drm_fd.\n");
}
+ bufmgr_data->hash_bos = drmHashCreate();
+
/* alloc and register bufmgr_funcs */
bufmgr_funcs = calloc(1, sizeof(struct _hal_tbm_bufmgr_funcs));
if (!bufmgr_funcs) {
diff --git a/src/libtbm-vigs/tbm_bufmgr_vigs.c b/src/libtbm-vigs/tbm_bufmgr_vigs.c
index d2b6d0b..bceb59b 100755
--- a/src/libtbm-vigs/tbm_bufmgr_vigs.c
+++ b/src/libtbm-vigs/tbm_bufmgr_vigs.c
@@ -78,6 +78,7 @@ struct _tbm_bo_vigs {
/* tbm bufmgr private for vigs */
struct _tbm_bufmgr_vigs {
struct vigs_drm_device *drm_dev;
+ void *hash_bos;
tbm_backend_bufmgr_func *bufmgr_func;
tbm_backend_bo_func *bo_func;
@@ -98,6 +99,20 @@ static int _tbm_vigs_open_drm(void)
return fd;
}
+static unsigned int
+_get_name(int fd, unsigned int gem)
+{
+ struct drm_gem_flink arg = {0,};
+
+ arg.handle = gem;
+ if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) {
+ TBM_ERR("fail to DRM_IOCTL_GEM_FLINK gem:%d", gem);
+ return 0;
+ }
+
+ return (unsigned int)arg.name;
+}
+
static tbm_bo_handle get_tbm_bo_handle(struct vigs_drm_surface *sfc, int device)
{
tbm_bo_handle bo_handle;
@@ -332,6 +347,19 @@ tbm_vigs_bufmgr_alloc_bo(tbm_backend_bufmgr_data *bufmgr_data, unsigned int size
bo_vigs->bufmgr_vigs = bufmgr_vigs;
bo_vigs->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_vigs);
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
+ TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
+
TBM_DBG("size = %d, flags = 0x%X", size, flags);
if (error)
@@ -413,6 +441,19 @@ tbm_bufmgr_vigs_alloc_bo_with_format(tbm_backend_bufmgr_data *bufmgr_data, int f
bo_vigs->bufmgr_vigs = bufmgr_vigs;
bo_vigs->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_vigs);
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
+ TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
+
TBM_DBG("width = %d, height = %d, format = %x, flags = 0x%X bo_idx = %d",
width, height, format, flags, bo_idx);
@@ -431,6 +472,9 @@ tbm_vigs_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_
struct vigs_drm_surface *sfc;
int ret;
char buf[STRERR_BUFSIZE];
+ struct drm_prime_handle arg = {0, };
+ unsigned int gem;
+ unsigned int name;
if (bufmgr_vigs == NULL || bufmgr_vigs->drm_dev == NULL) {
TBM_ERR("bufmgr_data is null\n");
@@ -441,6 +485,34 @@ tbm_vigs_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_
drm_dev = bufmgr_vigs->drm_dev;
+ arg.fd = key;
+ if (drmIoctl(bufmgr_vigs->drm_dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) {
+ TBM_ERR("Cannot get gem handle from fd:%d (%s)\n",
+ arg.fd, strerror_r(errno, buf, STRERR_BUFSIZE));
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ return NULL;
+ }
+ gem = arg.handle;
+
+ name = _get_name(bufmgr_vigs->drm_dev->fd, gem);
+ if (!name) {
+ TBM_ERR("Cannot get name from gem:%d, fd:%d (%s)\n",
+ gem, key, strerror_r(errno, buf, STRERR_BUFSIZE));
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ return NULL;
+ }
+
+ ret = drmHashLookup(bufmgr_vigs->hash_bos, name, (void **)&bo_vigs);
+ if (ret == 0) {
+ if (gem == bo_vigs->sfc->gem.handle) {
+ if (error)
+ *error = TBM_ERROR_NONE;
+ return (tbm_backend_bo_data *)bo_vigs;
+ }
+ }
+
ret = vigs_drm_prime_import_fd(drm_dev, key, &sfc);
if (ret != 0) {
TBM_ERR("vigs_drm_prime_import_fd failed for key %d: %s",
@@ -461,6 +533,19 @@ tbm_vigs_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_
bo_vigs->bufmgr_vigs = bufmgr_vigs;
bo_vigs->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_vigs);
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
+ TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
+
TBM_DBG("bo_vigs = %p, key = %u handle = %u", bo_vigs, key, sfc->gem.handle);
if (error)
@@ -488,6 +573,13 @@ tbm_vigs_bufmgr_import_key(tbm_backend_bufmgr_data *bufmgr_data, tbm_key key, tb
drm_dev = bufmgr_vigs->drm_dev;
+ ret = drmHashLookup(bufmgr_vigs->hash_bos, key, (void **)&bo_vigs);
+ if (ret == 0) {
+ if (error)
+ *error = TBM_ERROR_NONE;
+ return (tbm_backend_bo_data *)bo_vigs;
+ }
+
ret = vigs_drm_surface_open(drm_dev, key, &sfc);
if (ret != 0) {
TBM_ERR("vigs_drm_surface_open failed for key %u: %s",
@@ -508,6 +600,19 @@ tbm_vigs_bufmgr_import_key(tbm_backend_bufmgr_data *bufmgr_data, tbm_key key, tb
bo_vigs->bufmgr_vigs = bufmgr_vigs;
bo_vigs->sfc = sfc;
+ ret = vigs_drm_gem_get_name(&sfc->gem);
+ if (ret != 0) {
+ TBM_ERR("vigs_drm_gem_get_name failed: %s", strerror_r(errno, buf, STRERR_BUFSIZE));
+ vigs_drm_gem_unref(&sfc->gem);
+ free(bo_vigs);
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ return 0;
+ }
+
+ if (drmHashInsert(bufmgr_vigs->hash_bos, bo_vigs->sfc->gem.name, (void *)bo_vigs) < 0)
+ TBM_ERR("Cannot insert bo_vigs to Hash(%d)\n", bo_vigs->sfc->gem.name);
+
TBM_DBG("bo_vigs = %p, key = %u handle = %u", bo_vigs, key, sfc->gem.handle);
if (error)
@@ -520,15 +625,30 @@ static void
tbm_vigs_bo_free(tbm_backend_bo_data *bo_data)
{
tbm_bo_vigs bo_vigs = (tbm_bo_vigs)bo_data;
+ tbm_bo_vigs temp;
struct vigs_drm_surface *sfc;
+ tbm_bufmgr_vigs bufmgr_vigs;
+ int ret;
if (!bo_data)
return;
+ bufmgr_vigs = bo_vigs->bufmgr_vigs;
+ if (!bufmgr_vigs)
+ return;
+
TBM_DBG("bo_vigs = %p", bo_vigs);
sfc = bo_vigs->sfc;
+ /* delete bo from hash */
+ ret = drmHashLookup(bufmgr_vigs->hash_bos, sfc->gem.name,
+ (void **)&temp);
+ if (ret == 0)
+ drmHashDelete(bufmgr_vigs->hash_bos, sfc->gem.name);
+ else
+ TBM_ERR("Cannot find bo_vigs to Hash(%d), ret=%d\n", sfc->gem.name, ret);
+
vigs_drm_gem_unref(&sfc->gem);
}
@@ -767,6 +887,8 @@ tbm_vigs_deinit(tbm_backend_bufmgr_data *bufmgr_data)
struct vigs_drm_device *drm_dev;
tbm_error_e error;
tbm_bufmgr bufmgr;
+ unsigned long key;
+ void *value;
TBM_DBG("enter");
@@ -781,6 +903,16 @@ tbm_vigs_deinit(tbm_backend_bufmgr_data *bufmgr_data)
if (!bufmgr)
return;
+ if (bufmgr_vigs->hash_bos) {
+ while (drmHashFirst(bufmgr_vigs->hash_bos, &key, &value) > 0) {
+ free(value);
+ drmHashDelete(bufmgr_vigs->hash_bos, key);
+ }
+
+ drmHashDestroy(bufmgr_vigs->hash_bos);
+ bufmgr_vigs->hash_bos = NULL;
+ }
+
if (tbm_backend_bufmgr_query_display_server(bufmgr, &error)) {
tbm_drm_helper_wl_auth_server_deinit();
tbm_drm_helper_unset_tbm_master_fd();
@@ -867,6 +999,8 @@ tbm_vigs_init(tbm_bufmgr bufmgr, tbm_error_e *error)
bufmgr_vigs->drm_dev = drm_dev;
g_drm_dev = drm_dev;
+ bufmgr_vigs->hash_bos = drmHashCreate();
+
/* alloc and register bufmgr_funcs */
bufmgr_func = tbm_backend_bufmgr_alloc_bufmgr_func(bufmgr, &err);
if (!bufmgr_func) {