Changeset 978130a in mainline


Ignore:
Timestamp:
2024-10-28T16:03:24Z (7 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
4dd650a
Parents:
76cd345
Message:

hr: optimize RAID 0, 4, 5 to write whole strip

Location:
uspace/srv/bd/hr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/hr/raid0.c

    r76cd345 r978130a  
    7474};
    7575
    76 static void raid0_geometry(uint64_t x, hr_volume_t *vol, size_t *extent,
    77     uint64_t *phys_block)
    78 {
    79         uint64_t N = vol->dev_no; /* extents */
    80         uint64_t L = vol->strip_size / vol->bsize; /* size of strip in blocks */
    81 
    82         uint64_t i = (x / L) % N; /* extent */
    83         uint64_t j = (x / L) / N; /* stripe */
    84         uint64_t k = x % L; /* strip offset */
    85 
    86         *extent = i;
    87         *phys_block = j * L + k;
    88 }
    89 
    9076static errno_t hr_raid0_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    9177{
     
    10692        errno_t rc;
    10793        uint64_t phys_block;
    108         size_t extent, left;
     94        size_t left;
    10995
    11096        if (type == HR_BD_READ || type == HR_BD_WRITE)
     
    116102                return rc;
    117103
     104        uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
     105        uint64_t stripe = ba / strip_size; /* stripe number */
     106        uint64_t extent = stripe % vol->dev_no;
     107        uint64_t ext_stripe = stripe / vol->dev_no; /* stripe level */
     108        uint64_t strip_off = ba % strip_size; /* strip offset */
     109
    118110        fibril_mutex_lock(&vol->lock);
    119111
    120112        left = cnt;
    121113        while (left != 0) {
    122                 raid0_geometry(ba, vol, &extent, &phys_block);
     114                phys_block = ext_stripe * strip_size + strip_off;
     115                cnt = min(left, strip_size - strip_off);
    123116                hr_add_ba_offset(vol, &phys_block);
    124117                switch (type) {
    125118                case HR_BD_SYNC:
    126119                        rc = block_sync_cache(vol->extents[extent].svc_id,
    127                             phys_block, 1);
     120                            phys_block, cnt);
    128121                        break;
    129122                case HR_BD_READ:
    130123                        rc = block_read_direct(vol->extents[extent].svc_id,
    131                             phys_block, 1, data_read);
    132                         data_read = data_read + vol->bsize;
     124                            phys_block, cnt, data_read);
     125                        data_read = (void *) ((uintptr_t) data_read +
     126                            (vol->bsize * cnt));
    133127                        break;
    134128                case HR_BD_WRITE:
    135129                        rc = block_write_direct(vol->extents[extent].svc_id,
    136                             phys_block, 1, data_write);
    137                         data_write = data_write + vol->bsize;
     130                            phys_block, cnt, data_write);
     131                        data_write = (void *) ((uintptr_t) data_write +
     132                            (vol->bsize * cnt));
    138133                        break;
    139134                default:
    140135                        rc = EINVAL;
    141136                }
    142 
    143137                if (rc != EOK)
    144138                        goto error;
    145139
    146                 left--;
    147                 ba++;
     140                left -= cnt;
     141                strip_off = 0;
     142                extent++;
     143                if (extent >= vol->dev_no) {
     144                        ext_stripe++;
     145                        extent = 0;
     146                }
    148147        }
    149148
  • uspace/srv/bd/hr/raid4.c

    r76cd345 r978130a  
    4343#include <ipc/services.h>
    4444#include <loc.h>
     45#include <mem.h>
    4546#include <task.h>
    4647#include <stdio.h>
     
    8586
    8687static errno_t write_parity(hr_volume_t *vol, uint64_t extent, uint64_t block,
    87     const void *data)
    88 {
    89         errno_t rc;
    90         size_t i;
     88    const void *data, size_t cnt)
     89{
     90        errno_t rc;
     91        size_t i, j;
    9192        void *xorbuf;
    9293        void *buf;
    9394
    94         xorbuf = calloc(1, vol->bsize);
     95        xorbuf = malloc(vol->bsize);
    9596        if (xorbuf == NULL)
    9697                return ENOMEM;
     
    102103        }
    103104
    104         for (i = 1; i < vol->dev_no; i++) {
    105                 if (i == extent) {
    106                         xor(xorbuf, data, vol->bsize);
    107                 } else {
    108                         rc = block_read_direct(vol->extents[i].svc_id, block, 1,
    109                             buf);
    110                         if (rc != EOK)
    111                                 goto end;
    112                         xor(xorbuf, buf, vol->bsize);
     105        for (j = 0; j < cnt; j++) {
     106                memset(xorbuf, 0, vol->bsize);
     107                for (i = 1; i < vol->dev_no; i++) {
     108                        if (i == extent) {
     109                                xor(xorbuf, data, vol->bsize);
     110                        } else {
     111                                rc = block_read_direct(vol->extents[i].svc_id,
     112                                    block, 1, buf);
     113                                if (rc != EOK)
     114                                        goto end;
     115                                xor(xorbuf, buf, vol->bsize);
     116                        }
    113117                }
    114         }
    115 
    116         rc = block_write_direct(vol->extents[0].svc_id, block, 1, xorbuf);
    117 
     118                rc = block_write_direct(vol->extents[0].svc_id, block, 1,
     119                    xorbuf);
     120                if (rc != EOK)
     121                        goto end;
     122                data = (void *) ((uintptr_t) data + vol->bsize);
     123                block++;
     124        }
    118125end:
    119126        free(xorbuf);
     
    122129}
    123130
    124 static void raid4_geometry(uint64_t x, hr_volume_t *vol, size_t *extent,
    125     uint64_t *phys_block)
    126 {
    127         uint64_t N = vol->dev_no; /* extents */
    128         uint64_t L = vol->strip_size / vol->bsize; /* size of strip in blocks */
    129 
    130         uint64_t i = ((x / L) % (N - 1)) + 1; /* extent */
    131         uint64_t j = (x / L) / (N - 1); /* stripe */
    132         uint64_t k = x % L; /* strip offset */
    133 
    134         *extent = i;
    135         *phys_block = j * L + k;
    136 }
    137 
    138131static errno_t hr_raid4_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    139132{
     
    154147        errno_t rc;
    155148        uint64_t phys_block;
    156         size_t extent, left;
     149        size_t left;
    157150
    158151        if (type == HR_BD_READ || type == HR_BD_WRITE)
     
    164157                return rc;
    165158
     159        uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
     160        uint64_t stripe = (ba / strip_size); /* stripe number */
     161        uint64_t extent = (stripe % (vol->dev_no - 1)) + 1;
     162        uint64_t ext_stripe = stripe / (vol->dev_no - 1); /* stripe level */
     163        uint64_t strip_off = ba % strip_size; /* strip offset */
     164
    166165        fibril_mutex_lock(&vol->lock);
    167166
    168167        left = cnt;
    169168        while (left != 0) {
    170                 raid4_geometry(ba, vol, &extent, &phys_block);
     169                phys_block = ext_stripe * strip_size + strip_off;
     170                cnt = min(left, strip_size - strip_off);
    171171                hr_add_ba_offset(vol, &phys_block);
    172172                switch (type) {
    173173                case HR_BD_SYNC:
    174174                        rc = block_sync_cache(vol->extents[extent].svc_id,
    175                             phys_block, 1);
     175                            phys_block, cnt);
    176176                        break;
    177177                case HR_BD_READ:
    178178                        rc = block_read_direct(vol->extents[extent].svc_id,
    179                             phys_block, 1, data_read);
    180                         data_read = data_read + vol->bsize;
     179                            phys_block, cnt, data_read);
     180                        data_read = (void *) ((uintptr_t) data_read +
     181                            (vol->bsize * cnt));
    181182                        break;
    182183                case HR_BD_WRITE:
    183184                        rc = block_write_direct(vol->extents[extent].svc_id,
    184                             phys_block, 1, data_write);
     185                            phys_block, cnt, data_write);
    185186                        if (rc != EOK)
    186187                                goto error;
    187                         rc = write_parity(vol, extent, phys_block, data_write);
     188                        rc = write_parity(vol, extent, phys_block, data_write,
     189                            cnt);
    188190                        if (rc != EOK)
    189191                                goto error;
    190                         data_write = data_write + vol->bsize;
     192                        data_write = (void *) ((uintptr_t) data_write +
     193                            (vol->bsize * cnt));
    191194                        break;
    192195                default:
     
    197200                        goto error;
    198201
    199                 left--;
    200                 ba++;
     202                left -= cnt;
     203                strip_off = 0;
     204                extent++;
     205                if (extent >= vol->dev_no) {
     206                        ext_stripe++;
     207                        extent = 1;
     208                }
    201209        }
    202210
  • uspace/srv/bd/hr/raid5.c

    r76cd345 r978130a  
    4343#include <ipc/services.h>
    4444#include <loc.h>
     45#include <mem.h>
    4546#include <task.h>
    4647#include <stdio.h>
     
    8586
    8687static errno_t write_parity(hr_volume_t *vol, uint64_t p_extent,
    87     uint64_t extent, uint64_t block, const void *data)
     88    uint64_t extent, uint64_t block, const void *data, size_t cnt)
    8889{
    8990        errno_t rc;
    90         size_t i;
     91        size_t i, j;
    9192        void *xorbuf;
    9293        void *buf;
    9394
    94         xorbuf = calloc(1, vol->bsize);
     95        xorbuf = malloc(vol->bsize);
    9596        if (xorbuf == NULL)
    9697                return ENOMEM;
     
    102103        }
    103104
    104         for (i = 0; i < vol->dev_no; i++) {
    105                 if (i == p_extent)
    106                         continue;
    107 
    108                 if (i == extent) {
    109                         xor(xorbuf, data, vol->bsize);
    110                 } else {
    111                         rc = block_read_direct(vol->extents[i].svc_id, block, 1,
    112                             buf);
    113                         if (rc != EOK)
    114                                 goto end;
    115                         xor(xorbuf, buf, vol->bsize);
     105        for (j = 0; j < cnt; j++) {
     106                memset(xorbuf, 0, vol->bsize);
     107                for (i = 0; i < vol->dev_no; i++) {
     108                        if (i == p_extent)
     109                                continue;
     110
     111                        if (i == extent) {
     112                                xor(xorbuf, data, vol->bsize);
     113                        } else {
     114                                rc = block_read_direct(vol->extents[i].svc_id,
     115                                    block, 1, buf);
     116                                if (rc != EOK)
     117                                        goto end;
     118                                xor(xorbuf, buf, vol->bsize);
     119                        }
    116120                }
     121
     122                rc = block_write_direct(vol->extents[p_extent].svc_id, block, 1,
     123                    xorbuf);
     124                if (rc != EOK)
     125                        goto end;
     126                data = (void *) ((uintptr_t) data + vol->bsize);
     127                block++;
    117128        }
    118 
    119         rc = block_write_direct(vol->extents[p_extent].svc_id, block, 1,
    120             xorbuf);
    121129
    122130end:
     
    126134}
    127135
    128 static void raid5_geometry(uint64_t x, hr_volume_t *vol, size_t *extent,
    129     uint64_t *phys_block, uint64_t *p_extent)
    130 {
    131         uint64_t N = vol->dev_no; /* extents */
    132         uint64_t L = vol->strip_size / vol->bsize; /* size of strip in blocks */
    133 
    134         uint64_t p = ((x / L) / (N - 1)) % N;
    135 
    136         uint64_t i; /* extent */
    137         if (((x / L) % (N - 1)) < p)
    138                 i = (x / L) % (N - 1);
    139         else
    140                 i = ((x / L) % (N - 1)) + 1;
    141 
    142         uint64_t j = (x / L) / (N - 1); /* stripe */
    143         uint64_t k = x % L; /* strip offset */
    144 
    145         *extent = i;
    146         *phys_block = j * L + k;
    147         if (p_extent != NULL)
    148                 *p_extent = p;
    149 }
    150 
    151136static errno_t hr_raid5_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    152137{
     
    166151        hr_volume_t *vol = bd->srvs->sarg;
    167152        errno_t rc;
    168         uint64_t phys_block, p_extent;
    169         size_t extent, left;
     153        uint64_t phys_block;
     154        size_t left;
    170155
    171156        if (type == HR_BD_READ || type == HR_BD_WRITE)
     
    177162                return rc;
    178163
     164        uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
     165        uint64_t stripe = (ba / strip_size); /* stripe number */
     166        uint64_t p_extent = (stripe / (vol->dev_no - 1)) % vol->dev_no; /* parity extent */
     167        uint64_t extent;
     168        if ((stripe % (vol->dev_no - 1)) < p_extent)
     169                extent = (stripe % (vol->dev_no - 1));
     170        else
     171                extent = ((stripe % (vol->dev_no - 1)) + 1);
     172        uint64_t ext_stripe = stripe / (vol->dev_no - 1); /* stripe level */
     173        uint64_t strip_off = ba % strip_size; /* strip offset */
     174
    179175        fibril_mutex_lock(&vol->lock);
    180176
    181177        left = cnt;
    182178        while (left != 0) {
     179                phys_block = ext_stripe * strip_size + strip_off;
     180                cnt = min(left, strip_size - strip_off);
     181                hr_add_ba_offset(vol, &phys_block);
    183182                switch (type) {
    184183                case HR_BD_SYNC:
    185                         raid5_geometry(ba, vol, &extent, &phys_block, NULL);
    186                         hr_add_ba_offset(vol, &phys_block);
    187184                        rc = block_sync_cache(vol->extents[extent].svc_id,
    188                             phys_block, 1);
     185                            phys_block, cnt);
    189186                        break;
    190187                case HR_BD_READ:
    191                         raid5_geometry(ba, vol, &extent, &phys_block, NULL);
    192                         hr_add_ba_offset(vol, &phys_block);
    193188                        rc = block_read_direct(vol->extents[extent].svc_id,
    194                             phys_block, 1, data_read);
    195                         data_read = data_read + vol->bsize;
     189                            phys_block, cnt, data_read);
     190                        data_read = (void *) ((uintptr_t) data_read +
     191                            (vol->bsize * cnt));
    196192                        break;
    197193                case HR_BD_WRITE:
    198                         raid5_geometry(ba, vol, &extent, &phys_block,
    199                             &p_extent);
    200                         hr_add_ba_offset(vol, &phys_block);
    201194                        rc = block_write_direct(vol->extents[extent].svc_id,
    202                             phys_block, 1, data_write);
     195                            phys_block, cnt, data_write);
    203196                        if (rc != EOK)
    204197                                goto error;
    205198                        rc = write_parity(vol, p_extent, extent, phys_block,
    206                             data_write);
     199                            data_write, cnt);
    207200                        if (rc != EOK)
    208201                                goto error;
    209                         data_write = data_write + vol->bsize;
     202                        data_write = (void *) ((uintptr_t) data_write +
     203                            (vol->bsize * cnt));
    210204                        break;
    211205                default:
     
    216210                        goto error;
    217211
    218                 left--;
    219                 ba++;
     212                left -= cnt;
     213                strip_off = 0;
     214                if (extent + 1 >= vol->dev_no ||
     215                    (extent + 1 == p_extent && p_extent + 1 >= vol->dev_no))
     216                        ext_stripe++;
     217                stripe++;
     218                p_extent = (stripe / (vol->dev_no - 1)) % vol->dev_no; /* parity extent */
     219                if ((stripe % (vol->dev_no - 1)) < p_extent)
     220                        extent = (stripe % (vol->dev_no - 1));
     221                else
     222                        extent = ((stripe % (vol->dev_no - 1)) + 1);
    220223        }
    221224
Note: See TracChangeset for help on using the changeset viewer.