Changeset bc3d695 in mainline for uspace/srv/bd/hr/raid0.c


Ignore:
Timestamp:
2025-01-05T18:22:28Z (4 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
7bf29e5
Parents:
40be7eb
Message:

hr: RAID0 parallelization

File:
1 edited

Legend:

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

    r40be7eb rbc3d695  
    11/*
    2  * Copyright (c) 2024 Miroslav Cimerman
     2 * Copyright (c) 2025 Miroslav Cimerman
    33 * All rights reserved.
    44 *
     
    4848#include <str_error.h>
    4949
     50#include "io.h"
    5051#include "superblock.h"
    5152#include "util.h"
     
    5455extern loc_srv_t *hr_srv;
    5556
    56 static errno_t hr_raid0_check_vol_status(hr_volume_t *);
    5757static errno_t hr_raid0_update_vol_status(hr_volume_t *);
    5858static errno_t hr_raid0_bd_op(hr_bd_op_type_t, bd_srv_t *, aoff64_t, size_t,
     
    9595                return rc;
    9696
     97        hr_update_vol_status(new_volume, HR_VOL_ONLINE);
     98
    9799        bd_srvs_init(&new_volume->hr_bds);
    98100        new_volume->hr_bds.ops = &hr_raid0_bd_ops;
     
    127129void hr_raid0_status_event(hr_volume_t *vol)
    128130{
    129         fibril_mutex_lock(&vol->lock);
    130131        (void)hr_raid0_update_vol_status(vol);
    131         fibril_mutex_unlock(&vol->lock);
    132132}
    133133
     
    175175        *rnb = vol->data_blkno;
    176176        return EOK;
    177 }
    178 
    179 static errno_t hr_raid0_check_vol_status(hr_volume_t *vol)
    180 {
    181         if (vol->status == HR_VOL_ONLINE)
    182                 return EOK;
    183         return EIO;
    184177}
    185178
     
    190183static errno_t hr_raid0_update_vol_status(hr_volume_t *vol)
    191184{
     185        fibril_rwlock_read_lock(&vol->states_lock);
    192186        hr_vol_status_t old_state = vol->status;
    193187
    194188        for (size_t i = 0; i < vol->extent_no; i++) {
    195189                if (vol->extents[i].status != HR_EXT_ONLINE) {
     190                        fibril_rwlock_read_unlock(&vol->states_lock);
     191                        fibril_rwlock_write_lock(&vol->states_lock);
    196192                        if (old_state != HR_VOL_FAULTY)
    197193                                hr_update_vol_status(vol, HR_VOL_FAULTY);
     194                        fibril_rwlock_write_unlock(&vol->states_lock);
    198195                        return EIO;
    199196                }
    200197        }
    201 
    202         if (old_state != HR_VOL_ONLINE)
    203                 hr_update_vol_status(vol, HR_VOL_ONLINE);
    204 
    205         return EOK;
     198        fibril_rwlock_read_unlock(&vol->states_lock);
     199
     200        return EOK;
     201}
     202
     203static void raid0_state_callback(hr_volume_t *vol, size_t extent, errno_t rc)
     204{
     205        if (rc == EOK)
     206                return;
     207
     208        fibril_rwlock_write_lock(&vol->states_lock);
     209
     210        switch (rc) {
     211        case ENOENT:
     212                hr_update_ext_status(vol, extent, HR_EXT_MISSING);
     213                break;
     214        default:
     215                hr_update_ext_status(vol, extent, HR_EXT_FAILED);
     216        }
     217
     218        hr_update_vol_status(vol, HR_VOL_FAULTY);
     219
     220        fibril_rwlock_write_unlock(&vol->states_lock);
    206221}
    207222
     
    216231        uint8_t *data_read = dst;
    217232
     233        fibril_rwlock_read_lock(&vol->states_lock);
     234        if (vol->status != HR_VOL_ONLINE) {
     235                fibril_rwlock_read_unlock(&vol->states_lock);
     236                return EIO;
     237        }
     238        fibril_rwlock_read_unlock(&vol->states_lock);
     239
    218240        /* propagate sync */
    219241        if (type == HR_BD_SYNC && ba == 0 && cnt == 0) {
    220                 hr_sync_all_extents(vol);
    221                 rc = hr_raid0_update_vol_status(vol);
    222                 return rc;
     242                hr_fgroup_t *group = hr_fgroup_create(vol->fge, vol->extent_no);
     243
     244                for (size_t i = 0; i < vol->extent_no; i++) {
     245                        hr_io_t *io = hr_fgroup_alloc(group);
     246                        io->extent = i;
     247                        io->ba = ba;
     248                        io->cnt = cnt;
     249                        io->type = type;
     250                        io->vol = vol;
     251                        io->state_callback = raid0_state_callback;
     252
     253                        hr_fgroup_submit(group, hr_io_worker, io);
     254                }
     255
     256                size_t bad;
     257                (void)hr_fgroup_wait(group, NULL, &bad);
     258                if (bad > 0)
     259                        return EIO;
     260                return EOK;
    223261        }
    224262
     
    232270
    233271        uint64_t strip_size = vol->strip_size / vol->bsize; /* in blocks */
    234         uint64_t stripe = ba / strip_size; /* stripe number */
    235         uint64_t extent = stripe % vol->extent_no;
    236         uint64_t ext_stripe = stripe / vol->extent_no; /* stripe level */
    237         uint64_t strip_off = ba % strip_size; /* strip offset */
    238 
    239         fibril_mutex_lock(&vol->lock);
    240 
    241         rc = hr_raid0_check_vol_status(vol);
    242         if (rc != EOK) {
    243                 fibril_mutex_unlock(&vol->lock);
    244                 return EIO;
    245         }
     272        uint64_t strip_no = ba / strip_size;
     273        uint64_t extent = strip_no % vol->extent_no;
     274        uint64_t stripe = strip_no / vol->extent_no;
     275        uint64_t strip_off = ba % strip_size;
    246276
    247277        left = cnt;
    248278
     279        /* calculate how many strips does the IO span */
     280        size_t end_strip_no = (ba + cnt - 1) / strip_size;
     281        size_t span = end_strip_no - strip_no + 1;
     282
     283        hr_fgroup_t *group = hr_fgroup_create(vol->fge, span);
     284
    249285        while (left != 0) {
    250                 phys_block = ext_stripe * strip_size + strip_off;
     286                phys_block = stripe * strip_size + strip_off;
    251287                cnt = min(left, strip_size - strip_off);
    252288                len = vol->bsize * cnt;
    253289                hr_add_ba_offset(vol, &phys_block);
    254                 switch (type) {
    255                 case HR_BD_SYNC:
    256                         rc = block_sync_cache(vol->extents[extent].svc_id,
    257                             phys_block, cnt);
    258                         /* allow unsupported sync */
    259                         if (rc == ENOTSUP)
    260                                 rc = EOK;
    261                         break;
    262                 case HR_BD_READ:
    263                         rc = block_read_direct(vol->extents[extent].svc_id,
    264                             phys_block, cnt, data_read);
     290
     291                hr_io_t *io = hr_fgroup_alloc(group);
     292                io->extent = extent;
     293                io->data_write = data_write;
     294                io->data_read = data_read;
     295                io->ba = ba;
     296                io->cnt = cnt;
     297                io->type = type;
     298                io->vol = vol;
     299                io->state_callback = raid0_state_callback;
     300
     301                hr_fgroup_submit(group, hr_io_worker, io);
     302
     303                if (type == HR_BD_READ)
    265304                        data_read += len;
    266                         break;
    267                 case HR_BD_WRITE:
    268                         rc = block_write_direct(vol->extents[extent].svc_id,
    269                             phys_block, cnt, data_write);
     305                else if (type == HR_BD_WRITE)
    270306                        data_write += len;
    271                         break;
    272                 default:
    273                         rc = EINVAL;
    274                 }
    275 
    276                 if (rc == ENOENT) {
    277                         hr_update_ext_status(vol, extent, HR_EXT_MISSING);
    278                         rc = EIO;
    279                         goto error;
    280                 } else if (rc != EOK) {
    281                         hr_update_ext_status(vol, extent, HR_EXT_FAILED);
    282                         rc = EIO;
    283                         goto error;
    284                 }
    285307
    286308                left -= cnt;
     
    288310                extent++;
    289311                if (extent >= vol->extent_no) {
    290                         ext_stripe++;
     312                        stripe++;
    291313                        extent = 0;
    292314                }
    293315        }
    294316
    295 error:
    296         (void)hr_raid0_update_vol_status(vol);
    297         fibril_mutex_unlock(&vol->lock);
    298         return rc;
     317        size_t bad;
     318        (void)hr_fgroup_wait(group, NULL, &bad);
     319        if (bad > 0)
     320                return EIO;
     321
     322        return EOK;
    299323}
    300324
Note: See TracChangeset for help on using the changeset viewer.