summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-10-16 17:00:55 -0400
committerBrian Behlendorf <[email protected]>2018-10-24 14:37:02 -0700
commita783dd96843699744e0543b579b5f50c9023432f (patch)
treeed3ee0c03f7b8acffb29689b93a485cbcf6d6ed3
parentab4c009e3d0cf794bbe84aff3b9ac203eaed03c7 (diff)
Fix lock inversion in txg_sync_thread()
This patch fixes a lock inversion issue in txg_sync_thread() where the code would attempt hold the spa config lock as a reader while holding tx->tx_sync_lock. This races with spa_vdev_remove() which attempts to hold the tx->tx_sync_lock to assign a new tx (via spa_history_log_internal()) while holding the spa config lock as a writer. Reviewed-by: Serapheim Dimitropoulos <[email protected]> Reviewed-by: Matthew Ahrens <[email protected]> Co-authored-by: Brian Behlendorf <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes #8010
-rw-r--r--module/zfs/txg.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/module/zfs/txg.c b/module/zfs/txg.c
index aad1a8e57..db0f60cd1 100644
--- a/module/zfs/txg.c
+++ b/module/zfs/txg.c
@@ -562,22 +562,22 @@ txg_sync_thread(void *arg)
tx->tx_quiesced_txg = 0;
tx->tx_syncing_txg = txg;
DTRACE_PROBE2(txg__syncing, dsl_pool_t *, dp, uint64_t, txg);
- txg_stat_t *ts = spa_txg_history_init_io(spa, txg, dp);
cv_broadcast(&tx->tx_quiesce_more_cv);
dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n",
txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting);
mutex_exit(&tx->tx_sync_lock);
+ txg_stat_t *ts = spa_txg_history_init_io(spa, txg, dp);
start = ddi_get_lbolt();
spa_sync(spa, txg);
delta = ddi_get_lbolt() - start;
+ spa_txg_history_fini_io(spa, ts);
mutex_enter(&tx->tx_sync_lock);
tx->tx_synced_txg = txg;
tx->tx_syncing_txg = 0;
DTRACE_PROBE2(txg__synced, dsl_pool_t *, dp, uint64_t, txg);
- spa_txg_history_fini_io(spa, ts);
cv_broadcast(&tx->tx_sync_done_cv);
/*