When the shader state is destroyed before the async shader compile is
done, we get a use after free in the async thread, as the shader state
it is operating on is gone. Fix this by dropping any pending job from
the async queue or wait for it to finish before destroying the state
by calling util_queue_drop_job.
Also call util_queue_fence_destroy, which would have caught this issue
by asserting that the queue_fence is in signalled state when the
shader state is destroyed.
Fixes:
1141ed585901 ("etnaviv: async shader compile")
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17534>
static void
etna_delete_shader_state(struct pipe_context *pctx, void *ss)
{
+ struct etna_context *ctx = etna_context(pctx);
+ struct etna_screen *screen = ctx->screen;
struct etna_shader *shader = ss;
struct etna_shader_variant *v, *t;
+ util_queue_drop_job(&screen->shader_compiler_queue, &shader->ready);
+
v = shader->variants;
while (v) {
t = v;
tgsi_free_tokens(shader->tokens);
ralloc_free(shader->nir);
+ util_queue_fence_destroy(&shader->ready);
FREE(shader);
}