On Fri, Mar 27, 2015 at 10:05:06AM +0900, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daen...@amd.com>
> 
> Fixes a crash in genymotion with several threads compiling shaders
> concurrently.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89746
> 
> Cc: 10.5 <mesa-sta...@lists.freedesktop.org>
> Signed-off-by: Michel Dänzer <michel.daen...@amd.com>

Reviewed-by: Tom Stellard <thomas.stell...@amd.com>

Thanks for looking into this.
> ---
>  src/gallium/drivers/radeonsi/si_compute.c       |  3 +-
>  src/gallium/drivers/radeonsi/si_pipe.c          | 43 
> +++++++++++++------------
>  src/gallium/drivers/radeonsi/si_pipe.h          |  3 +-
>  src/gallium/drivers/radeonsi/si_shader.c        | 13 +++++---
>  src/gallium/drivers/radeonsi/si_shader.h        |  5 +--
>  src/gallium/drivers/radeonsi/si_state_shaders.c |  4 ++-
>  6 files changed, 41 insertions(+), 30 deletions(-)
> 
> diff --git a/src/gallium/drivers/radeonsi/si_compute.c 
> b/src/gallium/drivers/radeonsi/si_compute.c
> index 8609b89..89bef2e 100644
> --- a/src/gallium/drivers/radeonsi/si_compute.c
> +++ b/src/gallium/drivers/radeonsi/si_compute.c
> @@ -130,7 +130,8 @@ static void *si_create_compute_state(
>               for (i = 0; i < program->num_kernels; i++) {
>                       LLVMModuleRef mod = 
> radeon_llvm_get_kernel_module(program->llvm_ctx, i,
>                                                          code, 
> header->num_bytes);
> -                     si_compile_llvm(sctx->screen, &program->kernels[i], 
> mod);
> +                     si_compile_llvm(sctx->screen, &program->kernels[i], 
> sctx->tm,
> +                                     mod);
>                       LLVMDisposeModule(mod);
>               }
>       }
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
> b/src/gallium/drivers/radeonsi/si_pipe.c
> index d335bda..0eada72 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -69,6 +69,11 @@ static void si_destroy_context(struct pipe_context 
> *context)
>       si_pm4_cleanup(sctx);
>  
>       r600_common_context_cleanup(&sctx->b);
> +
> +#if HAVE_LLVM >= 0x0306
> +     LLVMDisposeTargetMachine(sctx->tm);
> +#endif
> +
>       FREE(sctx);
>  }
>  
> @@ -77,6 +82,12 @@ static struct pipe_context *si_create_context(struct 
> pipe_screen *screen, void *
>       struct si_context *sctx = CALLOC_STRUCT(si_context);
>       struct si_screen* sscreen = (struct si_screen *)screen;
>       struct radeon_winsys *ws = sscreen->b.ws;
> +     LLVMTargetRef r600_target;
> +#if HAVE_LLVM >= 0x0306
> +     const char *triple = "amdgcn--";
> +#else
> +     const char *triple = "r600--";
> +#endif
>       int shader, i;
>  
>       if (sctx == NULL)
> @@ -170,6 +181,17 @@ static struct pipe_context *si_create_context(struct 
> pipe_screen *screen, void *
>        */
>       sctx->scratch_waves = 32 * sscreen->b.info.max_compute_units;
>  
> +#if HAVE_LLVM >= 0x0306
> +     /* Initialize LLVM TargetMachine */
> +     r600_target = radeon_llvm_get_r600_target(triple);
> +     sctx->tm = LLVMCreateTargetMachine(r600_target, triple,
> +                                        
> r600_get_llvm_processor_name(sscreen->b.family),
> +                                        "+DumpCode,+vgpr-spilling",
> +                                        LLVMCodeGenLevelDefault,
> +                                        LLVMRelocDefault,
> +                                        LLVMCodeModelDefault);
> +#endif
> +
>       return &sctx->b.b;
>  fail:
>       si_destroy_context(&sctx->b.b);
> @@ -445,12 +467,6 @@ static void si_destroy_screen(struct pipe_screen* 
> pscreen)
>       if (!sscreen->b.ws->unref(sscreen->b.ws))
>               return;
>  
> -#if HAVE_LLVM >= 0x0306
> -     // r600_destroy_common_screen() frees sscreen, so we need to make
> -     // sure to dispose the TargetMachine before we call it.
> -     LLVMDisposeTargetMachine(sscreen->tm);
> -#endif
> -
>       r600_destroy_common_screen(&sscreen->b);
>  }
>  
> @@ -508,12 +524,7 @@ static bool si_initialize_pipe_config(struct si_screen 
> *sscreen)
>  struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
>  {
>       struct si_screen *sscreen = CALLOC_STRUCT(si_screen);
> -     LLVMTargetRef r600_target;
> -#if HAVE_LLVM >= 0x0306
> -     const char *triple = "amdgcn--";
> -#else
> -     const char *triple = "r600--";
> -#endif
> +
>       if (sscreen == NULL) {
>               return NULL;
>       }
> @@ -541,13 +552,5 @@ struct pipe_screen *radeonsi_screen_create(struct 
> radeon_winsys *ws)
>       /* Create the auxiliary context. This must be done last. */
>       sscreen->b.aux_context = sscreen->b.b.context_create(&sscreen->b.b, 
> NULL);
>  
> -#if HAVE_LLVM >= 0x0306
> -     /* Initialize LLVM TargetMachine */
> -     r600_target = radeon_llvm_get_r600_target(triple);
> -     sscreen->tm = LLVMCreateTargetMachine(r600_target, triple,
> -                             r600_get_llvm_processor_name(sscreen->b.family),
> -                             "+DumpCode,+vgpr-spilling", 
> LLVMCodeGenLevelDefault, LLVMRelocDefault,
> -                             LLVMCodeModelDefault);
> -#endif
>       return &sscreen->b.b;
>  }
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h 
> b/src/gallium/drivers/radeonsi/si_pipe.h
> index 422b873..f98c7a8 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -85,7 +85,6 @@ struct si_compute;
>  
>  struct si_screen {
>       struct r600_common_screen       b;
> -     LLVMTargetMachineRef            tm;
>  };
>  
>  struct si_sampler_view {
> @@ -203,6 +202,8 @@ struct si_context {
>       struct pipe_resource    *esgs_ring;
>       struct pipe_resource    *gsvs_ring;
>  
> +     LLVMTargetMachineRef            tm;
> +
>       /* SI state handling */
>       union si_state  queued;
>       union si_state  emitted;
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
> b/src/gallium/drivers/radeonsi/si_shader.c
> index 4dcf756..b4709ac 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -72,6 +72,7 @@ struct si_shader_context
>       int param_streamout_offset[4];
>       int param_vertex_id;
>       int param_instance_id;
> +     LLVMTargetMachineRef tm;
>       LLVMValueRef const_md;
>       LLVMValueRef const_resource[SI_NUM_CONST_BUFFERS];
>       LLVMValueRef ddxy_lds;
> @@ -2697,13 +2698,13 @@ int si_shader_binary_read(struct si_screen *sscreen,
>  }
>  
>  int si_compile_llvm(struct si_screen *sscreen, struct si_shader *shader,
> -                                                     LLVMModuleRef mod)
> +                 LLVMTargetMachineRef tm, LLVMModuleRef mod)
>  {
>       int r = 0;
>       bool dump = r600_can_dump_shader(&sscreen->b,
>                       shader->selector ? shader->selector->tokens : NULL);
>       r = radeon_llvm_compile(mod, &shader->binary,
> -             r600_get_llvm_processor_name(sscreen->b.family), dump, 
> sscreen->tm);
> +             r600_get_llvm_processor_name(sscreen->b.family), dump, tm);
>  
>       if (r) {
>               return r;
> @@ -2791,7 +2792,7 @@ static int si_generate_gs_copy_shader(struct si_screen 
> *sscreen,
>               fprintf(stderr, "Copy Vertex Shader for Geometry Shader:\n\n");
>  
>       r = si_compile_llvm(sscreen, si_shader_ctx->shader,
> -                         bld_base->base.gallivm->module);
> +                         si_shader_ctx->tm, bld_base->base.gallivm->module);
>  
>       radeon_llvm_dispose(&si_shader_ctx->radeon_bld);
>  
> @@ -2836,7 +2837,8 @@ static void si_dump_key(unsigned shader, union 
> si_shader_key *key)
>       }
>  }
>  
> -int si_shader_create(struct si_screen *sscreen, struct si_shader *shader)
> +int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
> +                  struct si_shader *shader)
>  {
>       struct si_shader_selector *sel = shader->selector;
>       struct tgsi_token *tokens = sel->tokens;
> @@ -2909,6 +2911,7 @@ int si_shader_create(struct si_screen *sscreen, struct 
> si_shader *shader)
>       si_shader_ctx.shader = shader;
>       si_shader_ctx.type = tgsi_get_processor_type(tokens);
>       si_shader_ctx.screen = sscreen;
> +     si_shader_ctx.tm = tm;
>  
>       switch (si_shader_ctx.type) {
>       case TGSI_PROCESSOR_VERTEX:
> @@ -2964,7 +2967,7 @@ int si_shader_create(struct si_screen *sscreen, struct 
> si_shader *shader)
>       radeon_llvm_finalize_module(&si_shader_ctx.radeon_bld);
>  
>       mod = bld_base->base.gallivm->module;
> -     r = si_compile_llvm(sscreen, shader, mod);
> +     r = si_compile_llvm(sscreen, shader, tm, mod);
>       if (r) {
>               fprintf(stderr, "LLVM failed to compile shader\n");
>               goto out;
> diff --git a/src/gallium/drivers/radeonsi/si_shader.h 
> b/src/gallium/drivers/radeonsi/si_shader.h
> index 5b602ac..51055af 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.h
> +++ b/src/gallium/drivers/radeonsi/si_shader.h
> @@ -183,9 +183,10 @@ static inline struct si_shader* si_get_vs_state(struct 
> si_context *sctx)
>  }
>  
>  /* radeonsi_shader.c */
> -int si_shader_create(struct si_screen *sscreen, struct si_shader *shader);
> +int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
> +                  struct si_shader *shader);
>  int si_compile_llvm(struct si_screen *sscreen, struct si_shader *shader,
> -                 LLVMModuleRef mod);
> +                 LLVMTargetMachineRef tm, LLVMModuleRef mod);
>  void si_shader_destroy(struct pipe_context *ctx, struct si_shader *shader);
>  unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned 
> index);
>  int si_shader_binary_read(struct si_screen *sscreen, struct si_shader 
> *shader,
> diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c 
> b/src/gallium/drivers/radeonsi/si_state_shaders.c
> index 382738a..b0a6fb9 100644
> --- a/src/gallium/drivers/radeonsi/si_state_shaders.c
> +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
> @@ -405,6 +405,7 @@ static INLINE void si_shader_selector_key(struct 
> pipe_context *ctx,
>  static int si_shader_select(struct pipe_context *ctx,
>                           struct si_shader_selector *sel)
>  {
> +     struct si_context *sctx = (struct si_context *)ctx;
>       union si_shader_key key;
>       struct si_shader * shader = NULL;
>       int r;
> @@ -444,7 +445,8 @@ static int si_shader_select(struct pipe_context *ctx,
>  
>               shader->next_variant = sel->current;
>               sel->current = shader;
> -             r = si_shader_create((struct si_screen*)ctx->screen, shader);
> +             r = si_shader_create((struct si_screen*)ctx->screen, sctx->tm,
> +                                  shader);
>               if (unlikely(r)) {
>                       R600_ERR("Failed to build shader variant (type=%u) 
> %d\n",
>                                sel->type, r);
> -- 
> 2.1.4
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to