module/raid: partial completions for raid_bdev_io

Replace the 'expected' and 'completed' raid_bdev_io counters with a
single 'remaining' counter. This can represent either remaining blocks
or IOs required to complete the raid_bdev_io. Add a function which
decrements the counter and completes the raid_bdev_io if it reaches 0.

Change-Id: Ifa8bcc05c33e80159aad21d6e73d1f6185cca1cf
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/856
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
Artur Paszkiewicz 2019-11-15 15:07:32 +01:00 committed by Tomasz Zawadzki
parent 73763d40ec
commit 2efe6d922b
3 changed files with 62 additions and 25 deletions

View File

@ -317,28 +317,37 @@ raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status sta
/*
* brief:
* raid_bdev_base_io_completion is the completion callback for member disk requests
* raid_bdev_io_complete_part - signal the completion of a part of the expected
* base bdev IOs and complete the raid_io if this is the final expected IO.
* The caller should first set raid_io->base_bdev_io_remaining. This function
* will decrement this counter by the value of the 'completed' parameter and
* complete the raid_io if the counter reaches 0. The caller is free to
* interpret the 'base_bdev_io_remaining' and 'completed' values as needed,
* it can represent e.g. blocks or IOs.
* params:
* bdev_io - pointer to member disk requested bdev_io
* success - true if successful, false if unsuccessful
* cb_arg - callback argument (parent raid_bdev_io)
* raid_io - pointer to raid_bdev_io
* completed - the part of the raid_io that has been completed
* status - status of the base IO
* returns:
* none
* true - if the raid_io is completed
* false - otherwise
*/
void
raid_bdev_base_io_completion(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
bool
raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed,
enum spdk_bdev_io_status status)
{
struct raid_bdev_io *raid_io = cb_arg;
assert(raid_io->base_bdev_io_remaining >= completed);
raid_io->base_bdev_io_remaining -= completed;
spdk_bdev_free_io(bdev_io);
if (!success) {
raid_io->base_bdev_io_status = SPDK_BDEV_IO_STATUS_FAILED;
if (status != SPDK_BDEV_IO_STATUS_SUCCESS) {
raid_io->base_bdev_io_status = status;
}
raid_io->base_bdev_io_completed++;
if (raid_io->base_bdev_io_completed == raid_io->base_bdev_io_expected) {
if (raid_io->base_bdev_io_remaining == 0) {
raid_bdev_io_complete(raid_io, raid_io->base_bdev_io_status);
return true;
} else {
return false;
}
}
@ -364,6 +373,18 @@ raid_bdev_queue_io_wait(struct raid_bdev_io *raid_io, struct spdk_bdev *bdev,
spdk_bdev_queue_io_wait(bdev, ch, &raid_io->waitq_entry);
}
static void
raid_base_bdev_reset_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
struct raid_bdev_io *raid_io = cb_arg;
spdk_bdev_free_io(bdev_io);
raid_bdev_io_complete_part(raid_io, 1, success ?
SPDK_BDEV_IO_STATUS_SUCCESS :
SPDK_BDEV_IO_STATUS_FAILED);
}
static void
raid_bdev_submit_reset_request(struct raid_bdev_io *raid_io);
@ -396,14 +417,16 @@ raid_bdev_submit_reset_request(struct raid_bdev_io *raid_io)
raid_bdev = raid_io->raid_bdev;
raid_io->base_bdev_io_expected = raid_bdev->num_base_bdevs;
if (raid_io->base_bdev_io_remaining == 0) {
raid_io->base_bdev_io_remaining = raid_bdev->num_base_bdevs;
}
while (raid_io->base_bdev_io_submitted < raid_bdev->num_base_bdevs) {
i = raid_io->base_bdev_io_submitted;
base_info = &raid_bdev->base_bdev_info[i];
base_ch = raid_io->raid_ch->base_channel[i];
ret = spdk_bdev_reset(base_info->desc, base_ch,
raid_bdev_base_io_completion, raid_io);
raid_base_bdev_reset_complete, raid_io);
if (ret == 0) {
raid_io->base_bdev_io_submitted++;
} else if (ret == -ENOMEM) {
@ -461,8 +484,8 @@ raid_bdev_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_i
raid_io->raid_bdev = bdev_io->bdev->ctxt;
raid_io->raid_ch = spdk_io_channel_get_ctx(ch);
raid_io->base_bdev_io_remaining = 0;
raid_io->base_bdev_io_submitted = 0;
raid_io->base_bdev_io_completed = 0;
raid_io->base_bdev_io_status = SPDK_BDEV_IO_STATUS_SUCCESS;
switch (bdev_io->type) {

View File

@ -104,9 +104,8 @@ struct raid_bdev_io {
struct raid_bdev_io_channel *raid_ch;
/* Used for tracking progress on io requests sent to member disks. */
uint64_t base_bdev_io_remaining;
uint8_t base_bdev_io_submitted;
uint8_t base_bdev_io_completed;
uint8_t base_bdev_io_expected;
uint8_t base_bdev_io_status;
};
@ -308,8 +307,9 @@ __RAID_MODULE_REGISTER(__LINE__)(void) \
raid_bdev_module_list_add(_module); \
}
void
raid_bdev_base_io_completion(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
bool
raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed,
enum spdk_bdev_io_status status);
void
raid_bdev_queue_io_wait(struct raid_bdev_io *raid_io, struct spdk_bdev *bdev,
struct spdk_io_channel *ch, spdk_bdev_io_wait_cb cb_fn);

View File

@ -262,6 +262,18 @@ _raid0_submit_null_payload_request(void *_raid_io)
raid0_submit_null_payload_request(raid_io);
}
static void
raid0_base_io_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
struct raid_bdev_io *raid_io = cb_arg;
raid_bdev_io_complete_part(raid_io, 1, success ?
SPDK_BDEV_IO_STATUS_SUCCESS :
SPDK_BDEV_IO_STATUS_FAILED);
spdk_bdev_free_io(bdev_io);
}
/*
* brief:
* raid0_submit_null_payload_request function submits the next batch of
@ -290,9 +302,11 @@ raid0_submit_null_payload_request(struct raid_bdev_io *raid_io)
raid_bdev->strip_size, raid_bdev->strip_size_shift,
bdev_io->u.bdev.offset_blocks, bdev_io->u.bdev.num_blocks);
raid_io->base_bdev_io_expected = io_range.n_disks_involved;
if (raid_io->base_bdev_io_remaining == 0) {
raid_io->base_bdev_io_remaining = io_range.n_disks_involved;
}
while (raid_io->base_bdev_io_submitted < raid_io->base_bdev_io_expected) {
while (raid_io->base_bdev_io_submitted < io_range.n_disks_involved) {
uint8_t disk_idx;
uint64_t offset_in_disk;
uint64_t nblocks_in_disk;
@ -310,13 +324,13 @@ raid0_submit_null_payload_request(struct raid_bdev_io *raid_io)
case SPDK_BDEV_IO_TYPE_UNMAP:
ret = spdk_bdev_unmap_blocks(base_info->desc, base_ch,
offset_in_disk, nblocks_in_disk,
raid_bdev_base_io_completion, raid_io);
raid0_base_io_complete, raid_io);
break;
case SPDK_BDEV_IO_TYPE_FLUSH:
ret = spdk_bdev_flush_blocks(base_info->desc, base_ch,
offset_in_disk, nblocks_in_disk,
raid_bdev_base_io_completion, raid_io);
raid0_base_io_complete, raid_io);
break;
default: