Fix cached EC decoding of multiple stripes with ISA-L
This commit is contained in:
+4
-1
@@ -286,6 +286,10 @@ static void* get_jerasure_decoding_matrix(osd_rmw_stripe_t *stripes, int pg_size
|
|||||||
if (edd == 0)
|
if (edd == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
reed_sol_matrix_t *matrix = get_ec_matrix(pg_size, pg_minsize);
|
reed_sol_matrix_t *matrix = get_ec_matrix(pg_size, pg_minsize);
|
||||||
|
#ifdef WITH_ISAL
|
||||||
|
if (item_size)
|
||||||
|
*item_size = matrix->isal_item_size;
|
||||||
|
#endif
|
||||||
auto dec_it = matrix->decodings.find((reed_sol_erased_t){ .data = erased, .size = pg_size });
|
auto dec_it = matrix->decodings.find((reed_sol_erased_t){ .data = erased, .size = pg_size });
|
||||||
if (dec_it == matrix->decodings.end())
|
if (dec_it == matrix->decodings.end())
|
||||||
{
|
{
|
||||||
@@ -330,7 +334,6 @@ static void* get_jerasure_decoding_matrix(osd_rmw_stripe_t *stripes, int pg_size
|
|||||||
int *erased_copy = (int*)(rectable + 32*smrow*pg_minsize);
|
int *erased_copy = (int*)(rectable + 32*smrow*pg_minsize);
|
||||||
memcpy(erased_copy, erased, pg_size*sizeof(int));
|
memcpy(erased_copy, erased, pg_size*sizeof(int));
|
||||||
matrix->decodings.emplace((reed_sol_erased_t){ .data = erased_copy, .size = pg_size }, rectable);
|
matrix->decodings.emplace((reed_sol_erased_t){ .data = erased_copy, .size = pg_size }, rectable);
|
||||||
*item_size = matrix->isal_item_size;
|
|
||||||
return rectable;
|
return rectable;
|
||||||
#else
|
#else
|
||||||
int *dm_ids = (int*)malloc_or_die(sizeof(int)*(pg_minsize + pg_minsize*pg_minsize + pg_size));
|
int *dm_ids = (int*)malloc_or_die(sizeof(int)*(pg_minsize + pg_minsize*pg_minsize + pg_size));
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ void test14();
|
|||||||
void test15(bool second);
|
void test15(bool second);
|
||||||
void test16();
|
void test16();
|
||||||
void test_recover_22_d2();
|
void test_recover_22_d2();
|
||||||
|
void test_recover_22_d01_cache();
|
||||||
void test_ec43_error_bruteforce();
|
void test_ec43_error_bruteforce();
|
||||||
void test_recover_53_d5();
|
void test_recover_53_d5();
|
||||||
void test_recover_22();
|
void test_recover_22();
|
||||||
@@ -68,6 +69,8 @@ int main(int narg, char *args[])
|
|||||||
test16();
|
test16();
|
||||||
// Test 17
|
// Test 17
|
||||||
test_recover_22_d2();
|
test_recover_22_d2();
|
||||||
|
// Test 17b: regression — cached ISA-L decoder with multi-range missing data roles
|
||||||
|
test_recover_22_d01_cache();
|
||||||
// Error bruteforce
|
// Error bruteforce
|
||||||
test_ec43_error_bruteforce();
|
test_ec43_error_bruteforce();
|
||||||
test_ec_find_good_multi_chunks();
|
test_ec_find_good_multi_chunks();
|
||||||
@@ -1120,6 +1123,77 @@ void test_recover_22_d2()
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
||||||
|
17b. EC 2+2 — two missing data roles with different read ranges, decoder cached.
|
||||||
|
Regression test for the get_jerasure_decoding_matrix() / reconstruct_stripes_ec()
|
||||||
|
bug where *item_size was set only on cache miss, so on a subsequent call
|
||||||
|
(cache hit) item_size stayed 0 and `dectable + wanted_base*item_size*pg_minsize`
|
||||||
|
collapsed to dectable for every group — the second `recover_seq()` invocation
|
||||||
|
then decoded role 1 using the matrix row that reconstructs role 0.
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
void test_recover_22_d01_cache()
|
||||||
|
{
|
||||||
|
use_ec(4, 2, true);
|
||||||
|
// Step 1: encode known data through the normal path to obtain the two parity blocks.
|
||||||
|
osd_num_t enc_set[4] = { 1, 2, 3, 4 };
|
||||||
|
osd_rmw_stripe_t enc[4] = {};
|
||||||
|
split_stripes(2, 8192, 0, 16384, enc);
|
||||||
|
void *write_buf = malloc_or_die(16384);
|
||||||
|
set_pattern((uint8_t*)write_buf+0*4096, 4096, PATTERN0); // data 0, [0..4K)
|
||||||
|
set_pattern((uint8_t*)write_buf+1*4096, 4096, PATTERN1); // data 0, [4K..8K)
|
||||||
|
set_pattern((uint8_t*)write_buf+2*4096, 4096, PATTERN2); // data 1, [0..4K)
|
||||||
|
set_pattern((uint8_t*)write_buf+3*4096, 4096, PATTERN3); // data 1, [4K..8K)
|
||||||
|
void *rmw_buf = calc_rmw(write_buf, enc, enc_set, 4, 2, 4, enc_set, 8192, 0);
|
||||||
|
calc_rmw_parity_ec(enc, 4, 2, enc_set, enc_set, 8192, 0);
|
||||||
|
// Step 2: first reconstruction — cache miss, same read range for both missing roles.
|
||||||
|
// Always passes; this populates matrix->decodings for the (1,1,0,0) erasure pattern.
|
||||||
|
{
|
||||||
|
osd_rmw_stripe_t s[4] = {};
|
||||||
|
uint8_t *buf = (uint8_t*)malloc_or_die(8192*4);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
s[i].read_start = 0;
|
||||||
|
s[i].read_end = 8192;
|
||||||
|
s[i].read_buf = buf + i*8192;
|
||||||
|
}
|
||||||
|
s[0].missing = true;
|
||||||
|
s[1].missing = true;
|
||||||
|
memcpy(s[2].read_buf, enc[2].write_buf, 8192);
|
||||||
|
memcpy(s[3].read_buf, enc[3].write_buf, 8192);
|
||||||
|
reconstruct_stripes_ec(s, 4, 2, 0);
|
||||||
|
check_pattern((uint8_t*)s[0].read_buf+0*4096, 4096, PATTERN0);
|
||||||
|
check_pattern((uint8_t*)s[0].read_buf+1*4096, 4096, PATTERN1);
|
||||||
|
check_pattern((uint8_t*)s[1].read_buf+0*4096, 4096, PATTERN2);
|
||||||
|
check_pattern((uint8_t*)s[1].read_buf+1*4096, 4096, PATTERN3);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
// Step 3: second reconstruction — cache HIT, missing roles have DIFFERENT ranges,
|
||||||
|
// so recover_seq() runs twice and wanted_base becomes 1 between the calls.
|
||||||
|
// With the bug, role 1 gets decoded using row 0 of the rectable (PATTERN1 instead of PATTERN3).
|
||||||
|
{
|
||||||
|
osd_rmw_stripe_t s[4] = {};
|
||||||
|
uint8_t *buf = (uint8_t*)malloc_or_die(8192*4);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
s[i].read_buf = buf + i*8192;
|
||||||
|
s[0].read_start = 0; s[0].read_end = 4096; s[0].missing = true;
|
||||||
|
s[1].read_start = 4096; s[1].read_end = 8192; s[1].missing = true;
|
||||||
|
s[2].read_start = 0; s[2].read_end = 8192;
|
||||||
|
s[3].read_start = 0; s[3].read_end = 8192;
|
||||||
|
memcpy(s[2].read_buf, enc[2].write_buf, 8192);
|
||||||
|
memcpy(s[3].read_buf, enc[3].write_buf, 8192);
|
||||||
|
reconstruct_stripes_ec(s, 4, 2, 0);
|
||||||
|
check_pattern((uint8_t*)s[0].read_buf, 4096, PATTERN0);
|
||||||
|
check_pattern((uint8_t*)s[1].read_buf, 4096, PATTERN3);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
use_ec(4, 2, false);
|
||||||
|
free(rmw_buf);
|
||||||
|
free(write_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
|
||||||
18. EC 4+2 error location bruteforce
|
18. EC 4+2 error location bruteforce
|
||||||
|
|
||||||
***/
|
***/
|
||||||
|
|||||||
Reference in New Issue
Block a user