Commit 5a8a57c1 authored by Mateusz Kozlowski's avatar Mateusz Kozlowski Committed by Konrad Sztyber
Browse files

lib/ftl: Add nv cache write to vss cache device



Change-Id: I6759b0c539eb0e410437f75366244e5ffc9ec2af
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@solidigm.com>
Signed-off-by: default avatarMariusz Barczak <Mariusz.Barczak@solidigmtechnology.com>
Signed-off-by: default avatarMateusz Kozlowski <mateusz.kozlowski@solidigm.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19610


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent f74d16be
Loading
Loading
Loading
Loading
+16 −55
Original line number Diff line number Diff line
@@ -1159,7 +1159,6 @@ ftl_nv_cache_submit_cb_done(struct ftl_io *io)
	chunk_advance_blocks(nv_cache, io->nv_cache_chunk, io->num_blocks);
	io->nv_cache_chunk = NULL;

	ftl_mempool_put(nv_cache->md_pool, io->md);
	ftl_io_complete(io);
}

@@ -1178,51 +1177,6 @@ ftl_nv_cache_l2p_update(struct ftl_io *io)
	ftl_nv_cache_submit_cb_done(io);
}

static void
ftl_nv_cache_submit_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
	struct ftl_io *io = cb_arg;

	ftl_stats_bdev_io_completed(io->dev, FTL_STATS_TYPE_USER, bdev_io);

	spdk_bdev_free_io(bdev_io);

	if (spdk_unlikely(!success)) {
		FTL_ERRLOG(io->dev, "Non-volatile cache write failed at %"PRIx64"\n",
			   io->addr);
		io->status = -EIO;
		ftl_l2p_unpin(io->dev, io->lba, io->num_blocks);
		ftl_nv_cache_submit_cb_done(io);
	} else {
		ftl_nv_cache_l2p_update(io);
	}
}

static void
nv_cache_write(void *_io)
{
	struct ftl_io *io = _io;
	struct spdk_ftl_dev *dev = io->dev;
	struct ftl_nv_cache *nv_cache = &dev->nv_cache;
	int rc;

	rc = spdk_bdev_writev_blocks_with_md(nv_cache->bdev_desc, nv_cache->cache_ioch,
					     io->iov, io->iov_cnt, io->md,
					     ftl_addr_to_nvc_offset(dev, io->addr), io->num_blocks,
					     ftl_nv_cache_submit_cb, io);
	if (spdk_unlikely(rc)) {
		if (rc == -ENOMEM) {
			struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
			io->bdev_io_wait.bdev = bdev;
			io->bdev_io_wait.cb_fn = nv_cache_write;
			io->bdev_io_wait.cb_arg = io;
			spdk_bdev_queue_io_wait(bdev, nv_cache->cache_ioch, &io->bdev_io_wait);
		} else {
			ftl_abort();
		}
	}
}

static void
ftl_nv_cache_pin_cb(struct spdk_ftl_dev *dev, int status, struct ftl_l2p_pin_ctx *pin_ctx)
{
@@ -1247,7 +1201,22 @@ ftl_nv_cache_pin_cb(struct spdk_ftl_dev *dev, int status, struct ftl_l2p_pin_ctx

	ftl_trace_submission(io->dev, io, io->addr, io->num_blocks);

	nv_cache_write(io);
	dev->nv_cache.nvc_type->ops.write(io);
}

void
ftl_nv_cache_write_complete(struct ftl_io *io, bool success)
{
	if (spdk_unlikely(!success)) {
		FTL_ERRLOG(io->dev, "Non-volatile cache write failed at %"PRIx64"\n",
			   io->addr);
		io->status = -EIO;
		ftl_l2p_unpin(io->dev, io->lba, io->num_blocks);
		ftl_nv_cache_submit_cb_done(io);
		return;
	}

	ftl_nv_cache_l2p_update(io);
}

bool
@@ -1256,22 +1225,14 @@ ftl_nv_cache_write(struct ftl_io *io)
	struct spdk_ftl_dev *dev = io->dev;
	uint64_t cache_offset;

	io->md = ftl_mempool_get(dev->nv_cache.md_pool);
	if (spdk_unlikely(!io->md)) {
		return false;
	}

	/* Reserve area on the write buffer cache */
	cache_offset = ftl_nv_cache_get_wr_buffer(&dev->nv_cache, io);
	if (cache_offset == FTL_LBA_INVALID) {
		/* No free space in NV cache, resubmit request */
		ftl_mempool_put(dev->nv_cache.md_pool, io->md);
		return false;
	}
	io->addr = ftl_addr_from_nvc_offset(dev, cache_offset);
	io->nv_cache_chunk = dev->nv_cache.chunk_current;

	ftl_nv_cache_fill_md(io);
	ftl_l2p_pin(io->dev, io->lba, io->num_blocks,
		    ftl_nv_cache_pin_cb, io,
		    &io->l2p_pin_ctx);
+1 −0
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ void ftl_nv_cache_scrub(struct spdk_ftl_dev *dev, nvc_scrub_cb cb, void *cb_ctx)
int ftl_nv_cache_init(struct spdk_ftl_dev *dev);
void ftl_nv_cache_deinit(struct spdk_ftl_dev *dev);
bool ftl_nv_cache_write(struct ftl_io *io);
void ftl_nv_cache_write_complete(struct ftl_io *io, bool success);
void ftl_nv_cache_fill_md(struct ftl_io *io);
int ftl_nv_cache_read(struct ftl_io *io, ftl_addr addr, uint32_t num_blocks,
		      spdk_bdev_io_completion_cb cb, void *cb_arg);
+60 −0
Original line number Diff line number Diff line
@@ -117,6 +117,65 @@ md_region_open(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, u
	return 0;
}

static void
write_io_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
	struct ftl_io *io = cb_arg;
	struct ftl_nv_cache *nv_cache = &io->dev->nv_cache;

	ftl_stats_bdev_io_completed(io->dev, FTL_STATS_TYPE_USER, bdev_io);

	spdk_bdev_free_io(bdev_io);

	ftl_mempool_put(nv_cache->md_pool, io->md);

	ftl_nv_cache_write_complete(io, success);
}

static void write_io(struct ftl_io *io);

static void
_nvc_vss_write(void *io)
{
	write_io(io);
}

static void
write_io(struct ftl_io *io)
{
	struct spdk_ftl_dev *dev = io->dev;
	struct ftl_nv_cache *nv_cache = &dev->nv_cache;
	int rc;

	io->md = ftl_mempool_get(dev->nv_cache.md_pool);
	if (spdk_unlikely(!io->md)) {
		ftl_abort();
	}

	ftl_nv_cache_fill_md(io);

	rc = spdk_bdev_writev_blocks_with_md(nv_cache->bdev_desc, nv_cache->cache_ioch,
					     io->iov, io->iov_cnt, io->md,
					     ftl_addr_to_nvc_offset(dev, io->addr), io->num_blocks,
					     write_io_cb, io);
	if (spdk_unlikely(rc)) {
		if (rc == -ENOMEM) {
			struct spdk_bdev *bdev;

			ftl_mempool_put(nv_cache->md_pool, io->md);
			io->md = NULL;

			bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
			io->bdev_io_wait.bdev = bdev;
			io->bdev_io_wait.cb_fn = _nvc_vss_write;
			io->bdev_io_wait.cb_arg = io;
			spdk_bdev_queue_io_wait(bdev, nv_cache->cache_ioch, &io->bdev_io_wait);
		} else {
			ftl_abort();
		}
	}
}

struct ftl_nv_cache_device_type nvc_bdev_vss = {
	.name = "bdev",
	.features = {
@@ -128,6 +187,7 @@ struct ftl_nv_cache_device_type nvc_bdev_vss = {
			.region_create = md_region_create,
			.region_open = md_region_open,
		},
		.write = write_io,
	}
};
FTL_NV_CACHE_DEVICE_TYPE_REGISTER(nvc_bdev_vss)
+9 −1
Original line number Diff line number Diff line
@@ -10,8 +10,8 @@
#include "ftl_layout.h"

struct spdk_ftl_dev;
struct ftl_mngt_process;
struct ftl_nv_cache_chunk;
struct ftl_io;

/**
 * @brief NV Cache device features and capabilities
@@ -48,6 +48,14 @@ struct ftl_nv_cache_device_ops {
	 */
	bool (*is_chunk_active)(struct spdk_ftl_dev *dev, uint64_t chunk_offset);

	/**
	 * @brief Write user IO to the NV cache device
	 *
	 * @param io FTL IO
	 *
	 */
	void (*write)(struct ftl_io *io);

	struct ftl_md_layout_ops md_layout_ops;
};