Mesa (master): winsys/amdgpu: Keep track of retrieved KMS handles using hash tables

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 23 17:04:47 UTC 2020


Module: Mesa
Branch: master
Commit: 24075ac60fcc09dad173cb792e8f186c6379c086
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=24075ac60fcc09dad173cb792e8f186c6379c086

Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Sep 30 18:00:50 2019 +0200

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 at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3202>

---

 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 *



More information about the mesa-commit mailing list