Skip to content

Commit

Permalink
Fix lock inversion in txg_sync_thread()
Browse files Browse the repository at this point in the history
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 openzfs#8010
  • Loading branch information
Tom Caputi authored and ghfields committed Oct 29, 2018
1 parent 7ff4cdb commit 37f1b6e
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions module/zfs/txg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*
Expand Down

0 comments on commit 37f1b6e

Please sign in to comment.