Index: spa_misc.c =================================================================== --- spa_misc.c (revision 258354) +++ spa_misc.c (working copy) @@ -312,7 +312,7 @@ spa_config_lock_init(spa_t *spa) { for (int i = 0; i < SCL_LOCKS; i++) { spa_config_lock_t *scl = &spa->spa_config_lock[i]; - mutex_init(&scl->scl_lock, NULL, MUTEX_DEFAULT, NULL); + rw_init(&scl->scl_lock, NULL, RW_DEFAULT, NULL); cv_init(&scl->scl_cv, NULL, CV_DEFAULT, NULL); refcount_create_untracked(&scl->scl_count); scl->scl_writer = NULL; @@ -325,7 +325,7 @@ spa_config_lock_destroy(spa_t *spa) { for (int i = 0; i < SCL_LOCKS; i++) { spa_config_lock_t *scl = &spa->spa_config_lock[i]; - mutex_destroy(&scl->scl_lock); + rw_destroy(&scl->scl_lock); cv_destroy(&scl->scl_cv); refcount_destroy(&scl->scl_count); ASSERT(scl->scl_writer == NULL); @@ -340,10 +340,10 @@ spa_config_tryenter(spa_t *spa, int locks, void *t spa_config_lock_t *scl = &spa->spa_config_lock[i]; if (!(locks & (1 << i))) continue; - mutex_enter(&scl->scl_lock); + rw_enter(&scl->scl_lock, rw); if (rw == RW_READER) { if (scl->scl_writer || scl->scl_write_wanted) { - mutex_exit(&scl->scl_lock); + rw_exit(&scl->scl_lock); spa_config_exit(spa, locks ^ (1 << i), tag); return (0); } @@ -350,7 +350,7 @@ spa_config_tryenter(spa_t *spa, int locks, void *t } else { ASSERT(scl->scl_writer != curthread); if (!refcount_is_zero(&scl->scl_count)) { - mutex_exit(&scl->scl_lock); + rw_exit(&scl->scl_lock); spa_config_exit(spa, locks ^ (1 << i), tag); return (0); } @@ -357,7 +357,7 @@ spa_config_tryenter(spa_t *spa, int locks, void *t scl->scl_writer = curthread; } (void) refcount_add(&scl->scl_count, tag); - mutex_exit(&scl->scl_lock); + rw_exit(&scl->scl_lock); } return (1); } @@ -375,7 +375,7 @@ spa_config_enter(spa_t *spa, int locks, void *tag, wlocks_held |= (1 << i); if (!(locks & (1 << i))) continue; - mutex_enter(&scl->scl_lock); + rw_enter(&scl->scl_lock, rw); if (rw == RW_READER) { while (scl->scl_writer || scl->scl_write_wanted) { cv_wait(&scl->scl_cv, &scl->scl_lock); @@ -390,7 +390,7 @@ spa_config_enter(spa_t *spa, int locks, void *tag, scl->scl_writer = curthread; } (void) refcount_add(&scl->scl_count, tag); - mutex_exit(&scl->scl_lock); + rw_exit(&scl->scl_lock); } ASSERT(wlocks_held <= locks); } @@ -402,7 +402,8 @@ spa_config_exit(spa_t *spa, int locks, void *tag) spa_config_lock_t *scl = &spa->spa_config_lock[i]; if (!(locks & (1 << i))) continue; - mutex_enter(&scl->scl_lock); + rw_enter(&scl->scl_lock, + scl->scl_writer == curthread ? RW_WRITER : RW_READER); ASSERT(!refcount_is_zero(&scl->scl_count)); if (refcount_remove(&scl->scl_count, tag) == 0) { ASSERT(scl->scl_writer == NULL || @@ -410,7 +411,7 @@ spa_config_exit(spa_t *spa, int locks, void *tag) scl->scl_writer = NULL; /* OK in either case */ cv_broadcast(&scl->scl_cv); } - mutex_exit(&scl->scl_lock); + rw_exit(&scl->scl_lock); } } Index: sys/spa_impl.h =================================================================== --- sys/spa_impl.h (revision 258354) +++ sys/spa_impl.h (working copy) @@ -69,7 +69,7 @@ struct spa_aux_vdev { }; typedef struct spa_config_lock { - kmutex_t scl_lock; + krwlock_t scl_lock; kthread_t *scl_writer; int scl_write_wanted; kcondvar_t scl_cv;