From bf3d6707968d0aaad7890fa44ecea018b5dabb07 Mon Sep 17 00:00:00 2001 From: Tomasz Kulasek Date: Thu, 14 Nov 2019 11:18:40 -0500 Subject: [PATCH] lib/nvme: stop all NVMe io producers on detach Now all registered producers should be stopped (unregistered) before NVMe detach, otherwise NVMe controller cannot be safely detached. This patch allows to stop all not unregistered io producers before NVMe detach: 1. Callback to the "struct nvme_io_msg_producer" to stop producer started on selected controller. 2. On nvme_io_msg_ctrlr_detach() if there's some unregistered producers, stop all before freeing resources. This approach also fixes issue with not to stop CUSE device when NVMe controller is detached without unregistering producer (github issue #1033). Fixes #1033 Signed-off-by: Tomasz Kulasek Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/474273 (master) (cherry picked from commit fd2af7afa9a53bc0855ce1ae19710a373c015077) Change-Id: Ia1ffef566bb745edb55c54d6786ea481a35bbefd Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478350 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- lib/nvme/nvme_cuse.c | 1 + lib/nvme/nvme_io_msg.c | 8 ++++++++ lib/nvme/nvme_io_msg.h | 1 + 3 files changed, 10 insertions(+) diff --git a/lib/nvme/nvme_cuse.c b/lib/nvme/nvme_cuse.c index 4d5507274..b06e2065c 100644 --- a/lib/nvme/nvme_cuse.c +++ b/lib/nvme/nvme_cuse.c @@ -784,6 +784,7 @@ nvme_cuse_stop(struct spdk_nvme_ctrlr *ctrlr) static struct nvme_io_msg_producer cuse_nvme_io_msg_producer = { .name = "cuse", + .stop = nvme_cuse_stop, }; int diff --git a/lib/nvme/nvme_io_msg.c b/lib/nvme/nvme_io_msg.c index 41a1aee62..a89a55fe9 100644 --- a/lib/nvme/nvme_io_msg.c +++ b/lib/nvme/nvme_io_msg.c @@ -147,6 +147,14 @@ nvme_io_msg_ctrlr_register(struct spdk_nvme_ctrlr *ctrlr, void nvme_io_msg_ctrlr_detach(struct spdk_nvme_ctrlr *ctrlr) { + struct nvme_io_msg_producer *io_msg_producer, *tmp; + + /* Stop all producers */ + STAILQ_FOREACH_SAFE(io_msg_producer, &ctrlr->io_producers, link, tmp) { + io_msg_producer->stop(ctrlr); + STAILQ_REMOVE(&ctrlr->io_producers, io_msg_producer, nvme_io_msg_producer, link); + } + if (ctrlr->external_io_msgs) { spdk_ring_free(ctrlr->external_io_msgs); } diff --git a/lib/nvme/nvme_io_msg.h b/lib/nvme/nvme_io_msg.h index 60e8c54d0..d909e9d52 100644 --- a/lib/nvme/nvme_io_msg.h +++ b/lib/nvme/nvme_io_msg.h @@ -52,6 +52,7 @@ struct spdk_nvme_io_msg { struct nvme_io_msg_producer { const char *name; + void (*stop)(struct spdk_nvme_ctrlr *ctrlr); STAILQ_ENTRY(nvme_io_msg_producer) link; };