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 <james.r.harris@intel.com>
Change-Id: I58c995237db486fecdd89d95e9e7a64379d0b0e5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13940
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Dong Yi <dongx.yi@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Jim Harris 2022-08-09 15:04:13 +00:00 committed by Tomasz Zawadzki
parent 43ebecdf60
commit 0f068506ca
3 changed files with 15 additions and 4 deletions

View File

@ -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;
};
/*

View File

@ -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);
}
}

View File

@ -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);