From c6468f66c7a47f0e16df2f1200db33eef6d2d1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 23 Dec 2019 18:51:57 +0100 Subject: [PATCH] winsys/amdgpu: Only re-export KMS handles for different DRM FDs When the amdgpu_screen_winsys uses the same FD as the amdgpu_winsys (which is always the case for the first amdgpu_screen_winsys), we can just use bo->u.real.kms_handle. v2: * Also only create the kms_handles hash table if the amdgpu_screen_winsys fd is different from the amdgpu_winsys one. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 16 +++++++++++-- src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 23 +++++++++++-------- src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h | 4 ++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index 5f44b02d351..e6a5a7773e0 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -184,8 +184,10 @@ void amdgpu_bo_destroy(struct pb_buffer *_buf) } simple_mtx_lock(&ws->sws_list_lock); - for (sws_iter = ws->sws_list; sws_iter; sws_iter = sws_iter->next) - _mesa_hash_table_remove_key(sws_iter->kms_handles, bo); + for (sws_iter = ws->sws_list; sws_iter; sws_iter = sws_iter->next) { + if (sws_iter->kms_handles) + _mesa_hash_table_remove_key(sws_iter->kms_handles, bo); + } simple_mtx_unlock(&ws->sws_list_lock); simple_mtx_lock(&ws->bo_export_table_lock); @@ -1551,6 +1553,15 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, type = amdgpu_bo_handle_type_gem_flink_name; break; case WINSYS_HANDLE_TYPE_KMS: + if (sws->fd == ws->fd) { + whandle->handle = bo->u.real.kms_handle; + + if (bo->is_shared) + return true; + + goto hash_table_set; + } + simple_mtx_lock(&ws->sws_list_lock); entry = _mesa_hash_table_search(sws->kms_handles, bo); simple_mtx_unlock(&ws->sws_list_lock); @@ -1586,6 +1597,7 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, simple_mtx_unlock(&ws->sws_list_lock); } + hash_table_set: simple_mtx_lock(&ws->bo_export_table_lock); util_hash_table_set(ws->bo_export_table, bo->bo, bo); simple_mtx_unlock(&ws->bo_export_table_lock); diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index 7bc5fed02f6..000abd00a14 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -188,7 +188,11 @@ static void amdgpu_winsys_destroy(struct radeon_winsys *rws) simple_mtx_unlock(&ws->sws_list_lock); } - _mesa_hash_table_destroy(sws->kms_handles, NULL); + if (sws->kms_handles) { + assert(!destroy); + _mesa_hash_table_destroy(sws->kms_handles, NULL); + } + close(sws->fd); FREE(rws); } @@ -336,11 +340,6 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, ws->fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); - ws->kms_handles = _mesa_hash_table_create(NULL, kms_handle_hash, - kms_handle_equals); - if (!ws->kms_handles) - goto fail; - /* Look up the winsys from the dev table. */ simple_mtx_lock(&dev_tab_mutex); if (!dev_tab) @@ -348,7 +347,7 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, /* Initialize the amdgpu device. This should always return the same pointer * for the same fd. */ - r = amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev); + r = amdgpu_device_initialize(ws->fd, &drm_major, &drm_minor, &dev); if (r) { fprintf(stderr, "amdgpu: amdgpu_device_initialize failed.\n"); goto fail; @@ -357,13 +356,18 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, /* Lookup a winsys if we have already created one for this device. */ aws = util_hash_table_get(dev_tab, dev); if (aws) { - pipe_reference(NULL, &aws->reference); - /* Release the device handle, because we don't need it anymore. * This function is returning an existing winsys instance, which * has its own device handle. */ amdgpu_device_deinitialize(dev); + + ws->kms_handles = _mesa_hash_table_create(NULL, kms_handle_hash, + kms_handle_equals); + if (!ws->kms_handles) + goto fail; + + pipe_reference(NULL, &aws->reference); } else { /* Create a new winsys. */ aws = CALLOC_STRUCT(amdgpu_winsys); @@ -371,6 +375,7 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, goto fail; aws->dev = dev; + aws->fd = ws->fd; aws->info.drm_major = drm_major; aws->info.drm_minor = drm_minor; diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h index 147e4b23b9b..c2edf4f46dc 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h @@ -42,6 +42,10 @@ struct amdgpu_cs; struct amdgpu_winsys { struct pipe_reference reference; + + /* File descriptor which was passed to amdgpu_device_initialize */ + int fd; + struct pb_cache bo_cache; /* Each slab buffer can only contain suballocations of equal sizes, so we