Commit 843f296e authored by Wojciech Malikowski's avatar Wojciech Malikowski Committed by Tomasz Zawadzki
Browse files

lib/ftl: Replace Open Channel dependencies with zone bdev API



This patch replaces NVMe Open Channel API usage
inside FTL library with corresponding zone bdev
API calls. This include following calls:
 - spdk_nvme_ctrlr_cmd_get_log_page -> spdk_bdev_get_zone_info
 - spdk_nvme_ocssd_ns_cmd_vector_reset -> spdk_bdev_zone_management
 - spdk_nvme_ns_cmd_read -> spdk_bdev_read_blocks
 - spdk_nvme_ns_cmd_write_with_md -> spdk_bdev_write_blocks

Change-Id: I1b5a6863d9ce72f4af1cfbb0e449fc1a5b638144
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479702


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 0178395e
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -35,8 +35,6 @@
#define SPDK_FTL_H

#include "spdk/stdinc.h"
#include "spdk/nvme.h"
#include "spdk/nvme_ocssd.h"
#include "spdk/uuid.h"
#include "spdk/thread.h"
#include "spdk/bdev.h"
@@ -109,10 +107,8 @@ enum spdk_ftl_mode {
};

struct spdk_ftl_dev_init_opts {
	/* NVMe controller */
	struct spdk_nvme_ctrlr			*ctrlr;
	/* Controller's transport ID */
	struct spdk_nvme_transport_id		trid;
	/* Underlying device */
	struct spdk_bdev_desc			*base_bdev_desc;
	/* Write buffer cache */
	struct spdk_bdev_desc			*cache_bdev_desc;

@@ -155,8 +151,7 @@ typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *, void *, int);
 * Initialize the FTL on given NVMe device and parallel unit range.
 *
 * Covers the following:
 * - initialize and register NVMe ctrlr,
 * - retrieve geometry and check if the device has proper configuration,
 * - retrieve zone device information,
 * - allocate buffers and resources,
 * - initialize internal structures,
 * - initialize internal thread(s),
+0 −18
Original line number Diff line number Diff line
@@ -80,22 +80,4 @@ struct ftl_addr {
	};
};

struct ftl_ppa_fmt {
	/* Logical block */
	unsigned int				lbk_offset;
	unsigned int				lbk_mask;

	/* Chunk */
	unsigned int				chk_offset;
	unsigned int				chk_mask;

	/* Parallel unit (NAND die) */
	unsigned int				pu_offset;
	unsigned int				pu_mask;

	/* Group */
	unsigned int				grp_offset;
	unsigned int				grp_mask;
};

#endif /* FTL_ADDR_H */
+36 −29
Original line number Diff line number Diff line
@@ -161,12 +161,12 @@ ftl_remove_wptr(struct ftl_wptr *wptr)
}

static void
ftl_io_cmpl_cb(void *arg, const struct spdk_nvme_cpl *status)
ftl_io_cmpl_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
	struct ftl_io *io = arg;
	struct ftl_io *io = cb_arg;

	if (spdk_nvme_cpl_is_error(status)) {
		ftl_io_process_error(io, status);
	if (spdk_unlikely(!success)) {
		io->status = -EIO;
	}

	ftl_trace_completion(io->dev, io, FTL_TRACE_COMPLETION_DISK);
@@ -175,6 +175,8 @@ ftl_io_cmpl_cb(void *arg, const struct spdk_nvme_cpl *status)
	if (ftl_io_done(io)) {
		ftl_io_complete(io);
	}

	spdk_bdev_free_io(bdev_io);
}

static void
@@ -340,11 +342,13 @@ ftl_submit_erase(struct ftl_io *io)
	struct spdk_ftl_dev *dev = io->dev;
	struct ftl_band *band = io->band;
	struct ftl_addr addr = io->addr;
	struct ftl_io_channel *ioch;
	struct ftl_zone *zone;
	uint64_t addr_packed;
	int rc = 0;
	size_t i;

	ioch = spdk_io_channel_get_ctx(ftl_get_io_channel(dev));

	for (i = 0; i < io->lbk_cnt; ++i) {
		if (i != 0) {
			zone = ftl_band_next_zone(band, ftl_band_zone_from_addr(band, addr));
@@ -353,11 +357,11 @@ ftl_submit_erase(struct ftl_io *io)
		}

		assert(addr.offset == 0);
		addr_packed = ftl_addr_addr_pack(dev, addr);

		ftl_trace_submission(dev, io, addr, 1);
		rc = spdk_nvme_ocssd_ns_cmd_vector_reset(dev->ns, ftl_get_write_qpair(dev),
				&addr_packed, 1, NULL, ftl_io_cmpl_cb, io);
		rc = spdk_bdev_zone_management(dev->base_bdev_desc, ioch->base_ioch,
					       ftl_block_offset_from_addr(dev, addr),
					       SPDK_BDEV_ZONE_RESET, ftl_io_cmpl_cb, io);
		if (spdk_unlikely(rc)) {
			ftl_io_fail(io, rc);
			SPDK_ERRLOG("Vector reset failed with status: %d\n", rc);
@@ -957,7 +961,8 @@ ftl_read_next_logical_addr(struct ftl_io *io, struct ftl_addr *addr)
			break;
		}

		if (ftl_addr_addr_pack(dev, *addr) + i != ftl_addr_addr_pack(dev, next_addr)) {
		if (ftl_block_offset_from_addr(dev, *addr) + i !=
		    ftl_block_offset_from_addr(dev, next_addr)) {
			break;
		}
	}
@@ -969,9 +974,12 @@ static int
ftl_submit_read(struct ftl_io *io)
{
	struct spdk_ftl_dev *dev = io->dev;
	struct ftl_io_channel *ioch;
	struct ftl_addr addr;
	int rc = 0, lbk_cnt;

	ioch = spdk_io_channel_get_ctx(io->ioch);

	assert(LIST_EMPTY(&io->children));

	while (io->pos < io->lbk_cnt) {
@@ -1000,10 +1008,10 @@ ftl_submit_read(struct ftl_io *io)
		assert(lbk_cnt > 0);

		ftl_trace_submission(dev, io, addr, lbk_cnt);
		rc = spdk_nvme_ns_cmd_read(dev->ns, ftl_get_read_qpair(dev),
		rc = spdk_bdev_read_blocks(dev->base_bdev_desc, ioch->base_ioch,
					   ftl_io_iovec_addr(io),
					   ftl_addr_addr_pack(io->dev, addr), lbk_cnt,
					   ftl_io_cmpl_cb, io, 0);
					   ftl_block_offset_from_addr(dev, addr),
					   lbk_cnt, ftl_io_cmpl_cb, io);
		if (spdk_unlikely(rc)) {
			if (rc == -ENOMEM) {
				ftl_add_to_retry_queue(io);
@@ -1496,9 +1504,12 @@ static int
ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
{
	struct spdk_ftl_dev	*dev = io->dev;
	struct ftl_io_channel	*ioch;
	struct ftl_io		*child;
	int			rc;
	struct ftl_addr		addr;
	int			rc;

	ioch = spdk_io_channel_get_ctx(io->ioch);

	if (spdk_likely(!wptr->direct_mode)) {
		addr = wptr->addr;
@@ -1516,15 +1527,16 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
	}

	wptr->num_outstanding++;
	rc = spdk_nvme_ns_cmd_write_with_md(dev->ns, ftl_get_write_qpair(dev),
					    ftl_io_iovec_addr(child), child->md,
					    ftl_addr_addr_pack(dev, addr),
					    lbk_cnt, ftl_io_cmpl_cb, child, 0, 0, 0);

	rc = spdk_bdev_write_blocks(dev->base_bdev_desc, ioch->base_ioch,
				    ftl_io_iovec_addr(child),
				    ftl_block_offset_from_addr(dev, addr),
				    lbk_cnt, ftl_io_cmpl_cb, child);
	if (rc) {
		wptr->num_outstanding--;
		ftl_io_fail(child, rc);
		ftl_io_complete(child);
		SPDK_ERRLOG("spdk_nvme_ns_cmd_write_with_md failed with status:%d, addr:%lu\n",
		SPDK_ERRLOG("spdk_bdev_write_blocks_with_md failed with status:%d, addr:%lu\n",
			    rc, addr.addr);
		return -EIO;
	}
@@ -1676,7 +1688,7 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
	}

	SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write addr:%lx, %lx\n", wptr->addr.addr,
		      ftl_addr_addr_pack(dev, wptr->addr));
		      ftl_block_offset_from_addr(dev, wptr->addr));

	if (ftl_submit_write(wptr, io)) {
		/* TODO: we need some recovery here */
@@ -1887,8 +1899,8 @@ spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *at
	attrs->lbk_cnt = dev->num_lbas;
	attrs->lbk_size = FTL_BLOCK_SIZE;
	attrs->cache_bdev_desc = dev->nv_cache.bdev_desc;
	attrs->num_zones = dev->geo.num_chk;
	attrs->zone_size = dev->geo.clba;
	attrs->num_zones = ftl_get_num_zones(dev);
	attrs->zone_size = ftl_get_num_blocks_in_zone(dev);
	attrs->conf = dev->conf;
}

@@ -2154,8 +2166,6 @@ ftl_task_read(void *ctx)
{
	struct ftl_thread *thread = ctx;
	struct spdk_ftl_dev *dev = thread->dev;
	struct spdk_nvme_qpair *qpair = ftl_get_read_qpair(dev);
	size_t num_completed;

	if (dev->halt) {
		if (ftl_shutdown_complete(dev)) {
@@ -2164,13 +2174,12 @@ ftl_task_read(void *ctx)
		}
	}

	num_completed = spdk_nvme_qpair_process_completions(qpair, 0);

	if (num_completed && !TAILQ_EMPTY(&dev->retry_queue)) {
	if (!TAILQ_EMPTY(&dev->retry_queue)) {
		ftl_process_retry_queue(dev);
		return 1;
	}

	return num_completed;
	return 0;
}

int
@@ -2178,7 +2187,6 @@ ftl_task_core(void *ctx)
{
	struct ftl_thread *thread = ctx;
	struct spdk_ftl_dev *dev = thread->dev;
	struct spdk_nvme_qpair *qpair = ftl_get_write_qpair(dev);

	if (dev->halt) {
		if (ftl_shutdown_complete(dev)) {
@@ -2188,7 +2196,6 @@ ftl_task_core(void *ctx)
	}

	ftl_process_writes(dev);
	spdk_nvme_qpair_process_completions(qpair, 0);
	ftl_process_relocs(dev);

	return 0;
+51 −81
Original line number Diff line number Diff line
@@ -35,8 +35,6 @@
#define FTL_CORE_H

#include "spdk/stdinc.h"
#include "spdk/nvme.h"
#include "spdk/nvme_ocssd.h"
#include "spdk/uuid.h"
#include "spdk/thread.h"
#include "spdk/util.h"
@@ -45,6 +43,7 @@
#include "spdk/queue.h"
#include "spdk/ftl.h"
#include "spdk/bdev.h"
#include "spdk/bdev_zone.h"

#include "ftl_addr.h"
#include "ftl_io.h"
@@ -78,8 +77,6 @@ struct ftl_stats {
struct ftl_thread {
	/* Owner */
	struct spdk_ftl_dev			*dev;
	/* I/O queue pair */
	struct spdk_nvme_qpair			*qpair;

	/* Thread on which the poller is running */
	struct spdk_thread			*thread;
@@ -158,12 +155,8 @@ struct spdk_ftl_dev {
	/* Destruction context */
	struct ftl_init_context			fini_ctx;

	/* NVMe controller */
	struct spdk_nvme_ctrlr			*ctrlr;
	/* NVMe namespace */
	struct spdk_nvme_ns			*ns;
	/* NVMe transport ID */
	struct spdk_nvme_transport_id		trid;
	/* Underlying device */
	struct spdk_bdev_desc			*base_bdev_desc;

	/* Non-volatile write buffer cache */
	struct ftl_nv_cache			nv_cache;
@@ -201,12 +194,8 @@ struct spdk_ftl_dev {
	/* Size of the l2p table */
	uint64_t				num_lbas;

	/* PPA format */
	struct ftl_ppa_fmt			ppaf;
	/* Address size */
	size_t					addr_len;
	/* Device's geometry */
	struct spdk_ocssd_geometry_data		geo;

	/* Flush list */
	LIST_HEAD(, ftl_flush)			flush_list;
@@ -279,9 +268,6 @@ int ftl_restore_md(struct spdk_ftl_dev *dev, ftl_restore_fn cb);
int	ftl_restore_device(struct ftl_restore *restore, ftl_restore_fn cb);
void	ftl_restore_nv_cache(struct ftl_restore *restore, ftl_restore_fn cb);
int	ftl_band_set_direct_access(struct ftl_band *band, bool access);
int	ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_addr addr,
				struct spdk_ocssd_chunk_information_entry *info,
				unsigned int num_entries);
bool	ftl_addr_is_written(struct ftl_band *band, struct ftl_addr addr);
int	ftl_flush_active_bands(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg);
int	ftl_nv_cache_write_header(struct ftl_nv_cache *nv_cache, bool shutdown,
@@ -304,22 +290,46 @@ ftl_get_core_thread(const struct spdk_ftl_dev *dev)
	return dev->core_thread.thread;
}

static inline struct spdk_nvme_qpair *
ftl_get_write_qpair(const struct spdk_ftl_dev *dev)
{
	return dev->core_thread.qpair;
}

static inline struct spdk_thread *
ftl_get_read_thread(const struct spdk_ftl_dev *dev)
{
	return dev->read_thread.thread;
}

static inline struct spdk_nvme_qpair *
ftl_get_read_qpair(const struct spdk_ftl_dev *dev)
static inline size_t
ftl_get_num_bands(const struct spdk_ftl_dev *dev)
{
	return dev->read_thread.qpair;
	return dev->num_bands;
}

static inline size_t
ftl_get_num_punits(const struct spdk_ftl_dev *dev)
{
	return spdk_bdev_get_optimal_open_zones(spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
}

static inline size_t
ftl_get_num_zones(const struct spdk_ftl_dev *dev)
{
	return ftl_get_num_bands(dev) * ftl_get_num_punits(dev);
}

static inline size_t
ftl_get_num_blocks_in_zone(const struct spdk_ftl_dev *dev)
{
	return spdk_bdev_get_zone_size(spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
}

static inline uint64_t
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
{
	return ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev);
}

static inline size_t
ftl_vld_map_size(const struct spdk_ftl_dev *dev)
{
	return (size_t)spdk_divide_round_up(ftl_get_num_blocks_in_band(dev), CHAR_BIT);
}

static inline int
@@ -340,35 +350,25 @@ ftl_addr_cached(struct ftl_addr addr)
	return !ftl_addr_invalid(addr) && addr.cached;
}

static inline uint64_t
ftl_addr_addr_pack(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
static inline struct ftl_addr
ftl_addr_from_block_offset(const struct spdk_ftl_dev *dev, uint64_t offset)
{
	uint64_t lbk, chk, pu, grp;
	struct ftl_addr addr = {};
	uint64_t zone_num;

	lbk = addr.offset;
	chk = addr.zone_id;
	pu = addr.pu / dev->geo.num_grp;
	grp = addr.pu % dev->geo.num_grp;
	addr.offset = offset % ftl_get_num_blocks_in_zone(dev);
	zone_num = offset / ftl_get_num_blocks_in_zone(dev);
	addr.pu = zone_num % ftl_get_num_punits(dev);
	addr.zone_id = zone_num / ftl_get_num_punits(dev);

	return (lbk << dev->ppaf.lbk_offset) |
	       (chk << dev->ppaf.chk_offset) |
	       (pu  << dev->ppaf.pu_offset) |
	       (grp << dev->ppaf.grp_offset);
	return addr;
}

static inline struct ftl_addr
ftl_addr_addr_unpack(const struct spdk_ftl_dev *dev, uint64_t addr)
static inline uint64_t
ftl_block_offset_from_addr(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
{
	struct ftl_addr res = {};
	unsigned int pu, grp;

	res.offset = (addr >> dev->ppaf.lbk_offset) & dev->ppaf.lbk_mask;
	res.zone_id = (addr >> dev->ppaf.chk_offset) & dev->ppaf.chk_mask;
	pu  = (addr >> dev->ppaf.pu_offset)  & dev->ppaf.pu_mask;
	grp = (addr >> dev->ppaf.grp_offset) & dev->ppaf.grp_mask;
	res.pu = grp * dev->geo.num_pu + pu;

	return res;
	return (addr.zone_id * ftl_get_num_punits(dev) + addr.pu) *
	       ftl_get_num_blocks_in_zone(dev) + addr.offset;
}

static inline struct ftl_addr
@@ -382,7 +382,7 @@ ftl_addr_to_packed(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
		p.pack.cached = 1;
		p.pack.cache_offset = (uint32_t) addr.cache_offset;
	} else {
		p.pack.addr = (uint32_t) ftl_addr_addr_pack(dev, addr);
		p.pack.addr = (uint32_t) ftl_block_offset_from_addr(dev, addr);
	}

	return p;
@@ -399,7 +399,7 @@ ftl_addr_from_packed(const struct spdk_ftl_dev *dev, struct ftl_addr p)
		addr.cached = 1;
		addr.cache_offset = p.pack.cache_offset;
	} else {
		addr = ftl_addr_addr_unpack(dev, p.pack.addr);
		addr = ftl_addr_from_block_offset(dev, p.pack.addr);
	}

	return addr;
@@ -450,36 +450,6 @@ ftl_l2p_get(struct spdk_ftl_dev *dev, uint64_t lba)
		return ftl_to_addr(_ftl_l2p_get64(dev->l2p, lba));
	}
}
static inline size_t
ftl_get_num_bands(const struct spdk_ftl_dev *dev)
{
	return dev->geo.num_chk;
}

static inline size_t
ftl_get_num_blocks_in_zone(const struct spdk_ftl_dev *dev)
{
	return dev->geo.clba;
}

static inline size_t
ftl_get_num_punits(const struct spdk_ftl_dev *dev)
{
	return dev->geo.num_pu * dev->geo.num_grp;
}

static inline uint64_t
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
{
	return ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev);
}

static inline size_t
ftl_vld_map_size(const struct spdk_ftl_dev *dev)
{
	return (size_t)spdk_divide_round_up(ftl_get_num_blocks_in_band(dev), CHAR_BIT);
}

static inline bool
ftl_dev_has_nv_cache(const struct spdk_ftl_dev *dev)
{
+319 −342

File changed.

Preview size limit exceeded, changes collapsed.

Loading