diff --git a/.pick_status.json b/.pick_status.json index 92848da9c58..c3327aa5572 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1273,7 +1273,7 @@ "description": "panfrost: Protect the variants array with a lock", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index c4c94f5c300..55b9f511ed6 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -297,6 +297,8 @@ panfrost_create_shader_state( struct panfrost_device *dev = pan_device(pctx->screen); so->base = *cso; + simple_mtx_init(&so->lock, mtx_plain); + /* Token deep copy to prevent memory corruption */ if (cso->type == PIPE_SHADER_IR_TGSI) @@ -337,6 +339,8 @@ panfrost_delete_shader_state( panfrost_bo_unreference(shader_state->linkage.bo); } + simple_mtx_destroy(&cso->lock); + free(cso->variants); free(so); } @@ -449,6 +453,8 @@ panfrost_bind_shader_state( signed variant = -1; struct panfrost_shader_variants *variants = (struct panfrost_shader_variants *) hwcso; + simple_mtx_lock(&variants->lock); + for (unsigned i = 0; i < variants->variant_count; ++i) { if (panfrost_variant_matches(ctx, &variants->variants[i], type)) { variant = i; @@ -526,6 +532,11 @@ panfrost_bind_shader_state( update_so_info(&shader_state->stream_output, shader_state->info.outputs_written); } + + /* TODO: it would be more efficient to release the lock before + * compiling instead of after, but that can race if thread A compiles a + * variant while thread B searches for that same variant */ + simple_mtx_unlock(&variants->lock); } static void * diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index b2ad9af36ba..4079c3fee45 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -44,6 +44,7 @@ #include "pipe/p_state.h" #include "util/u_blitter.h" #include "util/hash_table.h" +#include "util/simple_mtx.h" #include "midgard/midgard_compile.h" #include "compiler/shader_enums.h" @@ -290,6 +291,9 @@ struct panfrost_shader_variants { struct pipe_compute_state cbase; }; + /** Lock for the variants array */ + simple_mtx_t lock; + struct panfrost_shader_state *variants; unsigned variant_space;