Commit 360ccc4e authored by Ni Xun's avatar Ni Xun Committed by Jim Harris
Browse files

bdev_split: add support for bdev_io_wait when no memory to submit



according to commit:
     bdev: add spdk_bdev_queue_io_wait
This patch will make io_wait to support bdev_split

Change-Id: Ie5c57db3fbd9e777f69daf65b080f2659d85032a
Signed-off-by: default avatarNi Xun <nixun@baidu.com>
Signed-off-by: default avatarLi Lin <lilin24@baidu.com>
Signed-off-by: default avatarZhang Yu <zhangyu31@baidu.com>
Reviewed-on: https://review.gerrithub.io/426649


Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent d705ab93
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -904,8 +904,9 @@ int spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_
 *
 * \param ch The I/O channel associated with the spdk_bdev_part.
 * \param bdev_io The I/O to be submitted to the underlying bdev.
 * \return 0 on success or non-zero if submit request failed.
 */
void spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io);
int spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io);

/**
 * Return a pointer to this part's spdk_bdev.
+6 −1
Original line number Diff line number Diff line
@@ -191,7 +191,12 @@ vbdev_error_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bde

	error_type = vbdev_error_get_error_type(error_disk, bdev_io->type);
	if (error_type == 0) {
		spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);
		int rc = spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);

		if (rc) {
			SPDK_ERRLOG("bdev_error: submit request failed, rc=%d\n", rc);
			spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
		}
		return;
	} else if (error_type == VBDEV_IO_FAILURE) {
		error_disk->error_vector[bdev_io->type].error_num--;
+6 −1
Original line number Diff line number Diff line
@@ -160,8 +160,13 @@ static void
vbdev_gpt_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
{
	struct gpt_channel *ch = spdk_io_channel_get_ctx(_ch);
	int rc;

	spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);
	rc = spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);
	if (rc) {
		SPDK_ERRLOG("gpt: error on bdev_io submission, rc=%d.\n", rc);
		spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
	}
}

static void
+4 −6
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ spdk_bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_
	spdk_bdev_free_io(bdev_io);
}

void
int
spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io)
{
	struct spdk_bdev_part *part = ch->part;
@@ -238,14 +238,12 @@ spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bde
		break;
	default:
		SPDK_ERRLOG("split: unknown I/O type %d\n", bdev_io->type);
		spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
		return;
		return SPDK_BDEV_IO_STATUS_FAILED;
	}

	if (rc != 0) {
		spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
	}
	return rc;
}

static int
spdk_bdev_part_channel_create_cb(void *io_device, void *ctx_buf)
{
+63 −1
Original line number Diff line number Diff line
@@ -67,17 +67,30 @@ struct vbdev_split_channel {
	struct spdk_bdev_part_channel	part_ch;
};

struct vbdev_split_bdev_io {
	struct spdk_io_channel *ch;
	struct spdk_bdev_io *bdev_io;

	/* for bdev_io_wait */
	struct spdk_bdev_io_wait_entry bdev_io_wait;
};

static void vbdev_split_del_config(struct spdk_vbdev_split_config *cfg);

static int vbdev_split_init(void);
static void vbdev_split_fini(void);
static void vbdev_split_examine(struct spdk_bdev *bdev);
static int vbdev_split_config_json(struct spdk_json_write_ctx *w);
static int vbdev_split_get_ctx_size(void);

static void
vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io);

static struct spdk_bdev_module split_if = {
	.name = "split",
	.module_init = vbdev_split_init,
	.module_fini = vbdev_split_fini,
	.get_ctx_size = vbdev_split_get_ctx_size,
	.examine_config = vbdev_split_examine,
	.config_json = vbdev_split_config_json,
};
@@ -109,12 +122,50 @@ vbdev_split_base_bdev_hotremove_cb(void *_base_bdev)
	spdk_bdev_part_base_hotremove(_base_bdev, &g_split_disks);
}

static void
vbdev_split_resubmit_io(void *arg)
{
	struct vbdev_split_bdev_io *split_io = (struct vbdev_split_bdev_io *)arg;

	vbdev_split_submit_request(split_io->ch, split_io->bdev_io);
}

static void
vbdev_split_queue_io(struct vbdev_split_bdev_io *split_io)
{
	int rc;

	split_io->bdev_io_wait.bdev = split_io->bdev_io->bdev;
	split_io->bdev_io_wait.cb_fn = vbdev_split_resubmit_io;
	split_io->bdev_io_wait.cb_arg = split_io;

	rc = spdk_bdev_queue_io_wait(split_io->bdev_io->bdev,
				     split_io->ch, &split_io->bdev_io_wait);
	if (rc != 0) {
		SPDK_ERRLOG("Queue io failed in vbdev_split_queue_io, rc=%d\n", rc);
		spdk_bdev_io_complete(split_io->bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
	}
}

static void
vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
{
	struct vbdev_split_channel *ch = spdk_io_channel_get_ctx(_ch);
	struct vbdev_split_bdev_io *io_ctx = (struct vbdev_split_bdev_io *)bdev_io->driver_ctx;
	int rc;

	spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);
	rc = spdk_bdev_part_submit_request(&ch->part_ch, bdev_io);
	if (rc) {
		if (rc == -ENOMEM) {
			SPDK_DEBUGLOG(SPDK_LOG_VBDEV_SPLIT, "split: no memory, queue io.\n");
			io_ctx->ch = _ch;
			io_ctx->bdev_io = bdev_io;
			vbdev_split_queue_io(io_ctx);
		} else {
			SPDK_ERRLOG("split: error on io submission, rc=%d.\n", rc);
			spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
		}
	}
}

static int
@@ -500,4 +551,15 @@ spdk_vbdev_split_get_part_base(struct spdk_bdev *bdev)
	return cfg->split_base;
}

/*
 * During init we'll be asked how much memory we'd like passed to us
 * in bev_io structures as context. Here's where we specify how
 * much context we want per IO.
 */
static int
vbdev_split_get_ctx_size(void)
{
	return sizeof(struct vbdev_split_bdev_io);
}

SPDK_LOG_REGISTER_COMPONENT("vbdev_split", SPDK_LOG_VBDEV_SPLIT)