nvmf/vfio-user: post completions in one thread
For CREATE IO SQ command, we will defer to post completion until the SQ was connected, we may call post_completion() in different threads, so here we will send a message to CQ thread when necessary. Change-Id: I87a0f8982811c76ce8eb49db6a136f4cbe6e0a93 Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11078 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
e03c7acf31
commit
a2ca3c4acf
@ -195,6 +195,7 @@ struct nvmf_vfio_user_sq {
|
|||||||
|
|
||||||
struct nvmf_vfio_user_cq {
|
struct nvmf_vfio_user_cq {
|
||||||
struct spdk_nvmf_transport_poll_group *group;
|
struct spdk_nvmf_transport_poll_group *group;
|
||||||
|
struct spdk_thread *thread;
|
||||||
struct nvme_q cq;
|
struct nvme_q cq;
|
||||||
enum nvmf_vfio_user_cq_state cq_state;
|
enum nvmf_vfio_user_cq_state cq_state;
|
||||||
uint32_t cq_ref;
|
uint32_t cq_ref;
|
||||||
@ -2722,11 +2723,28 @@ vfio_user_poll_vfu_ctx(void *ctx)
|
|||||||
return ret != 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
|
return ret != 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vfio_user_post_cpl_ctx {
|
||||||
|
struct nvmf_vfio_user_ctrlr *ctrlr;
|
||||||
|
struct nvmf_vfio_user_cq *cq;
|
||||||
|
struct spdk_nvme_cpl cpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_post_completion_msg(void *ctx)
|
||||||
|
{
|
||||||
|
struct vfio_user_post_cpl_ctx *cpl_ctx = ctx;
|
||||||
|
|
||||||
|
post_completion(cpl_ctx->ctrlr, cpl_ctx->cq, cpl_ctx->cpl.cdw0, cpl_ctx->cpl.sqid,
|
||||||
|
cpl_ctx->cpl.cid, cpl_ctx->cpl.status.sc, cpl_ctx->cpl.status.sct);
|
||||||
|
free(cpl_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handle_queue_connect_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
|
handle_queue_connect_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
|
||||||
{
|
{
|
||||||
struct nvmf_vfio_user_poll_group *vu_group;
|
struct nvmf_vfio_user_poll_group *vu_group;
|
||||||
struct nvmf_vfio_user_sq *vu_sq = cb_arg;
|
struct nvmf_vfio_user_sq *vu_sq = cb_arg;
|
||||||
|
struct nvmf_vfio_user_cq *vu_cq;
|
||||||
struct nvmf_vfio_user_ctrlr *vu_ctrlr;
|
struct nvmf_vfio_user_ctrlr *vu_ctrlr;
|
||||||
struct nvmf_vfio_user_endpoint *endpoint;
|
struct nvmf_vfio_user_endpoint *endpoint;
|
||||||
|
|
||||||
@ -2749,6 +2767,9 @@ handle_queue_connect_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
|
|||||||
TAILQ_INSERT_TAIL(&vu_group->sqs, vu_sq, link);
|
TAILQ_INSERT_TAIL(&vu_group->sqs, vu_sq, link);
|
||||||
vu_sq->sq_state = VFIO_USER_SQ_ACTIVE;
|
vu_sq->sq_state = VFIO_USER_SQ_ACTIVE;
|
||||||
|
|
||||||
|
vu_cq = vu_ctrlr->cqs[0];
|
||||||
|
assert(vu_cq != NULL);
|
||||||
|
|
||||||
pthread_mutex_lock(&endpoint->lock);
|
pthread_mutex_lock(&endpoint->lock);
|
||||||
if (nvmf_qpair_is_admin_queue(&vu_sq->qpair)) {
|
if (nvmf_qpair_is_admin_queue(&vu_sq->qpair)) {
|
||||||
vu_ctrlr->cntlid = vu_sq->qpair.ctrlr->cntlid;
|
vu_ctrlr->cntlid = vu_sq->qpair.ctrlr->cntlid;
|
||||||
@ -2756,14 +2777,36 @@ handle_queue_connect_rsp(struct nvmf_vfio_user_req *req, void *cb_arg)
|
|||||||
vu_ctrlr->ctrlr = vu_sq->qpair.ctrlr;
|
vu_ctrlr->ctrlr = vu_sq->qpair.ctrlr;
|
||||||
vu_ctrlr->state = VFIO_USER_CTRLR_RUNNING;
|
vu_ctrlr->state = VFIO_USER_CTRLR_RUNNING;
|
||||||
vu_ctrlr->vfu_ctx_poller = SPDK_POLLER_REGISTER(vfio_user_poll_vfu_ctx, vu_ctrlr, 0);
|
vu_ctrlr->vfu_ctx_poller = SPDK_POLLER_REGISTER(vfio_user_poll_vfu_ctx, vu_ctrlr, 0);
|
||||||
|
vu_cq->thread = spdk_get_thread();
|
||||||
} else {
|
} else {
|
||||||
/* For I/O queues this command was generated in response to an
|
/* For I/O queues this command was generated in response to an
|
||||||
* ADMIN I/O CREATE SUBMISSION QUEUE command which has not yet
|
* ADMIN I/O CREATE SUBMISSION QUEUE command which has not yet
|
||||||
* been completed. Complete it now.
|
* been completed. Complete it now.
|
||||||
*/
|
*/
|
||||||
post_completion(vu_ctrlr, vu_ctrlr->cqs[0], 0, 0,
|
|
||||||
vu_sq->create_io_sq_cmd.cid, SPDK_NVME_SC_SUCCESS, SPDK_NVME_SCT_GENERIC);
|
assert(vu_cq->thread != NULL);
|
||||||
|
if (vu_cq->thread != spdk_get_thread()) {
|
||||||
|
struct vfio_user_post_cpl_ctx *cpl_ctx;
|
||||||
|
|
||||||
|
cpl_ctx = calloc(1, sizeof(*cpl_ctx));
|
||||||
|
if (!cpl_ctx) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
cpl_ctx->ctrlr = vu_ctrlr;
|
||||||
|
cpl_ctx->cq = vu_cq;
|
||||||
|
cpl_ctx->cpl.sqid = 0;
|
||||||
|
cpl_ctx->cpl.cdw0 = 0;
|
||||||
|
cpl_ctx->cpl.cid = vu_sq->create_io_sq_cmd.cid;
|
||||||
|
cpl_ctx->cpl.status.sc = SPDK_NVME_SC_SUCCESS;
|
||||||
|
cpl_ctx->cpl.status.sct = SPDK_NVME_SCT_GENERIC;
|
||||||
|
|
||||||
|
spdk_thread_send_msg(vu_cq->thread, _post_completion_msg, cpl_ctx);
|
||||||
|
} else {
|
||||||
|
post_completion(vu_ctrlr, vu_cq, 0, 0,
|
||||||
|
vu_sq->create_io_sq_cmd.cid, SPDK_NVME_SC_SUCCESS, SPDK_NVME_SCT_GENERIC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&vu_ctrlr->connected_sqs, vu_sq, tailq);
|
TAILQ_INSERT_TAIL(&vu_ctrlr->connected_sqs, vu_sq, tailq);
|
||||||
pthread_mutex_unlock(&endpoint->lock);
|
pthread_mutex_unlock(&endpoint->lock);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user