diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2017-02-14 11:12:58 +0100 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2017-02-21 04:45:08 -0500 |
commit | 9f9d1482868e8e1044790c8358893f4421d89692 (patch) | |
tree | 63fd583a1706c92c871a366501a765859a3e1163 /xlators/cluster/ec/src/ec-code.c | |
parent | 431011098efc5702a2f49fad1975fb956cdc9e00 (diff) |
cluster/ec: Fallback to precompiled code
When dynamic code generation fails for some reason, instead of causing
a failure in encode/decode, fallback to the precompiled version.
Change-Id: I4f8a97d3033aa5885779722b19c6e611caa4ffea
BUG: 1421955
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: https://review.gluster.org/16614
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/cluster/ec/src/ec-code.c')
-rw-r--r-- | xlators/cluster/ec/src/ec-code.c | 99 |
1 files changed, 60 insertions, 39 deletions
diff --git a/xlators/cluster/ec/src/ec-code.c b/xlators/cluster/ec/src/ec-code.c index 25a501e61b7..7b5d53d0a37 100644 --- a/xlators/cluster/ec/src/ec-code.c +++ b/xlators/cluster/ec/src/ec-code.c @@ -679,11 +679,6 @@ ec_code_create(ec_gf_t *gf, ec_code_gen_t *gen) code->gf = gf; code->gen = gen; - if (gen == NULL) { - code->width = sizeof(uint64_t); - } else { - code->width = gen->width; - } return code; } @@ -717,45 +712,70 @@ ec_code_value_next(uint32_t *values, uint32_t count, uint32_t *offset) } static void * +ec_code_build_dynamic(ec_code_t *code, uint32_t width, uint32_t *values, + uint32_t count, gf_boolean_t linear) +{ + ec_code_builder_t *builder; + uint32_t offset, val, next; + + builder = ec_code_prepare(code, count, width, linear); + if (EC_IS_ERR(builder)) { + return builder; + } + + offset = -1; + next = ec_code_value_next(values, count, &offset); + if (next != 0) { + ec_code_gf_load(builder, offset); + do { + val = next; + next = ec_code_value_next(values, count, &offset); + if (next != 0) { + ec_code_gf_mul(builder, ec_gf_div(code->gf, + val, next)); + ec_code_gf_load_xor(builder, offset); + } + } while (next != 0); + ec_code_gf_mul(builder, val); + ec_code_gf_store(builder); + } else { + ec_code_gf_clear(builder); + } + + return ec_code_compile(builder); +} + +static void * ec_code_build(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count, gf_boolean_t linear) { - ec_code_builder_t *builder; - uint32_t offset, val, next; + void *func; - if (code->gen == NULL) { - ec_code_c_prepare(code->gf, values, count); - if (linear) { - return ec_code_c_linear; - } else { - return ec_code_c_interleaved; + if (code->gen != NULL) { + func = ec_code_build_dynamic(code, width, values, count, + linear); + if (!EC_IS_ERR(func)) { + return func; + } + + gf_msg_debug(THIS->name, GF_LOG_DEBUG, + "Unable to generate dynamic code. Falling back " + "to precompiled code"); + + /* The dynamic code generation shouldn't fail in normal + * conditions, but if it fails at some point, it's very + * probable that it will fail again, so we completely disable + * dynamic code generation. */ + code->gen = NULL; } - } - builder = ec_code_prepare(code, count, width, linear); - if (EC_IS_ERR(builder)) { - return builder; - } + ec_code_c_prepare(code->gf, values, count); - offset = -1; - next = ec_code_value_next(values, count, &offset); - if (next != 0) { - ec_code_gf_load(builder, offset); - do { - val = next; - next = ec_code_value_next(values, count, &offset); - if (next != 0) { - ec_code_gf_mul(builder, ec_gf_div(code->gf, val, next)); - ec_code_gf_load_xor(builder, offset); - } - } while (next != 0); - ec_code_gf_mul(builder, val); - ec_code_gf_store(builder); - } else { - ec_code_gf_clear(builder); - } + if (linear) { + return ec_code_c_linear; + } - return ec_code_compile(builder); + return ec_code_c_interleaved; } ec_code_func_linear_t @@ -777,9 +797,10 @@ ec_code_build_interleaved(ec_code_t *code, uint32_t width, uint32_t *values, void ec_code_release(ec_code_t *code, ec_code_func_t *func) { - if (code->gen != NULL) { - ec_code_free(ec_code_chunk_from_func(func->linear)); - } + if ((func->linear != ec_code_c_linear) && + (func->interleaved != ec_code_c_interleaved)) { + ec_code_free(ec_code_chunk_from_func(func->linear)); + } } void |