Changeset 978130a in mainline for uspace/srv/bd/hr/raid5.c


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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.