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: Michael Haeuptle <michael.haeuptle@hpe.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4831 (master)
(cherry picked from commit 7fc48a5ffc
)
Change-Id: Ia238c8aeae720832068de28ce4d34a9d233344fb
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4959
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
ede2227a7c
commit
807019734e
@ -314,6 +314,14 @@ nvme_wait_for_completion_robust_lock_timeout(
|
|||||||
rc = -1;
|
rc = -1;
|
||||||
break;
|
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) {
|
if (status->done == false) {
|
||||||
|
@ -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;
|
union spdk_nvme_csts_register csts;
|
||||||
|
|
||||||
if (nvme_ctrlr_get_csts(ctrlr, &csts)) {
|
if (nvme_ctrlr_get_csts(ctrlr, &csts)) {
|
||||||
csts.raw = 0xFFFFFFFFu;
|
csts.raw = SPDK_NVME_INVALID_REGISTER_VALUE;
|
||||||
}
|
}
|
||||||
return csts;
|
return csts;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +191,9 @@ extern pid_t g_spdk_nvme_pid;
|
|||||||
#define NVME_FABRIC_CONNECT_COMMAND_TIMEOUT 500000
|
#define NVME_FABRIC_CONNECT_COMMAND_TIMEOUT 500000
|
||||||
#endif
|
#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 {
|
enum nvme_payload_type {
|
||||||
NVME_PAYLOAD_TYPE_INVALID = 0,
|
NVME_PAYLOAD_TYPE_INVALID = 0,
|
||||||
|
|
||||||
|
@ -91,6 +91,13 @@ nvme_ctrlr_destruct_poll_async(struct spdk_nvme_ctrlr *ctrlr,
|
|||||||
return 0;
|
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
|
void
|
||||||
spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t opts_size)
|
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)
|
test_nvme_wait_for_completion(void)
|
||||||
{
|
{
|
||||||
struct spdk_nvme_qpair qpair;
|
struct spdk_nvme_qpair qpair;
|
||||||
|
struct spdk_nvme_ctrlr ctrlr;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
memset(&ctrlr, 0, sizeof(ctrlr));
|
||||||
|
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
|
||||||
memset(&qpair, 0, sizeof(qpair));
|
memset(&qpair, 0, sizeof(qpair));
|
||||||
|
qpair.ctrlr = &ctrlr;
|
||||||
|
|
||||||
/* completion timeout */
|
/* completion timeout */
|
||||||
memset(&g_status, 0, sizeof(g_status));
|
memset(&g_status, 0, sizeof(g_status));
|
||||||
|
Loading…
Reference in New Issue
Block a user