]> granicus.if.org Git - zfs/commitdiff
Fix overly broad spa config lock
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 27 Feb 2019 18:49:22 +0000 (10:49 -0800)
committerGitHub <noreply@github.com>
Wed, 27 Feb 2019 18:49:22 +0000 (10:49 -0800)
The spa_txg_history_init_io() and spa_txg_history_fini_io() were
mistakenly taking SCL_ALL when only SCL_CONFIG is required to
access the vdev stats.  This could result in a deadlock which
was observed when running ztest.

Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
Reviewed-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #8445

module/zfs/spa_stats.c
module/zfs/vdev.c

index c02ef86b51c66062edfc84e8d9d75fdc30913d51..e01d2d19879c2ead5c04197db048a1b21196642e 100644 (file)
@@ -414,9 +414,9 @@ spa_txg_history_init_io(spa_t *spa, uint64_t txg, dsl_pool_t *dp)
 
        ts = kmem_alloc(sizeof (txg_stat_t), KM_SLEEP);
 
-       spa_config_enter(spa, SCL_ALL, FTAG, RW_READER);
+       spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
        vdev_get_stats(spa->spa_root_vdev, &ts->vs1);
-       spa_config_exit(spa, SCL_ALL, FTAG);
+       spa_config_exit(spa, SCL_CONFIG, FTAG);
 
        ts->txg = txg;
        ts->ndirty = dp->dp_dirty_pertxg[txg & TXG_MASK];
@@ -437,9 +437,9 @@ spa_txg_history_fini_io(spa_t *spa, txg_stat_t *ts)
                return;
        }
 
-       spa_config_enter(spa, SCL_ALL, FTAG, RW_READER);
+       spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
        vdev_get_stats(spa->spa_root_vdev, &ts->vs2);
-       spa_config_exit(spa, SCL_ALL, FTAG);
+       spa_config_exit(spa, SCL_CONFIG, FTAG);
 
        spa_txg_history_set(spa, ts->txg, TXG_STATE_SYNCED, gethrtime());
        spa_txg_history_set_io(spa, ts->txg,
index a803833ba63b1e520376dc21f34a20957a335992..1332c720f79b2af87dccf5d12aff58f8b59038c1 100644 (file)
@@ -3892,7 +3892,6 @@ vdev_get_stats_ex(vdev_t *vd, vdev_stat_t *vs, vdev_stat_ex_t *vsx)
                        vs->vs_resilver_deferred = vd->vdev_resilver_deferred;
        }
 
-       ASSERT(spa_config_held(vd->vdev_spa, SCL_ALL, RW_READER) != 0);
        vdev_get_stats_ex_impl(vd, vs, vsx);
        mutex_exit(&vd->vdev_stat_lock);
 }