<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>