Commit 53b92a6c authored by Michael Haeuptle's avatar Michael Haeuptle Committed by Jim Harris
Browse files

nvme: allow setting of completion queue CDW0



This change allows setting of the NVMe completion queue
CDW0 in spdk_bdev_io_complete_nvme_status.

Before that change, handling of vendor specific NVMe IO
commands was limited since there wasn't a way to return
command specific info back to the initiator.

Change-Id: I250d5df3bd1e62ddb89a011503d42bd4c8390f9b
Signed-off-by: default avatarMichael Haeuptle <michael.haeuptle@hpe.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470678


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 2ec99ada
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -2,6 +2,13 @@

## v19.10: (Upcoming Release)

### bdev

Added new parameter `cdw0` to `spdk_bdev_io_complete_nvme_status()` and
`spdk_bdev_io_get_nvme_status()` that allows setting/getting
the NVMe completion queue DW0 entry. This allows vendor specific IO commands
to return commmand specific completion info back to the initiator.

### bdev zone

Added new public header for zoned bdev. Zoned bdev is an extension
+5 −2
Original line number Diff line number Diff line
@@ -1359,13 +1359,16 @@ void spdk_bdev_get_device_stat(struct spdk_bdev *bdev, struct spdk_bdev_io_stat
			       spdk_bdev_get_device_stat_cb cb, void *cb_arg);

/**
 * Get the status of bdev_io as an NVMe status code.
 * Get the status of bdev_io as an NVMe status code and command specific
 * completion queue value.
 *
 * \param bdev_io I/O to get the status from.
 * \param cdw0 Command specific completion queue value
 * \param sct Status Code Type return value, as defined by the NVMe specification.
 * \param sc Status Code return value, as defined by the NVMe specification.
 */
void spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, int *sct, int *sc);
void spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0, int *sct,
				  int *sc);

/**
 * Get the status of bdev_io as a SCSI status code.
+6 −3
Original line number Diff line number Diff line
@@ -556,8 +556,9 @@ struct spdk_bdev_io {

		/** Error information from a device */
		union {
			/** Only valid when status is SPDK_BDEV_IO_STATUS_NVME_ERROR */
			struct {
				/** NVMe completion queue entry DW0 */
				uint32_t cdw0;
				/** NVMe status code type */
				uint8_t sct;
				/** NVMe status code */
@@ -817,13 +818,15 @@ void spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io,
			   enum spdk_bdev_io_status status);

/**
 * Complete a bdev_io with an NVMe status code.
 * Complete a bdev_io with an NVMe status code and DW0 completion queue entry
 *
 * \param bdev_io I/O to complete.
 * \param cdw0 NVMe Completion Queue DW0 value (set to 0 if not applicable)
 * \param sct NVMe Status Code Type.
 * \param sc NVMe Status Code.
 */
void spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io *bdev_io, int sct, int sc);
void spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io *bdev_io, uint32_t cdw0, int sct,
				       int sc);

/**
 * Complete a bdev_io with a SCSI status code.
+11 −4
Original line number Diff line number Diff line
@@ -1917,6 +1917,7 @@ spdk_bdev_io_init(struct spdk_bdev_io *bdev_io,
	bdev_io->internal.orig_iovs = NULL;
	bdev_io->internal.orig_iovcnt = 0;
	bdev_io->internal.orig_md_buf = NULL;
	bdev_io->internal.error.nvme.cdw0 = 0;
}

static bool
@@ -3710,6 +3711,7 @@ _spdk_bdev_ch_retry_io(struct spdk_bdev_channel *bdev_ch)
		bdev_io->internal.ch->io_outstanding++;
		shared_resource->io_outstanding++;
		bdev_io->internal.status = SPDK_BDEV_IO_STATUS_PENDING;
		bdev_io->internal.error.nvme.cdw0 = 0;
		bdev->fn_table->submit_request(spdk_bdev_io_get_io_channel(bdev_io), bdev_io);
		if (bdev_io->internal.status == SPDK_BDEV_IO_STATUS_NOMEM) {
			break;
@@ -3933,24 +3935,27 @@ spdk_bdev_io_get_scsi_status(const struct spdk_bdev_io *bdev_io,
}

void
spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io *bdev_io, int sct, int sc)
spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io *bdev_io, uint32_t cdw0, int sct, int sc)
{
	if (sct == SPDK_NVME_SCT_GENERIC && sc == SPDK_NVME_SC_SUCCESS) {
		bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
	} else {
		bdev_io->internal.error.nvme.sct = sct;
		bdev_io->internal.error.nvme.sc = sc;
		bdev_io->internal.status = SPDK_BDEV_IO_STATUS_NVME_ERROR;
	}

	bdev_io->internal.error.nvme.cdw0 = cdw0;
	bdev_io->internal.error.nvme.sct = sct;
	bdev_io->internal.error.nvme.sc = sc;

	spdk_bdev_io_complete(bdev_io, bdev_io->internal.status);
}

void
spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, int *sct, int *sc)
spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0, int *sct, int *sc)
{
	assert(sct != NULL);
	assert(sc != NULL);
	assert(cdw0 != NULL);

	if (bdev_io->internal.status == SPDK_BDEV_IO_STATUS_NVME_ERROR) {
		*sct = bdev_io->internal.error.nvme.sct;
@@ -3962,6 +3967,8 @@ spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, int *sct, int *
		*sct = SPDK_NVME_SCT_GENERIC;
		*sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
	}

	*cdw0 = bdev_io->internal.error.nvme.cdw0;
}

struct spdk_thread *
+6 −2
Original line number Diff line number Diff line
@@ -93,8 +93,10 @@ nvmf_bdev_ctrlr_complete_cmd(struct spdk_bdev_io *bdev_io, bool success,
	struct spdk_nvmf_request	*req = cb_arg;
	struct spdk_nvme_cpl		*response = &req->rsp->nvme_cpl;
	int				sc, sct;
	uint32_t			cdw0;

	spdk_bdev_io_get_nvme_status(bdev_io, &sct, &sc);
	spdk_bdev_io_get_nvme_status(bdev_io, &cdw0, &sct, &sc);
	response->cdw0 = cdw0;
	response->status.sc = sc;
	response->status.sct = sct;

@@ -386,12 +388,14 @@ nvmf_bdev_ctrlr_unmap_cpl(struct spdk_bdev_io *bdev_io, bool success,
	struct spdk_nvmf_request	*req = unmap_ctx->req;
	struct spdk_nvme_cpl		*response = &req->rsp->nvme_cpl;
	int				sc, sct;
	uint32_t			cdw0;

	unmap_ctx->count--;

	if (response->status.sct == SPDK_NVME_SCT_GENERIC &&
	    response->status.sc == SPDK_NVME_SC_SUCCESS) {
		spdk_bdev_io_get_nvme_status(bdev_io, &sct, &sc);
		spdk_bdev_io_get_nvme_status(bdev_io, &cdw0, &sct, &sc);
		response->cdw0 = cdw0;
		response->status.sc = sc;
		response->status.sct = sct;
	}
Loading