From dfe331930c63a5a245b90740061d47a174eb10eb Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 22 Feb 2024 09:19:35 -0500 Subject: [PATCH] zink: don't destroy the current batch state on context destroy these are owned by the screen now should fix some flakiness with shared contexts Fixes: b06f6e00fba ("zink: fix heap-use-after-free on batch_state with sub-allocated pipe_resources") Part-of: --- src/gallium/drivers/zink/zink_context.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 4556e1dea38..a5a2a543eac 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -188,21 +188,31 @@ zink_context_destroy(struct pipe_context *pctx) screen->free_batch_states = ctx->batch_states; screen->last_free_batch_state = screen->free_batch_states; } - while (screen->last_free_batch_state->next) - screen->last_free_batch_state = screen->last_free_batch_state->next; } + while (screen->last_free_batch_state && screen->last_free_batch_state->next) + screen->last_free_batch_state = screen->last_free_batch_state->next; if (ctx->free_batch_states) { if (screen->free_batch_states) screen->last_free_batch_state->next = ctx->free_batch_states; - else + else { screen->free_batch_states = ctx->free_batch_states; - screen->last_free_batch_state = ctx->last_free_batch_state; + screen->last_free_batch_state = ctx->last_free_batch_state; + } } - simple_mtx_unlock(&screen->free_batch_states_lock); + while (screen->last_free_batch_state && screen->last_free_batch_state->next) + screen->last_free_batch_state = screen->last_free_batch_state->next; if (ctx->batch.state) { zink_clear_batch_state(ctx, ctx->batch.state); - zink_batch_state_destroy(screen, ctx->batch.state); + if (screen->free_batch_states) + screen->last_free_batch_state->next = ctx->batch.state; + else { + screen->free_batch_states = ctx->batch.state; + screen->last_free_batch_state = screen->free_batch_states; + } } + while (screen->last_free_batch_state && screen->last_free_batch_state->next) + screen->last_free_batch_state = screen->last_free_batch_state->next; + simple_mtx_unlock(&screen->free_batch_states_lock); for (unsigned i = 0; i < 2; i++) { util_idalloc_fini(&ctx->di.bindless[i].tex_slots);