diff --git a/include/spdk_internal/rdma.h b/include/spdk_internal/rdma.h index fd69d9e25..2808db42a 100644 --- a/include/spdk_internal/rdma.h +++ b/include/spdk_internal/rdma.h @@ -62,9 +62,16 @@ struct spdk_rdma_qp *spdk_rdma_qp_create(struct rdma_cm_id *cm_id, struct spdk_rdma_qp_init_attr *qp_attr); /** - * Destory RDMA provider specific qpair + * Destroy RDMA provider specific qpair * \param spdk_rdma_qp Pointer to qpair to be destroyed */ void spdk_rdma_qp_destroy(struct spdk_rdma_qp *spdk_rdma_qp); +/** + * Disconnect a connection and transition assoiciated qpair to error state. + * Generates RDMA_CM_EVENT_DISCONNECTED on both connection sides + * \param spdk_rdma_qp Pointer to qpair to be destroyed + */ +int spdk_rdma_qp_disconnect(struct spdk_rdma_qp *spdk_rdma_qp); + #endif /* SPDK_RDMA_H */ diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index 59b7e8118..80af8788a 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -1672,7 +1672,7 @@ nvme_rdma_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme } if (rqpair->cm_id) { - rdma_disconnect(rqpair->cm_id); + spdk_rdma_qp_disconnect(rqpair->rdma_qp); if (rctrlr != NULL) { if (nvme_rdma_process_event(rqpair, rctrlr->cm_channel, RDMA_CM_EVENT_DISCONNECTED)) { SPDK_DEBUGLOG(SPDK_LOG_NVME, "Target did not respond to qpair disconnect.\n"); diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index f920d0738..3983b7c4b 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -3579,7 +3579,7 @@ nvmf_rdma_close_qpair(struct spdk_nvmf_qpair *qpair) } if (rqpair->cm_id) { - rdma_disconnect(rqpair->cm_id); + spdk_rdma_qp_disconnect(rqpair->rdma_qp); } rqpair->destruct_poller = SPDK_POLLER_REGISTER(nvmf_rdma_destroy_defunct_qpair, (void *)rqpair, diff --git a/lib/rdma/rdma_verbs.c b/lib/rdma/rdma_verbs.c index dd1a93d86..41fcf4d24 100644 --- a/lib/rdma/rdma_verbs.c +++ b/lib/rdma/rdma_verbs.c @@ -85,3 +85,20 @@ spdk_rdma_qp_destroy(struct spdk_rdma_qp *spdk_rdma_qp) free(spdk_rdma_qp); } + +int +spdk_rdma_qp_disconnect(struct spdk_rdma_qp *spdk_rdma_qp) +{ + int rc = 0; + + assert(spdk_rdma_qp != NULL); + + if (spdk_rdma_qp->cm_id) { + rc = rdma_disconnect(spdk_rdma_qp->cm_id); + if (rc) { + SPDK_ERRLOG("rdma_disconnect failed, errno %s (%d)\n", spdk_strerror(errno), errno); + } + } + + return rc; +} diff --git a/lib/rdma/spdk_rdma.map b/lib/rdma/spdk_rdma.map index 6a8f13d2b..7e487339d 100644 --- a/lib/rdma/spdk_rdma.map +++ b/lib/rdma/spdk_rdma.map @@ -4,6 +4,7 @@ # Public functions spdk_rdma_qp_create; spdk_rdma_qp_destroy; + spdk_rdma_qp_disconnect; local: *; }; diff --git a/test/common/lib/test_rdma.c b/test/common/lib/test_rdma.c index 2e9de9640..9ebeb3da1 100644 --- a/test/common/lib/test_rdma.c +++ b/test/common/lib/test_rdma.c @@ -39,3 +39,4 @@ DEFINE_STUB(spdk_rdma_qp_create, struct spdk_rdma_qp *, (struct rdma_cm_id *cm_id, struct spdk_rdma_qp_init_attr *qp_attr), NULL); DEFINE_STUB_V(spdk_rdma_qp_destroy, (struct spdk_rdma_qp *spdk_rdma_qp)); +DEFINE_STUB(spdk_rdma_qp_disconnect, int, (struct spdk_rdma_qp *spdk_rdma_qp), 0);