Mesa (main): etnaviv: drm: always use hash to track BO index

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Jul 3 17:49:44 UTC 2022


Module: Mesa
Branch: main
Commit: 8997b9579ff62ba6445659a6826e46cad6bedc18
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8997b9579ff62ba6445659a6826e46cad6bedc18

Author: Lucas Stach <l.stach at pengutronix.de>
Date:   Fri Dec 10 21:35:11 2021 +0100

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 at pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14466>

---

 src/etnaviv/drm/etnaviv_cmd_stream.c | 51 ++++++++++++------------------------
 src/etnaviv/drm/etnaviv_priv.h       |  8 ------
 2 files changed, 17 insertions(+), 42 deletions(-)

diff --git a/src/etnaviv/drm/etnaviv_cmd_stream.c b/src/etnaviv/drm/etnaviv_cmd_stream.c
index 34daa8de427..3630d155d76 100644
--- a/src/etnaviv/drm/etnaviv_cmd_stream.c
+++ b/src/etnaviv/drm/etnaviv_cmd_stream.c
@@ -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];
-
-		bo->current_stream = NULL;
-		etna_bo_del(bo);
-	}
+	for (uint32_t i = 0; i < priv->nr_bos; i++)
+		etna_bo_del(priv->bos[i]);
 
-	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;
diff --git a/src/etnaviv/drm/etnaviv_priv.h b/src/etnaviv/drm/etnaviv_priv.h
index f6be72357cb..3cd380f2dc0 100644
--- a/src/etnaviv/drm/etnaviv_priv.h
+++ b/src/etnaviv/drm/etnaviv_priv.h
@@ -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 */



More information about the mesa-commit mailing list