diff --git a/lib/nvme/nvme.c b/lib/nvme/nvme.c index ac09f82d3..f631c5041 100644 --- a/lib/nvme/nvme.c +++ b/lib/nvme/nvme.c @@ -206,7 +206,7 @@ nvme_free_request(struct nvme_request *req) } int -nvme_mutex_init_shared(pthread_mutex_t *mtx) +nvme_robust_mutex_init_shared(pthread_mutex_t *mtx) { int rc = 0; @@ -219,6 +219,7 @@ nvme_mutex_init_shared(pthread_mutex_t *mtx) return -1; } if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) || + pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) || pthread_mutex_init(mtx, &attr)) { rc = -1; } @@ -281,7 +282,7 @@ nvme_driver_init(void) */ assert(spdk_process_is_primary()); - ret = nvme_mutex_init_shared(&g_spdk_nvme_driver->lock); + ret = nvme_robust_mutex_init_shared(&g_spdk_nvme_driver->lock); if (ret != 0) { SPDK_ERRLOG("failed to initialize mutex\n"); spdk_memzone_free(SPDK_NVME_DRIVER_NAME); diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index b42ae619b..877a121a3 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -1240,7 +1240,7 @@ nvme_ctrlr_start(struct spdk_nvme_ctrlr *ctrlr) } int -nvme_mutex_init_recursive_shared(pthread_mutex_t *mtx) +nvme_robust_mutex_init_recursive_shared(pthread_mutex_t *mtx) { pthread_mutexattr_t attr; int rc = 0; @@ -1250,6 +1250,7 @@ nvme_mutex_init_recursive_shared(pthread_mutex_t *mtx) } if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) || #ifndef __FreeBSD__ + pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) || pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) || #endif pthread_mutex_init(mtx, &attr)) { @@ -1276,7 +1277,7 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr) TAILQ_INIT(&ctrlr->active_io_qpairs); - rc = nvme_mutex_init_recursive_shared(&ctrlr->ctrlr_lock); + rc = nvme_robust_mutex_init_recursive_shared(&ctrlr->ctrlr_lock); if (rc != 0) { return rc; } diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 791015150..3174e3b82 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -465,6 +465,26 @@ nvme_qpair_is_io_queue(struct spdk_nvme_qpair *qpair) return qpair->id != 0; } +static inline int +nvme_robust_mutex_lock(pthread_mutex_t *mtx) +{ + int rc = pthread_mutex_lock(mtx); + +#ifndef __FreeBSD__ + if (rc == EOWNERDEAD) { + rc = pthread_mutex_consistent(mtx); + } +#endif + + return rc; +} + +static inline int +nvme_robust_mutex_unlock(pthread_mutex_t *mtx) +{ + return pthread_mutex_unlock(mtx); +} + /* Admin functions */ int nvme_ctrlr_cmd_identify_controller(struct spdk_nvme_ctrlr *ctrlr, void *payload, @@ -540,8 +560,8 @@ uint64_t nvme_get_quirks(const struct spdk_pci_id *id); void spdk_nvme_ctrlr_opts_set_defaults(struct spdk_nvme_ctrlr_opts *opts); -int nvme_mutex_init_shared(pthread_mutex_t *mtx); -int nvme_mutex_init_recursive_shared(pthread_mutex_t *mtx); +int nvme_robust_mutex_init_shared(pthread_mutex_t *mtx); +int nvme_robust_mutex_init_recursive_shared(pthread_mutex_t *mtx); bool nvme_completion_is_retry(const struct spdk_nvme_cpl *cpl); void nvme_qpair_print_command(struct spdk_nvme_qpair *qpair, struct spdk_nvme_cmd *cmd);