nvme_rdma: let UL know when we fail qpairs.

Also, adds a field to the generic qpair for future use in other
transports.

Change-Id: Ie5a66e7f5ebfec1131155fc07e3c671be814fb9b
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471414
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Seth Howell 2019-10-15 09:58:56 -07:00 committed by Jim Harris
parent 552898ec17
commit 0a42e658b5
2 changed files with 20 additions and 5 deletions

View File

@ -356,6 +356,8 @@ struct spdk_nvme_qpair {
uint8_t in_completion_context : 1; uint8_t in_completion_context : 1;
uint8_t delete_after_completion_context: 1; uint8_t delete_after_completion_context: 1;
uint8_t transport_qp_is_failed: 1;
/* /*
* Set when no deletion notification is needed. For example, the process * Set when no deletion notification is needed. For example, the process
* which allocated this qpair exited unexpectedly. * which allocated this qpair exited unexpectedly.

View File

@ -281,11 +281,13 @@ nvme_rdma_qpair_process_cm_event(struct nvme_rdma_qpair *rqpair)
break; break;
case RDMA_CM_EVENT_DISCONNECTED: case RDMA_CM_EVENT_DISCONNECTED:
case RDMA_CM_EVENT_DEVICE_REMOVAL: case RDMA_CM_EVENT_DEVICE_REMOVAL:
rqpair->qpair.transport_qp_is_failed = true;
break; break;
case RDMA_CM_EVENT_MULTICAST_JOIN: case RDMA_CM_EVENT_MULTICAST_JOIN:
case RDMA_CM_EVENT_MULTICAST_ERROR: case RDMA_CM_EVENT_MULTICAST_ERROR:
break; break;
case RDMA_CM_EVENT_ADDR_CHANGE: case RDMA_CM_EVENT_ADDR_CHANGE:
rqpair->qpair.transport_qp_is_failed = true;
break; break;
case RDMA_CM_EVENT_TIMEWAIT_EXIT: case RDMA_CM_EVENT_TIMEWAIT_EXIT:
break; break;
@ -1020,8 +1022,10 @@ nvme_rdma_qpair_connect(struct nvme_rdma_qpair *rqpair)
return -1; return -1;
} }
rqpair->qpair.transport_qp_is_failed = false;
rc = nvme_fabric_qpair_connect(&rqpair->qpair, rqpair->num_entries); rc = nvme_fabric_qpair_connect(&rqpair->qpair, rqpair->num_entries);
if (rc < 0) { if (rc < 0) {
rqpair->qpair.transport_qp_is_failed = true;
SPDK_ERRLOG("Failed to send an NVMe-oF Fabric CONNECT command\n"); SPDK_ERRLOG("Failed to send an NVMe-oF Fabric CONNECT command\n");
return -1; return -1;
} }
@ -1458,6 +1462,7 @@ nvme_rdma_qpair_disconnect(struct spdk_nvme_qpair *qpair)
{ {
struct nvme_rdma_qpair *rqpair = nvme_rdma_qpair(qpair); struct nvme_rdma_qpair *rqpair = nvme_rdma_qpair(qpair);
qpair->transport_qp_is_failed = true;
nvme_rdma_unregister_mem(rqpair); nvme_rdma_unregister_mem(rqpair);
nvme_rdma_unregister_reqs(rqpair); nvme_rdma_unregister_reqs(rqpair);
nvme_rdma_unregister_rsps(rqpair); nvme_rdma_unregister_rsps(rqpair);
@ -1838,6 +1843,10 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair,
} }
nvme_rdma_qpair_process_cm_event(rqpair); nvme_rdma_qpair_process_cm_event(rqpair);
if (spdk_unlikely(qpair->transport_qp_is_failed)) {
goto fail;
}
cq = rqpair->cq; cq = rqpair->cq;
reaped = 0; reaped = 0;
@ -1848,7 +1857,7 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair,
if (rc < 0) { if (rc < 0) {
SPDK_ERRLOG("Error polling CQ! (%d): %s\n", SPDK_ERRLOG("Error polling CQ! (%d): %s\n",
errno, spdk_strerror(errno)); errno, spdk_strerror(errno));
return -1; goto fail;
} else if (rc == 0) { } else if (rc == 0) {
/* Ran out of completions */ /* Ran out of completions */
break; break;
@ -1858,7 +1867,7 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair,
if (wc[i].status) { if (wc[i].status) {
SPDK_ERRLOG("CQ error on Queue Pair %p, Response Index %lu (%d): %s\n", SPDK_ERRLOG("CQ error on Queue Pair %p, Response Index %lu (%d): %s\n",
qpair, wc[i].wr_id, wc[i].status, ibv_wc_status_str(wc[i].status)); qpair, wc[i].wr_id, wc[i].status, ibv_wc_status_str(wc[i].status));
return -1; goto fail;
} }
switch (wc[i].opcode) { switch (wc[i].opcode) {
@ -1869,12 +1878,12 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair,
if (wc[i].byte_len < sizeof(struct spdk_nvme_cpl)) { if (wc[i].byte_len < sizeof(struct spdk_nvme_cpl)) {
SPDK_ERRLOG("recv length %u less than expected response size\n", wc[i].byte_len); SPDK_ERRLOG("recv length %u less than expected response size\n", wc[i].byte_len);
return -1; goto fail;
} }
if (nvme_rdma_recv(rqpair, wc[i].wr_id)) { if (nvme_rdma_recv(rqpair, wc[i].wr_id)) {
SPDK_ERRLOG("nvme_rdma_recv processing failure\n"); SPDK_ERRLOG("nvme_rdma_recv processing failure\n");
return -1; goto fail;
} }
break; break;
@ -1890,7 +1899,7 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair,
default: default:
SPDK_ERRLOG("Received an unexpected opcode on the CQ: %d\n", wc[i].opcode); SPDK_ERRLOG("Received an unexpected opcode on the CQ: %d\n", wc[i].opcode);
return -1; goto fail;
} }
} }
} while (reaped < max_completions); } while (reaped < max_completions);
@ -1900,6 +1909,10 @@ nvme_rdma_qpair_process_completions(struct spdk_nvme_qpair *qpair,
} }
return reaped; return reaped;
fail:
nvme_rdma_qpair_disconnect(qpair);
return -ENXIO;
} }
uint32_t uint32_t