From 4faf9fc37bb2dbab40dae791dae9b5ac01df9bb1 Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 16 Apr 2020 13:34:31 -0700 Subject: [PATCH] nvme: Make spdk_nvme_cuse_register thread safe There is no indication right now that this function couldn't be called by multiple threads on different controllers. However, internally it is using two globals that can become corrupted if the user were to do this. Put a lock around them so it is safe. Signed-off-by: Ben Walker Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1903 (master) (cherry picked from commit 5340d17823cf5cd1806f92a98930257fa8e215ca) Change-Id: I59361f510eb1659c2346f1fd33c375add1dc9c81 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2158 Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/nvme/nvme_cuse.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/nvme/nvme_cuse.c b/lib/nvme/nvme_cuse.c index 669960e38..558c8e235 100644 --- a/lib/nvme/nvme_cuse.c +++ b/lib/nvme/nvme_cuse.c @@ -60,6 +60,7 @@ struct cuse_device { TAILQ_ENTRY(cuse_device) tailq; }; +static pthread_mutex_t g_cuse_mtx = PTHREAD_MUTEX_INITIALIZER; static TAILQ_HEAD(, cuse_device) g_ctrlr_ctx_head = TAILQ_HEAD_INITIALIZER(g_ctrlr_ctx_head); static struct spdk_bit_array *g_ctrlr_started; @@ -916,13 +917,18 @@ nvme_cuse_stop(struct spdk_nvme_ctrlr *ctrlr) { struct cuse_device *ctrlr_device; + pthread_mutex_lock(&g_cuse_mtx); + ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); if (!ctrlr_device) { SPDK_ERRLOG("Cannot find associated CUSE device\n"); + pthread_mutex_unlock(&g_cuse_mtx); return; } cuse_nvme_ctrlr_stop(ctrlr_device); + + pthread_mutex_unlock(&g_cuse_mtx); } static struct nvme_io_msg_producer cuse_nvme_io_msg_producer = { @@ -940,11 +946,15 @@ spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr) return rc; } + pthread_mutex_lock(&g_cuse_mtx); + rc = nvme_cuse_start(ctrlr); if (rc) { nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer); } + pthread_mutex_unlock(&g_cuse_mtx); + return rc; } @@ -953,14 +963,19 @@ spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr) { struct cuse_device *ctrlr_device; + pthread_mutex_lock(&g_cuse_mtx); + ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); if (!ctrlr_device) { SPDK_ERRLOG("Cannot find associated CUSE device\n"); + pthread_mutex_unlock(&g_cuse_mtx); return; } cuse_nvme_ctrlr_stop(ctrlr_device); + pthread_mutex_unlock(&g_cuse_mtx); + nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer); } @@ -969,11 +984,15 @@ spdk_nvme_cuse_get_ctrlr_name(struct spdk_nvme_ctrlr *ctrlr) { struct cuse_device *ctrlr_device; + pthread_mutex_lock(&g_cuse_mtx); + ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); if (!ctrlr_device) { + pthread_mutex_unlock(&g_cuse_mtx); return NULL; } + pthread_mutex_unlock(&g_cuse_mtx); return ctrlr_device->dev_name; } @@ -982,10 +1001,14 @@ spdk_nvme_cuse_get_ns_name(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid) { struct cuse_device *ns_device; + pthread_mutex_lock(&g_cuse_mtx); + ns_device = nvme_cuse_get_cuse_ns_device(ctrlr, nsid); if (!ns_device) { + pthread_mutex_unlock(&g_cuse_mtx); return NULL; } + pthread_mutex_unlock(&g_cuse_mtx); return ns_device->dev_name; }