nvmf/vfio-user: fix empty free request issue

It's too strict to fail the controller when there are no free requests.

Change-Id: I0a66ff2d294a2fd9326506ea50af4213aaaf8e92
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9848
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: GangCao <gang.cao@intel.com>
This commit is contained in:
Changpeng Liu 2021-10-13 17:45:22 +08:00 committed by Tomasz Zawadzki
parent 3494f69c90
commit 5509f57e2e

View File

@ -816,12 +816,9 @@ vfio_user_map_cmd(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvmf_request *
length, 4096, _map_one); length, 4096, _map_one);
} }
static struct spdk_nvmf_request *
get_nvmf_req(struct nvmf_vfio_user_qpair *qp);
static int static int
handle_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd, handle_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd,
struct spdk_nvmf_request *req); struct nvmf_vfio_user_qpair *vu_qpair);
/* /*
* Posts a CQE in the completion queue. * Posts a CQE in the completion queue.
@ -1339,7 +1336,7 @@ consume_admin_cmd(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd)
return handle_del_io_q(ctrlr, cmd, return handle_del_io_q(ctrlr, cmd,
cmd->opc == SPDK_NVME_OPC_DELETE_IO_CQ); cmd->opc == SPDK_NVME_OPC_DELETE_IO_CQ);
default: default:
return handle_cmd_req(ctrlr, cmd, get_nvmf_req(ctrlr->qp[0])); return handle_cmd_req(ctrlr, cmd, ctrlr->qp[0]);
} }
} }
@ -1377,7 +1374,7 @@ consume_cmd(struct nvmf_vfio_user_ctrlr *ctrlr, struct nvmf_vfio_user_qpair *qpa
return consume_admin_cmd(ctrlr, cmd); return consume_admin_cmd(ctrlr, cmd);
} }
return handle_cmd_req(ctrlr, cmd, get_nvmf_req(qpair)); return handle_cmd_req(ctrlr, cmd, qpair);
} }
/* Returns the number of commands processed, or a negative value on error. */ /* Returns the number of commands processed, or a negative value on error. */
@ -2573,17 +2570,6 @@ get_nvmf_vfio_user_req(struct nvmf_vfio_user_qpair *qpair)
return req; return req;
} }
static struct spdk_nvmf_request *
get_nvmf_req(struct nvmf_vfio_user_qpair *qpair)
{
struct nvmf_vfio_user_req *req = get_nvmf_vfio_user_req(qpair);
if (req == NULL) {
return NULL;
}
return &req->req;
}
static int static int
get_nvmf_io_req_length(struct spdk_nvmf_request *req) get_nvmf_io_req_length(struct spdk_nvmf_request *req)
{ {
@ -2723,29 +2709,28 @@ map_io_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvmf_request *req
static int static int
handle_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd, handle_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd,
struct spdk_nvmf_request *req) struct nvmf_vfio_user_qpair *vu_qpair)
{ {
int err; int err;
struct nvmf_vfio_user_req *vu_req; struct nvmf_vfio_user_req *vu_req;
struct spdk_nvmf_request *req;
assert(ctrlr != NULL); assert(ctrlr != NULL);
assert(cmd != NULL); assert(cmd != NULL);
/* vu_req = get_nvmf_vfio_user_req(vu_qpair);
* TODO: this means that there are no free requests available, if (spdk_unlikely(vu_req == NULL)) {
* returning -1 will fail the controller. Theoretically this error can SPDK_ERRLOG("%s: no request for NVMe command opc 0x%x\n", ctrlr_id(ctrlr), cmd->opc);
* be avoided completely by ensuring we have as many requests as slots return post_completion(ctrlr, &vu_qpair->cq, 0, 0, cmd->cid,
* in the SQ, plus one for the the property request. SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, SPDK_NVME_SCT_GENERIC);
*/
if (spdk_unlikely(req == NULL)) {
return -1;
} }
req = &vu_req->req;
assert(req->qpair != NULL); assert(req->qpair != NULL);
SPDK_DEBUGLOG(nvmf_vfio, "%s: handle qid%u, req opc=%#x cid=%d\n", SPDK_DEBUGLOG(nvmf_vfio, "%s: handle qid%u, req opc=%#x cid=%d\n",
ctrlr_id(ctrlr), req->qpair->qid, cmd->opc, cmd->cid); ctrlr_id(ctrlr), req->qpair->qid, cmd->opc, cmd->cid);
vu_req = SPDK_CONTAINEROF(req, struct nvmf_vfio_user_req, req);
vu_req->cb_fn = handle_cmd_rsp; vu_req->cb_fn = handle_cmd_rsp;
vu_req->cb_arg = SPDK_CONTAINEROF(req->qpair, struct nvmf_vfio_user_qpair, qpair); vu_req->cb_arg = SPDK_CONTAINEROF(req->qpair, struct nvmf_vfio_user_qpair, qpair);
req->cmd->nvme_cmd = *cmd; req->cmd->nvme_cmd = *cmd;
@ -2767,14 +2752,11 @@ handle_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd,
} }
if (spdk_unlikely(err < 0)) { if (spdk_unlikely(err < 0)) {
struct nvmf_vfio_user_qpair *vu_qpair;
SPDK_ERRLOG("%s: process NVMe command opc 0x%x failed\n", SPDK_ERRLOG("%s: process NVMe command opc 0x%x failed\n",
ctrlr_id(ctrlr), cmd->opc); ctrlr_id(ctrlr), cmd->opc);
req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC;
err = handle_cmd_rsp(vu_req, vu_req->cb_arg); err = handle_cmd_rsp(vu_req, vu_req->cb_arg);
vu_qpair = SPDK_CONTAINEROF(req->qpair, struct nvmf_vfio_user_qpair, qpair);
_nvmf_vfio_user_req_free(vu_qpair, vu_req); _nvmf_vfio_user_req_free(vu_qpair, vu_req);
return err; return err;
} }