summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec/src/ec-code.c
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2017-02-14 11:12:58 +0100
committerPranith Kumar Karampuri <pkarampu@redhat.com>2017-02-21 04:45:08 -0500
commit9f9d1482868e8e1044790c8358893f4421d89692 (patch)
tree63fd583a1706c92c871a366501a765859a3e1163 /xlators/cluster/ec/src/ec-code.c
parent431011098efc5702a2f49fad1975fb956cdc9e00 (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.c99
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