Mesa (master): zink: add locking for batch states

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Mar 30 15:21:23 UTC 2021


Module: Mesa
Branch: master
Commit: 6eaaaaa542e3b7d642b23df74d48b39347f8f116
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6eaaaaa542e3b7d642b23df74d48b39347f8f116

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Mon Mar 22 10:27:50 2021 -0400

zink: add locking for batch states

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9885>

---

 src/gallium/drivers/zink/zink_batch.c   |  7 ++++++-
 src/gallium/drivers/zink/zink_context.c | 12 ++++++++++--
 src/gallium/drivers/zink/zink_context.h |  1 +
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c
index 81a55774812..f9560b8df43 100644
--- a/src/gallium/drivers/zink/zink_batch.c
+++ b/src/gallium/drivers/zink/zink_batch.c
@@ -97,12 +97,14 @@ zink_clear_batch_state(struct zink_context *ctx, struct zink_batch_state *bs)
 void
 zink_batch_reset_all(struct zink_context *ctx)
 {
+   simple_mtx_lock(&ctx->batch_mtx);
    hash_table_foreach(&ctx->batch_states, entry) {
       struct zink_batch_state *bs = entry->data;
       zink_reset_batch_state(ctx, bs);
       _mesa_hash_table_remove(&ctx->batch_states, entry);
       util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, bs);
    }
+   simple_mtx_unlock(&ctx->batch_mtx);
 }
 
 void
@@ -186,6 +188,7 @@ init_batch_state(struct zink_context *ctx, struct zink_batch *batch)
 {
    struct zink_batch_state *bs = NULL;
 
+   simple_mtx_lock(&ctx->batch_mtx);
    if (util_dynarray_num_elements(&ctx->free_batch_states, struct zink_batch_state*))
       bs = util_dynarray_pop(&ctx->free_batch_states, struct zink_batch_state*);
    if (!bs) {
@@ -195,6 +198,7 @@ init_batch_state(struct zink_context *ctx, struct zink_batch *batch)
          _mesa_hash_table_remove(&ctx->batch_states, he);
       }
    }
+   simple_mtx_unlock(&ctx->batch_mtx);
    if (bs)
       zink_reset_batch_state(ctx, bs);
    else {
@@ -300,9 +304,10 @@ zink_end_batch(struct zink_context *ctx, struct zink_batch *batch)
          ctx->reset.reset(ctx->reset.data, PIPE_GUILTY_CONTEXT_RESET);
       }
    }
-
+   simple_mtx_lock(&ctx->batch_mtx);
    ctx->last_fence = &batch->state->fence;
    _mesa_hash_table_insert_pre_hashed(&ctx->batch_states, batch->state->fence.batch_id, (void*)(uintptr_t)batch->state->fence.batch_id, batch->state);
+   simple_mtx_unlock(&ctx->batch_mtx);
    ctx->resource_size += batch->state->resource_size;
 }
 
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 9307d35aebe..a353d52cc2c 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -302,6 +302,7 @@ zink_context_destroy(struct pipe_context *pctx)
    for (unsigned i = 0; i < ARRAY_SIZE(ctx->null_buffers); i++)
       pipe_resource_reference(&ctx->null_buffers[i], NULL);
 
+   simple_mtx_destroy(&ctx->batch_mtx);
    struct zink_fence *fence = zink_fence(&ctx->batch.state);
    zink_clear_batch_state(ctx, ctx->batch.state);
    zink_fence_reference(screen, &fence, NULL);
@@ -1930,6 +1931,7 @@ zink_wait_on_batch(struct zink_context *ctx, uint32_t batch_id)
       /* not submitted yet */
       flush_batch(ctx);
 
+   simple_mtx_lock(&ctx->batch_mtx);
    struct zink_fence *fence;
 
    assert(batch_id || ctx->last_fence);
@@ -1939,18 +1941,23 @@ zink_wait_on_batch(struct zink_context *ctx, uint32_t batch_id)
       struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&ctx->batch_states, batch_id, (void*)(uintptr_t)batch_id);
       if (!he) {
         util_dynarray_foreach(&ctx->free_batch_states, struct zink_batch_state*, bs) {
-           if ((*bs)->fence.batch_id == batch_id)
+           if ((*bs)->fence.batch_id == batch_id) {
+              simple_mtx_unlock(&ctx->batch_mtx);
               return;
+           }
         }
-        if (ctx->last_fence && ctx->last_fence->batch_id > batch_id)
+        if (ctx->last_fence && ctx->last_fence->batch_id > batch_id) {
            /* already completed */
+           simple_mtx_unlock(&ctx->batch_mtx);
            return;
+        }
         unreachable("should've found batch state");
       }
       fence = he->data;
    }
    assert(fence);
    ctx->base.screen->fence_finish(ctx->base.screen, &ctx->base, (struct pipe_fence_handle*)fence, PIPE_TIMEOUT_INFINITE);
+   simple_mtx_unlock(&ctx->batch_mtx);
 }
 
 static void
@@ -2564,6 +2571,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
       goto fail;
 
    vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &ctx->queue);
+   simple_mtx_init(&ctx->batch_mtx, mtx_plain);
 
    ctx->program_cache = _mesa_hash_table_create(NULL,
                                                 hash_gfx_program,
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index 02cfc44e57f..74ffad05c39 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -134,6 +134,7 @@ struct zink_context {
 
    uint32_t curr_batch; //the current batch id
    struct zink_batch batch;
+   simple_mtx_t batch_mtx;
    struct zink_fence *last_fence; //the last command buffer submitted
    VkQueue queue; //gfx+compute
    struct hash_table batch_states; //submitted batch states



More information about the mesa-commit mailing list