diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index d2c2f0050..59df2071e 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -138,6 +138,7 @@ struct spdk_nvmf_subsystem { struct spdk_nvme_qpair *io_qpair; struct spdk_pci_addr pci_addr; struct spdk_poller *admin_poller; + int32_t outstanding_admin_cmd_count; } direct; struct { diff --git a/lib/nvmf/direct.c b/lib/nvmf/direct.c index 1b4f8b64b..24141322c 100644 --- a/lib/nvmf/direct.c +++ b/lib/nvmf/direct.c @@ -63,6 +63,10 @@ nvmf_direct_ctrlr_poll_for_admin_completions(void *arg) static void nvmf_direct_ctrlr_poll_for_completions(struct spdk_nvmf_subsystem *subsystem) { + if (subsystem->dev.direct.outstanding_admin_cmd_count > 0) { + nvmf_direct_ctrlr_poll_for_admin_completions(subsystem); + } + if (subsystem->dev.direct.admin_poller == NULL) { int lcore = spdk_app_get_current_core(); @@ -71,8 +75,6 @@ nvmf_direct_ctrlr_poll_for_completions(struct spdk_nvmf_subsystem *subsystem) subsystem, lcore, 10000); } - nvmf_direct_ctrlr_poll_for_admin_completions(subsystem); - spdk_nvme_qpair_process_completions(subsystem->dev.direct.io_qpair, 0); } @@ -88,6 +90,17 @@ nvmf_direct_ctrlr_complete_cmd(void *ctx, const struct spdk_nvme_cpl *cmp) spdk_nvmf_request_complete(req); } +static void +nvmf_direct_ctrlr_complete_admin_cmd(void *ctx, const struct spdk_nvme_cpl *cmp) +{ + struct spdk_nvmf_request *req = ctx; + struct spdk_nvmf_subsystem *subsystem = req->conn->sess->subsys; + + subsystem->dev.direct.outstanding_admin_cmd_count--; + + nvmf_direct_ctrlr_complete_cmd(ctx, cmp); +} + static int nvmf_direct_ctrlr_admin_identify_nslist(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvmf_request *req) @@ -224,13 +237,16 @@ passthrough: rc = spdk_nvme_ctrlr_cmd_admin_raw(subsystem->dev.direct.ctrlr, cmd, req->data, req->length, - nvmf_direct_ctrlr_complete_cmd, + nvmf_direct_ctrlr_complete_admin_cmd, req); if (rc) { SPDK_ERRLOG("Error submitting admin opc 0x%02x\n", cmd->opc); response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } + + subsystem->dev.direct.outstanding_admin_cmd_count++; + return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; } diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index 88c592ffd..917a4e47a 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -208,6 +208,7 @@ spdk_nvmf_create_subsystem(const char *nqn, if (mode == NVMF_SUBSYSTEM_MODE_DIRECT) { subsystem->ops = &spdk_nvmf_direct_ctrlr_ops; + subsystem->dev.direct.outstanding_admin_cmd_count = 0; } else { subsystem->ops = &spdk_nvmf_virtual_ctrlr_ops; }