]>
git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/erasure_code/erasure_code_update_test.c
1 /**********************************************************************
2 Copyright(c) 2011-2015 Intel Corporation All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
32 #include <string.h> // for memset, memcmp
33 #include "erasure_code.h"
37 # define ALIGN_SIZE 16
40 //By default, test multibinary version
41 #ifndef FUNCTION_UNDER_TEST
42 # define FUNCTION_UNDER_TEST ec_encode_data_update
43 # define REF_FUNCTION ec_encode_data
47 #define TEST_SIZE (TEST_LEN/2)
50 # define TEST_SOURCES 127
56 #define MMAX TEST_SOURCES
57 #define KMAX TEST_SOURCES
59 #ifdef EC_ALIGNED_ADDR
60 // Define power of 2 range to check ptr, len alignment
61 # define PTR_ALIGN_CHK_B 0
62 # define LEN_ALIGN_CHK_B 0 // 0 for aligned only
64 // Define power of 2 range to check ptr, len alignment
65 # define PTR_ALIGN_CHK_B ALIGN_SIZE
66 # define LEN_ALIGN_CHK_B ALIGN_SIZE // 0 for aligned only
74 #define xstr(s) str(s)
76 typedef unsigned char u8
;
78 void dump(unsigned char *buf
, int len
)
81 for (i
= 0; i
< len
;) {
82 printf(" %2x", 0xff & buf
[i
++]);
89 void dump_matrix(unsigned char **s
, int k
, int m
)
92 for (i
= 0; i
< k
; i
++) {
93 for (j
= 0; j
< m
; j
++) {
94 printf(" %2x", s
[i
][j
]);
101 void dump_u8xu8(unsigned char *s
, int k
, int m
)
104 for (i
= 0; i
< k
; i
++) {
105 for (j
= 0; j
< m
; j
++) {
106 printf(" %2x", 0xff & s
[j
+ (i
* m
)]);
113 // Generate Random errors
114 static void gen_err_list(unsigned char *src_err_list
,
115 unsigned char *src_in_err
, int *pnerrs
, int *pnsrcerrs
, int k
, int m
)
118 int nerrs
= 0, nsrcerrs
= 0;
120 for (i
= 0, nerrs
= 0, nsrcerrs
= 0; i
< m
&& nerrs
< m
- k
; i
++) {
124 src_err_list
[nerrs
++] = i
;
130 if (nerrs
== 0) { // should have at least one error
131 while ((err
= (rand() % KMAX
)) >= m
) ;
132 src_err_list
[nerrs
++] = err
;
138 *pnsrcerrs
= nsrcerrs
;
142 #define NO_INVERT_MATRIX -2
143 // Generate decode matrix from encode matrix
144 static int gf_gen_decode_matrix(unsigned char *encode_matrix
,
145 unsigned char *decode_matrix
,
146 unsigned char *invert_matrix
,
147 unsigned int *decode_index
,
148 unsigned char *src_err_list
,
149 unsigned char *src_in_err
,
150 int nerrs
, int nsrcerrs
, int k
, int m
)
154 unsigned char *backup
, *b
, s
;
157 b
= malloc(MMAX
* KMAX
);
158 backup
= malloc(MMAX
* KMAX
);
160 if (b
== NULL
|| backup
== NULL
) {
161 printf("Test failure! Error with malloc\n");
166 // Construct matrix b by removing error rows
167 for (i
= 0, r
= 0; i
< k
; i
++, r
++) {
168 while (src_in_err
[r
])
170 for (j
= 0; j
< k
; j
++) {
171 b
[k
* i
+ j
] = encode_matrix
[k
* r
+ j
];
172 backup
[k
* i
+ j
] = encode_matrix
[k
* r
+ j
];
177 while (gf_invert_matrix(b
, invert_matrix
, k
) < 0) {
178 if (nerrs
== (m
- k
)) {
181 printf("BAD MATRIX\n");
182 return NO_INVERT_MATRIX
;
185 memcpy(b
, backup
, MMAX
* KMAX
);
186 for (i
= nsrcerrs
; i
< nerrs
- nsrcerrs
; i
++) {
187 if (src_err_list
[i
] == (decode_index
[k
- 1] + incr
)) {
188 // skip the erased parity line
193 if (decode_index
[k
- 1] + incr
>= m
) {
196 printf("BAD MATRIX\n");
197 return NO_INVERT_MATRIX
;
199 decode_index
[k
- 1] += incr
;
200 for (j
= 0; j
< k
; j
++)
201 b
[k
* (k
- 1) + j
] = encode_matrix
[k
* decode_index
[k
- 1] + j
];
205 for (i
= 0; i
< nsrcerrs
; i
++) {
206 for (j
= 0; j
< k
; j
++) {
207 decode_matrix
[k
* i
+ j
] = invert_matrix
[k
* src_err_list
[i
] + j
];
210 /* src_err_list from encode_matrix * invert of b for parity decoding */
211 for (p
= nsrcerrs
; p
< nerrs
; p
++) {
212 for (i
= 0; i
< k
; i
++) {
214 for (j
= 0; j
< k
; j
++)
215 s
^= gf_mul(invert_matrix
[j
* k
+ i
],
216 encode_matrix
[k
* src_err_list
[p
] + j
]);
218 decode_matrix
[k
* p
+ i
] = s
;
226 int main(int argc
, char *argv
[])
229 int i
, j
, p
, rtest
, m
, k
;
232 unsigned int decode_index
[MMAX
];
233 unsigned char *temp_buffs
[TEST_SOURCES
], *buffs
[TEST_SOURCES
];
234 unsigned char *update_buffs
[TEST_SOURCES
];
235 unsigned char *encode_matrix
, *decode_matrix
, *invert_matrix
, *g_tbls
;
236 unsigned char src_in_err
[TEST_SOURCES
], src_err_list
[TEST_SOURCES
];
237 unsigned char *recov
[TEST_SOURCES
];
239 int rows
, align
, size
;
240 unsigned char *efence_buffs
[TEST_SOURCES
];
241 unsigned char *efence_update_buffs
[TEST_SOURCES
];
243 u8
*ubuffs
[TEST_SOURCES
];
244 u8
*update_ubuffs
[TEST_SOURCES
];
245 u8
*temp_ubuffs
[TEST_SOURCES
];
247 printf("test " xstr(FUNCTION_UNDER_TEST
) ": %dx%d ", TEST_SOURCES
, TEST_LEN
);
250 // Allocate the arrays
251 for (i
= 0; i
< TEST_SOURCES
; i
++) {
252 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
253 printf("alloc error: Fail");
259 for (i
= 0; i
< TEST_SOURCES
; i
++) {
260 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
261 printf("alloc error: Fail");
265 memset(temp_buffs
[i
], 0, TEST_LEN
); // initialize the destination buffer to be zero for update function
268 for (i
= 0; i
< TEST_SOURCES
; i
++) {
269 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
270 printf("alloc error: Fail");
273 update_buffs
[i
] = buf
;
274 memset(update_buffs
[i
], 0, TEST_LEN
); // initialize the destination buffer to be zero for update function
276 // Test erasure code by encode and recovery
278 encode_matrix
= malloc(MMAX
* KMAX
);
279 decode_matrix
= malloc(MMAX
* KMAX
);
280 invert_matrix
= malloc(MMAX
* KMAX
);
281 g_tbls
= malloc(KMAX
* TEST_SOURCES
* 32);
282 if (encode_matrix
== NULL
|| decode_matrix
== NULL
283 || invert_matrix
== NULL
|| g_tbls
== NULL
) {
284 printf("Test failure! Error with malloc\n");
290 if (m
> MMAX
|| k
> KMAX
)
294 for (i
= 0; i
< k
; i
++) {
295 for (j
= 0; j
< TEST_LEN
; j
++) {
296 buffs
[i
][j
] = rand();
297 update_buffs
[i
][j
] = buffs
[i
][j
];
301 // Generate encode matrix encode_matrix
302 // The matrix generated by gf_gen_rs_matrix
303 // is not always invertable.
304 gf_gen_rs_matrix(encode_matrix
, m
, k
);
306 // Generate g_tbls from encode matrix encode_matrix
307 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
309 // Perform matrix dot_prod for EC encoding
310 // using g_tbls from encode matrix encode_matrix
311 REF_FUNCTION(TEST_LEN
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
312 for (i
= 0; i
< k
; i
++) {
313 FUNCTION_UNDER_TEST(TEST_LEN
, k
, m
- k
, i
, g_tbls
, update_buffs
[i
],
316 for (i
= 0; i
< m
- k
; i
++) {
317 if (0 != memcmp(update_buffs
[k
+ i
], buffs
[k
+ i
], TEST_LEN
)) {
318 printf("\nupdate_buffs%d :", i
);
319 dump(update_buffs
[k
+ i
], 25);
320 printf("buffs%d :", i
);
321 dump(buffs
[k
+ i
], 25);
326 // Choose random buffers to be in erasure
327 memset(src_in_err
, 0, TEST_SOURCES
);
328 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
330 // Generate decode matrix
331 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
332 invert_matrix
, decode_index
, src_err_list
, src_in_err
,
333 nerrs
, nsrcerrs
, k
, m
);
335 printf("Fail to gf_gen_decode_matrix\n");
338 // Pack recovery array as list of valid sources
339 // Its order must be the same as the order
340 // to generate matrix b in gf_gen_decode_matrix
341 for (i
= 0; i
< k
; i
++) {
342 recov
[i
] = update_buffs
[decode_index
[i
]];
346 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
347 REF_FUNCTION(TEST_LEN
, k
, nerrs
, g_tbls
, recov
, &temp_buffs
[k
]);
348 for (i
= 0; i
< nerrs
; i
++) {
350 if (0 != memcmp(temp_buffs
[k
+ i
], update_buffs
[src_err_list
[i
]], TEST_LEN
)) {
351 printf("Fail error recovery (%d, %d, %d)\n", m
, k
, nerrs
);
352 printf(" - erase list = ");
353 for (j
= 0; j
< nerrs
; j
++)
354 printf(" %d", src_err_list
[j
]);
355 printf(" - Index = ");
356 for (p
= 0; p
< k
; p
++)
357 printf(" %d", decode_index
[p
]);
358 printf("\nencode_matrix:\n");
359 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
361 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
362 printf("\ndecode_matrix:\n");
363 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
364 printf("recov %d:", src_err_list
[i
]);
365 dump(temp_buffs
[k
+ i
], 25);
367 dump(update_buffs
[src_err_list
[i
]], 25);
376 if (m
> MMAX
|| k
> KMAX
)
379 // Zero the destination buffer for update function
380 for (i
= k
; i
< TEST_SOURCES
; i
++) {
381 memset(buffs
[i
], 0, TEST_LEN
);
382 memset(update_buffs
[i
], 0, TEST_LEN
);
385 for (i
= 0; i
< k
; i
++) {
386 for (j
= 0; j
< TEST_LEN
; j
++) {
387 buffs
[i
][j
] = rand();
388 update_buffs
[i
][j
] = buffs
[i
][j
];
392 // The matrix generated by gf_gen_cauchy1_matrix
393 // is always invertable.
394 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
396 // Generate g_tbls from encode matrix encode_matrix
397 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
399 // Perform matrix dot_prod for EC encoding
400 // using g_tbls from encode matrix encode_matrix
401 REF_FUNCTION(TEST_LEN
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
402 for (i
= 0; i
< k
; i
++) {
403 FUNCTION_UNDER_TEST(TEST_LEN
, k
, m
- k
, i
, g_tbls
, update_buffs
[i
],
406 for (i
= 0; i
< m
- k
; i
++) {
407 if (0 != memcmp(update_buffs
[k
+ i
], buffs
[k
+ i
], TEST_LEN
)) {
408 printf("\nupdate_buffs%d :", i
);
409 dump(update_buffs
[k
+ i
], 25);
410 printf("buffs%d :", i
);
411 dump(buffs
[k
+ i
], 25);
416 // Choose random buffers to be in erasure
417 memset(src_in_err
, 0, TEST_SOURCES
);
418 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
420 // Generate decode matrix
421 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
422 invert_matrix
, decode_index
, src_err_list
, src_in_err
,
423 nerrs
, nsrcerrs
, k
, m
);
425 printf("Fail to gf_gen_decode_matrix\n");
428 // Pack recovery array as list of valid sources
429 // Its order must be the same as the order
430 // to generate matrix b in gf_gen_decode_matrix
431 for (i
= 0; i
< k
; i
++) {
432 recov
[i
] = update_buffs
[decode_index
[i
]];
436 for (i
= 0; i
< TEST_SOURCES
; i
++) {
437 memset(temp_buffs
[i
], 0, TEST_LEN
);
439 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
440 for (i
= 0; i
< k
; i
++) {
441 FUNCTION_UNDER_TEST(TEST_LEN
, k
, nerrs
, i
, g_tbls
, recov
[i
], &temp_buffs
[k
]);
443 for (i
= 0; i
< nerrs
; i
++) {
445 if (0 != memcmp(temp_buffs
[k
+ i
], update_buffs
[src_err_list
[i
]], TEST_LEN
)) {
446 printf("Fail error recovery (%d, %d, %d)\n", m
, k
, nerrs
);
447 printf(" - erase list = ");
448 for (j
= 0; j
< nerrs
; j
++)
449 printf(" %d", src_err_list
[j
]);
450 printf(" - Index = ");
451 for (p
= 0; p
< k
; p
++)
452 printf(" %d", decode_index
[p
]);
453 printf("\nencode_matrix:\n");
454 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
456 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
457 printf("\ndecode_matrix:\n");
458 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
459 printf("recov %d:", src_err_list
[i
]);
460 dump(temp_buffs
[k
+ i
], 25);
462 dump(update_buffs
[src_err_list
[i
]], 25);
468 // Do more random tests
469 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
470 while ((m
= (rand() % MMAX
)) < 2) ;
471 while ((k
= (rand() % KMAX
)) >= m
|| k
< 1) ;
473 if (m
> MMAX
|| k
> KMAX
)
476 // Zero the destination buffer for update function
477 for (i
= k
; i
< TEST_SOURCES
; i
++) {
478 memset(buffs
[i
], 0, TEST_LEN
);
479 memset(update_buffs
[i
], 0, TEST_LEN
);
482 for (i
= 0; i
< k
; i
++) {
483 for (j
= 0; j
< TEST_LEN
; j
++) {
484 buffs
[i
][j
] = rand();
485 update_buffs
[i
][j
] = buffs
[i
][j
];
489 // The matrix generated by gf_gen_cauchy1_matrix
490 // is always invertable.
491 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
494 // Generate g_tbls from encode matrix a
495 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
496 // Perform matrix dot_prod for EC encoding
497 // using g_tbls from encode matrix a
498 REF_FUNCTION(TEST_LEN
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
499 for (i
= 0; i
< k
; i
++) {
500 FUNCTION_UNDER_TEST(TEST_LEN
, k
, m
- k
, i
, g_tbls
, update_buffs
[i
],
503 for (i
= 0; i
< m
- k
; i
++) {
504 if (0 != memcmp(update_buffs
[k
+ i
], buffs
[k
+ i
], TEST_LEN
)) {
505 printf("\nupdate_buffs%d :", i
);
506 dump(update_buffs
[k
+ i
], 25);
507 printf("buffs%d :", i
);
508 dump(buffs
[k
+ i
], 25);
514 memset(src_in_err
, 0, TEST_SOURCES
);
515 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
517 // Generate decode matrix
518 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
519 invert_matrix
, decode_index
, src_err_list
,
520 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
522 printf("Fail to gf_gen_decode_matrix\n");
525 // Pack recovery array as list of valid sources
526 // Its order must be the same as the order
527 // to generate matrix b in gf_gen_decode_matrix
528 for (i
= 0; i
< k
; i
++) {
529 recov
[i
] = update_buffs
[decode_index
[i
]];
533 for (i
= 0; i
< TEST_SOURCES
; i
++) {
534 memset(temp_buffs
[i
], 0, TEST_LEN
);
536 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
537 for (i
= 0; i
< k
; i
++) {
538 FUNCTION_UNDER_TEST(TEST_LEN
, k
, nerrs
, i
, g_tbls
, recov
[i
],
542 for (i
= 0; i
< nerrs
; i
++) {
545 memcmp(temp_buffs
[k
+ i
], update_buffs
[src_err_list
[i
]],
547 printf("Fail error recovery (%d, %d, %d) - ", m
, k
, nerrs
);
548 printf(" - erase list = ");
549 for (j
= 0; j
< nerrs
; j
++)
550 printf(" %d", src_err_list
[j
]);
551 printf(" - Index = ");
552 for (p
= 0; p
< k
; p
++)
553 printf(" %d", decode_index
[p
]);
554 printf("\nencode_matrix:\n");
555 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
557 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
558 printf("\ndecode_matrix:\n");
559 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
560 printf("orig data:\n");
561 dump_matrix(update_buffs
, m
, 25);
563 dump(update_buffs
[src_err_list
[i
]], 25);
564 printf("recov %d:", src_err_list
[i
]);
565 dump(temp_buffs
[k
+ i
], 25);
572 // Run tests at end of buffer for Electric Fence
574 align
= (LEN_ALIGN_CHK_B
!= 0) ? 1 : ALIGN_SIZE
;
578 for (rows
= 1; rows
<= 16; rows
++) {
583 for (i
= k
; i
< TEST_SOURCES
; i
++) {
584 memset(buffs
[i
], 0, TEST_LEN
);
585 memset(update_buffs
[i
], 0, TEST_LEN
);
588 for (i
= 0; i
< k
; i
++) {
589 for (j
= 0; j
< TEST_LEN
; j
++) {
590 buffs
[i
][j
] = rand();
591 update_buffs
[i
][j
] = buffs
[i
][j
];
595 for (size
= 0; size
<= TEST_SIZE
; size
+= align
) {
596 for (i
= 0; i
< m
; i
++) { // Line up TEST_SIZE from end
597 efence_buffs
[i
] = buffs
[i
] + TEST_LEN
- size
;
598 efence_update_buffs
[i
] = update_buffs
[i
] + TEST_LEN
- size
;
600 // Zero the destination buffer for update function
601 for (i
= k
; i
< m
; i
++) {
602 memset(efence_buffs
[i
], 0, size
);
603 memset(efence_update_buffs
[i
], 0, size
);
606 // The matrix generated by gf_gen_cauchy1_matrix
607 // is always invertable.
608 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
611 // Generate g_tbls from encode matrix a
612 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
613 // Perform matrix dot_prod for EC encoding
614 // using g_tbls from encode matrix a
615 REF_FUNCTION(size
, k
, m
- k
, g_tbls
, efence_buffs
, &efence_buffs
[k
]);
616 for (i
= 0; i
< k
; i
++) {
617 FUNCTION_UNDER_TEST(size
, k
, m
- k
, i
, g_tbls
,
618 efence_update_buffs
[i
],
619 &efence_update_buffs
[k
]);
621 for (i
= 0; i
< m
- k
; i
++) {
623 memcmp(efence_update_buffs
[k
+ i
], efence_buffs
[k
+ i
],
625 printf("\nefence_update_buffs%d :", i
);
626 dump(efence_update_buffs
[k
+ i
], 25);
627 printf("efence_buffs%d :", i
);
628 dump(efence_buffs
[k
+ i
], 25);
634 memset(src_in_err
, 0, TEST_SOURCES
);
635 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
637 // Generate decode matrix
638 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
639 invert_matrix
, decode_index
, src_err_list
,
640 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
642 printf("Fail to gf_gen_decode_matrix\n");
645 // Pack recovery array as list of valid sources
646 // Its order must be the same as the order
647 // to generate matrix b in gf_gen_decode_matrix
648 for (i
= 0; i
< k
; i
++) {
649 recov
[i
] = efence_update_buffs
[decode_index
[i
]];
653 for (i
= 0; i
< TEST_SOURCES
; i
++) {
654 memset(temp_buffs
[i
], 0, TEST_LEN
);
656 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
657 for (i
= 0; i
< k
; i
++) {
658 FUNCTION_UNDER_TEST(size
, k
, nerrs
, i
, g_tbls
, recov
[i
],
662 for (i
= 0; i
< nerrs
; i
++) {
665 memcmp(temp_buffs
[k
+ i
],
666 efence_update_buffs
[src_err_list
[i
]], size
)) {
667 printf("Efence: Fail error recovery (%d, %d, %d)\n", m
,
670 printf("size = %d\n", size
);
672 printf("Test erase list = ");
673 for (j
= 0; j
< nerrs
; j
++)
674 printf(" %d", src_err_list
[j
]);
675 printf(" - Index = ");
676 for (p
= 0; p
< k
; p
++)
677 printf(" %d", decode_index
[p
]);
678 printf("\nencode_matrix:\n");
679 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
681 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
682 printf("\ndecode_matrix:\n");
683 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
685 printf("recov %d:", src_err_list
[i
]);
686 dump(temp_buffs
[k
+ i
], align
);
688 dump(efence_update_buffs
[src_err_list
[i
]], align
);
697 // Test rand ptr alignment if available
699 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
700 while ((m
= (rand() % MMAX
)) < 2) ;
701 while ((k
= (rand() % KMAX
)) >= m
|| k
< 1) ;
703 if (m
> MMAX
|| k
> KMAX
)
706 size
= (TEST_LEN
- PTR_ALIGN_CHK_B
) & ~15;
708 offset
= (PTR_ALIGN_CHK_B
!= 0) ? 1 : PTR_ALIGN_CHK_B
;
709 // Add random offsets
710 for (i
= 0; i
< m
; i
++) {
711 memset(buffs
[i
], 0, TEST_LEN
); // zero pad to check write-over
712 memset(update_buffs
[i
], 0, TEST_LEN
); // zero pad to check write-over
713 memset(temp_buffs
[i
], 0, TEST_LEN
); // zero pad to check write-over
714 ubuffs
[i
] = buffs
[i
] + (rand() & (PTR_ALIGN_CHK_B
- offset
));
716 update_buffs
[i
] + (rand() & (PTR_ALIGN_CHK_B
- offset
));
717 temp_ubuffs
[i
] = temp_buffs
[i
] + (rand() & (PTR_ALIGN_CHK_B
- offset
));
720 // Zero the destination buffer for update function
721 for (i
= k
; i
< m
; i
++) {
722 memset(ubuffs
[i
], 0, size
);
723 memset(update_ubuffs
[i
], 0, size
);
726 for (i
= 0; i
< k
; i
++) {
727 for (j
= 0; j
< size
; j
++) {
728 ubuffs
[i
][j
] = rand();
729 update_ubuffs
[i
][j
] = ubuffs
[i
][j
];
733 // The matrix generated by gf_gen_cauchy1_matrix
734 // is always invertable.
735 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
738 // Generate g_tbls from encode matrix a
739 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
740 // Perform matrix dot_prod for EC encoding
741 // using g_tbls from encode matrix a
742 REF_FUNCTION(size
, k
, m
- k
, g_tbls
, ubuffs
, &ubuffs
[k
]);
743 for (i
= 0; i
< k
; i
++) {
744 FUNCTION_UNDER_TEST(size
, k
, m
- k
, i
, g_tbls
, update_ubuffs
[i
],
747 for (i
= 0; i
< m
- k
; i
++) {
748 if (0 != memcmp(update_ubuffs
[k
+ i
], ubuffs
[k
+ i
], size
)) {
749 printf("\nupdate_ubuffs%d :", i
);
750 dump(update_ubuffs
[k
+ i
], 25);
751 printf("ubuffs%d :", i
);
752 dump(ubuffs
[k
+ i
], 25);
758 memset(src_in_err
, 0, TEST_SOURCES
);
759 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
761 // Generate decode matrix
762 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
763 invert_matrix
, decode_index
, src_err_list
,
764 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
766 printf("Fail to gf_gen_decode_matrix\n");
769 // Pack recovery array as list of valid sources
770 // Its order must be the same as the order
771 // to generate matrix b in gf_gen_decode_matrix
772 for (i
= 0; i
< k
; i
++) {
773 recov
[i
] = update_ubuffs
[decode_index
[i
]];
777 for (i
= 0; i
< m
; i
++) {
778 memset(temp_ubuffs
[i
], 0, size
);
780 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
781 for (i
= 0; i
< k
; i
++) {
782 FUNCTION_UNDER_TEST(size
, k
, nerrs
, i
, g_tbls
, recov
[i
],
786 for (i
= 0; i
< nerrs
; i
++) {
789 memcmp(temp_ubuffs
[k
+ i
], update_ubuffs
[src_err_list
[i
]], size
)) {
790 printf("Fail error recovery (%d, %d, %d) - ", m
, k
, nerrs
);
791 printf(" - erase list = ");
792 for (j
= 0; j
< nerrs
; j
++)
793 printf(" %d", src_err_list
[j
]);
794 printf(" - Index = ");
795 for (p
= 0; p
< k
; p
++)
796 printf(" %d", decode_index
[p
]);
797 printf("\nencode_matrix:\n");
798 dump_u8xu8((unsigned char *)encode_matrix
, m
, k
);
800 dump_u8xu8((unsigned char *)invert_matrix
, k
, k
);
801 printf("\ndecode_matrix:\n");
802 dump_u8xu8((unsigned char *)decode_matrix
, m
, k
);
803 printf("orig data:\n");
804 dump_matrix(update_ubuffs
, m
, 25);
806 dump(update_ubuffs
[src_err_list
[i
]], 25);
807 printf("recov %d:", src_err_list
[i
]);
808 dump(temp_ubuffs
[k
+ i
], 25);
813 // Confirm that padding around dests is unchanged
814 memset(temp_buffs
[0], 0, PTR_ALIGN_CHK_B
); // Make reference zero buff
816 for (i
= 0; i
< m
; i
++) {
818 offset
= update_ubuffs
[i
] - update_buffs
[i
];
820 if (memcmp(update_buffs
[i
], temp_buffs
[0], offset
)) {
821 printf("Fail rand ualign encode pad start\n");
825 (update_buffs
[i
] + offset
+ size
, temp_buffs
[0],
826 PTR_ALIGN_CHK_B
- offset
)) {
827 printf("Fail rand ualign encode pad end\n");
832 for (i
= 0; i
< nerrs
; i
++) {
834 offset
= temp_ubuffs
[k
+ i
] - temp_buffs
[k
+ i
];
835 if (memcmp(temp_buffs
[k
+ i
], temp_buffs
[0], offset
)) {
836 printf("Fail rand ualign decode pad start\n");
840 (temp_buffs
[k
+ i
] + offset
+ size
, temp_buffs
[0],
841 PTR_ALIGN_CHK_B
- offset
)) {
842 printf("Fail rand ualign decode pad end\n");
850 // Test size alignment
852 align
= (LEN_ALIGN_CHK_B
!= 0) ? 13 : ALIGN_SIZE
;
854 for (size
= TEST_LEN
; size
>= 0; size
-= align
) {
855 while ((m
= (rand() % MMAX
)) < 2) ;
856 while ((k
= (rand() % KMAX
)) >= m
|| k
< 1) ;
858 if (m
> MMAX
|| k
> KMAX
)
861 // Zero the destination buffer for update function
862 for (i
= k
; i
< TEST_SOURCES
; i
++) {
863 memset(buffs
[i
], 0, size
);
864 memset(update_buffs
[i
], 0, size
);
867 for (i
= 0; i
< k
; i
++) {
868 for (j
= 0; j
< size
; j
++) {
869 buffs
[i
][j
] = rand();
870 update_buffs
[i
][j
] = buffs
[i
][j
];
874 // The matrix generated by gf_gen_cauchy1_matrix
875 // is always invertable.
876 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
879 // Generate g_tbls from encode matrix a
880 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
881 // Perform matrix dot_prod for EC encoding
882 // using g_tbls from encode matrix a
883 REF_FUNCTION(size
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
884 for (i
= 0; i
< k
; i
++) {
885 FUNCTION_UNDER_TEST(size
, k
, m
- k
, i
, g_tbls
, update_buffs
[i
],
888 for (i
= 0; i
< m
- k
; i
++) {
889 if (0 != memcmp(update_buffs
[k
+ i
], buffs
[k
+ i
], size
)) {
890 printf("\nupdate_buffs%d (size=%d) :", i
, size
);
891 dump(update_buffs
[k
+ i
], 25);
892 printf("buffs%d (size=%d) :", i
, size
);
893 dump(buffs
[k
+ i
], 25);
899 memset(src_in_err
, 0, TEST_SOURCES
);
900 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
901 // Generate decode matrix
902 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
903 invert_matrix
, decode_index
, src_err_list
,
904 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
906 printf("Fail to gf_gen_decode_matrix\n");
909 // Pack recovery array as list of valid sources
910 // Its order must be the same as the order
911 // to generate matrix b in gf_gen_decode_matrix
912 for (i
= 0; i
< k
; i
++) {
913 recov
[i
] = update_buffs
[decode_index
[i
]];
917 for (i
= 0; i
< TEST_SOURCES
; i
++) {
918 memset(temp_buffs
[i
], 0, TEST_LEN
);
920 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
921 for (i
= 0; i
< k
; i
++) {
922 FUNCTION_UNDER_TEST(size
, k
, nerrs
, i
, g_tbls
, recov
[i
],
926 for (i
= 0; i
< nerrs
; i
++) {
929 memcmp(temp_buffs
[k
+ i
], update_buffs
[src_err_list
[i
]], size
)) {
930 printf("Fail error recovery (%d, %d, %d) - ", m
, k
, nerrs
);
931 printf(" - erase list = ");
932 for (j
= 0; j
< nerrs
; j
++)
933 printf(" %d", src_err_list
[j
]);
934 printf(" - Index = ");
935 for (p
= 0; p
< k
; p
++)
936 printf(" %d", decode_index
[p
]);
937 printf("\nencode_matrix:\n");
938 dump_u8xu8((unsigned char *)encode_matrix
, m
, k
);
940 dump_u8xu8((unsigned char *)invert_matrix
, k
, k
);
941 printf("\ndecode_matrix:\n");
942 dump_u8xu8((unsigned char *)decode_matrix
, m
, k
);
943 printf("orig data:\n");
944 dump_matrix(update_buffs
, m
, 25);
946 dump(update_buffs
[src_err_list
[i
]], 25);
947 printf("recov %d:", src_err_list
[i
]);
948 dump(temp_buffs
[k
+ i
], 25);
955 printf("done EC tests: Pass\n");