Commit c11e5c11 authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

bdev: introduce bdev_nvme_cdw12 and cdw13, and add them to ext_opts



nvmf target may directly expose nvme namespace bdevs to hosts. In this
case, we still use bdev APIs for I/O paths - but there is no way to pass
things like NVMe directives with existing APIs.

One option would be to use NVME_PASSTHRU bdev path in this case. But I
think it's better to use the native bdev APIs when possible - otherwise
bdev layer can't do things like QoS, splitting, etc. effectively.

So instead, introduce spdk_bdev_nvme_cdw12 and cdw13. These by convention
match the ones defined by NVMe specification, but allows the flexibility
to be used by bdevs that don't support NVMe.

We then add these cdw12 and cdw13 to the spdk_bdev_ext_io_opts. nvmf
target can use this to pass these values through bdev layer to the
bdev/nvme module.
These will be only be passed through for write commands.

Signed-off-by: default avatarJim Harris <jim.harris@samsung.com>
Signed-off-by: default avatarAnkit Kumar <ankit.kumar@samsung.com>
Change-Id: I238ce5c73581c3f2130da632cbbc3e78628253f0
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/22344


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 037d5165
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -223,6 +223,39 @@ union spdk_bdev_nvme_ctratt {
};
SPDK_STATIC_ASSERT(sizeof(union spdk_bdev_nvme_ctratt) == 4, "Incorrect size");

/**
 * Union for command dword 12, which by convention matches the NVMe command dword 12 definition.
 * This is used to pass NVMe specific fields to bdevs, that reports support for them as indicated
 * by \ref spdk_bdev_get_nvme_ctratt
 */
union spdk_bdev_nvme_cdw12 {
	uint32_t raw;

	struct {
		uint32_t reserved	: 20;
		/* Directive type */
		uint32_t dtype		: 4;
		uint32_t reserved2	: 8;
	} write;
};
SPDK_STATIC_ASSERT(sizeof(union spdk_bdev_nvme_cdw12) == 4, "Incorrect size");

/**
 * Union for command dword 13, which by convention matches the NVMe command dword 13 definition.
 * This is used to pass NVMe specific fields to bdevs, that reports support for them as indicated
 * by \ref spdk_bdev_get_nvme_ctratt
 */
union spdk_bdev_nvme_cdw13 {
	uint32_t raw;

	struct {
		uint32_t reserved	: 16;
		/* Directive specific */
		uint32_t dspec		: 16;
	} write;
};
SPDK_STATIC_ASSERT(sizeof(union spdk_bdev_nvme_cdw13) == 4, "Incorrect size");

/**
 * Structure with optional IO request parameters
 */
@@ -249,8 +282,12 @@ struct spdk_bdev_ext_io_opts {
	 * is set, that flag will be excluded from any DIF operations for this IO.
	 */
	uint32_t dif_check_flags_exclude_mask;
	/** defined by \ref spdk_bdev_nvme_cdw12 */
	union spdk_bdev_nvme_cdw12 nvme_cdw12;
	/** defined by \ref spdk_bdev_nvme_cdw13 */
	union spdk_bdev_nvme_cdw13 nvme_cdw13;
} __attribute__((packed));
SPDK_STATIC_ASSERT(sizeof(struct spdk_bdev_ext_io_opts) == 44, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_bdev_ext_io_opts) == 52, "Incorrect size");

/**
 * Get the options for the bdev module.
+6 −0
Original line number Diff line number Diff line
@@ -840,6 +840,12 @@ struct spdk_bdev_io {
			/** Specify whether each DIF check type is enabled. */
			uint32_t dif_check_flags;

			/** defined by \ref spdk_bdev_nvme_cdw12 */
			union spdk_bdev_nvme_cdw12 nvme_cdw12;

			/** defined by \ref spdk_bdev_nvme_cdw13 */
			union spdk_bdev_nvme_cdw13 nvme_cdw13;

			struct {
				/** Whether the buffer should be populated with the real data */
				uint8_t populate : 1;
+16 −4
Original line number Diff line number Diff line
@@ -413,6 +413,7 @@ static int bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_i
				      uint64_t offset_blocks, uint64_t num_blocks,
				      struct spdk_memory_domain *domain, void *domain_ctx,
				      struct spdk_accel_sequence *seq, uint32_t dif_check_flags,
				      uint32_t nvme_cdw12_raw, uint32_t nvme_cdw13_raw,
				      spdk_bdev_io_completion_cb cb, void *cb_arg);

static int bdev_lock_lba_range(struct spdk_bdev_desc *desc, struct spdk_io_channel *_ch,
@@ -3010,6 +3011,8 @@ bdev_io_split_submit(struct spdk_bdev_io *bdev_io, struct iovec *iov, int iovcnt
						num_blocks, bdev_io->internal.memory_domain,
						bdev_io->internal.memory_domain_ctx, NULL,
						bdev_io->u.bdev.dif_check_flags,
						bdev_io->u.bdev.nvme_cdw12.raw,
						bdev_io->u.bdev.nvme_cdw13.raw,
						bdev_io_split_done, bdev_io);
		break;
	case SPDK_BDEV_IO_TYPE_UNMAP:
@@ -5565,6 +5568,7 @@ bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *
			   uint64_t offset_blocks, uint64_t num_blocks,
			   struct spdk_memory_domain *domain, void *domain_ctx,
			   struct spdk_accel_sequence *seq, uint32_t dif_check_flags,
			   uint32_t nvme_cdw12_raw, uint32_t nvme_cdw13_raw,
			   spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
@@ -5601,6 +5605,8 @@ bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *
	bdev_io->u.bdev.memory_domain_ctx = domain_ctx;
	bdev_io->u.bdev.accel_sequence = seq;
	bdev_io->u.bdev.dif_check_flags = dif_check_flags;
	bdev_io->u.bdev.nvme_cdw12.raw = nvme_cdw12_raw;
	bdev_io->u.bdev.nvme_cdw13.raw = nvme_cdw13_raw;

	_bdev_io_submit_ext(desc, bdev_io);

@@ -5632,7 +5638,8 @@ spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);

	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, NULL, offset_blocks,
					  num_blocks, NULL, NULL, NULL, bdev->dif_check_flags, cb, cb_arg);
					  num_blocks, NULL, NULL, NULL, bdev->dif_check_flags, 0, 0,
					  cb, cb_arg);
}

int
@@ -5652,7 +5659,8 @@ spdk_bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_chan
	}

	return bdev_writev_blocks_with_md(desc, ch, iov, iovcnt, md_buf, offset_blocks,
					  num_blocks, NULL, NULL, NULL, bdev->dif_check_flags, cb, cb_arg);
					  num_blocks, NULL, NULL, NULL, bdev->dif_check_flags, 0, 0,
					  cb, cb_arg);
}

int
@@ -5667,16 +5675,19 @@ spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel
	void *domain_ctx = NULL, *md = NULL;
	uint32_t dif_check_flags = 0;
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
	uint32_t nvme_cdw12_raw = 0;
	uint32_t nvme_cdw13_raw = 0;

	if (opts) {
		if (spdk_unlikely(!_bdev_io_check_opts(opts, iov))) {
			return -EINVAL;
		}

		md = opts->metadata;
		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);
		nvme_cdw13_raw = bdev_get_ext_io_opt(opts, nvme_cdw13.raw, 0);
		if (md) {
			if (spdk_unlikely(!spdk_bdev_is_md_separate(bdev))) {
				return -EINVAL;
@@ -5696,7 +5707,8 @@ spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel
			  ~(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,
					  domain, domain_ctx, seq, dif_check_flags, cb, cb_arg);
					  domain, domain_ctx, seq, dif_check_flags,
					  nvme_cdw12_raw, nvme_cdw13_raw, cb, cb_arg);
}

static void