nvmf: free AER resourcess before disconnecting qpair

It is necessary to free the AER without sending a completion to ensure
that the host does not attempt to send an additional AER upon receiving
the first completion.

Change-Id: I2b3f8f286d6396019d8ace97d2376547705b8d9d
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/420661
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Seth Howell 2018-07-27 10:39:25 -07:00 committed by Jim Harris
parent 388e310150
commit 4bee4e03b6
4 changed files with 32 additions and 3 deletions

View File

@ -1729,7 +1729,22 @@ spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr)
}
void
spdk_nvmf_ctrlr_drain_aer_req(struct spdk_nvmf_ctrlr *ctrlr)
spdk_nvmf_qpair_free_aer(struct spdk_nvmf_qpair *qpair)
{
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
if (!spdk_nvmf_qpair_is_admin_queue(qpair)) {
return;
}
if (ctrlr->aer_req != NULL) {
spdk_nvmf_request_free(ctrlr->aer_req);
ctrlr->aer_req = NULL;
}
}
void
spdk_nvmf_ctrlr_abort_aer(struct spdk_nvmf_ctrlr *ctrlr)
{
if (!ctrlr->aer_req) {
return;

View File

@ -688,6 +688,7 @@ _spdk_nvmf_qpair_deactivate(void *ctx)
if (!TAILQ_EMPTY(&qpair->outstanding)) {
qpair->state_cb = _spdk_nvmf_qpair_destroy;
qpair->state_cb_arg = qpair_ctx;
spdk_nvmf_qpair_free_aer(qpair);
return;
}

View File

@ -293,7 +293,20 @@ struct spdk_nvmf_ctrlr *spdk_nvmf_subsystem_get_ctrlr(struct spdk_nvmf_subsystem
uint16_t cntlid);
int spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr);
void spdk_nvmf_ctrlr_drain_aer_req(struct spdk_nvmf_ctrlr *ctrlr);
/*
* Abort aer is sent on a per controller basis and sends a completion for the aer to the host.
* This function should be called when attempting to recover in error paths when it is OK for
* the host to send a subsequent AER.
*/
void spdk_nvmf_ctrlr_abort_aer(struct spdk_nvmf_ctrlr *ctrlr);
/*
* Free aer simply frees the rdma resources for the aer without informing the host.
* This function should be called when deleting a qpair when one wants to make sure
* the qpair is completely empty before freeing the request. The reason we free the
* AER without sending a completion is to prevent the host from sending another AER.
*/
void spdk_nvmf_qpair_free_aer(struct spdk_nvmf_qpair *qpair);
static inline struct spdk_nvmf_ns *
_spdk_nvmf_subsystem_get_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid)

View File

@ -2027,7 +2027,7 @@ spdk_nvmf_rdma_qp_drained(struct spdk_nvmf_rdma_qpair *rqpair)
SPDK_NOTICELOG("IBV QP#%u drained\n", rqpair->qpair.qid);
if (spdk_nvmf_qpair_is_admin_queue(&rqpair->qpair)) {
spdk_nvmf_ctrlr_drain_aer_req(rqpair->qpair.ctrlr);
spdk_nvmf_ctrlr_abort_aer(rqpair->qpair.ctrlr);
}
spdk_nvmf_rdma_drain_pending_reqs(rqpair);