Commit 9ccef490 authored by Jacek Kalwas's avatar Jacek Kalwas Committed by Tomasz Zawadzki
Browse files

nvme/tcp: fix seq failure handling



In case sequence failure happen pdu_write_fail -> pdu_write_done were
called with non 0 status which led to qpair disconnection. Such handling
is contagious in the way all outstanding requests are affected. This is
rather last option to recover from critical error. With current solution
only given request will be terminated with internal device error status
propagated.

Change-Id: I4429d2eec6107bbe4d3711befd64c648badb4756
Signed-off-by: default avatarJacek Kalwas <jacek.kalwas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23360


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
parent 2a268d7a
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -484,6 +484,17 @@ pdu_write_fail(struct nvme_tcp_pdu *pdu, int status)
	pdu_write_done(pdu, status);
}

static void
pdu_seq_fail(struct nvme_tcp_pdu *pdu, int status)
{
	struct nvme_tcp_req *treq = pdu->req;

	SPDK_ERRLOG("Failed to execute accel sequence: %d\n", status);
	nvme_tcp_cond_schedule_qpair_polling(pdu->qpair);
	treq->rsp.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
	nvme_tcp_req_complete(treq, treq->tqpair, &treq->rsp, true);
}

static void
_tcp_write_pdu(struct nvme_tcp_pdu *pdu)
{
@@ -518,8 +529,7 @@ tcp_write_pdu_seq_cb(void *ctx, int status)

	req->accel_sequence = NULL;
	if (spdk_unlikely(status != 0)) {
		SPDK_ERRLOG("Failed to execute accel sequence: %d\n", status);
		pdu_write_fail(pdu, status);
		pdu_seq_fail(pdu, status);
		return;
	}

@@ -585,8 +595,7 @@ pdu_accel_compute_crc32_seq_cb(void *cb_arg, int status)

	req->accel_sequence = NULL;
	if (spdk_unlikely(status != 0)) {
		SPDK_ERRLOG("Failed to execute accel sequence: %d\n", status);
		pdu_write_fail(pdu, status);
		pdu_seq_fail(pdu, status);
		return;
	}

@@ -670,8 +679,7 @@ pdu_compute_crc32_seq_cb(void *cb_arg, int status)

	req->accel_sequence = NULL;
	if (spdk_unlikely(status != 0)) {
		SPDK_ERRLOG("Failed to execute accel sequence: %d\n", status);
		pdu_write_fail(pdu, status);
		pdu_seq_fail(pdu, status);
		return;
	}

@@ -1282,8 +1290,8 @@ nvme_tcp_recv_payload_seq_cb(void *cb_arg, int status)

	req->accel_sequence = NULL;
	if (spdk_unlikely(status != 0)) {
		SPDK_ERRLOG("Failed to execute accel sequence: %d\n", status);
		treq->rsp.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
		pdu_seq_fail(treq->pdu, status);
		return;
	}

	nvme_tcp_req_complete_safe(treq);