Commit 5165aee6 authored by Ben Walker's avatar Ben Walker Committed by Jim Harris
Browse files

channel: Make spdk_for_each_channel support async operations



While iterating, allow the user to perform asynchronous
operations. To continue iteration, the user is expected
to call spdk_for_each_channel_continue.

Change-Id: Ifd7d03d5fbf17cf13843704274b036d49ca0484a
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/391309


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
parent 250f8e07
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ framework (include/spdk/event.h) to the I/O channel library
(include/spdk/io_channel.h). This allows code that doesn't depend on the event
framework to request registration and unregistration of pollers.

spdk_for_each_channel() now allows asynchronous operations during iteration.
Instead of immediately continuing the interation upon returning from the iteration
callback, the user must call spdk_for_each_channel_continue() to resume iteration.

### Block Device Abstraction Layer (bdev)

The poller abstraction was removed from the bdev layer. There is now a general purpose
+13 −4
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ extern "C" {

struct spdk_thread;
struct spdk_io_channel;
struct spdk_io_channel_iter;
struct spdk_poller;

typedef void (*spdk_thread_fn)(void *ctx);
@@ -66,9 +67,8 @@ typedef void (*spdk_io_channel_destroy_cb)(void *io_device, void *ctx_buf);

typedef void (*spdk_io_device_unregister_cb)(void *io_device);

typedef int (*spdk_channel_msg)(void *io_device, struct spdk_io_channel *ch,
				void *ctx);
typedef void (*spdk_channel_for_each_cpl)(void *io_device, void *ctx, int status);
typedef void (*spdk_channel_msg)(struct spdk_io_channel_iter *i);
typedef void (*spdk_channel_for_each_cpl)(struct spdk_io_channel_iter *i, int status);

/**
 * \brief Initializes the calling thread for I/O channel allocation.
@@ -216,7 +216,8 @@ struct spdk_thread *spdk_io_channel_get_thread(struct spdk_io_channel *ch);
 * asynchronously, so fn may be called after spdk_for_each_channel returns.
 * 'fn' will be called on the correct thread for each channel. 'fn' will be
 * called for each channel serially, such that two calls to 'fn' will not
 * overlap in time.
 * overlap in time. After 'fn' has been called, call
 * spdk_for_each_channel_continue() to continue iterating.
 *
 * Once 'fn' has been called on each channel, 'cpl' will be called
 * on the thread that spdk_for_each_channel was initially called from.
@@ -224,6 +225,14 @@ struct spdk_thread *spdk_io_channel_get_thread(struct spdk_io_channel *ch);
void spdk_for_each_channel(void *io_device, spdk_channel_msg fn, void *ctx,
			   spdk_channel_for_each_cpl cpl);

void *spdk_io_channel_iter_get_io_device(struct spdk_io_channel_iter *i);

struct spdk_io_channel *spdk_io_channel_iter_get_channel(struct spdk_io_channel_iter *i);

void *spdk_io_channel_iter_get_ctx(struct spdk_io_channel_iter *i);

void spdk_for_each_channel_continue(struct spdk_io_channel_iter *i, int status);

#ifdef __cplusplus
}
#endif
+9 −7
Original line number Diff line number Diff line
@@ -232,25 +232,27 @@ bdev_aio_poll(void *arg)
	}
}

static int
_bdev_aio_get_io_inflight(void *io_device, struct spdk_io_channel *ch,
			  void *ctx)
static void
_bdev_aio_get_io_inflight(struct spdk_io_channel_iter *i)
{
	struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i);
	struct bdev_aio_io_channel *aio_ch = spdk_io_channel_get_ctx(ch);

	if (aio_ch->io_inflight) {
		return -1;
		spdk_for_each_channel_continue(i, -1);
		return;
	}
	return 0;

	spdk_for_each_channel_continue(i, 0);
}

static void
bdev_aio_reset_retry_timer(void *arg);

static void
_bdev_aio_get_io_inflight_done(void *io_device, void *ctx, int status)
_bdev_aio_get_io_inflight_done(struct spdk_io_channel_iter *i, int status)
{
	struct file_disk *fdisk = ctx;
	struct file_disk *fdisk = spdk_io_channel_iter_get_ctx(i);

	if (status == -1) {
		fdisk->reset_retry_timer = spdk_poller_register(bdev_aio_reset_retry_timer, fdisk, 500);
+13 −11
Original line number Diff line number Diff line
@@ -1310,9 +1310,9 @@ spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
}

static void
_spdk_bdev_reset_dev(void *io_device, void *ctx, int status)
_spdk_bdev_reset_dev(struct spdk_io_channel_iter *i, int status)
{
	struct spdk_bdev_channel *ch = ctx;
	struct spdk_bdev_channel *ch = spdk_io_channel_iter_get_ctx(i);
	struct spdk_bdev_io *bdev_io;

	bdev_io = TAILQ_FIRST(&ch->queued_resets);
@@ -1320,13 +1320,14 @@ _spdk_bdev_reset_dev(void *io_device, void *ctx, int status)
	spdk_bdev_io_submit_reset(bdev_io);
}

static int
_spdk_bdev_reset_freeze_channel(void *io_device, struct spdk_io_channel *ch,
				void *ctx)
static void
_spdk_bdev_reset_freeze_channel(struct spdk_io_channel_iter *i)
{
	struct spdk_io_channel 		*ch;
	struct spdk_bdev_channel	*channel;
	struct spdk_bdev_mgmt_channel	*mgmt_channel;

	ch = spdk_io_channel_iter_get_channel(i);
	channel = spdk_io_channel_get_ctx(ch);
	mgmt_channel = spdk_io_channel_get_ctx(channel->mgmt_channel);

@@ -1336,7 +1337,7 @@ _spdk_bdev_reset_freeze_channel(void *io_device, struct spdk_io_channel *ch,
	_spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_small, channel);
	_spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_large, channel);

	return 0;
	spdk_for_each_channel_continue(i, 0);
}

static void
@@ -1583,9 +1584,9 @@ _spdk_bdev_io_complete(void *ctx)
}

static void
_spdk_bdev_reset_complete(void *io_device, void *ctx, int status)
_spdk_bdev_reset_complete(struct spdk_io_channel_iter *i, int status)
{
	struct spdk_bdev_io *bdev_io = ctx;
	struct spdk_bdev_io *bdev_io = spdk_io_channel_iter_get_ctx(i);

	if (bdev_io->u.reset.ch_ref != NULL) {
		spdk_put_io_channel(bdev_io->u.reset.ch_ref);
@@ -1595,9 +1596,10 @@ _spdk_bdev_reset_complete(void *io_device, void *ctx, int status)
	_spdk_bdev_io_complete(bdev_io);
}

static int
_spdk_bdev_unfreeze_channel(void *io_device, struct spdk_io_channel *_ch, void *ctx)
static void
_spdk_bdev_unfreeze_channel(struct spdk_io_channel_iter *i)
{
	struct spdk_io_channel *_ch = spdk_io_channel_iter_get_channel(i);
	struct spdk_bdev_channel *ch = spdk_io_channel_get_ctx(_ch);

	ch->flags &= ~BDEV_CH_RESET_IN_PROGRESS;
@@ -1605,7 +1607,7 @@ _spdk_bdev_unfreeze_channel(void *io_device, struct spdk_io_channel *_ch, void *
		_spdk_bdev_channel_start_reset(ch);
	}

	return 0;
	spdk_for_each_channel_continue(i, 0);
}

void
+19 −16
Original line number Diff line number Diff line
@@ -271,35 +271,38 @@ bdev_nvme_flush(struct nvme_bdev *nbdev, struct nvme_bdev_io *bio,
}

static void
_bdev_nvme_reset_done(void *io_device, void *ctx, int status)
_bdev_nvme_reset_done(struct spdk_io_channel_iter *i, int status)
{
	void *ctx = spdk_io_channel_iter_get_ctx(i);
	int rc = SPDK_BDEV_IO_STATUS_SUCCESS;

	if (status) {
		rc = SPDK_BDEV_IO_STATUS_FAILED;
	}
	spdk_bdev_io_complete(spdk_bdev_io_from_ctx(ctx), rc);
}

static int
_bdev_nvme_reset_create_qpair(void *io_device, struct spdk_io_channel *ch,
			      void *ctx)
static void
_bdev_nvme_reset_create_qpair(struct spdk_io_channel_iter *i)
{
	struct spdk_nvme_ctrlr *ctrlr = io_device;
	struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(ch);
	struct spdk_nvme_ctrlr *ctrlr = spdk_io_channel_iter_get_io_device(i);
	struct spdk_io_channel *_ch = spdk_io_channel_iter_get_channel(i);
	struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(_ch);

	nvme_ch->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, NULL, 0);
	if (!nvme_ch->qpair) {
		return -1;
		spdk_for_each_channel_continue(i, -1);
		return;
	}

	return 0;
	spdk_for_each_channel_continue(i, 0);
}

static void
_bdev_nvme_reset(void *io_device, void *ctx, int status)
_bdev_nvme_reset(struct spdk_io_channel_iter *i, int status)
{
	struct spdk_nvme_ctrlr *ctrlr = io_device;
	struct nvme_bdev_io *bio = ctx;
	struct spdk_nvme_ctrlr *ctrlr = spdk_io_channel_iter_get_io_device(i);
	struct nvme_bdev_io *bio = spdk_io_channel_iter_get_ctx(i);
	int rc;

	if (status) {
@@ -316,16 +319,16 @@ _bdev_nvme_reset(void *io_device, void *ctx, int status)
	/* Recreate all of the I/O queue pairs */
	spdk_for_each_channel(ctrlr,
			      _bdev_nvme_reset_create_qpair,
			      ctx,
			      bio,
			      _bdev_nvme_reset_done);


}

static int
_bdev_nvme_reset_destroy_qpair(void *io_device, struct spdk_io_channel *ch,
			       void *ctx)
static void
_bdev_nvme_reset_destroy_qpair(struct spdk_io_channel_iter *i)
{
	struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i);
	struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(ch);
	int rc;

@@ -334,7 +337,7 @@ _bdev_nvme_reset_destroy_qpair(void *io_device, struct spdk_io_channel *ch,
		nvme_ch->qpair = NULL;
	}

	return rc;
	spdk_for_each_channel_continue(i, rc);
}

static int
Loading