etnaviv: drm: always use hash to track BO index
Currently the buffer index hash is only used if the BO is used in multiple streams and the current index is cached on the BO. This introduces some shared state on the BO, which necessitates the use of a lock to keep this state consistent across threads, which negates some of the benefits of caching the index. Always use the hash to keep track of the submit BOs, to get rid of the shared state and simplify the code. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14466>
This commit is contained in:
parent
7bb62d9dd8
commit
8997b9579f
|
@ -27,11 +27,11 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "util/hash_table.h"
|
||||
|
||||
#include "etnaviv_drmif.h"
|
||||
#include "etnaviv_priv.h"
|
||||
|
||||
static simple_mtx_t idx_lock = _SIMPLE_MTX_INITIALIZER_NP;
|
||||
|
||||
static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
|
||||
{
|
||||
if ((nr + 1) > *max) {
|
||||
|
@ -117,6 +117,8 @@ struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe,
|
|||
stream->force_flush = force_flush;
|
||||
stream->force_flush_priv = priv;
|
||||
|
||||
stream->bo_table = _mesa_pointer_hash_table_create(NULL);
|
||||
|
||||
return &stream->base;
|
||||
|
||||
fail:
|
||||
|
@ -130,6 +132,8 @@ void etna_cmd_stream_del(struct etna_cmd_stream *stream)
|
|||
{
|
||||
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
|
||||
|
||||
_mesa_hash_table_destroy(priv->bo_table, NULL);
|
||||
|
||||
free(stream->buffer);
|
||||
free(priv->submit.relocs);
|
||||
free(priv->submit.pmrs);
|
||||
|
@ -154,8 +158,6 @@ static uint32_t append_bo(struct etna_cmd_stream *stream, struct etna_bo *bo)
|
|||
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
|
||||
uint32_t idx;
|
||||
|
||||
simple_mtx_assert_locked(&idx_lock);
|
||||
|
||||
idx = APPEND(&priv->submit, bos);
|
||||
idx = APPEND(priv, bos);
|
||||
|
||||
|
@ -173,31 +175,19 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo,
|
|||
uint32_t flags)
|
||||
{
|
||||
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
|
||||
uint32_t hash = _mesa_hash_pointer(bo);
|
||||
struct hash_entry *entry;
|
||||
uint32_t idx;
|
||||
|
||||
simple_mtx_lock(&idx_lock);
|
||||
entry = _mesa_hash_table_search_pre_hashed(priv->bo_table, hash, bo);
|
||||
|
||||
if (bo->current_stream == stream) {
|
||||
idx = bo->idx;
|
||||
if (entry) {
|
||||
idx = (uint32_t)(uintptr_t)entry->data;
|
||||
} else {
|
||||
void *val;
|
||||
|
||||
if (!priv->bo_table)
|
||||
priv->bo_table = drmHashCreate();
|
||||
|
||||
if (!drmHashLookup(priv->bo_table, bo->handle, &val)) {
|
||||
/* found */
|
||||
idx = (uint32_t)(uintptr_t)val;
|
||||
} else {
|
||||
idx = append_bo(stream, bo);
|
||||
val = (void *)(uintptr_t)idx;
|
||||
drmHashInsert(priv->bo_table, bo->handle, val);
|
||||
}
|
||||
|
||||
bo->current_stream = stream;
|
||||
bo->idx = idx;
|
||||
idx = append_bo(stream, bo);
|
||||
_mesa_hash_table_insert_pre_hashed(priv->bo_table, hash, bo,
|
||||
(void *)(uintptr_t)idx);
|
||||
}
|
||||
simple_mtx_unlock(&idx_lock);
|
||||
|
||||
if (flags & ETNA_RELOC_READ)
|
||||
priv->submit.bos[idx].flags |= ETNA_SUBMIT_BO_READ;
|
||||
|
@ -249,17 +239,10 @@ void etna_cmd_stream_flush(struct etna_cmd_stream *stream, int in_fence_fd,
|
|||
else
|
||||
priv->last_timestamp = req.fence;
|
||||
|
||||
for (uint32_t i = 0; i < priv->nr_bos; i++) {
|
||||
struct etna_bo *bo = priv->bos[i];
|
||||
for (uint32_t i = 0; i < priv->nr_bos; i++)
|
||||
etna_bo_del(priv->bos[i]);
|
||||
|
||||
bo->current_stream = NULL;
|
||||
etna_bo_del(bo);
|
||||
}
|
||||
|
||||
if (priv->bo_table) {
|
||||
drmHashDestroy(priv->bo_table);
|
||||
priv->bo_table = NULL;
|
||||
}
|
||||
_mesa_hash_table_clear(priv->bo_table, NULL);
|
||||
|
||||
if (out_fence_fd)
|
||||
*out_fence_fd = req.fence_fd;
|
||||
|
|
|
@ -113,14 +113,6 @@ struct etna_bo {
|
|||
uint32_t va; /* GPU virtual address */
|
||||
int refcnt;
|
||||
|
||||
/*
|
||||
* To avoid excess hashtable lookups, cache the stream this bo was
|
||||
* last emitted on (since that will probably also be the next ring
|
||||
* it is emitted on).
|
||||
*/
|
||||
struct etna_cmd_stream *current_stream;
|
||||
uint32_t idx;
|
||||
|
||||
int reuse;
|
||||
struct list_head list; /* bucket-list entry */
|
||||
time_t free_time; /* time when added to bucket-list */
|
||||
|
|
Loading…
Reference in New Issue