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:
parent
388e310150
commit
4bee4e03b6
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user