<div dir="ltr"><div>Reviewed-by: Marek Olšák <<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a>></div><div><br></div><div>Marek<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 7, 2019 at 6:02 PM Rob Clark <<a href="mailto:robdclark@gmail.com">robdclark@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Rob Clark <<a href="mailto:robdclark@chromium.org" target="_blank">robdclark@chromium.org</a>><br>
<br>
I noticed slab_free() showing up at the top of perf results in<br>
gl_driver2, due to "streaming" GPU state objects, which are allocated<br>
and destroyed within a single draw call.<br>
<br>
In this case, it is guaranteed that we free on the same child pool,<br>
from the same (only) thread accessing the child pool. So add a faster,<br>
but more restricted version of slab_free() to cut the overhead.<br>
<br>
Signed-off-by: Rob Clark <<a href="mailto:robdclark@chromium.org" target="_blank">robdclark@chromium.org</a>><br>
---<br>
src/util/slab.c | 20 ++++++++++++++++++++<br>
src/util/slab.h | 1 +<br>
2 files changed, 21 insertions(+)<br>
<br>
diff --git a/src/util/slab.c b/src/util/slab.c<br>
index 62634034fdc..21076a80238 100644<br>
--- a/src/util/slab.c<br>
+++ b/src/util/slab.c<br>
@@ -276,6 +276,26 @@ void slab_free(struct slab_child_pool *pool, void *ptr)<br>
}<br>
}<br>
<br>
+/**<br>
+ * Similar to slab_free(), except that freeing an object in a different pool<br>
+ * from the one it was allocated from is *not* allowed.<br>
+ */<br>
+void slab_free_fast(struct slab_child_pool *pool, void *ptr)<br>
+{<br>
+ struct slab_element_header *elt = ((struct slab_element_header*)ptr - 1);<br>
+<br>
+ CHECK_MAGIC(elt, SLAB_MAGIC_ALLOCATED);<br>
+ SET_MAGIC(elt, SLAB_MAGIC_FREE);<br>
+<br>
+ assert(p_atomic_read(&elt->owner) == (intptr_t)pool);<br>
+<br>
+ /* This is the simple case: The caller guarantees that we can safely<br>
+ * access the free list.<br>
+ */<br>
+ elt->next = pool->free;<br>
+ pool->free = elt;<br>
+}<br>
+<br>
/**<br>
* Allocate an object from the slab. Single-threaded (no mutex).<br>
*/<br>
diff --git a/src/util/slab.h b/src/util/slab.h<br>
index 5a25adaf7f4..9748cd95858 100644<br>
--- a/src/util/slab.h<br>
+++ b/src/util/slab.h<br>
@@ -78,6 +78,7 @@ void slab_create_child(struct slab_child_pool *pool,<br>
void slab_destroy_child(struct slab_child_pool *pool);<br>
void *slab_alloc(struct slab_child_pool *pool);<br>
void slab_free(struct slab_child_pool *pool, void *ptr);<br>
+void slab_free_fast(struct slab_child_pool *pool, void *ptr);<br>
<br>
struct slab_mempool {<br>
struct slab_parent_pool parent;<br>
-- <br>
2.21.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></blockquote></div>