i965/drm: Switch from uthash to Mesa's hash table.
No performance data has been gathered about this choice. I just don't want that many hash tables. Chris points out that this is not performance critical - we should not be recreating that many handles from scratch. In the past we used a linear list, which became unreasonable in stress tests that used hundreds of thousands of BOs. In real usage, it shouldn't matter that much. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
ad1b1cce44
commit
2662894baa
|
@ -160,8 +160,7 @@ i965_FILES = \
|
|||
intel_tiled_memcpy.c \
|
||||
intel_tiled_memcpy.h \
|
||||
intel_upload.c \
|
||||
libdrm_macros.h \
|
||||
uthash.h
|
||||
libdrm_macros.h
|
||||
|
||||
i965_gen6_FILES = \
|
||||
genX_blorp_exec.c
|
||||
|
|
|
@ -61,12 +61,12 @@
|
|||
#include "libdrm_macros.h"
|
||||
#include "main/macros.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/list.h"
|
||||
#include "brw_bufmgr.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "i915_drm.h"
|
||||
#include "uthash.h"
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
#include <valgrind.h>
|
||||
|
@ -139,8 +139,8 @@ typedef struct _drm_bacon_bufmgr {
|
|||
|
||||
struct list_head managers;
|
||||
|
||||
drm_bacon_bo_gem *name_table;
|
||||
drm_bacon_bo_gem *handle_table;
|
||||
struct hash_table *name_table;
|
||||
struct hash_table *handle_table;
|
||||
|
||||
struct list_head vma_cache;
|
||||
int vma_count, vma_open, vma_max;
|
||||
|
@ -169,9 +169,6 @@ struct _drm_bacon_bo_gem {
|
|||
*/
|
||||
unsigned int global_name;
|
||||
|
||||
UT_hash_handle handle_hh;
|
||||
UT_hash_handle name_hh;
|
||||
|
||||
/**
|
||||
* Index of the buffer within the validation list while preparing a
|
||||
* batchbuffer execution.
|
||||
|
@ -272,6 +269,25 @@ static inline drm_bacon_bo_gem *to_bo_gem(drm_bacon_bo *bo)
|
|||
return (drm_bacon_bo_gem *)bo;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
key_hash_uint(const void *key)
|
||||
{
|
||||
return _mesa_hash_data(key, 4);
|
||||
}
|
||||
|
||||
static bool
|
||||
key_uint_equal(const void *a, const void *b)
|
||||
{
|
||||
return *((unsigned *) a) == *((unsigned *) b);
|
||||
}
|
||||
|
||||
static drm_bacon_bo_gem *
|
||||
hash_find_bo(struct hash_table *ht, unsigned int key)
|
||||
{
|
||||
struct hash_entry *entry = _mesa_hash_table_search(ht, &key);
|
||||
return entry ? (drm_bacon_bo_gem *) entry->data : NULL;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
drm_bacon_gem_bo_tile_size(drm_bacon_bufmgr *bufmgr, unsigned long size,
|
||||
uint32_t *tiling_mode)
|
||||
|
@ -635,9 +651,8 @@ retry:
|
|||
}
|
||||
|
||||
bo_gem->gem_handle = create.handle;
|
||||
HASH_ADD(handle_hh, bufmgr->handle_table,
|
||||
gem_handle, sizeof(bo_gem->gem_handle),
|
||||
bo_gem);
|
||||
_mesa_hash_table_insert(bufmgr->handle_table,
|
||||
&bo_gem->gem_handle, bo_gem);
|
||||
|
||||
bo_gem->bo.handle = bo_gem->gem_handle;
|
||||
bo_gem->bo.bufmgr = bufmgr;
|
||||
|
@ -767,8 +782,7 @@ drm_bacon_bo_gem_create_from_name(drm_bacon_bufmgr *bufmgr,
|
|||
* provides a sufficiently fast match.
|
||||
*/
|
||||
pthread_mutex_lock(&bufmgr->lock);
|
||||
HASH_FIND(name_hh, bufmgr->name_table,
|
||||
&handle, sizeof(handle), bo_gem);
|
||||
bo_gem = hash_find_bo(bufmgr->name_table, handle);
|
||||
if (bo_gem) {
|
||||
drm_bacon_bo_reference(&bo_gem->bo);
|
||||
goto out;
|
||||
|
@ -789,8 +803,7 @@ drm_bacon_bo_gem_create_from_name(drm_bacon_bufmgr *bufmgr,
|
|||
* object from the kernel before by looking through the list
|
||||
* again for a matching gem_handle
|
||||
*/
|
||||
HASH_FIND(handle_hh, bufmgr->handle_table,
|
||||
&open_arg.handle, sizeof(open_arg.handle), bo_gem);
|
||||
bo_gem = hash_find_bo(bufmgr->handle_table, open_arg.handle);
|
||||
if (bo_gem) {
|
||||
drm_bacon_bo_reference(&bo_gem->bo);
|
||||
goto out;
|
||||
|
@ -814,10 +827,10 @@ drm_bacon_bo_gem_create_from_name(drm_bacon_bufmgr *bufmgr,
|
|||
bo_gem->global_name = handle;
|
||||
bo_gem->reusable = false;
|
||||
|
||||
HASH_ADD(handle_hh, bufmgr->handle_table,
|
||||
gem_handle, sizeof(bo_gem->gem_handle), bo_gem);
|
||||
HASH_ADD(name_hh, bufmgr->name_table,
|
||||
global_name, sizeof(bo_gem->global_name), bo_gem);
|
||||
_mesa_hash_table_insert(bufmgr->handle_table,
|
||||
&bo_gem->gem_handle, bo_gem);
|
||||
_mesa_hash_table_insert(bufmgr->name_table,
|
||||
&bo_gem->global_name, bo_gem);
|
||||
|
||||
memclear(get_tiling);
|
||||
get_tiling.handle = bo_gem->gem_handle;
|
||||
|
@ -849,6 +862,7 @@ drm_bacon_gem_bo_free(drm_bacon_bo *bo)
|
|||
drm_bacon_bufmgr *bufmgr = bo->bufmgr;
|
||||
drm_bacon_bo_gem *bo_gem = (drm_bacon_bo_gem *) bo;
|
||||
struct drm_gem_close close;
|
||||
struct hash_entry *entry;
|
||||
int ret;
|
||||
|
||||
list_del(&bo_gem->vma_list);
|
||||
|
@ -867,9 +881,14 @@ drm_bacon_gem_bo_free(drm_bacon_bo *bo)
|
|||
bufmgr->vma_count--;
|
||||
}
|
||||
|
||||
if (bo_gem->global_name)
|
||||
HASH_DELETE(name_hh, bufmgr->name_table, bo_gem);
|
||||
HASH_DELETE(handle_hh, bufmgr->handle_table, bo_gem);
|
||||
if (bo_gem->global_name) {
|
||||
entry = _mesa_hash_table_search(bufmgr->name_table,
|
||||
&bo_gem->global_name);
|
||||
_mesa_hash_table_remove(bufmgr->name_table, entry);
|
||||
}
|
||||
entry = _mesa_hash_table_search(bufmgr->handle_table,
|
||||
&bo_gem->gem_handle);
|
||||
_mesa_hash_table_remove(bufmgr->handle_table, entry);
|
||||
|
||||
/* Close this object */
|
||||
memclear(close);
|
||||
|
@ -1523,6 +1542,9 @@ drm_bacon_bufmgr_gem_destroy(drm_bacon_bufmgr *bufmgr)
|
|||
}
|
||||
}
|
||||
|
||||
_mesa_hash_table_destroy(bufmgr->name_table, NULL);
|
||||
_mesa_hash_table_destroy(bufmgr->handle_table, NULL);
|
||||
|
||||
free(bufmgr);
|
||||
}
|
||||
|
||||
|
@ -1894,8 +1916,7 @@ drm_bacon_bo_gem_create_from_prime(drm_bacon_bufmgr *bufmgr, int prime_fd, int s
|
|||
* for named buffers, we must not create two bo's pointing at the same
|
||||
* kernel object
|
||||
*/
|
||||
HASH_FIND(handle_hh, bufmgr->handle_table,
|
||||
&handle, sizeof(handle), bo_gem);
|
||||
bo_gem = hash_find_bo(bufmgr->handle_table, handle);
|
||||
if (bo_gem) {
|
||||
drm_bacon_bo_reference(&bo_gem->bo);
|
||||
goto out;
|
||||
|
@ -1923,8 +1944,8 @@ drm_bacon_bo_gem_create_from_prime(drm_bacon_bufmgr *bufmgr, int prime_fd, int s
|
|||
bo_gem->bo.bufmgr = bufmgr;
|
||||
|
||||
bo_gem->gem_handle = handle;
|
||||
HASH_ADD(handle_hh, bufmgr->handle_table,
|
||||
gem_handle, sizeof(bo_gem->gem_handle), bo_gem);
|
||||
_mesa_hash_table_insert(bufmgr->handle_table,
|
||||
&bo_gem->gem_handle, bo_gem);
|
||||
|
||||
bo_gem->name = "prime";
|
||||
bo_gem->validate_index = -1;
|
||||
|
@ -1988,9 +2009,8 @@ drm_bacon_bo_flink(drm_bacon_bo *bo, uint32_t *name)
|
|||
bo_gem->global_name = flink.name;
|
||||
bo_gem->reusable = false;
|
||||
|
||||
HASH_ADD(name_hh, bufmgr->name_table,
|
||||
global_name, sizeof(bo_gem->global_name),
|
||||
bo_gem);
|
||||
_mesa_hash_table_insert(bufmgr->name_table,
|
||||
&bo_gem->global_name, bo_gem);
|
||||
}
|
||||
pthread_mutex_unlock(&bufmgr->lock);
|
||||
}
|
||||
|
@ -2565,6 +2585,11 @@ drm_bacon_bufmgr_gem_init(struct gen_device_info *devinfo,
|
|||
|
||||
list_add(&bufmgr->managers, &bufmgr_list);
|
||||
|
||||
bufmgr->name_table =
|
||||
_mesa_hash_table_create(NULL, key_hash_uint, key_uint_equal);
|
||||
bufmgr->handle_table =
|
||||
_mesa_hash_table_create(NULL, key_hash_uint, key_uint_equal);
|
||||
|
||||
exit:
|
||||
pthread_mutex_unlock(&bufmgr_list_mutex);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue