[Mesa-dev] [PATCH v2] radeonsi: Lock a mutex when checking scratch relocations.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Thu Apr 21 20:10:04 UTC 2016


We can use shaders from multiple contexts, and they were not
otherwise locked yet.

v2: Fix the shader = NULL case.

Signed-off-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
---
 src/gallium/drivers/radeonsi/si_compute.c       | 20 ++++++++++++++++----
 src/gallium/drivers/radeonsi/si_state_shaders.c | 13 +++++++++++--
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c
index 7e05be5..a99a985 100644
--- a/src/gallium/drivers/radeonsi/si_compute.c
+++ b/src/gallium/drivers/radeonsi/si_compute.c
@@ -37,6 +37,7 @@
 #define MAX_GLOBAL_BUFFERS 20
 
 struct si_compute {
+	pipe_mutex mutex;
 	unsigned ir_type;
 	unsigned local_size;
 	unsigned private_size;
@@ -116,6 +117,7 @@ static void *si_create_compute_state(
 		si_shader_binary_upload(sctx->screen, &program->shader);
 	}
 
+	pipe_mutex_init(program->mutex);
 	return program;
 }
 
@@ -196,15 +198,19 @@ static void si_initialize_compute(struct si_context *sctx)
 }
 
 static bool si_setup_compute_scratch_buffer(struct si_context *sctx,
-                                            struct si_shader *shader,
+                                            struct si_compute *program,
                                             struct si_shader_config *config)
 {
+	struct si_shader *shader = &program->shader;
 	uint64_t scratch_bo_size, scratch_needed;
 	scratch_bo_size = 0;
 	scratch_needed = config->scratch_bytes_per_wave * sctx->scratch_waves;
 	if (sctx->compute_scratch_buffer)
 		scratch_bo_size = sctx->compute_scratch_buffer->b.b.width0;
 
+	if (!scratch_needed)
+		return true;
+
 	if (scratch_bo_size < scratch_needed) {
 		pipe_resource_reference(
 			(struct pipe_resource**)&sctx->compute_scratch_buffer,
@@ -218,18 +224,23 @@ static bool si_setup_compute_scratch_buffer(struct si_context *sctx,
 			return false;
 	}
 
-	if (sctx->compute_scratch_buffer != shader->scratch_bo && scratch_needed) {
+	pipe_mutex_lock(program->mutex);
+
+	if (sctx->compute_scratch_buffer != shader->scratch_bo) {
 		uint64_t scratch_va = sctx->compute_scratch_buffer->gpu_address;
 
 		si_shader_apply_scratch_relocs(sctx, shader, config, scratch_va);
 
-		if (si_shader_binary_upload(sctx->screen, shader))
+		if (si_shader_binary_upload(sctx->screen, shader)) {
+			pipe_mutex_unlock(program->mutex);
 			return false;
+		}
 
 		r600_resource_reference(&shader->scratch_bo,
 		                        sctx->compute_scratch_buffer);
 	}
 
+	pipe_mutex_unlock(program->mutex);
 	return true;
 }
 
@@ -272,7 +283,7 @@ static bool si_switch_compute_shader(struct si_context *sctx,
 		config->rsrc2 |=  S_00B84C_LDS_SIZE(lds_blocks);
 	}
 
-	if (!si_setup_compute_scratch_buffer(sctx, shader, config))
+	if (!si_setup_compute_scratch_buffer(sctx, program, config))
 		return false;
 
 	if (shader->scratch_bo) {
@@ -503,6 +514,7 @@ static void si_delete_compute_state(struct pipe_context *ctx, void* state){
 		sctx->cs_shader_state.emitted_program = NULL;
 
 	si_shader_destroy(&program->shader);
+	pipe_mutex_destroy(program->mutex);
 	FREE(program);
 }
 
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 49e688a..c846001 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1618,6 +1618,7 @@ static int si_update_scratch_buffer(struct si_context *sctx,
 				    struct si_shader *shader)
 {
 	uint64_t scratch_va = sctx->scratch_buffer->gpu_address;
+	struct si_shader_selector *sel;
 	int r;
 
 	if (!shader)
@@ -1627,10 +1628,15 @@ static int si_update_scratch_buffer(struct si_context *sctx,
 	if (shader->config.scratch_bytes_per_wave == 0)
 		return 0;
 
+	sel = shader->selector;
+	pipe_mutex_lock(sel->mutex);
+
 	/* This shader is already configured to use the current
 	 * scratch buffer. */
-	if (shader->scratch_bo == sctx->scratch_buffer)
+	if (shader->scratch_bo == sctx->scratch_buffer) {
+		pipe_mutex_unlock(sel->mutex);
 		return 0;
+	}
 
 	assert(sctx->scratch_buffer);
 
@@ -1638,14 +1644,17 @@ static int si_update_scratch_buffer(struct si_context *sctx,
 
 	/* Replace the shader bo with a new bo that has the relocs applied. */
 	r = si_shader_binary_upload(sctx->screen, shader);
-	if (r)
+	if (r) {
+		pipe_mutex_unlock(sel->mutex);
 		return r;
+	}
 
 	/* Update the shader state to use the new shader bo. */
 	si_shader_init_pm4_state(shader);
 
 	r600_resource_reference(&shader->scratch_bo, sctx->scratch_buffer);
 
+	pipe_mutex_unlock(sel->mutex);
 	return 1;
 }
 
-- 
2.8.0



More information about the mesa-dev mailing list