125 lines
4.2 KiB
Diff
125 lines
4.2 KiB
Diff
From 34555d211c58ac7615d41547f56756ae02d22957 Mon Sep 17 00:00:00 2001
|
|
From: suweifeng <suweifeng1@huawei.com>
|
|
Date: Tue, 8 Jun 2021 22:11:53 +0800
|
|
Subject: [PATCH 26/27] Fix race condition in continuous setup and teardown
|
|
cuse session
|
|
|
|
If we continuous setup and teardown cuse session, It will teardown
|
|
uninitialized cuse session and cause segment fault, So add delay until
|
|
session created.
|
|
|
|
Signed-off-by: suweifeng <suweifeng1@huawei.com>
|
|
---
|
|
lib/nvme/nvme_cuse.c | 41 +++++++++++++++++++++++++++++++++++++----
|
|
1 file changed, 37 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/lib/nvme/nvme_cuse.c b/lib/nvme/nvme_cuse.c
|
|
index 3eccfd0..8f0be31 100644
|
|
--- a/lib/nvme/nvme_cuse.c
|
|
+++ b/lib/nvme/nvme_cuse.c
|
|
@@ -55,6 +55,8 @@ struct cuse_device {
|
|
|
|
pthread_t tid;
|
|
struct fuse_session *session;
|
|
+ pthread_cond_t session_cond; /* session condition variable */
|
|
+ pthread_mutex_t session_mtx; /* session mutex variable */
|
|
|
|
struct cuse_device *ctrlr_device;
|
|
struct cuse_device *ns_devices; /**< Array of cuse ns devices */
|
|
@@ -666,11 +668,17 @@ cuse_thread(void *arg)
|
|
cuse_device->session = cuse_lowlevel_setup(cuse_argc, cuse_argv, &ci, &cuse_ctrlr_clop,
|
|
&multithreaded, cuse_device);
|
|
}
|
|
+
|
|
if (!cuse_device->session) {
|
|
SPDK_ERRLOG("Cannot create cuse session\n");
|
|
+ pthread_mutex_lock(&cuse_device->session_mtx);
|
|
+ pthread_cond_signal(&cuse_device->session_cond);
|
|
+ pthread_mutex_unlock(&cuse_device->session_mtx);
|
|
goto err;
|
|
}
|
|
-
|
|
+ pthread_mutex_lock(&cuse_device->session_mtx);
|
|
+ pthread_cond_signal(&cuse_device->session_cond);
|
|
+ pthread_mutex_unlock(&cuse_device->session_mtx);
|
|
SPDK_NOTICELOG("fuse session for device %s created\n", cuse_device->dev_name);
|
|
|
|
/* Receive and process fuse requests */
|
|
@@ -718,13 +726,20 @@ cuse_nvme_ns_start(struct cuse_device *ctrlr_device, uint32_t nsid)
|
|
free(ns_device);
|
|
return -ENAMETOOLONG;
|
|
}
|
|
-
|
|
+ pthread_cond_init(&ns_device->session_cond, NULL);
|
|
+ pthread_mutex_init(&ns_device->session_mtx, NULL);
|
|
rv = pthread_create(&ns_device->tid, NULL, cuse_thread, ns_device);
|
|
if (rv != 0) {
|
|
SPDK_ERRLOG("pthread_create failed\n");
|
|
return -rv;
|
|
}
|
|
-
|
|
+ pthread_mutex_lock(&ns_device->session_mtx);
|
|
+ pthread_cond_wait(&ns_device->session_cond, &ns_device->session_mtx);
|
|
+ pthread_mutex_unlock(&ns_device->session_mtx);
|
|
+ if (!ns_device->session) {
|
|
+ SPDK_ERRLOG("create namespace session failed\n");
|
|
+ return -1;
|
|
+ }
|
|
ns_device->is_started = true;
|
|
|
|
return 0;
|
|
@@ -739,9 +754,10 @@ cuse_nvme_ns_stop(struct cuse_device *ctrlr_device, uint32_t nsid)
|
|
if (!ns_device->is_started) {
|
|
return;
|
|
}
|
|
-
|
|
fuse_session_exit(ns_device->session);
|
|
pthread_join(ns_device->tid, NULL);
|
|
+ pthread_cond_destroy(&ns_device->session_cond);
|
|
+ pthread_mutex_destroy(&ns_device->session_mtx);
|
|
ns_device->is_started = false;
|
|
}
|
|
|
|
@@ -817,8 +833,14 @@ cuse_nvme_ctrlr_stop(struct cuse_device *ctrlr_device)
|
|
cuse_nvme_ns_stop(ctrlr_device, i);
|
|
}
|
|
|
|
+ if (!ctrlr_device->is_started) {
|
|
+ return;
|
|
+ }
|
|
fuse_session_exit(ctrlr_device->session);
|
|
pthread_join(ctrlr_device->tid, NULL);
|
|
+ pthread_cond_destroy(&ctrlr_device->session_cond);
|
|
+ pthread_mutex_destroy(&ctrlr_device->session_mtx);
|
|
+ ctrlr_device->is_started = false;
|
|
TAILQ_REMOVE(&g_ctrlr_ctx_head, ctrlr_device, tailq);
|
|
spdk_bit_array_clear(g_ctrlr_started, ctrlr_device->index);
|
|
if (spdk_bit_array_count_set(g_ctrlr_started) == 0) {
|
|
@@ -894,12 +916,23 @@ nvme_cuse_start(struct spdk_nvme_ctrlr *ctrlr)
|
|
snprintf(ctrlr_device->dev_name, sizeof(ctrlr_device->dev_name), "spdk/nvme%d",
|
|
ctrlr_device->index);
|
|
|
|
+ pthread_cond_init(&ctrlr_device->session_cond, NULL);
|
|
+ pthread_mutex_init(&ctrlr_device->session_mtx, NULL);
|
|
rv = pthread_create(&ctrlr_device->tid, NULL, cuse_thread, ctrlr_device);
|
|
if (rv != 0) {
|
|
SPDK_ERRLOG("pthread_create failed\n");
|
|
rv = -rv;
|
|
goto err3;
|
|
}
|
|
+ pthread_mutex_lock(&ctrlr_device->session_mtx);
|
|
+ pthread_cond_wait(&ctrlr_device->session_cond, &ctrlr_device->session_mtx);
|
|
+ pthread_mutex_unlock(&ctrlr_device->session_mtx);
|
|
+ if (!ctrlr_device->session) {
|
|
+ SPDK_ERRLOG("cuse session create failed\n");
|
|
+ rv = -1;
|
|
+ goto err3;
|
|
+ }
|
|
+ ctrlr_device->is_started = true;
|
|
TAILQ_INSERT_TAIL(&g_ctrlr_ctx_head, ctrlr_device, tailq);
|
|
|
|
ctrlr_device->ns_devices = (struct cuse_device *)calloc(num_ns, sizeof(struct cuse_device));
|
|
--
|
|
2.33.0
|
|
|