lib/nvme: fix cm event handling during rdma qpair shutdown.

In the event that we have more than one event outstanding for a qpair
at the time of destruction, we need to ack all of the events, Luckily
the synchronization is already there in the form of the ctrlr lock.

Signed-off-by: Seth Howell <seth.howell@intel.com>
Change-Id: Ib297598f2e28d9b9bd83e904f950795a61fa883a
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479171
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Seth Howell 2020-01-02 16:54:47 -07:00 committed by Tomasz Zawadzki
parent 50cb6a04ac
commit ca693eaba8

View File

@ -1628,6 +1628,8 @@ void
nvme_rdma_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair)
{
struct nvme_rdma_qpair *rqpair = nvme_rdma_qpair(qpair);
struct nvme_rdma_ctrlr *rctrlr;
struct nvme_rdma_cm_event_entry *entry, *tmp;
nvme_qpair_set_state(qpair, NVME_QPAIR_DISABLED);
nvme_rdma_unregister_mem(rqpair);
@ -1639,6 +1641,21 @@ nvme_rdma_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme
rqpair->evt = NULL;
}
/*
* This works because we have the controller lock both in
* this function and in the function where we add new events.
*/
if (qpair->ctrlr != NULL) {
rctrlr = nvme_rdma_ctrlr(qpair->ctrlr);
STAILQ_FOREACH_SAFE(entry, &rctrlr->pending_cm_events, link, tmp) {
if (nvme_rdma_qpair(entry->evt->id->context) == rqpair) {
STAILQ_REMOVE(&rctrlr->pending_cm_events, entry, nvme_rdma_cm_event_entry, link);
rdma_ack_cm_event(entry->evt);
STAILQ_INSERT_HEAD(&rctrlr->free_cm_events, entry, link);
}
}
}
if (rqpair->cm_id) {
if (rqpair->cm_id->qp) {
rdma_destroy_qp(rqpair->cm_id);