Commit 2efe6d92 authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Tomasz Zawadzki
Browse files

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: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/856


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
parent 73763d40
Loading
Loading
Loading
Loading
+40 −17
Original line number Diff line number Diff line
@@ -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;

	spdk_bdev_free_io(bdev_io);
	assert(raid_io->base_bdev_io_remaining >= completed);
	raid_io->base_bdev_io_remaining -= completed;

	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) {
+4 −4
Original line number Diff line number Diff line
@@ -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);
+18 −4
Original line number Diff line number Diff line
@@ -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: