mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-04 23:40:33 +01:00
panfrost: Protect the variants array with a lock
Without a lock, two threads may bind the same shader CSO simultaneously,
allocate the same variant simultaneously, and then race each other in
the compiler. This manifests in various ways, most commonly failing the
assertion that UBO pushing has only run once. The simple_mtx_t solution
is used in Iris. Fixes the crash in:
dEQP-EGL.functional.sharing.gles2.multithread.simple.buffers.bufferdata_render
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12525>
(cherry picked from commit 40edc87956)
This commit is contained in:
parent
e5f2a4a416
commit
b389e1580c
3 changed files with 16 additions and 1 deletions
|
|
@ -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
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue