From: Tom Caputi Date: Tue, 16 Oct 2018 21:00:55 +0000 (-0400) Subject: Fix lock inversion in txg_sync_thread() X-Git-Tag: zfs-0.8.0~332 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=a783dd96843699744e0543b579b5f50c9023432f;p=mirror_zfs.git 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 Reviewed-by: Matthew Ahrens Co-authored-by: Brian Behlendorf Signed-off-by: Tom Caputi Closes #8010 --- 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); /*