mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
st/mesa/radeonsi: fix race between destruction of types and shader compilation
Commit624789e370moved the destruction of types out of atexit() and made use of a ref count instead. This is useful for avoiding a crash where drivers such as radeonsi are still compiling in a thread when the app exits and has not called MakeCurrent to change from the current context. While the above scenario is technically an app bug we shouldn't crash. However that change caused another race condition between the shader compilation tread in radeonsi and context teardown functions. This patch makes two changes to fix this new problem: First we explicitly call _mesa_destroy_shader_compiler_types() when destroying the st context rather than calling it indirectly via _mesa_free_context_data(). We do this as we must call it after st_destroy_context_priv() so that we don't destory the glsl types before the compilation threads finish. Next wait for the shader threads to finish in si_destroy_context() this also means we need to call context destroy before destroying the queues in si_destroy_screen(). Fixes:624789e370("compiler/glsl: handle case where we have multiple users for types") Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
parent
3844ed8d44
commit
a6b7068ff5
11 changed files with 29 additions and 17 deletions
|
|
@ -997,6 +997,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct glcpp_parser;
|
||||
struct _mesa_glsl_parse_state;
|
||||
|
||||
typedef void (*glcpp_extension_iterator)(
|
||||
struct _mesa_glsl_parse_state *state,
|
||||
|
|
|
|||
|
|
@ -150,6 +150,9 @@ static void si_destroy_context(struct pipe_context *context)
|
|||
struct si_context *sctx = (struct si_context *)context;
|
||||
int i;
|
||||
|
||||
util_queue_finish(&sctx->screen->shader_compiler_queue);
|
||||
util_queue_finish(&sctx->screen->shader_compiler_queue_low_priority);
|
||||
|
||||
/* Unreference the framebuffer normally to disable related logic
|
||||
* properly.
|
||||
*/
|
||||
|
|
@ -702,6 +705,9 @@ static void si_destroy_screen(struct pipe_screen* pscreen)
|
|||
if (!sscreen->ws->unref(sscreen->ws))
|
||||
return;
|
||||
|
||||
mtx_destroy(&sscreen->aux_context_lock);
|
||||
sscreen->aux_context->destroy(sscreen->aux_context);
|
||||
|
||||
util_queue_destroy(&sscreen->shader_compiler_queue);
|
||||
util_queue_destroy(&sscreen->shader_compiler_queue_low_priority);
|
||||
|
||||
|
|
@ -728,8 +734,6 @@ static void si_destroy_screen(struct pipe_screen* pscreen)
|
|||
si_gpu_load_kill_thread(sscreen);
|
||||
|
||||
mtx_destroy(&sscreen->gpu_load_mutex);
|
||||
mtx_destroy(&sscreen->aux_context_lock);
|
||||
sscreen->aux_context->destroy(sscreen->aux_context);
|
||||
|
||||
slab_destroy_parent(&sscreen->pool_transfers);
|
||||
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ intelDestroyContext(__DRIcontext * driContextPriv)
|
|||
driDestroyOptionCache(&intel->optionCache);
|
||||
|
||||
/* free the Mesa context */
|
||||
_mesa_free_context_data(&intel->ctx);
|
||||
_mesa_free_context_data(&intel->ctx, true);
|
||||
|
||||
_math_matrix_dtr(&intel->ViewportMatrix);
|
||||
|
||||
|
|
|
|||
|
|
@ -1226,7 +1226,7 @@ intelDestroyContext(__DRIcontext * driContextPriv)
|
|||
driDestroyOptionCache(&brw->optionCache);
|
||||
|
||||
/* free the Mesa context */
|
||||
_mesa_free_context_data(&brw->ctx);
|
||||
_mesa_free_context_data(&brw->ctx, true);
|
||||
|
||||
ralloc_free(brw);
|
||||
driContextPriv->driverPrivate = NULL;
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ nouveau_context_deinit(struct gl_context *ctx)
|
|||
nouveau_object_del(&nctx->hw.chan);
|
||||
|
||||
nouveau_scratch_destroy(ctx);
|
||||
_mesa_free_context_data(ctx);
|
||||
_mesa_free_context_data(ctx, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ void radeonDestroyContext(__DRIcontext *driContextPriv )
|
|||
|
||||
/* free atom list */
|
||||
/* free the Mesa context data */
|
||||
_mesa_free_context_data(&radeon->glCtx);
|
||||
_mesa_free_context_data(&radeon->glCtx, true);
|
||||
|
||||
/* free the option cache */
|
||||
driDestroyOptionCache(&radeon->optionCache);
|
||||
|
|
|
|||
|
|
@ -854,7 +854,7 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)
|
|||
osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
|
||||
if (!osmesa->gl_buffer) {
|
||||
_mesa_destroy_visual( osmesa->gl_visual );
|
||||
_mesa_free_context_data( &osmesa->mesa );
|
||||
_mesa_free_context_data(&osmesa->mesa, true);
|
||||
free(osmesa);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -891,7 +891,7 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)
|
|||
!_tnl_CreateContext( ctx ) ||
|
||||
!_swsetup_CreateContext( ctx )) {
|
||||
_mesa_destroy_visual(osmesa->gl_visual);
|
||||
_mesa_free_context_data(ctx);
|
||||
_mesa_free_context_data(ctx, true);
|
||||
free(osmesa);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -919,7 +919,7 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)
|
|||
|
||||
if (ctx->Version < version_major * 10 + version_minor) {
|
||||
_mesa_destroy_visual(osmesa->gl_visual);
|
||||
_mesa_free_context_data(ctx);
|
||||
_mesa_free_context_data(ctx, true);
|
||||
free(osmesa);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -955,7 +955,7 @@ OSMesaDestroyContext( OSMesaContext osmesa )
|
|||
_mesa_destroy_visual( osmesa->gl_visual );
|
||||
_mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
|
||||
|
||||
_mesa_free_context_data( &osmesa->mesa );
|
||||
_mesa_free_context_data(&osmesa->mesa, true);
|
||||
free( osmesa );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
|
|||
!_vbo_CreateContext( mesaCtx ) ||
|
||||
!_tnl_CreateContext( mesaCtx ) ||
|
||||
!_swsetup_CreateContext( mesaCtx )) {
|
||||
_mesa_free_context_data(&c->mesa);
|
||||
_mesa_free_context_data(&c->mesa, true);
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -982,7 +982,7 @@ void XMesaDestroyContext( XMesaContext c )
|
|||
_swrast_DestroyContext( mesaCtx );
|
||||
_tnl_DestroyContext( mesaCtx );
|
||||
_vbo_DestroyContext( mesaCtx );
|
||||
_mesa_free_context_data( mesaCtx );
|
||||
_mesa_free_context_data(mesaCtx, true);
|
||||
free( c );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1310,7 +1310,7 @@ fail:
|
|||
* \sa _mesa_initialize_context() and init_attrib_groups().
|
||||
*/
|
||||
void
|
||||
_mesa_free_context_data( struct gl_context *ctx )
|
||||
_mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types)
|
||||
{
|
||||
if (!_mesa_get_current_context()){
|
||||
/* No current context, but we may need one in order to delete
|
||||
|
|
@ -1385,7 +1385,8 @@ _mesa_free_context_data( struct gl_context *ctx )
|
|||
|
||||
free(ctx->VersionString);
|
||||
|
||||
_mesa_destroy_shader_compiler_types();
|
||||
if (destroy_compiler_types)
|
||||
_mesa_destroy_shader_compiler_types();
|
||||
|
||||
/* unbind the context if it's currently bound */
|
||||
if (ctx == _mesa_get_current_context()) {
|
||||
|
|
@ -1405,7 +1406,7 @@ void
|
|||
_mesa_destroy_context( struct gl_context *ctx )
|
||||
{
|
||||
if (ctx) {
|
||||
_mesa_free_context_data(ctx);
|
||||
_mesa_free_context_data(ctx, true);
|
||||
free( (void *) ctx );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ _mesa_initialize_context( struct gl_context *ctx,
|
|||
const struct dd_function_table *driverFunctions);
|
||||
|
||||
extern void
|
||||
_mesa_free_context_data( struct gl_context *ctx );
|
||||
_mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types);
|
||||
|
||||
extern void
|
||||
_mesa_destroy_context( struct gl_context *ctx );
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
#include "util/u_upload_mgr.h"
|
||||
#include "util/u_vbuf.h"
|
||||
#include "cso_cache/cso_context.h"
|
||||
#include "compiler/glsl/glsl_parser_extras.h"
|
||||
|
||||
|
||||
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)
|
||||
|
|
@ -977,13 +978,18 @@ st_destroy_context(struct st_context *st)
|
|||
|
||||
st_destroy_program_variants(st);
|
||||
|
||||
_mesa_free_context_data(ctx);
|
||||
_mesa_free_context_data(ctx, false);
|
||||
|
||||
/* This will free the st_context too, so 'st' must not be accessed
|
||||
* afterwards. */
|
||||
st_destroy_context_priv(st, true);
|
||||
st = NULL;
|
||||
|
||||
/* This must be called after st_destroy_context_priv() to avoid a race
|
||||
* condition between any shader compiler threads and context destruction.
|
||||
*/
|
||||
_mesa_destroy_shader_compiler_types();
|
||||
|
||||
free(ctx);
|
||||
|
||||
if (save_ctx == ctx) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue