From ac31590b37a9d0861a5e9cdc1d0623c91fc1553a Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Thu, 7 Jul 2022 15:02:01 +0800 Subject: [PATCH] nvme: make `spdk_nvme_ctrlr_free_io_qpair` multi-process safe In the multi-process case, a process may call `spdk_nvme_ctrlr_free_io_qpair` on a foreign I/O qpair (i.e. one that this process did not create) when that qpairs process exits unexpectedly. The variable `qpair->poll_group` isn't multi-process safe, we can't use it in `spdk_nvme_ctrlr_free_io_qpair` and related transport poll group APIs. Change-Id: Ic13a6a2c7d760477be5be5a56a45caa2b5518717 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13573 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Aleksey Marchuk Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- lib/nvme/nvme_ctrlr.c | 2 +- lib/nvme/nvme_transport.c | 7 +++++-- test/unit/lib/nvme/nvme_transport.c/nvme_transport_ut.c | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 2517978bf..6b9c40fab 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -593,7 +593,7 @@ spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair) nvme_transport_ctrlr_disconnect_qpair(ctrlr, qpair); - if (qpair->poll_group) { + if (qpair->poll_group && (qpair->active_proc == nvme_ctrlr_get_current_process(ctrlr))) { spdk_nvme_poll_group_remove(qpair->poll_group->group, qpair); } diff --git a/lib/nvme/nvme_transport.c b/lib/nvme/nvme_transport.c index f84558a1e..15623a4c8 100644 --- a/lib/nvme/nvme_transport.c +++ b/lib/nvme/nvme_transport.c @@ -508,7 +508,8 @@ nvme_transport_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk nvme_qpair_set_state(qpair, NVME_QPAIR_DISCONNECTING); assert(transport != NULL); - if (qpair->poll_group) { + + if (qpair->poll_group && (qpair->active_proc == nvme_ctrlr_get_current_process(ctrlr))) { nvme_poll_group_disconnect_qpair(qpair); } @@ -518,7 +519,9 @@ nvme_transport_ctrlr_disconnect_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk void nvme_transport_ctrlr_disconnect_qpair_done(struct spdk_nvme_qpair *qpair) { - nvme_qpair_abort_all_queued_reqs(qpair, 0); + if (qpair->active_proc == nvme_ctrlr_get_current_process(qpair->ctrlr)) { + nvme_qpair_abort_all_queued_reqs(qpair, 0); + } nvme_qpair_set_state(qpair, NVME_QPAIR_DISCONNECTED); } diff --git a/test/unit/lib/nvme/nvme_transport.c/nvme_transport_ut.c b/test/unit/lib/nvme/nvme_transport.c/nvme_transport_ut.c index 97cd10d58..825e6d360 100644 --- a/test/unit/lib/nvme/nvme_transport.c/nvme_transport_ut.c +++ b/test/unit/lib/nvme/nvme_transport.c/nvme_transport_ut.c @@ -22,6 +22,8 @@ DEFINE_STUB(spdk_nvme_qpair_process_completions, int32_t, (struct spdk_nvme_qpai DEFINE_STUB(spdk_nvme_poll_group_process_completions, int64_t, (struct spdk_nvme_poll_group *group, uint32_t completions_per_qpair, spdk_nvme_disconnected_qpair_cb disconnected_qpair_cb), 0); +DEFINE_STUB(nvme_ctrlr_get_current_process, struct spdk_nvme_ctrlr_process *, + (struct spdk_nvme_ctrlr *ctrlr), NULL); static void ut_construct_transport(struct spdk_nvme_transport *transport, const char name[])