From 4ab1336cabe0c1f5d7fc18c21b78f5d21aca5b60 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 16 Feb 2017 17:16:28 +1100 Subject: [PATCH] jerasure: plug memory leaks Jerasure inits some global variables on init. We need to free them, or we'll leak memory. Partial-Bug: #1666674 Change-Id: Ie7073738428a71910016e910a66dbd92ca98eb92 Signed-off-by: Daniel Axtens --- src/backends/jerasure/jerasure_rs_cauchy.c | 21 +++++++++++++++++++ src/backends/jerasure/jerasure_rs_vand.c | 24 +++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/backends/jerasure/jerasure_rs_cauchy.c b/src/backends/jerasure/jerasure_rs_cauchy.c index 816b45d..6400ca2 100644 --- a/src/backends/jerasure/jerasure_rs_cauchy.c +++ b/src/backends/jerasure/jerasure_rs_cauchy.c @@ -63,6 +63,7 @@ typedef int (*jerasure_make_decoding_bitmatrix_func) (int, int, int, int *, int *, int *, int *); typedef void (*jerasure_bitmatrix_dotprod_func) (int, int, int *, int *, int,char **, char **, int, int); +typedef void (*galois_uninit_field_func)(int); /* * ToDo (KMG): Should we make this a parameter, or is that @@ -76,6 +77,9 @@ struct jerasure_rs_cauchy_descriptor { jerasure_matrix_to_bitmatrix_func jerasure_matrix_to_bitmatrix; jerasure_smart_bitmatrix_to_schedule_func jerasure_smart_bitmatrix_to_schedule; + /* calls required for free */ + galois_uninit_field_func galois_uninit_field; + /* calls required for encode */ jerasure_bitmatrix_encode_func jerasure_bitmatrix_encode; @@ -273,6 +277,7 @@ static void * jerasure_rs_cauchy_init(struct ec_backend_args *args, cauchy_original_coding_matrix_func initp; jerasure_matrix_to_bitmatrix_func matrixtobitmatrixp; jerasure_smart_bitmatrix_to_schedule_func matrixschedulep; + galois_uninit_field_func uninitp; jerasure_bitmatrix_encode_func encodep; jerasure_bitmatrix_decode_func decodep; jerasure_erasures_to_erased_func erasedp; @@ -338,6 +343,13 @@ static void * jerasure_rs_cauchy_init(struct ec_backend_args *args, goto error; } + func_handle.vptr = NULL; + func_handle.vptr = dlsym(backend_sohandle, "galois_uninit_field"); + desc->galois_uninit_field = func_handle.uninitp; + if (NULL == desc->galois_uninit_field) { + goto error; + } + /* setup the Cauchy matrices and schedules */ desc->matrix = desc->cauchy_original_coding_matrix(k, m, w); if (NULL == desc->matrix) { @@ -385,6 +397,15 @@ static void free_rs_cauchy_desc( return; } + /* + * jerasure allocates some internal data structures for caching + * fields. It will allocate one for w, and if we do anything that + * needs to xor a region >= 16 bytes, it will also allocate one + * for 32. Fortunately we can safely uninit any value; if it + * wasn't inited it will be ignored. + */ + jerasure_desc->galois_uninit_field(jerasure_desc->w); + jerasure_desc->galois_uninit_field(32); free(jerasure_desc->matrix); free(jerasure_desc->bitmatrix); diff --git a/src/backends/jerasure/jerasure_rs_vand.c b/src/backends/jerasure/jerasure_rs_vand.c index 0c337a0..b0257a7 100644 --- a/src/backends/jerasure/jerasure_rs_vand.c +++ b/src/backends/jerasure/jerasure_rs_vand.c @@ -56,11 +56,15 @@ typedef int (*jerasure_matrix_decode_func)(int, int, int, int *, int, int*, char typedef int (*jerasure_make_decoding_matrix_func)(int, int, int, int *, int *, int *, int *); typedef int * (*jerasure_erasures_to_erased_func)(int, int, int *); typedef void (*jerasure_matrix_dotprod_func)(int, int, int *,int *, int,char **, char **, int); +typedef void (*galois_uninit_field_func)(int); struct jerasure_rs_vand_descriptor { /* calls required for init */ reed_sol_vandermonde_coding_matrix_func reed_sol_vandermonde_coding_matrix; - + + /* calls required for free */ + galois_uninit_field_func galois_uninit_field; + /* calls required for encode */ jerasure_matrix_encode_func jerasure_matrix_encode; @@ -235,6 +239,7 @@ static void * jerasure_rs_vand_init(struct ec_backend_args *args, */ union { reed_sol_vandermonde_coding_matrix_func initp; + galois_uninit_field_func uninitp; jerasure_matrix_encode_func encodep; jerasure_matrix_decode_func decodep; jerasure_make_decoding_matrix_func decodematrixp; @@ -287,6 +292,13 @@ static void * jerasure_rs_vand_init(struct ec_backend_args *args, goto error; } + func_handle.vptr = NULL; + func_handle.vptr = dlsym(backend_sohandle, "galois_uninit_field"); + desc->galois_uninit_field = func_handle.uninitp; + if (NULL == desc->galois_uninit_field) { + goto error; + } + desc->matrix = desc->reed_sol_vandermonde_coding_matrix( desc->k, desc->m, desc->w); if (NULL == desc->matrix) { @@ -323,6 +335,16 @@ static int jerasure_rs_vand_exit(void *desc) struct jerasure_rs_vand_descriptor *jerasure_desc = NULL; jerasure_desc = (struct jerasure_rs_vand_descriptor*) desc; + + /* + * jerasure allocates some internal data structures for caching + * fields. It will allocate one for w, and if we do anything that + * needs to xor a region >= 16 bytes, it will also allocate one + * for 32. Fortunately we can safely uninit any value; if it + * wasn't inited it will be ignored. + */ + jerasure_desc->galois_uninit_field(jerasure_desc->w); + jerasure_desc->galois_uninit_field(32); free(jerasure_desc->matrix); free(jerasure_desc);