diff options
author | mm <mm@FreeBSD.org> | 2013-04-24 21:21:03 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2013-04-24 21:21:03 +0000 |
commit | e2d108deacec294a8f0cec29f767a5b9dad3ca23 (patch) | |
tree | f131a04a41d09c25fa6216b876cb117a565fb0c5 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c | |
parent | df40a0e7efabf85cc2995e880b5da15ee78b748b (diff) | |
download | FreeBSD-src-e2d108deacec294a8f0cec29f767a5b9dad3ca23.zip FreeBSD-src-e2d108deacec294a8f0cec29f767a5b9dad3ca23.tar.gz |
MFV r249857:
Merge vendor bugfix for a possible deadlock related to async destroy
and improve write performance by introducing a new lock protecting
tx_open_txg.
Illumos ZFS issues:
3642 dsl_scan_active() should not issue I/O to determine if async
destroying is active
3643 txg_delay should not hold the tc_lock
MFC after: 1 week
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c index 7be37db..46b5c34 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c @@ -132,6 +132,8 @@ txg_init(dsl_pool_t *dp, uint64_t txg) int i; mutex_init(&tx->tx_cpu[c].tc_lock, NULL, MUTEX_DEFAULT, NULL); + mutex_init(&tx->tx_cpu[c].tc_open_lock, NULL, MUTEX_DEFAULT, + NULL); for (i = 0; i < TXG_SIZE; i++) { cv_init(&tx->tx_cpu[c].tc_cv[i], NULL, CV_DEFAULT, NULL); @@ -174,6 +176,7 @@ txg_fini(dsl_pool_t *dp) for (c = 0; c < max_ncpus; c++) { int i; + mutex_destroy(&tx->tx_cpu[c].tc_open_lock); mutex_destroy(&tx->tx_cpu[c].tc_lock); for (i = 0; i < TXG_SIZE; i++) { cv_destroy(&tx->tx_cpu[c].tc_cv[i]); @@ -297,10 +300,12 @@ txg_hold_open(dsl_pool_t *dp, txg_handle_t *th) tx_cpu_t *tc = &tx->tx_cpu[CPU_SEQID]; uint64_t txg; - mutex_enter(&tc->tc_lock); - + mutex_enter(&tc->tc_open_lock); txg = tx->tx_open_txg; + + mutex_enter(&tc->tc_lock); tc->tc_count[txg & TXG_MASK]++; + mutex_exit(&tc->tc_lock); th->th_cpu = tc; th->th_txg = txg; @@ -313,7 +318,8 @@ txg_rele_to_quiesce(txg_handle_t *th) { tx_cpu_t *tc = th->th_cpu; - mutex_exit(&tc->tc_lock); + ASSERT(!MUTEX_HELD(&tc->tc_lock)); + mutex_exit(&tc->tc_open_lock); } void @@ -350,10 +356,10 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg) int c; /* - * Grab all tx_cpu locks so nobody else can get into this txg. + * Grab all tc_open_locks so nobody else can get into this txg. */ for (c = 0; c < max_ncpus; c++) - mutex_enter(&tx->tx_cpu[c].tc_lock); + mutex_enter(&tx->tx_cpu[c].tc_open_lock); ASSERT(txg == tx->tx_open_txg); tx->tx_open_txg++; @@ -363,7 +369,7 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg) * enter the next transaction group. */ for (c = 0; c < max_ncpus; c++) - mutex_exit(&tx->tx_cpu[c].tc_lock); + mutex_exit(&tx->tx_cpu[c].tc_open_lock); /* * Quiesce the transaction group by waiting for everyone to txg_exit(). |