summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec
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
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')
-rw-r--r--xlators/cluster/ec/src/ec-code.c99
-rw-r--r--xlators/cluster/ec/src/ec-method.c32
-rw-r--r--xlators/cluster/ec/src/ec-types.h2
3 files changed, 63 insertions, 70 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
diff --git a/xlators/cluster/ec/src/ec-method.c b/xlators/cluster/ec/src/ec-method.c
index 41bf0406ecb..e0dd8e7f1a0 100644
--- a/xlators/cluster/ec/src/ec-method.c
+++ b/xlators/cluster/ec/src/ec-method.c
@@ -70,12 +70,11 @@ ec_method_matrix_inverse(ec_gf_t *gf, uint32_t *matrix, uint32_t *values,
}
}
-static int32_t
+static void
ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix,
uintptr_t mask, uint32_t *rows, gf_boolean_t inverse)
{
uint32_t i;
- int32_t err = 0;
matrix->refs = 1;
matrix->mask = mask;
@@ -94,11 +93,6 @@ ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix,
EC_METHOD_WORD_SIZE,
matrix->row_data[i].values,
matrix->columns);
- if (EC_IS_ERR(matrix->row_data[i].func.interleaved)) {
- err = EC_GET_ERR(matrix->row_data[i].func.interleaved);
- matrix->row_data[i].func.interleaved = NULL;
- break;
- }
}
} else {
matrix->rows = list->rows;
@@ -110,15 +104,8 @@ ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix,
ec_code_build_linear(matrix->code, EC_METHOD_WORD_SIZE,
matrix->row_data[i].values,
matrix->columns);
- if (EC_IS_ERR(matrix->row_data[i].func.linear)) {
- err = EC_GET_ERR(matrix->row_data[i].func.linear);
- matrix->row_data[i].func.linear = NULL;
- break;
- }
}
}
-
- return err;
}
static void
@@ -218,7 +205,6 @@ ec_method_matrix_get(ec_matrix_list_t *list, uintptr_t mask, uint32_t *rows)
{
ec_matrix_t *matrix;
uint32_t pos;
- int32_t err = 0;
LOCK(&list->lock);
@@ -247,13 +233,7 @@ ec_method_matrix_get(ec_matrix_list_t *list, uintptr_t mask, uint32_t *rows)
sizeof(ec_matrix_row_t) * list->columns);
}
- err = ec_method_matrix_init(list, matrix, mask, rows, _gf_true);
- if (err != 0) {
- ec_method_matrix_unref(list, matrix);
- matrix = EC_ERR(err);
-
- goto out;
- }
+ ec_method_matrix_init(list, matrix, mask, rows, _gf_true);
if (list->count < list->max) {
ec_method_matrix_insert(list, matrix);
@@ -303,22 +283,16 @@ ec_method_setup(xlator_t *xl, ec_matrix_list_t *list, const char *gen)
list->code = NULL;
goto failed_matrix;
}
- list->width = list->code->width;
for (i = 0; i < list->rows; i++) {
values[i] = i + 1;
}
- err = ec_method_matrix_init(list, matrix, 0, values, _gf_false);
- if (err != 0) {
- goto failed_code;
- }
+ ec_method_matrix_init(list, matrix, 0, values, _gf_false);
list->encode = matrix;
return 0;
-failed_code:
- ec_code_destroy(list->code);
failed_matrix:
GF_FREE(matrix);
failed:
diff --git a/xlators/cluster/ec/src/ec-types.h b/xlators/cluster/ec/src/ec-types.h
index 751652c20b1..d701fe7d25e 100644
--- a/xlators/cluster/ec/src/ec-types.h
+++ b/xlators/cluster/ec/src/ec-types.h
@@ -408,7 +408,6 @@ struct _ec_code_gen {
struct _ec_code {
gf_lock_t lock;
struct list_head spaces;
- uint32_t width;
ec_gf_t *gf;
ec_code_gen_t *gen;
};
@@ -484,7 +483,6 @@ struct _ec_matrix_list {
uint32_t rows;
uint32_t max;
uint32_t count;
- uint32_t width;
uint32_t stripe;
struct mem_pool *pool;
ec_gf_t *gf;