Commit 7fc48a5f authored by Michael Haeuptle's avatar Michael Haeuptle Committed by Tomasz Zawadzki
Browse files

nvme: break completion loop when ctrlr is invalid



This fixes #1423 where the completion loop never
breaks when the NVMe ctrlr is no longer present.
This condition can happen during a hot remove.

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


Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarVasuki Manikarnike <vasuki.manikarnike@hpe.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent ddf86600
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -314,6 +314,14 @@ nvme_wait_for_completion_robust_lock_timeout(
			rc = -1;
			break;
		}
		if (qpair->ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) {
			union spdk_nvme_csts_register csts = spdk_nvme_ctrlr_get_regs_csts(qpair->ctrlr);
			if (csts.raw == SPDK_NVME_INVALID_REGISTER_VALUE) {
				status->cpl.status.sct = SPDK_NVME_SCT_GENERIC;
				status->cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
				break;
			}
		}
	}

	if (status->done == false) {
+1 −1
Original line number Diff line number Diff line
@@ -3445,7 +3445,7 @@ union spdk_nvme_csts_register spdk_nvme_ctrlr_get_regs_csts(struct spdk_nvme_ctr
	union spdk_nvme_csts_register csts;

	if (nvme_ctrlr_get_csts(ctrlr, &csts)) {
		csts.raw = 0xFFFFFFFFu;
		csts.raw = SPDK_NVME_INVALID_REGISTER_VALUE;
	}
	return csts;
}
+3 −0
Original line number Diff line number Diff line
@@ -191,6 +191,9 @@ extern pid_t g_spdk_nvme_pid;
#define NVME_FABRIC_CONNECT_COMMAND_TIMEOUT 500000
#endif

/* This value indicates that a read from a PCIe register is invalid. This can happen when a device is no longer present */
#define SPDK_NVME_INVALID_REGISTER_VALUE 0xFFFFFFFFu

enum nvme_payload_type {
	NVME_PAYLOAD_TYPE_INVALID = 0,

+11 −0
Original line number Diff line number Diff line
@@ -91,6 +91,13 @@ nvme_ctrlr_destruct_poll_async(struct spdk_nvme_ctrlr *ctrlr,
	return 0;
}

union spdk_nvme_csts_register
	spdk_nvme_ctrlr_get_regs_csts(struct spdk_nvme_ctrlr *ctrlr)
{
	union spdk_nvme_csts_register csts = {};
	return csts;
}

void
spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t opts_size)
{
@@ -1270,9 +1277,13 @@ static void
test_nvme_wait_for_completion(void)
{
	struct spdk_nvme_qpair qpair;
	struct spdk_nvme_ctrlr ctrlr;
	int rc = 0;

	memset(&ctrlr, 0, sizeof(ctrlr));
	ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
	memset(&qpair, 0, sizeof(qpair));
	qpair.ctrlr = &ctrlr;

	/* completion timeout */
	memset(&g_status, 0, sizeof(g_status));