diff options
author | Marek Olšák <[email protected]> | 2017-04-27 19:12:22 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-05-05 00:23:44 +0200 |
commit | 8ac4923a67ae77ed26b5233b2dd72d14a4518ec1 (patch) | |
tree | a7a8b076a828739fef39ec21d7976b2eb07e7f1c | |
parent | 9dfc030b486afab38f86f2b04f3a7c90f0a02fe6 (diff) |
radeonsi: prevent race conditions when doing scratch patching
Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_shaders.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 032cc0c3965..7da52f63456 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -2586,6 +2586,22 @@ static bool si_update_gs_ring_buffers(struct si_context *sctx) return true; } +static void si_shader_lock(struct si_shader *shader) +{ + mtx_lock(&shader->selector->mutex); + if (shader->previous_stage_sel) { + assert(shader->previous_stage_sel != shader->selector); + mtx_lock(&shader->previous_stage_sel->mutex); + } +} + +static void si_shader_unlock(struct si_shader *shader) +{ + if (shader->previous_stage_sel) + mtx_unlock(&shader->previous_stage_sel->mutex); + mtx_unlock(&shader->selector->mutex); +} + /** * @returns 1 if \p sel has been updated to use a new scratch buffer * 0 if not @@ -2604,10 +2620,19 @@ static int si_update_scratch_buffer(struct si_context *sctx, if (shader->config.scratch_bytes_per_wave == 0) return 0; + /* Prevent race conditions when updating: + * - si_shader::scratch_bo + * - si_shader::binary::code + * - si_shader::previous_stage::binary::code. + */ + si_shader_lock(shader); + /* 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) { + si_shader_unlock(shader); return 0; + } assert(sctx->scratch_buffer); @@ -2618,14 +2643,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) { + si_shader_unlock(shader); return r; + } /* Update the shader state to use the new shader bo. */ si_shader_init_pm4_state(sctx->screen, shader); r600_resource_reference(&shader->scratch_bo, sctx->scratch_buffer); + si_shader_unlock(shader); return 1; } |