aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorKevin Jin <[email protected]>2022-05-26 12:36:14 -0400
committerGitHub <[email protected]>2022-05-26 09:36:14 -0700
commit152d6fda54e61042a70059c95c44b364aea0bbd8 (patch)
tree25bda55c56945d8872631e512772794ccd165608 /include
parentd98a67a53a180bd88ec8d9aeea75d92e1c9968b5 (diff)
Fix inflated quiesce time caused by lwb_tx during zil_commit()
In current zil_commit() process, transaction lwb_tx is assigned in zil_lwb_write_issue(), and is committed in zil_lwb_flush_vdevs_done(). Thus, during lwb write out process, the txg is held in open or quiesing state, until zil_lwb_flush_vdevs_done() is called. If the zil's zio latency is high, it will cause txg_sync_thread() to starve. The goal here is to defer waiting for zil_lwb_flush_vdevs_done to the 'syncing' txg state. That is, in zil_sync(). In this patch, it achieves the goal without holding transaction. A new function zil_lwb_flush_wait_all() is introduced. It waits for the completion of all the zil_lwb_flush_vdevs_done() by given txg. Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Prakash Surya <[email protected]> Signed-off-by: jxdking <[email protected]> Closes #12321
Diffstat (limited to 'include')
-rw-r--r--include/sys/zil_impl.h8
1 files changed, 7 insertions, 1 deletions
diff --git a/include/sys/zil_impl.h b/include/sys/zil_impl.h
index d2f401865..8409ce864 100644
--- a/include/sys/zil_impl.h
+++ b/include/sys/zil_impl.h
@@ -99,7 +99,7 @@ typedef struct lwb {
char *lwb_buf; /* log write buffer */
zio_t *lwb_write_zio; /* zio for the lwb buffer */
zio_t *lwb_root_zio; /* root zio for lwb write and flushes */
- dmu_tx_t *lwb_tx; /* tx for log block allocation */
+ uint64_t lwb_issued_txg; /* the txg when the write is issued */
uint64_t lwb_max_txg; /* highest txg in this lwb */
list_node_t lwb_node; /* zilog->zl_lwb_list linkage */
list_t lwb_itxs; /* list of itx's */
@@ -209,6 +209,12 @@ struct zilog {
uint_t zl_prev_rotor; /* rotor for zl_prev[] */
txg_node_t zl_dirty_link; /* protected by dp_dirty_zilogs list */
uint64_t zl_dirty_max_txg; /* highest txg used to dirty zilog */
+
+ kmutex_t zl_lwb_io_lock; /* protect following members */
+ uint64_t zl_lwb_inflight[TXG_SIZE]; /* io issued, but not done */
+ kcondvar_t zl_lwb_io_cv; /* signal when the flush is done */
+ uint64_t zl_lwb_max_issued_txg; /* max txg when lwb io issued */
+
/*
* Max block size for this ZIL. Note that this can not be changed
* while the ZIL is in use because consumers (ZPL/zvol) need to take