From 24075ac60fcc09dad173cb792e8f186c6379c086 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michel=20D=C3=A4nzer?= Date: Mon, 30 Sep 2019 18:00:50 +0200 Subject: [PATCH] winsys/amdgpu: Keep track of retrieved KMS handles using hash tables The assumption being that KMS handles are only retrieved for relatively few BOs, so hash tables should be efficient both in terms of performance and memory consumption. We use the address of struct amdgpu_winsys_bo as the key and its kms_handle field (the KMS handle valid for the DRM file descriptor passed to amdgpu_device_initialize) as the hash value. v2: * Add comment above amdgpu_screen_winsys::kms_handles (Pierre-Eric Pelloux-Prayer) v3: * Protect kms_handles hash table with amdgpu_winsys::sws_list_lock mutex. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 22 +++++++++++++++++++ src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 20 +++++++++++++++++ src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h | 5 +++++ 3 files changed, 47 insertions(+) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index 8bbdb9b2eb0..5f44b02d351 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -27,6 +27,7 @@ #include "amdgpu_cs.h" +#include "util/hash_table.h" #include "util/os_time.h" #include "util/u_hash_table.h" #include "state_tracker/drm_driver.h" @@ -164,6 +165,7 @@ static void amdgpu_bo_remove_fences(struct amdgpu_winsys_bo *bo) void amdgpu_bo_destroy(struct pb_buffer *_buf) { struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf); + struct amdgpu_screen_winsys *sws_iter; struct amdgpu_winsys *ws = bo->ws; assert(bo->bo && "must not be called for slab entries"); @@ -181,6 +183,11 @@ void amdgpu_bo_destroy(struct pb_buffer *_buf) simple_mtx_unlock(&ws->global_bo_list_lock); } + 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); + simple_mtx_unlock(&ws->sws_list_lock); + simple_mtx_lock(&ws->bo_export_table_lock); util_hash_table_remove(ws->bo_export_table, bo->bo); simple_mtx_unlock(&ws->bo_export_table_lock); @@ -1530,6 +1537,7 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(buffer); struct amdgpu_winsys *ws = bo->ws; enum amdgpu_bo_handle_type type; + struct hash_entry *entry; int r; /* Don't allow exports of slab entries and sparse buffers. */ @@ -1543,6 +1551,14 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, type = amdgpu_bo_handle_type_gem_flink_name; break; case WINSYS_HANDLE_TYPE_KMS: + simple_mtx_lock(&ws->sws_list_lock); + entry = _mesa_hash_table_search(sws->kms_handles, bo); + simple_mtx_unlock(&ws->sws_list_lock); + if (entry) { + whandle->handle = (uintptr_t)entry->data; + return true; + } + /* Fall through */ case WINSYS_HANDLE_TYPE_FD: type = amdgpu_bo_handle_type_dma_buf_fd; break; @@ -1562,6 +1578,12 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, if (r) return false; + + simple_mtx_lock(&ws->sws_list_lock); + _mesa_hash_table_insert_pre_hashed(sws->kms_handles, + bo->u.real.kms_handle, bo, + (void*)(uintptr_t)whandle->handle); + simple_mtx_unlock(&ws->sws_list_lock); } simple_mtx_lock(&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 dfdd6fb1631..7bc5fed02f6 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -188,6 +188,7 @@ static void amdgpu_winsys_destroy(struct radeon_winsys *rws) simple_mtx_unlock(&ws->sws_list_lock); } + _mesa_hash_table_destroy(sws->kms_handles, NULL); close(sws->fd); FREE(rws); } @@ -308,6 +309,18 @@ static void amdgpu_pin_threads_to_L3_cache(struct radeon_winsys *rws, util_cpu_caps.cores_per_L3); } +static uint32_t kms_handle_hash(const void *key) +{ + const struct amdgpu_winsys_bo *bo = key; + + return bo->u.real.kms_handle; +} + +static bool kms_handle_equals(const void *a, const void *b) +{ + return a == b; +} + PUBLIC struct radeon_winsys * amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, radeon_screen_create_t screen_create) @@ -323,6 +336,11 @@ 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) @@ -465,6 +483,8 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, fail_alloc: FREE(aws); fail: + if (ws->kms_handles) + _mesa_hash_table_destroy(ws->kms_handles, NULL); close(ws->fd); FREE(ws); simple_mtx_unlock(&dev_tab_mutex); diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h index 43e1df09ad5..147e4b23b9b 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h @@ -104,6 +104,11 @@ struct amdgpu_screen_winsys { struct amdgpu_winsys *aws; int fd; struct amdgpu_screen_winsys *next; + + /* Maps a BO to its KMS handle valid for this DRM file descriptor + * Protected by amdgpu_winsys::sws_list_lock + */ + struct hash_table *kms_handles; }; static inline struct amdgpu_screen_winsys * -- 2.30.2