LCOV - code coverage report
Current view: top level - raid - test.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 153 153 100.0 %
Date: 2017-11-06 22:14:04 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2013 Andrea Mazzoleni
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  */
      14             : 
      15             : #include "internal.h"
      16             : #include "cpu.h"
      17             : #include "combo.h"
      18             : #include "memory.h"
      19             : 
      20             : /**
      21             :  * Binomial coefficient of n over r.
      22             :  */
      23         120 : static int ibc(int n, int r)
      24             : {
      25         120 :         if (r == 0 || n == r)
      26          63 :                 return 1;
      27             :         else
      28          57 :                 return ibc(n - 1, r - 1) + ibc(n - 1, r);
      29             : }
      30             : 
      31             : /**
      32             :  * Power n ^ r;
      33             :  */
      34           6 : static int ipow(int n, int r)
      35             : {
      36           6 :         int v = 1;
      37             : 
      38          33 :         while (r) {
      39          21 :                 v *= n;
      40          21 :                 --r;
      41             :         }
      42           6 :         return v;
      43             : }
      44             : 
      45           1 : int raid_test_combo(void)
      46             : {
      47             :         int r;
      48             :         int count;
      49             :         int p[RAID_PARITY_MAX];
      50             : 
      51           7 :         for (r = 1; r <= RAID_PARITY_MAX; ++r) {
      52             :                 /* count combination (r of RAID_PARITY_MAX) elements */
      53           6 :                 count = 0;
      54             :                 combination_first(r, RAID_PARITY_MAX, p);
      55             : 
      56             :                 do {
      57          63 :                         ++count;
      58          63 :                 } while (combination_next(r, RAID_PARITY_MAX, p));
      59             : 
      60           6 :                 if (count != ibc(RAID_PARITY_MAX, r)) {
      61             :                         /* LCOV_EXCL_START */
      62             :                         return -1;
      63             :                         /* LCOV_EXCL_STOP */
      64             :                 }
      65             :         }
      66             : 
      67           7 :         for (r = 1; r <= RAID_PARITY_MAX; ++r) {
      68             :                 /* count permutation (r of RAID_PARITY_MAX) elements */
      69           6 :                 count = 0;
      70             :                 permutation_first(r, RAID_PARITY_MAX, p);
      71             : 
      72             :                 do {
      73       55986 :                         ++count;
      74       55986 :                 } while (permutation_next(r, RAID_PARITY_MAX, p));
      75             : 
      76           6 :                 if (count != ipow(RAID_PARITY_MAX, r)) {
      77             :                         /* LCOV_EXCL_START */
      78             :                         return -1;
      79             :                         /* LCOV_EXCL_STOP */
      80             :                 }
      81             :         }
      82             : 
      83           1 :         return 0;
      84             : }
      85             : 
      86           1 : int raid_test_insert(void)
      87             : {
      88             :         int p[RAID_PARITY_MAX];
      89             :         int r;
      90             : 
      91           7 :         for (r = 1; r <= RAID_PARITY_MAX; ++r) {
      92             :                 permutation_first(r, RAID_PARITY_MAX, p);
      93             :                 do {
      94             :                         int i[RAID_PARITY_MAX];
      95             :                         int j;
      96             : 
      97             :                         /* insert in order */
      98      380712 :                         for (j = 0; j < r; ++j)
      99      324726 :                                 raid_insert(j, i, p[j]);
     100             : 
     101             :                         /* check order */
     102      324726 :                         for (j = 1; j < r; ++j) {
     103      268740 :                                 if (i[j - 1] > i[j]) {
     104             :                                         /* LCOV_EXCL_START */
     105             :                                         return -1;
     106             :                                         /* LCOV_EXCL_STOP */
     107             :                                 }
     108             :                         }
     109       55986 :                 } while (permutation_next(r, RAID_PARITY_MAX, p));
     110             :         }
     111             : 
     112           1 :         return 0;
     113             : }
     114             : 
     115           1 : int raid_test_sort(void)
     116             : {
     117             :         int p[RAID_PARITY_MAX];
     118             :         int r;
     119             : 
     120           7 :         for (r = 1; r <= RAID_PARITY_MAX; ++r) {
     121             :                 permutation_first(r, RAID_PARITY_MAX, p);
     122             :                 do {
     123             :                         int i[RAID_PARITY_MAX];
     124             :                         int j;
     125             : 
     126             :                         /* make a copy */
     127      380712 :                         for (j = 0; j < r; ++j)
     128      324726 :                                 i[j] = p[j];
     129             : 
     130       55986 :                         raid_sort(r, i);
     131             : 
     132             :                         /* check order */
     133      324726 :                         for (j = 1; j < r; ++j) {
     134      268740 :                                 if (i[j - 1] > i[j]) {
     135             :                                         /* LCOV_EXCL_START */
     136             :                                         return -1;
     137             :                                         /* LCOV_EXCL_STOP */
     138             :                                 }
     139             :                         }
     140       55986 :                 } while (permutation_next(r, RAID_PARITY_MAX, p));
     141             :         }
     142             : 
     143           1 :         return 0;
     144             : }
     145             : 
     146           2 : int raid_test_rec(int mode, int nd, size_t size)
     147             : {
     148             :         void (*f[RAID_PARITY_MAX][4])(
     149             :                 int nr, int *id, int *ip, int nd, size_t size, void **vbuf);
     150             :         void *v_alloc;
     151             :         void **v;
     152             :         void **data;
     153             :         void **parity;
     154             :         void **test;
     155             :         void *data_save[RAID_PARITY_MAX];
     156             :         void *parity_save[RAID_PARITY_MAX];
     157             :         void *waste;
     158             :         int nv;
     159             :         int id[RAID_PARITY_MAX];
     160             :         int ip[RAID_PARITY_MAX];
     161             :         int i;
     162             :         int j;
     163             :         int nr;
     164             :         int nf[RAID_PARITY_MAX];
     165             :         int np;
     166             : 
     167           2 :         raid_mode(mode);
     168           2 :         if (mode == RAID_MODE_CAUCHY)
     169           1 :                 np = RAID_PARITY_MAX;
     170             :         else
     171           1 :                 np = 3;
     172             : 
     173           2 :         nv = nd + np * 2 + 2;
     174             : 
     175           2 :         v = raid_malloc_vector(nd, nv, size, &v_alloc);
     176           2 :         if (!v) {
     177             :                 /* LCOV_EXCL_START */
     178             :                 return -1;
     179             :                 /* LCOV_EXCL_STOP */
     180             :         }
     181             : 
     182           2 :         data = v;
     183           2 :         parity = v + nd;
     184           2 :         test = v + nd + np;
     185             : 
     186          11 :         for (i = 0; i < np; ++i)
     187           9 :                 parity_save[i] = parity[i];
     188             : 
     189           2 :         memset(v[nv - 2], 0, size);
     190           2 :         raid_zero(v[nv - 2]);
     191             : 
     192           2 :         waste = v[nv - 1];
     193             : 
     194             :         /* fill with pseudo-random data with the arbitrary seed "1" */
     195           2 :         raid_mrand_vector(1, nd, size, v);
     196             : 
     197             :         /* setup recov functions */
     198          11 :         for (i = 0; i < np; ++i) {
     199           9 :                 nf[i] = 0;
     200           9 :                 if (i == 0) {
     201           2 :                         f[i][nf[i]++] = raid_rec1_int8;
     202             : #ifdef CONFIG_X86
     203             : #ifdef CONFIG_SSSE3
     204           2 :                         if (raid_cpu_has_ssse3())
     205           2 :                                 f[i][nf[i]++] = raid_rec1_ssse3;
     206             : #endif
     207             : #ifdef CONFIG_AVX2
     208           2 :                         if (raid_cpu_has_avx2())
     209           2 :                                 f[i][nf[i]++] = raid_rec1_avx2;
     210             : #endif
     211             : #endif
     212           7 :                 } else if (i == 1) {
     213           2 :                         f[i][nf[i]++] = raid_rec2_int8;
     214             : #ifdef CONFIG_X86
     215             : #ifdef CONFIG_SSSE3
     216           2 :                         if (raid_cpu_has_ssse3())
     217           2 :                                 f[i][nf[i]++] = raid_rec2_ssse3;
     218             : #endif
     219             : #ifdef CONFIG_AVX2
     220           2 :                         if (raid_cpu_has_avx2())
     221           2 :                                 f[i][nf[i]++] = raid_rec2_avx2;
     222             : #endif
     223             : #endif
     224             :                 } else {
     225           5 :                         f[i][nf[i]++] = raid_recX_int8;
     226             : #ifdef CONFIG_X86
     227             : #ifdef CONFIG_SSSE3
     228           5 :                         if (raid_cpu_has_ssse3())
     229           5 :                                 f[i][nf[i]++] = raid_recX_ssse3;
     230             : #endif
     231             : #ifdef CONFIG_AVX2
     232           5 :                         if (raid_cpu_has_avx2())
     233           5 :                                 f[i][nf[i]++] = raid_recX_avx2;
     234             : #endif
     235             : #endif
     236             :                 }
     237             :         }
     238             : 
     239             :         /* compute the parity */
     240           2 :         raid_gen_ref(nd, np, size, v);
     241             : 
     242             :         /* set all the parity to the waste v */
     243          11 :         for (i = 0; i < np; ++i)
     244           9 :                 parity[i] = waste;
     245             : 
     246             :         /* all parity levels */
     247          11 :         for (nr = 1; nr <= np; ++nr) {
     248             :                 /* all combinations (nr of nd) disks */
     249             :                 combination_first(nr, nd, id);
     250             :                 do {
     251             :                         /* all combinations (nr of np) parities */
     252             :                         combination_first(nr, np, ip);
     253             :                         do {
     254             :                                 /* for each recover function */
     255       76068 :                                 for (j = 0; j < nf[nr - 1]; ++j) {
     256             :                                         /* set */
     257      283095 :                                         for (i = 0; i < nr; ++i) {
     258             :                                                 /* remove the missing data */
     259      226044 :                                                 data_save[i] = data[id[i]];
     260      226044 :                                                 data[id[i]] = test[i];
     261             :                                                 /* set the parity to use */
     262      226044 :                                                 parity[ip[i]] = parity_save[ip[i]];
     263             :                                         }
     264             : 
     265             :                                         /* recover */
     266       57051 :                                         f[nr - 1][j](nr, id, ip, nd, size, v);
     267             : 
     268             :                                         /* check */
     269      283095 :                                         for (i = 0; i < nr; ++i) {
     270      226044 :                                                 if (memcmp(test[i], data_save[i], size) != 0) {
     271             :                                                         /* LCOV_EXCL_START */
     272             :                                                         goto bail;
     273             :                                                         /* LCOV_EXCL_STOP */
     274             :                                                 }
     275             :                                         }
     276             : 
     277             :                                         /* restore */
     278      283095 :                                         for (i = 0; i < nr; ++i) {
     279             :                                                 /* restore the data */
     280      226044 :                                                 data[id[i]] = data_save[i];
     281             :                                                 /* restore the parity */
     282      226044 :                                                 parity[ip[i]] = waste;
     283             :                                         }
     284             :                                 }
     285       19017 :                         } while (combination_next(nr, np, ip));
     286        2807 :                 } while (combination_next(nr, nd, id));
     287             :         }
     288             : 
     289           2 :         free(v_alloc);
     290           2 :         free(v);
     291           2 :         return 0;
     292             : 
     293             : bail:
     294             :         /* LCOV_EXCL_START */
     295             :         free(v_alloc);
     296             :         free(v);
     297             :         return -1;
     298             :         /* LCOV_EXCL_STOP */
     299             : }
     300             : 
     301           3 : int raid_test_par(int mode, int nd, size_t size)
     302             : {
     303             :         void (*f[64])(int nd, size_t size, void **vbuf);
     304             :         void *v_alloc;
     305             :         void **v;
     306             :         int nv;
     307             :         int i, j;
     308             :         int nf;
     309             :         int np;
     310             : 
     311           3 :         raid_mode(mode);
     312           3 :         if (mode == RAID_MODE_CAUCHY)
     313           2 :                 np = RAID_PARITY_MAX;
     314             :         else
     315           1 :                 np = 3;
     316             : 
     317           3 :         nv = nd + np * 2;
     318             : 
     319           3 :         v = raid_malloc_vector(nd, nv, size, &v_alloc);
     320           3 :         if (!v) {
     321             :                 /* LCOV_EXCL_START */
     322             :                 return -1;
     323             :                 /* LCOV_EXCL_STOP */
     324             :         }
     325             : 
     326             :         /* check memory */
     327           3 :         if (raid_mtest_vector(nv, size, v) != 0) {
     328             :                 /* LCOV_EXCL_START */
     329             :                 goto bail;
     330             :                 /* LCOV_EXCL_STOP */
     331             :         }
     332             : 
     333             :         /* fill with pseudo-random data with the arbitrary seed "2" */
     334           3 :         raid_mrand_vector(2, nv, size, v);
     335             : 
     336             :         /* compute the parity */
     337           3 :         raid_gen_ref(nd, np, size, v);
     338             : 
     339             :         /* copy in back buffers */
     340          18 :         for (i = 0; i < np; ++i)
     341          15 :                 memcpy(v[nd + np + i], v[nd + i], size);
     342             : 
     343             :         /* load all the available functions */
     344           3 :         nf = 0;
     345             : 
     346           3 :         f[nf++] = raid_gen1_int32;
     347           3 :         f[nf++] = raid_gen1_int64;
     348           3 :         f[nf++] = raid_gen2_int32;
     349           3 :         f[nf++] = raid_gen2_int64;
     350             : 
     351             : #ifdef CONFIG_X86
     352             : #ifdef CONFIG_SSE2
     353           3 :         if (raid_cpu_has_sse2()) {
     354           3 :                 f[nf++] = raid_gen1_sse2;
     355           3 :                 f[nf++] = raid_gen2_sse2;
     356             : #ifdef CONFIG_X86_64
     357           3 :                 f[nf++] = raid_gen2_sse2ext;
     358             : #endif
     359             :         }
     360             : #endif
     361             : 
     362             : #ifdef CONFIG_AVX2
     363           3 :         if (raid_cpu_has_avx2()) {
     364           3 :                 f[nf++] = raid_gen1_avx2;
     365           3 :                 f[nf++] = raid_gen2_avx2;
     366             :         }
     367             : #endif
     368             : #endif /* CONFIG_X86 */
     369             : 
     370           3 :         if (mode == RAID_MODE_CAUCHY) {
     371           2 :                 f[nf++] = raid_gen3_int8;
     372           2 :                 f[nf++] = raid_gen4_int8;
     373           2 :                 f[nf++] = raid_gen5_int8;
     374           2 :                 f[nf++] = raid_gen6_int8;
     375             : 
     376             : #ifdef CONFIG_X86
     377             : #ifdef CONFIG_SSSE3
     378           2 :                 if (raid_cpu_has_ssse3()) {
     379           2 :                         f[nf++] = raid_gen3_ssse3;
     380           2 :                         f[nf++] = raid_gen4_ssse3;
     381           2 :                         f[nf++] = raid_gen5_ssse3;
     382           2 :                         f[nf++] = raid_gen6_ssse3;
     383             : #ifdef CONFIG_X86_64
     384           2 :                         f[nf++] = raid_gen3_ssse3ext;
     385           2 :                         f[nf++] = raid_gen4_ssse3ext;
     386           2 :                         f[nf++] = raid_gen5_ssse3ext;
     387           2 :                         f[nf++] = raid_gen6_ssse3ext;
     388             : #endif
     389             :                 }
     390             : #endif
     391             : 
     392             : #ifdef CONFIG_AVX2
     393             : #ifdef CONFIG_X86_64
     394           2 :                 if (raid_cpu_has_avx2()) {
     395           2 :                         f[nf++] = raid_gen3_avx2ext;
     396           2 :                         f[nf++] = raid_gen4_avx2ext;
     397           2 :                         f[nf++] = raid_gen5_avx2ext;
     398           2 :                         f[nf++] = raid_gen6_avx2ext;
     399             :                 }
     400             : #endif
     401             : #endif
     402             : #endif /* CONFIG_X86 */
     403             :         } else {
     404           1 :                 f[nf++] = raid_genz_int32;
     405           1 :                 f[nf++] = raid_genz_int64;
     406             : 
     407             : #ifdef CONFIG_X86
     408             : #ifdef CONFIG_SSE2
     409           1 :                 if (raid_cpu_has_sse2()) {
     410           1 :                         f[nf++] = raid_genz_sse2;
     411             : #ifdef CONFIG_X86_64
     412           1 :                         f[nf++] = raid_genz_sse2ext;
     413             : #endif
     414             :                 }
     415             : #endif
     416             : 
     417             : #ifdef CONFIG_AVX2
     418             : #ifdef CONFIG_X86_64
     419           1 :                 if (raid_cpu_has_avx2())
     420           1 :                         f[nf++] = raid_genz_avx2ext;
     421             : #endif
     422             : #endif
     423             : #endif /* CONFIG_X86 */
     424             :         }
     425             : 
     426             :         /* check all the functions */
     427          67 :         for (j = 0; j < nf; ++j) {
     428             :                 /* compute parity */
     429          64 :                 f[j](nd, size, v);
     430             : 
     431             :                 /* check it */
     432         406 :                 for (i = 0; i < np; ++i) {
     433         342 :                         if (memcmp(v[nd + np + i], v[nd + i], size) != 0) {
     434             :                                 /* LCOV_EXCL_START */
     435             :                                 goto bail;
     436             :                                 /* LCOV_EXCL_STOP */
     437             :                         }
     438             :                 }
     439             :         }
     440             : 
     441           3 :         free(v_alloc);
     442           3 :         free(v);
     443           3 :         return 0;
     444             : 
     445             : bail:
     446             :         /* LCOV_EXCL_START */
     447             :         free(v_alloc);
     448             :         free(v);
     449             :         return -1;
     450             :         /* LCOV_EXCL_STOP */
     451             : }
     452             : 

Generated by: LCOV version 1.13