nvmf: decrement mgmt_io_outstanding for all AER cases

We cannot count AERs as outstanding IO for purposes
of subsystem pause, because we cannot expect them
to be completed. Previously we would account for this
in nvmf_ctrlr_async_event_request() by decrementing
the counter, but this did not consider cases in the
calling function (nvmf_ctrlr_process_admin_cmd) where
an AER might complete with error before this function,
resulting in the counter getting stuck indefinitely
with a >0 value.

Rather than adding a decrement in all of those
error cases, do a single check at the beginning
of nvmf_ctrlr_process_admin_cmd, and remove the
one from nvmf_ctrlr_async_event_request.

Fixes issue #2215.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Ica969f116d80dfba0168369ff2fba9a4a42fc076
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13678
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Dong Yi <dongx.yi@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
Jim Harris 2022-07-14 23:32:39 +00:00 committed by Tomasz Zawadzki
parent 7cd8de9c2b
commit 9cb5f885df

View File

@ -1972,16 +1972,10 @@ nvmf_ctrlr_async_event_request(struct spdk_nvmf_request *req)
{
struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr;
struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl;
struct spdk_nvmf_subsystem_poll_group *sgroup;
struct spdk_nvmf_async_event_completion *pending_event;
SPDK_DEBUGLOG(nvmf, "Async Event Request\n");
/* AER cmd is an exception */
sgroup = &req->qpair->group->sgroups[ctrlr->subsys->id];
assert(sgroup != NULL);
sgroup->mgmt_io_outstanding--;
/* Four asynchronous events are supported for now */
if (ctrlr->nr_aer_reqs >= NVMF_MAX_ASYNC_EVENTS) {
SPDK_DEBUGLOG(nvmf, "AERL exceeded\n");
@ -3281,8 +3275,19 @@ nvmf_ctrlr_process_admin_cmd(struct spdk_nvmf_request *req)
struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr;
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl;
struct spdk_nvmf_subsystem_poll_group *sgroup;
int rc;
if (cmd->opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) {
/* We do not want to treat AERs as outstanding commands,
* so decrement mgmt_io_outstanding here to offset
* the increment that happened prior to this call.
*/
sgroup = &req->qpair->group->sgroups[ctrlr->subsys->id];
assert(sgroup != NULL);
sgroup->mgmt_io_outstanding--;
}
if (ctrlr == NULL) {
SPDK_ERRLOG("Admin command sent before CONNECT\n");
response->status.sct = SPDK_NVME_SCT_GENERIC;