[Mesa-dev] [PATCH] radeonsi: Cache LLVMTargetMachineRef in context instead of in screen
Tom Stellard
tom at stellard.net
Fri Mar 27 07:10:13 PDT 2015
On Fri, Mar 27, 2015 at 10:05:06AM +0900, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daenzer at 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-stable at lists.freedesktop.org>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
Reviewed-by: Tom Stellard <thomas.stellard at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list