Commit 67c9c1c5 authored by Tomasz Kulasek's avatar Tomasz Kulasek Committed by Tomasz Zawadzki
Browse files

lib/nvmf: add fused operations



Change-Id: If3162a5683d1c57011f9a66cbcfe47ba161734bf
Signed-off-by: default avatarTomasz Kulasek <tomaszx.kulasek@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/476138


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>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent adf90938
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -1623,6 +1623,7 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
	cdata->sgls.supported = 1;
	cdata->sgls.keyed_sgl = 1;
	cdata->sgls.sgl_offset = 1;
	cdata->fuses.compare_and_write = 0;
	spdk_strcpy_pad(cdata->subnqn, subsystem->subnqn, sizeof(cdata->subnqn), '\0');

	SPDK_DEBUGLOG(SPDK_LOG_NVMF, "ctrlr data: maxcmd 0x%x\n", cdata->maxcmd);
@@ -2461,6 +2462,33 @@ spdk_nvmf_ctrlr_process_io_cmd(struct spdk_nvmf_request *req)
	response->status.sc = SPDK_NVME_SC_SUCCESS;
	nsid = cmd->nsid;

	if (cmd->fuse == SPDK_NVME_CMD_FUSE_FIRST) {
		/* first fused operation (should be compare) */
		if (req->qpair->first_fused_req != NULL) {
			struct spdk_nvme_cpl *fused_response = &req->qpair->first_fused_req->rsp->nvme_cpl;

			SPDK_ERRLOG("Wrong sequence of fused operations\n");
			/* abort req->qpair->first_fused_request and continue with new fused command */
			fused_response->status.sc = SPDK_NVME_SC_ABORTED_MISSING_FUSED;
			fused_response->status.sct = SPDK_NVME_SCT_GENERIC;
			spdk_nvmf_request_complete(req->qpair->first_fused_req);
		}

		req->qpair->first_fused_req = req;
	} else if (cmd->fuse == SPDK_NVME_CMD_FUSE_SECOND) {
		/* second fused operation */
		if (req->qpair->first_fused_req == NULL) {
			SPDK_ERRLOG("Wrong sequence of fused operations\n");
			response->status.sct = SPDK_NVME_SCT_GENERIC;
			response->status.sc = SPDK_NVME_SC_ABORTED_MISSING_FUSED;
			return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
		}

		/* save request of first command to generate response later */
		req->first_fused_req = req->qpair->first_fused_req;
		req->qpair->first_fused_req = NULL;
	}

	if (spdk_unlikely(ctrlr == NULL)) {
		SPDK_ERRLOG("I/O command sent before CONNECT\n");
		response->status.sct = SPDK_NVME_SCT_GENERIC;
+20 −4
Original line number Diff line number Diff line
@@ -93,13 +93,29 @@ 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;
	int				first_sc, first_sct, second_sc, second_sct;
	uint32_t			cdw0;
	struct spdk_nvmf_request	*first_req = req->first_fused_req;

	if (spdk_unlikely(first_req != NULL)) {
		/* fused commands - get status for both operations */
		struct spdk_nvme_cpl *fused_response = &first_req->rsp->nvme_cpl;

		spdk_bdev_io_get_nvme_fused_status(bdev_io, &cdw0, &second_sct, &second_sc, &first_sct, &first_sc);
		fused_response->cdw0 = cdw0;
		fused_response->status.sc = second_sc;
		fused_response->status.sct = second_sct;

		/* first request should be completed */
		spdk_nvmf_request_complete(first_req);
		req->first_fused_req = NULL;
	} else {
		spdk_bdev_io_get_nvme_status(bdev_io, &cdw0, &first_sct, &first_sc);
	}

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

	spdk_nvmf_request_complete(req);
	spdk_bdev_free_io(bdev_io);
+3 −0
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@ struct spdk_nvmf_request {
	struct spdk_bdev_io_wait_entry	bdev_io_wait;
	struct spdk_nvmf_dif_info	dif;
	spdk_nvmf_nvme_passthru_cmd_cb	cmd_cb_fn;
	struct spdk_nvmf_request	*first_fused_req;

	STAILQ_ENTRY(spdk_nvmf_request)	buf_link;
	TAILQ_ENTRY(spdk_nvmf_request)	link;
@@ -273,6 +274,8 @@ struct spdk_nvmf_qpair {
	uint16_t				sq_head;
	uint16_t				sq_head_max;

	struct spdk_nvmf_request		*first_fused_req;

	TAILQ_HEAD(, spdk_nvmf_request)		outstanding;
	TAILQ_ENTRY(spdk_nvmf_qpair)		link;
};