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

Author: Mike Blumenkrantz <michael.blumenkra...@gmail.com>
Date:   Thu Oct 26 16:22:27 2023 -0400

zink: add more locking for compute pipelines

if multiple contexts are accessing this all at once then this needs
more locking to avoid unsynchronized cache access

cc: mesa-stable

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

---

 src/gallium/drivers/zink/zink_program.c | 22 ++++++++++++++++++----
 src/gallium/drivers/zink/zink_types.h   |  2 ++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_program.c 
b/src/gallium/drivers/zink/zink_program.c
index 796cc258a4f..024e19088e8 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -1367,6 +1367,7 @@ create_compute_program(struct zink_context *ctx, 
nir_shader *nir)
    struct zink_compute_program *comp = create_program(ctx, true);
    if (!comp)
       return NULL;
+   simple_mtx_init(&comp->cache_lock, mtx_plain);
    comp->scratch_size = nir->scratch_size;
    comp->nir = nir;
    comp->num_inlinable_uniforms = nir->info.num_inlinable_uniforms;
@@ -1595,6 +1596,7 @@ zink_get_compute_pipeline(struct zink_screen *screen,
                       struct zink_compute_pipeline_state *state)
 {
    struct hash_entry *entry = NULL;
+   struct compute_pipeline_cache_entry *cache_entry;
 
    if (!state->dirty && !state->module_changed)
       return state->pipeline;
@@ -1617,30 +1619,42 @@ zink_get_compute_pipeline(struct zink_screen *screen,
    entry = _mesa_hash_table_search_pre_hashed(&comp->pipelines, 
state->final_hash, state);
 
    if (!entry) {
+      simple_mtx_lock(&comp->cache_lock);
+      entry = _mesa_hash_table_search_pre_hashed(&comp->pipelines, 
state->final_hash, state);
+      if (entry) {
+         simple_mtx_unlock(&comp->cache_lock);
+         goto out;
+      }
       VkPipeline pipeline = zink_create_compute_pipeline(screen, comp, state);
 
-      if (pipeline == VK_NULL_HANDLE)
+      if (pipeline == VK_NULL_HANDLE) {
+         simple_mtx_unlock(&comp->cache_lock);
          return VK_NULL_HANDLE;
+      }
 
       zink_screen_update_pipeline_cache(screen, &comp->base, false);
       if (compute_can_shortcut(comp)) {
+         simple_mtx_unlock(&comp->cache_lock);
          /* don't add base pipeline to cache */
          state->pipeline = comp->base_pipeline = pipeline;
          return state->pipeline;
       }
 
       struct compute_pipeline_cache_entry *pc_entry = 
CALLOC_STRUCT(compute_pipeline_cache_entry);
-      if (!pc_entry)
+      if (!pc_entry) {
+         simple_mtx_unlock(&comp->cache_lock);
          return VK_NULL_HANDLE;
+      }
 
       memcpy(&pc_entry->state, state, sizeof(*state));
       pc_entry->pipeline = pipeline;
 
       entry = _mesa_hash_table_insert_pre_hashed(&comp->pipelines, 
state->final_hash, pc_entry, pc_entry);
       assert(entry);
+      simple_mtx_unlock(&comp->cache_lock);
    }
-
-   struct compute_pipeline_cache_entry *cache_entry = entry->data;
+out:
+   cache_entry = entry->data;
    state->pipeline = cache_entry->pipeline;
    return state->pipeline;
 }
diff --git a/src/gallium/drivers/zink/zink_types.h 
b/src/gallium/drivers/zink/zink_types.h
index 865fa7492c1..eabe85b183e 100644
--- a/src/gallium/drivers/zink/zink_types.h
+++ b/src/gallium/drivers/zink/zink_types.h
@@ -1160,6 +1160,8 @@ struct zink_compute_program {
    struct zink_shader *shader;
    struct hash_table pipelines;
 
+   simple_mtx_t cache_lock; //extra lock because threads are insane and sand 
was not meant to think
+
    VkPipeline base_pipeline;
 };
 

Reply via email to