summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <mdaenzer@redhat.com>2020-01-31 18:21:08 +0100
committerMarge Bot <eric+marge@anholt.net>2020-02-04 19:53:09 +0000
commit159995be353533d4ac7f59c9bb0f4edbd7c3741e (patch)
treee1f85186a5ed52410c503961505d4eef751c4973
parent23900be9109e6653536ccf52e3a9b14565478346 (diff)
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 <pierre-eric.pelloux-prayer@amd.com> (Cherry picked from commit 24075ac60fcc09dad173cb792e8f186c6379c086) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3693>
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_bo.c22
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c20
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h5
3 files changed, 47 insertions, 0 deletions
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index 32ac276d2b6..62ff9164ef1 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);
@@ -1525,6 +1532,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. */
@@ -1538,6 +1546,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;
@@ -1557,6 +1573,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 *