From 0f068506cabe0e8af01300af2497cc8d921f6e3f Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 9 Aug 2022 15:04:13 +0000 Subject: [PATCH] nvme: complete register_operations in the correct process In multi-process, we need to make sure we don't complete a register_operation in the wrong process. So save the pid in the nvme_register_completion structure when it is inserted into the STAILQ, then only complete operations where the pid matches. Fixes issue #2630. Signed-off-by: Jim Harris Change-Id: I58c995237db486fecdd89d95e9e7a64379d0b0e5 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13940 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Dong Yi Reviewed-by: Shuhei Matsumoto Reviewed-by: Changpeng Liu Reviewed-by: Aleksey Marchuk Reviewed-by: Tomasz Zawadzki --- lib/nvme/nvme_internal.h | 1 + lib/nvme/nvme_qpair.c | 15 ++++++++++++--- lib/nvme/nvme_transport.c | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 2e3773261..2b9426a3d 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -845,6 +845,7 @@ struct nvme_register_completion { spdk_nvme_reg_cb cb_fn; void *cb_ctx; STAILQ_ENTRY(nvme_register_completion) stailq; + pid_t pid; }; /* diff --git a/lib/nvme/nvme_qpair.c b/lib/nvme/nvme_qpair.c index 059398851..3eb1e805a 100644 --- a/lib/nvme/nvme_qpair.c +++ b/lib/nvme/nvme_qpair.c @@ -670,13 +670,22 @@ nvme_qpair_resubmit_requests(struct spdk_nvme_qpair *qpair, uint32_t num_request static void nvme_complete_register_operations(struct spdk_nvme_qpair *qpair) { - struct nvme_register_completion *ctx; + struct nvme_register_completion *ctx, *tmp; struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr; STAILQ_HEAD(, nvme_register_completion) operations; STAILQ_INIT(&operations); nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); - STAILQ_SWAP(&ctrlr->register_operations, &operations, nvme_register_completion); + STAILQ_FOREACH_SAFE(ctx, &ctrlr->register_operations, stailq, tmp) { + /* We need to make sure we complete the register operation in + * the correct process. + */ + if (ctx->pid != getpid()) { + continue; + } + STAILQ_REMOVE(&ctrlr->register_operations, ctx, nvme_register_completion, stailq); + STAILQ_INSERT_TAIL(&operations, ctx, stailq); + } nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock); while (!STAILQ_EMPTY(&operations)) { @@ -685,7 +694,7 @@ nvme_complete_register_operations(struct spdk_nvme_qpair *qpair) if (ctx->cb_fn != NULL) { ctx->cb_fn(ctx->cb_ctx, ctx->value, &ctx->cpl); } - free(ctx); + spdk_free(ctx); } } diff --git a/lib/nvme/nvme_transport.c b/lib/nvme/nvme_transport.c index 277abbe7c..3e060e590 100644 --- a/lib/nvme/nvme_transport.c +++ b/lib/nvme/nvme_transport.c @@ -196,7 +196,7 @@ nvme_queue_register_operation_completion(struct spdk_nvme_ctrlr *ctrlr, uint64_t { struct nvme_register_completion *ctx; - ctx = calloc(1, sizeof(*ctx)); + ctx = spdk_zmalloc(sizeof(*ctx), 0, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_SHARE); if (ctx == NULL) { return -ENOMEM; } @@ -206,6 +206,7 @@ nvme_queue_register_operation_completion(struct spdk_nvme_ctrlr *ctrlr, uint64_t ctx->cb_fn = cb_fn; ctx->cb_ctx = cb_ctx; ctx->value = value; + ctx->pid = getpid(); nvme_robust_mutex_lock(&ctrlr->ctrlr_lock); STAILQ_INSERT_TAIL(&ctrlr->register_operations, ctx, stailq);