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 | |
| 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>
| -rw-r--r-- | xlators/cluster/ec/src/ec-code.c | 99 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-method.c | 32 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-types.h | 2 | 
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;  | 
