Skip to content

Commit

Permalink
Allow stuck spa_namespace lock to be stolen
Browse files Browse the repository at this point in the history
Signed-off-by: Don Brady <don.brady@klarasystems.com>
  • Loading branch information
don-brady committed Mar 6, 2024
1 parent 9e4aac1 commit dfcfa28
Show file tree
Hide file tree
Showing 17 changed files with 313 additions and 175 deletions.
8 changes: 4 additions & 4 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -6912,11 +6912,11 @@ zdb_set_skip_mmp(char *target)
* Disable the activity check to allow examination of
* active pools.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
if ((spa = spa_lookup(target)) != NULL) {
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
}
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}

#define BOGUS_SUFFIX "_CHECKPOINTED_UNIVERSE"
Expand Down Expand Up @@ -8710,13 +8710,13 @@ main(int argc, char **argv)
* try opening the pool after clearing the
* log state.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
if ((spa = spa_lookup(target)) != NULL &&
spa->spa_log_state == SPA_LOG_MISSING) {
spa->spa_log_state = SPA_LOG_CLEAR;
error = 0;
}
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);

if (!error) {
error = spa_open_rewind(target, &spa,
Expand Down
16 changes: 8 additions & 8 deletions cmd/ztest/ztest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,9 +1183,9 @@ ztest_kill(ztest_shared_t *zs)
* Before we kill off ztest, make sure that the config is updated.
* See comment above spa_write_cachefile().
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);

(void) kill(getpid(), SIGKILL);
}
Expand Down Expand Up @@ -3571,10 +3571,10 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)

if (error == 0) {
(void) printf("successful split - results:\n");
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
show_pool_stats(spa);
show_pool_stats(spa_lookup("splitp"));
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
++zs->zs_splits;
--zs->zs_mirrors;
}
Expand Down Expand Up @@ -6858,11 +6858,11 @@ ztest_walk_pool_directory(char *header)
if (ztest_opts.zo_verbose >= 6)
(void) printf("%s\n", header);

mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
while ((spa = spa_next(spa)) != NULL)
if (ztest_opts.zo_verbose >= 6)
(void) printf("\t%s\n", spa_name(spa));
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}

static void
Expand Down Expand Up @@ -7604,11 +7604,11 @@ ztest_run(ztest_shared_t *zs)
/*
* Verify that we can loop over all pools.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa))
if (ztest_opts.zo_verbose > 3)
(void) printf("spa_next: found %s\n", spa_name(spa));
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);

/*
* Verify that we can export the pool and reimport it under a
Expand Down
8 changes: 5 additions & 3 deletions include/sys/spa.h
Original file line number Diff line number Diff line change
Expand Up @@ -828,9 +828,6 @@ extern void spa_sync_allpools(void);

extern int zfs_sync_pass_deferred_free;

/* spa namespace global mutex */
extern kmutex_t spa_namespace_lock;

/*
* SPA configuration functions in spa_config.c
*/
Expand Down Expand Up @@ -984,6 +981,11 @@ extern void spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw);
extern void spa_config_exit(spa_t *spa, int locks, const void *tag);
extern int spa_config_held(spa_t *spa, int locks, krw_t rw);

extern void spa_namespace_enter(const char *tag);
extern void spa_namespace_exit(const char *tag);
extern boolean_t spa_namespace_held(const char *tag);
extern boolean_t spa_namespace_tryenter(const char *tag);

/* Pool vdev add/remove lock */
extern uint64_t spa_vdev_enter(spa_t *spa);
extern uint64_t spa_vdev_detach_enter(spa_t *spa, uint64_t guid);
Expand Down
6 changes: 3 additions & 3 deletions module/os/linux/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,8 @@ zvol_open(struct block_device *bdev, fmode_t flag)
* the kernel so the only option is to return the error for
* the caller to handle it.
*/
if (!mutex_owned(&spa_namespace_lock)) {
if (!mutex_tryenter(&spa_namespace_lock)) {
if (!spa_namespace_held(FTAG)) {
if (!spa_namespace_tryenter(FTAG)) {
mutex_exit(&zv->zv_state_lock);
rw_exit(&zv->zv_suspend_lock);

Expand All @@ -593,7 +593,7 @@ zvol_open(struct block_device *bdev, fmode_t flag)
error = -zvol_first_open(zv, !(flag & FMODE_WRITE));

if (drop_namespace)
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}

if (error == 0) {
Expand Down
8 changes: 4 additions & 4 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8533,7 +8533,7 @@ l2arc_dev_get_next(void)
* of cache devices (l2arc_dev_mtx). Once a device has been selected,
* both locks will be dropped and a spa config lock held instead.
*/
mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
mutex_enter(&l2arc_dev_mtx);

/* if there are no vdevs, there is nothing to do */
Expand Down Expand Up @@ -8577,7 +8577,7 @@ l2arc_dev_get_next(void)
*/
if (next != NULL)
spa_config_enter(next->l2ad_spa, SCL_L2ARC, next, RW_READER);
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);

return (next);
}
Expand Down Expand Up @@ -10188,7 +10188,7 @@ l2arc_stop(void)
void
l2arc_spa_rebuild_start(spa_t *spa)
{
ASSERT(MUTEX_HELD(&spa_namespace_lock));
ASSERT(spa_namespace_held(FTAG));

/*
* Locate the spa's l2arc devices and kick off rebuild threads.
Expand All @@ -10213,7 +10213,7 @@ l2arc_spa_rebuild_start(spa_t *spa)
void
l2arc_spa_rebuild_stop(spa_t *spa)
{
ASSERT(MUTEX_HELD(&spa_namespace_lock));
ASSERT(spa_namespace_held(FTAG));

/*
* Locate the spa's l2arc devices and kick off rebuild threads.
Expand Down
4 changes: 2 additions & 2 deletions module/zfs/mmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,12 +723,12 @@ mmp_signal_all_threads(void)
{
spa_t *spa = NULL;

mutex_enter(&spa_namespace_lock);
spa_namespace_enter(FTAG);
while ((spa = spa_next(spa))) {
if (spa->spa_state == POOL_STATE_ACTIVE)
mmp_signal_thread(spa);
}
mutex_exit(&spa_namespace_lock);
spa_namespace_exit(FTAG);
}

/* BEGIN CSTYLED */
Expand Down
Loading

0 comments on commit dfcfa28

Please sign in to comment.