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 24075ac60f)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3693>
This commit is contained in:
Michel Dänzer 2020-01-31 18:21:08 +01:00 committed by Marge Bot
parent 23900be910
commit 159995be35
3 changed files with 47 additions and 0 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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 *