<div dir="ltr"><div>Reviewed-by: Marek Olšák <<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a>></div><div><br></div><div>Marek<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 23, 2019 at 2:04 AM Timothy Arceri <<a href="mailto:tarceri@itsqueeze.com">tarceri@itsqueeze.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Commit 624789e3708c moved the destruction of types out of atexit() and<br>
made use of a ref count instead. This is useful for avoiding a crash<br>
where drivers such as radeonsi are still compiling in a thread when the app<br>
exits and has not called MakeCurrent to change from the current context.<br>
<br>
While the above scenario is technically an app bug we shouldn't crash.<br>
However that change caused another race condition between the shader<br>
compilation tread in radeonsi and context teardown functions.<br>
<br>
This patch makes two changes to fix this new problem:<br>
<br>
First we explicitly call _mesa_destroy_shader_compiler_types() when destroying<br>
the st context rather than calling it indirectly via _mesa_free_context_data().<br>
We do this as we must call it after st_destroy_context_priv() so that we don't<br>
destory the glsl types before the compilation threads finish.<br>
<br>
Next wait for the shader threads to finish in si_destroy_context() this<br>
also means we need to call context destroy before destroying the queues<br>
in si_destroy_screen().<br>
<br>
Fixes: 624789e3708c ("compiler/glsl: handle case where we have multiple users for types")<br>
---<br>
src/compiler/glsl/glsl_parser_extras.h | 1 +<br>
src/gallium/drivers/radeonsi/si_pipe.c | 8 ++++++--<br>
src/mesa/drivers/dri/i915/intel_context.c | 2 +-<br>
src/mesa/drivers/dri/i965/brw_context.c | 2 +-<br>
src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 +-<br>
src/mesa/drivers/dri/radeon/radeon_common_context.c | 2 +-<br>
src/mesa/drivers/osmesa/osmesa.c | 8 ++++----<br>
src/mesa/drivers/x11/xm_api.c | 4 ++--<br>
src/mesa/main/context.c | 7 ++++---<br>
src/mesa/main/context.h | 2 +-<br>
src/mesa/state_tracker/st_context.c | 8 +++++++-<br>
11 files changed, 29 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h<br>
index f92d2160aac..edc6fc06c77 100644<br>
--- a/src/compiler/glsl/glsl_parser_extras.h<br>
+++ b/src/compiler/glsl/glsl_parser_extras.h<br>
@@ -997,6 +997,7 @@ extern "C" {<br>
#endif<br>
<br>
struct glcpp_parser;<br>
+struct _mesa_glsl_parse_state;<br>
<br>
typedef void (*glcpp_extension_iterator)(<br>
struct _mesa_glsl_parse_state *state,<br>
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c<br>
index fa96ce34224..e9e1bd0aa38 100644<br>
--- a/src/gallium/drivers/radeonsi/si_pipe.c<br>
+++ b/src/gallium/drivers/radeonsi/si_pipe.c<br>
@@ -150,6 +150,9 @@ static void si_destroy_context(struct pipe_context *context)<br>
struct si_context *sctx = (struct si_context *)context;<br>
int i;<br>
<br>
+ util_queue_finish(&sctx->screen->shader_compiler_queue);<br>
+ util_queue_finish(&sctx->screen->shader_compiler_queue_low_priority);<br>
+<br>
/* Unreference the framebuffer normally to disable related logic<br>
* properly.<br>
*/<br>
@@ -702,6 +705,9 @@ static void si_destroy_screen(struct pipe_screen* pscreen)<br>
if (!sscreen->ws->unref(sscreen->ws))<br>
return;<br>
<br>
+ mtx_destroy(&sscreen->aux_context_lock);<br>
+ sscreen->aux_context->destroy(sscreen->aux_context);<br>
+<br>
util_queue_destroy(&sscreen->shader_compiler_queue);<br>
util_queue_destroy(&sscreen->shader_compiler_queue_low_priority);<br>
<br>
@@ -728,8 +734,6 @@ static void si_destroy_screen(struct pipe_screen* pscreen)<br>
si_gpu_load_kill_thread(sscreen);<br>
<br>
mtx_destroy(&sscreen->gpu_load_mutex);<br>
- mtx_destroy(&sscreen->aux_context_lock);<br>
- sscreen->aux_context->destroy(sscreen->aux_context);<br>
<br>
slab_destroy_parent(&sscreen->pool_transfers);<br>
<br>
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c<br>
index c23e5ffb26e..aa3175816cf 100644<br>
--- a/src/mesa/drivers/dri/i915/intel_context.c<br>
+++ b/src/mesa/drivers/dri/i915/intel_context.c<br>
@@ -599,7 +599,7 @@ intelDestroyContext(__DRIcontext * driContextPriv)<br>
driDestroyOptionCache(&intel->optionCache);<br>
<br>
/* free the Mesa context */<br>
- _mesa_free_context_data(&intel->ctx);<br>
+ _mesa_free_context_data(&intel->ctx, true);<br>
<br>
_math_matrix_dtr(&intel->ViewportMatrix);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c<br>
index ab637ddf721..df12f373f22 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_context.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_context.c<br>
@@ -1226,7 +1226,7 @@ intelDestroyContext(__DRIcontext * driContextPriv)<br>
driDestroyOptionCache(&brw->optionCache);<br>
<br>
/* free the Mesa context */<br>
- _mesa_free_context_data(&brw->ctx);<br>
+ _mesa_free_context_data(&brw->ctx, true);<br>
<br>
ralloc_free(brw);<br>
driContextPriv->driverPrivate = NULL;<br>
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c<br>
index 93f6ce473a1..8fec35237c0 100644<br>
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c<br>
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c<br>
@@ -217,7 +217,7 @@ nouveau_context_deinit(struct gl_context *ctx)<br>
nouveau_object_del(&nctx->hw.chan);<br>
<br>
nouveau_scratch_destroy(ctx);<br>
- _mesa_free_context_data(ctx);<br>
+ _mesa_free_context_data(ctx, true);<br>
}<br>
<br>
void<br>
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c<br>
index 47719baa575..689304aa4fc 100644<br>
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c<br>
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c<br>
@@ -270,7 +270,7 @@ void radeonDestroyContext(__DRIcontext *driContextPriv )<br>
<br>
/* free atom list */<br>
/* free the Mesa context data */<br>
- _mesa_free_context_data(&radeon->glCtx);<br>
+ _mesa_free_context_data(&radeon->glCtx, true);<br>
<br>
/* free the option cache */<br>
driDestroyOptionCache(&radeon->optionCache);<br>
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c<br>
index 44374a2e917..a065161b89e 100644<br>
--- a/src/mesa/drivers/osmesa/osmesa.c<br>
+++ b/src/mesa/drivers/osmesa/osmesa.c<br>
@@ -854,7 +854,7 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)<br>
osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);<br>
if (!osmesa->gl_buffer) {<br>
_mesa_destroy_visual( osmesa->gl_visual );<br>
- _mesa_free_context_data( &osmesa->mesa );<br>
+ _mesa_free_context_data(&osmesa->mesa, true);<br>
free(osmesa);<br>
return NULL;<br>
}<br>
@@ -891,7 +891,7 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)<br>
!_tnl_CreateContext( ctx ) ||<br>
!_swsetup_CreateContext( ctx )) {<br>
_mesa_destroy_visual(osmesa->gl_visual);<br>
- _mesa_free_context_data(ctx);<br>
+ _mesa_free_context_data(ctx, true);<br>
free(osmesa);<br>
return NULL;<br>
}<br>
@@ -919,7 +919,7 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)<br>
<br>
if (ctx->Version < version_major * 10 + version_minor) {<br>
_mesa_destroy_visual(osmesa->gl_visual);<br>
- _mesa_free_context_data(ctx);<br>
+ _mesa_free_context_data(ctx, true);<br>
free(osmesa);<br>
return NULL;<br>
}<br>
@@ -955,7 +955,7 @@ OSMesaDestroyContext( OSMesaContext osmesa )<br>
_mesa_destroy_visual( osmesa->gl_visual );<br>
_mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );<br>
<br>
- _mesa_free_context_data( &osmesa->mesa );<br>
+ _mesa_free_context_data(&osmesa->mesa, true);<br>
free( osmesa );<br>
}<br>
}<br>
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c<br>
index e8405950656..90f89a36221 100644<br>
--- a/src/mesa/drivers/x11/xm_api.c<br>
+++ b/src/mesa/drivers/x11/xm_api.c<br>
@@ -945,7 +945,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )<br>
!_vbo_CreateContext( mesaCtx ) ||<br>
!_tnl_CreateContext( mesaCtx ) ||<br>
!_swsetup_CreateContext( mesaCtx )) {<br>
- _mesa_free_context_data(&c->mesa);<br>
+ _mesa_free_context_data(&c->mesa, true);<br>
free(c);<br>
return NULL;<br>
}<br>
@@ -982,7 +982,7 @@ void XMesaDestroyContext( XMesaContext c )<br>
_swrast_DestroyContext( mesaCtx );<br>
_tnl_DestroyContext( mesaCtx );<br>
_vbo_DestroyContext( mesaCtx );<br>
- _mesa_free_context_data( mesaCtx );<br>
+ _mesa_free_context_data(mesaCtx, true);<br>
free( c );<br>
}<br>
<br>
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c<br>
index 7300d2f3c46..2c3d9a11ce3 100644<br>
--- a/src/mesa/main/context.c<br>
+++ b/src/mesa/main/context.c<br>
@@ -1310,7 +1310,7 @@ fail:<br>
* \sa _mesa_initialize_context() and init_attrib_groups().<br>
*/<br>
void<br>
-_mesa_free_context_data( struct gl_context *ctx )<br>
+_mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types)<br>
{<br>
if (!_mesa_get_current_context()){<br>
/* No current context, but we may need one in order to delete<br>
@@ -1385,7 +1385,8 @@ _mesa_free_context_data( struct gl_context *ctx )<br>
<br>
free(ctx->VersionString);<br>
<br>
- _mesa_destroy_shader_compiler_types();<br>
+ if (destroy_compiler_types)<br>
+ _mesa_destroy_shader_compiler_types();<br>
<br>
/* unbind the context if it's currently bound */<br>
if (ctx == _mesa_get_current_context()) {<br>
@@ -1405,7 +1406,7 @@ void<br>
_mesa_destroy_context( struct gl_context *ctx )<br>
{<br>
if (ctx) {<br>
- _mesa_free_context_data(ctx);<br>
+ _mesa_free_context_data(ctx, true);<br>
free( (void *) ctx );<br>
}<br>
}<br>
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h<br>
index 7de10e9924b..e9b270df14c 100644<br>
--- a/src/mesa/main/context.h<br>
+++ b/src/mesa/main/context.h<br>
@@ -115,7 +115,7 @@ _mesa_initialize_context( struct gl_context *ctx,<br>
const struct dd_function_table *driverFunctions);<br>
<br>
extern void<br>
-_mesa_free_context_data( struct gl_context *ctx );<br>
+_mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types);<br>
<br>
extern void<br>
_mesa_destroy_context( struct gl_context *ctx );<br>
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c<br>
index 09d467aa360..067d47ef5e9 100644<br>
--- a/src/mesa/state_tracker/st_context.c<br>
+++ b/src/mesa/state_tracker/st_context.c<br>
@@ -85,6 +85,7 @@<br>
#include "util/u_upload_mgr.h"<br>
#include "util/u_vbuf.h"<br>
#include "cso_cache/cso_context.h"<br>
+#include "compiler/glsl/glsl_parser_extras.h"<br>
<br>
<br>
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)<br>
@@ -976,13 +977,18 @@ st_destroy_context(struct st_context *st)<br>
<br>
st_destroy_program_variants(st);<br>
<br>
- _mesa_free_context_data(ctx);<br>
+ _mesa_free_context_data(ctx, false);<br>
<br>
/* This will free the st_context too, so 'st' must not be accessed<br>
* afterwards. */<br>
st_destroy_context_priv(st, true);<br>
st = NULL;<br>
<br>
+ /* This must be called after st_destroy_context_priv() to avoid a race<br>
+ * condition between any shader compiler threads and context destruction.<br>
+ */<br>
+ _mesa_destroy_shader_compiler_types();<br>
+<br>
free(ctx);<br>
<br>
if (save_ctx == ctx) {<br>
-- <br>
2.20.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></blockquote></div>