Commit d9a631ad authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Jim Harris
Browse files

FTL: Add io channel logic

parent e7a03e68
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ FTL_SUBDIRS := mngt utils

C_SRCS = ftl_core.c ftl_init.c ftl_layout.c ftl_debug.c ftl_io.c
C_SRCS += mngt/ftl_mngt.c mngt/ftl_mngt_bdev.c mngt/ftl_mngt_shutdown.c mngt/ftl_mngt_startup.c
C_SRCS += mngt/ftl_mngt_md.c mngt/ftl_mngt_misc.c
C_SRCS += mngt/ftl_mngt_md.c mngt/ftl_mngt_misc.c mngt/ftl_mngt_ioch.c
C_SRCS += utils/ftl_conf.c utils/ftl_md.c utils/ftl_mempool.c

SPDK_MAP_FILE = $(abspath $(CURDIR)/spdk_ftl.map)
+72 −0
Original line number Diff line number Diff line
@@ -46,6 +46,76 @@ spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *at
	attrs->optimum_io_size = dev->xfer_size;
}

static void
start_io(struct ftl_io *io)
{
	struct ftl_io_channel *ioch = ftl_io_channel_get_ctx(io->ioch);

	io->map = ftl_mempool_get(ioch->map_pool);
	if (spdk_unlikely(!io->map)) {
		io->status = -ENOMEM;
		ftl_io_complete(io);
		return;
	}

	switch (io->type) {
	case FTL_IO_READ:
	case FTL_IO_WRITE:
	case FTL_IO_UNMAP:
	default:
		io->status = -EOPNOTSUPP;
		ftl_io_complete(io);
	}
}

#define FTL_IO_QUEUE_BATCH 16
int
ftl_io_channel_poll(void *arg)
{
	struct ftl_io_channel *ch = arg;
	void *ios[FTL_IO_QUEUE_BATCH];
	uint64_t i, count;

	count = spdk_ring_dequeue(ch->cq, ios, FTL_IO_QUEUE_BATCH);
	if (count == 0) {
		return SPDK_POLLER_IDLE;
	}

	for (i = 0; i < count; i++) {
		struct ftl_io *io = ios[i];
		io->user_fn(io->cb_ctx, io->status);
	}

	return SPDK_POLLER_BUSY;
}

static void
ftl_process_io_channel(struct spdk_ftl_dev *dev, struct ftl_io_channel *ioch)
{
	void *ios[FTL_IO_QUEUE_BATCH];
	size_t count, i;

	count = spdk_ring_dequeue(ioch->sq, ios, FTL_IO_QUEUE_BATCH);
	if (count == 0) {
		return;
	}

	for (i = 0; i < count; i++) {
		struct ftl_io *io = ios[i];
		start_io(io);
	}
}

static void
ftl_process_io_queue(struct spdk_ftl_dev *dev)
{
	struct ftl_io_channel *ioch;

	TAILQ_FOREACH(ioch, &dev->ioch_queue, entry) {
		ftl_process_io_channel(dev, ioch);
	}
}

int
ftl_core_poller(void *ctx)
{
@@ -57,6 +127,8 @@ ftl_core_poller(void *ctx)
		return SPDK_POLLER_IDLE;
	}

	ftl_process_io_queue(dev);

	if (io_activity_total_old != dev->io_activity_total) {
		return SPDK_POLLER_BUSY;
	}
+19 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ struct spdk_ftl_dev {
	/* FTL device layout */
	struct ftl_layout		layout;

	/* Queue of registered IO channels */
	TAILQ_HEAD(, ftl_io_channel)	ioch_queue;

	/* Underlying device */
	struct spdk_bdev_desc		*base_bdev_desc;

@@ -49,6 +52,12 @@ struct spdk_ftl_dev {
	/* Indicates the device is about to be stopped */
	bool				halt;

	/* Indicates if the device is registered as an IO device */
	bool				io_device_registered;

	/* Management process to be continued after IO device unregistration completes */
	struct ftl_mngt_process		*unregister_process;

	/* counters for poller busy, include
	   1. nv cache read/write
	   2. metadata read/write
@@ -99,6 +108,10 @@ struct spdk_ftl_dev {

int ftl_core_poller(void *ctx);

int ftl_io_channel_poll(void *arg);

struct ftl_io_channel *ftl_io_channel_get_ctx(struct spdk_io_channel *ioch);

static inline uint64_t
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
{
@@ -128,6 +141,12 @@ ftl_get_write_unit_size(struct spdk_bdev *bdev)
	return 32;
}

static inline struct spdk_thread *
ftl_get_core_thread(const struct spdk_ftl_dev *dev)
{
	return dev->core_thread;
}

static inline size_t
ftl_get_num_bands(const struct spdk_ftl_dev *dev)
{
+1 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ allocate_dev(const struct spdk_ftl_conf *conf, int *error)

	TAILQ_INIT(&dev->rd_sq);
	TAILQ_INIT(&dev->wr_sq);
	TAILQ_INIT(&dev->ioch_queue);

	return dev;
error:
+11 −3
Original line number Diff line number Diff line
@@ -117,6 +117,9 @@ ftl_io_iovec_len_left(struct ftl_io *io)
static void
ftl_io_cb(struct ftl_io *io, void *arg, int status)
{
	struct ftl_io_channel *ioch = ftl_io_channel_get_ctx(io->ioch);
	size_t result;

	if (spdk_unlikely(status)) {
		io->status = status;

@@ -145,15 +148,20 @@ ftl_io_cb(struct ftl_io *io, void *arg, int status)
		}
	}

	/* User completion added in next patch */
	if (io->map) {
		ftl_mempool_put(ioch->map_pool, io->map);
	}

	result = spdk_ring_enqueue(ioch->cq, (void **)&io, 1, NULL);
	assert(result != 0);
}

int
ftl_io_init(struct spdk_io_channel *_ioch, struct ftl_io *io, uint64_t lba, size_t num_blocks,
	    struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_ctx, int type)
{
	/* dev initialized from io channel context in next patch */
	struct spdk_ftl_dev *dev = NULL;
	struct ftl_io_channel *ioch = ftl_io_channel_get_ctx(_ioch);
	struct spdk_ftl_dev *dev = ioch->dev;

	memset(io, 0, sizeof(struct ftl_io));
	io->ioch = _ioch;
Loading