Commit f7ce1526 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

bdev: Insert or overwrite metadata using bounce/accel buffer if NVMe PRACT is set



spdk_dif_generate_copy() and spdk_dif_verify_copy() already support NVMe
PRACT. Support NVMe PRACT in the generic bdev layer by utilizing these
APIs via accel framework.

Read or write I/O copies pract bit of ext_io_opts to dif_check_flags of
bdev_io. Then, if pract bit is set in dif_check_flags of bdev_io,
allocate bounce/accel buffer and insert/overwrite metadata as same as
no_metadata option. Clear pract bit in dif_check_flags of bdev_io after
appending acccel sequence not to passthrough pract bit to the underlying
bdev module.

Signed-off-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: I56ed4ba9dad677635e36684f93696dec7d90cdb6
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/25437


Community-CI: Mellanox Build Bot
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
parent aa58c9e0
Loading
Loading
Loading
Loading
+39 −5
Original line number Diff line number Diff line
@@ -974,6 +974,16 @@ bdev_desc_get_block_size(struct spdk_bdev_desc *desc)
static inline uint32_t
bdev_io_get_block_size(struct spdk_bdev_io *bdev_io)
{
	struct spdk_bdev *bdev = bdev_io->bdev;

	if (bdev_io->u.bdev.dif_check_flags & SPDK_DIF_FLAGS_NVME_PRACT) {
		if (bdev->md_len == spdk_dif_pi_format_get_size(bdev->dif_pi_format)) {
			return bdev->blocklen - bdev->md_len;
		} else {
			return bdev->blocklen;
		}
	}

	return bdev_desc_get_block_size(bdev_io->internal.desc);
}

@@ -1065,7 +1075,9 @@ _are_iovs_aligned(struct iovec *iovs, int iovcnt, uint32_t alignment)
static inline bool
bdev_io_needs_metadata(struct spdk_bdev_desc *desc, struct spdk_bdev_io *bdev_io)
{
	return desc->opts.hide_metadata && bdev_io->bdev->md_len != 0;
	return (bdev_io->bdev->md_len != 0) &&
	       (desc->opts.hide_metadata ||
		(bdev_io->u.bdev.dif_check_flags & SPDK_DIF_FLAGS_NVME_PRACT));
}

static inline bool
@@ -1332,6 +1344,8 @@ bdev_io_pull_data(struct spdk_bdev_io *bdev_io)
	if (bdev_io_needs_metadata(desc, bdev_io)) {
		assert(bdev_io->bdev->md_interleave);

		bdev_io->u.bdev.dif_check_flags &= ~SPDK_DIF_FLAGS_NVME_PRACT;

		if (!bdev_io_use_accel_sequence(bdev_io)) {
			bdev_io->internal.accel_sequence = NULL;
		}
@@ -5887,6 +5901,7 @@ spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *
	struct spdk_accel_sequence *seq = NULL;
	void *domain_ctx = NULL, *md = NULL;
	uint32_t dif_check_flags = 0;
	uint32_t nvme_cdw12_raw;
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);

	if (opts) {
@@ -5898,6 +5913,7 @@ spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *
		domain = bdev_get_ext_io_opt(opts, memory_domain, NULL);
		domain_ctx = bdev_get_ext_io_opt(opts, memory_domain_ctx, NULL);
		seq = bdev_get_ext_io_opt(opts, accel_sequence, NULL);
		nvme_cdw12_raw = bdev_get_ext_io_opt(opts, nvme_cdw12.raw, 0);
		if (md) {
			if (spdk_unlikely(!spdk_bdev_is_md_separate(bdev))) {
				return -EINVAL;
@@ -5910,10 +5926,19 @@ spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *
			if (spdk_unlikely(seq != NULL)) {
				return -EINVAL;
			}

			if (nvme_cdw12_raw & SPDK_DIF_FLAGS_NVME_PRACT) {
				SPDK_ERRLOG("Separate metadata with NVMe PRACT is not supported.\n");
				return -ENOTSUP;
			}
		}

		if (nvme_cdw12_raw & SPDK_DIF_FLAGS_NVME_PRACT) {
			dif_check_flags |= SPDK_DIF_FLAGS_NVME_PRACT;
		}
	}

	dif_check_flags = bdev->dif_check_flags &
	dif_check_flags |= bdev->dif_check_flags &
			   ~(bdev_get_ext_io_opt(opts, dif_check_flags_exclude_mask, 0));

	return bdev_readv_blocks_with_md(desc, ch, iov, iovcnt, md, offset_blocks,
@@ -6150,10 +6175,19 @@ spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel
			if (spdk_unlikely(seq != NULL)) {
				return -EINVAL;
			}

			if (nvme_cdw12_raw & SPDK_DIF_FLAGS_NVME_PRACT) {
				SPDK_ERRLOG("Separate metadata with NVMe PRACT is not supported.\n");
				return -ENOTSUP;
			}
		}

		if (nvme_cdw12_raw & SPDK_DIF_FLAGS_NVME_PRACT) {
			dif_check_flags |= SPDK_DIF_FLAGS_NVME_PRACT;
		}
	}

	dif_check_flags = bdev->dif_check_flags &
	dif_check_flags |= bdev->dif_check_flags &
			   ~(bdev_get_ext_io_opt(opts, dif_check_flags_exclude_mask, 0));

	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, md, offset_blocks, num_blocks,