Mesa (main): freedreno: Fix batch reference handling in flush_resource().

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 17 16:32:13 UTC 2021


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

Author: Emma Anholt <emma at anholt.net>
Date:   Tue Jun 15 10:38:49 2021 -0700

freedreno: Fix batch reference handling in flush_resource().

We take references under the lock, but then accessed the lock-requiring
batch_cache structure without holding the lock.  The batches wouldn't get
freed and removed from their slots until the last ref goes away so it was
safe (other than the assert at the end), but writing the simple code is
shorter and requires fewer assumptions.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11439>

---

 src/gallium/drivers/freedreno/freedreno_resource.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 74b0b10cf5b..d3981c15fd9 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -672,7 +672,7 @@ flush_resource(struct fd_context *ctx, struct fd_resource *rsc,
 
    if (usage & PIPE_MAP_WRITE) {
       struct fd_batch *batch, *batches[32] = {};
-      uint32_t batch_mask;
+      uint32_t batch_count = 0;
 
       /* This is a bit awkward, probably a fd_batch_flush_locked()
        * would make things simpler.. but we need to hold the lock
@@ -680,18 +680,14 @@ flush_resource(struct fd_context *ctx, struct fd_resource *rsc,
        * we must first grab references under a lock, then flush.
        */
       fd_screen_lock(ctx->screen);
-      batch_mask = rsc->track->batch_mask;
-      foreach_batch (batch, &ctx->screen->batch_cache, batch_mask)
-         fd_batch_reference_locked(&batches[batch->idx], batch);
+      foreach_batch (batch, &ctx->screen->batch_cache, rsc->track->batch_mask)
+         fd_batch_reference_locked(&batches[batch_count++], batch);
       fd_screen_unlock(ctx->screen);
 
-      foreach_batch (batch, &ctx->screen->batch_cache, batch_mask)
-         fd_batch_flush(batch);
-
-      foreach_batch (batch, &ctx->screen->batch_cache, batch_mask) {
-         fd_batch_reference(&batches[batch->idx], NULL);
+      for (int i = 0; i < batch_count; i++) {
+         fd_batch_flush(batches[i]);
+         fd_batch_reference(&batches[i], NULL);
       }
-      assert(rsc->track->batch_mask == 0);
    } else if (write_batch) {
       fd_batch_flush(write_batch);
    }



More information about the mesa-commit mailing list