panfrost: Compact the bo_access readers array
authorIcecream95 <ixn@keemail.me>
Wed, 15 Jan 2020 20:51:17 +0000 (09:51 +1300)
committerMarge Bot <eric+marge@anholt.net>
Sat, 18 Jan 2020 13:58:43 +0000 (13:58 +0000)
Previously, the array bo_access->readers was only cleared when there
were no unsignaled fences, which in some situations never happened.

That resulted in the array having thousands of NULL pointers, but only
a handful of active readers.

With this patch, all the unsignaled readers are moved to the front of
the array, effectively building a new array only containing the active
readers in-place. This results in the readers array usually only having
a couple of elements.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3419>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3419>

src/gallium/drivers/panfrost/pan_job.c

index 1b7d370b9982f7dda2d3fca9f60b3f8bd7f05bd1..8ec00022999c4673d913de796d32a1f56d080ab4 100644 (file)
@@ -346,7 +346,9 @@ panfrost_bo_access_gc_fences(struct panfrost_context *ctx,
                 access->writer = NULL;
         }
 
-        unsigned nreaders = 0;
+        struct panfrost_batch_fence **readers_array = util_dynarray_begin(&access->readers);
+        struct panfrost_batch_fence **new_readers = readers_array;
+
         util_dynarray_foreach(&access->readers, struct panfrost_batch_fence *,
                               reader) {
                 if (!(*reader))
@@ -356,12 +358,15 @@ panfrost_bo_access_gc_fences(struct panfrost_context *ctx,
                         panfrost_batch_fence_unreference(*reader);
                         *reader = NULL;
                 } else {
-                        nreaders++;
+                        /* Build a new array of only unsignaled fences in-place */
+                        *(new_readers++) = *reader;
                 }
         }
 
-        if (!nreaders)
-                util_dynarray_clear(&access->readers);
+        if (!util_dynarray_resize(&access->readers, struct panfrost_batch_fence *,
+                                  new_readers - readers_array) &&
+            new_readers != readers_array)
+                unreachable("Invalid dynarray access->readers");
 }
 
 /* Collect signaled fences to keep the kernel-side syncobj-map small. The