diff options
author | Changyeon Lee <cyeon.lee@samsung.com> | 2021-04-08 17:47:03 +0900 |
---|---|---|
committer | Changyeon Lee <cyeon.lee@samsung.com> | 2021-04-08 17:53:24 +0900 |
commit | c9deb29166723207883c78750e4cc928df4271bf (patch) | |
tree | 0c83d0628d4f863751acb26f2a27b8db1b2c876e | |
parent | 0ff413cbd14305a63bbe3f8758d7a2d91fd1aecf (diff) | |
download | libtbm-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.c | 135 | ||||
-rwxr-xr-x | src/libtbm-vigs/tbm_bufmgr_vigs.c | 134 |
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) { |