Commit e6464f32 authored by Changpeng Liu's avatar Changpeng Liu Committed by Jim Harris
Browse files

nvmf: abort AERs when doing controller reset and shutdown



The vfio-user target emulated NVMe device is treated as
PCIe NVMe SSD in the Guest VM, so when doing controller
reset or shutdown, we should abort the AERs which in the
NVMf library.

Users may switch kernel NVMe driver to SPDK NVMe driver
in the VM, without this fix, we will got "AERL exceeded"
response very frequently, because the AERs submitted by
previous driver will never be aborted in runtime.

Change-Id: I0222ed509629ccb0e98217414dd9043857105686
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8558


Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 4fa3d991
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3229,6 +3229,10 @@ nvmf_ctrlr_abort_aer(struct spdk_nvmf_ctrlr *ctrlr)
	struct spdk_nvmf_request *req;
	int i;

	if (!ctrlr->nr_aer_reqs) {
		return;
	}

	for (i = 0; i < ctrlr->nr_aer_reqs; i++) {
		req = ctrlr->aer_req[i];

+26 −0
Original line number Diff line number Diff line
@@ -1032,6 +1032,27 @@ handle_cmd_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
			       req->req.rsp->nvme_cpl.status.sct);
}

static int
handle_admin_aer_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
{
	struct nvmf_vfio_user_qpair *qpair = cb_arg;

	assert(qpair != NULL);
	assert(req != NULL);

	vfu_unmap_sg(qpair->ctrlr->endpoint->vfu_ctx, req->sg, req->iov, req->iovcnt);

	if (qpair->state != VFIO_USER_QPAIR_ACTIVE) {
		return 0;
	}

	return post_completion(qpair->ctrlr, &req->req.cmd->nvme_cmd,
			       &qpair->ctrlr->qp[req->req.qpair->qid]->cq,
			       req->req.rsp->nvme_cpl.cdw0,
			       req->req.rsp->nvme_cpl.status.sc,
			       req->req.rsp->nvme_cpl.status.sct);
}

static int
consume_cmd(struct nvmf_vfio_user_ctrlr *ctrlr, struct nvmf_vfio_user_qpair *qpair,
	    struct spdk_nvme_cmd *cmd)
@@ -1284,6 +1305,8 @@ nvmf_vfio_user_prop_req_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
					      ctrlr_id(qpair->ctrlr));
				unmap_admin_queue(qpair->ctrlr);
				qpair->state = VFIO_USER_QPAIR_INACTIVE;
				/* For PCIe controller reset, we will drop all AER responses */
				nvmf_ctrlr_abort_aer(req->req.qpair->ctrlr);
			}
		}
	}
@@ -2350,6 +2373,9 @@ handle_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd,
	req->cmd->nvme_cmd = *cmd;
	if (nvmf_qpair_is_admin_queue(req->qpair)) {
		err = map_admin_cmd_req(ctrlr, req);
		if (cmd->opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) {
			vu_req->cb_fn = handle_admin_aer_rsp;
		}
	} else {
		err = map_io_cmd_req(ctrlr, req);
	}