diff options
author | Brian Behlendorf <[email protected]> | 2019-04-04 09:44:46 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2019-04-04 09:44:46 -0700 |
commit | f4e35b165c1a3dff5c635fe89e7a52277731ca56 (patch) | |
tree | 94e34a8d8edcc0a2613d9ee4438b3f6f4104ec95 /module/zfs/txg.c | |
parent | ce4432c5424eb9aa4d00833ee7529cf24491bdde (diff) |
Fix txg_wait_open() load average inflation
Callers of txg_wait_open() which set should_quiesce=B_TRUE should be
accounted for as iowait time. Otherwise, the caller is understood
to be idle and cv_wait_sig() is used to prevent incorrectly inflating
the system load average.
Similarly txg_wait_wait() has been updated to use cv_wait_io() to
be accounted against iowait.
Reviewed-by: Tim Chase <[email protected]>
Reviewed-by: Olaf Faaland <[email protected]>
Reviewed-by: Matt Ahrens <[email protected]>
Reviewed-by: George Melikov <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #8550
Closes #8558
Diffstat (limited to 'module/zfs/txg.c')
-rw-r--r-- | module/zfs/txg.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/module/zfs/txg.c b/module/zfs/txg.c index b3f895302..0fcd569e3 100644 --- a/module/zfs/txg.c +++ b/module/zfs/txg.c @@ -242,11 +242,17 @@ txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, clock_t time) { CALLB_CPR_SAFE_BEGIN(cpr); - if (time) + /* + * cv_wait_sig() is used instead of cv_wait() in order to prevent + * this process from incorrectly contributing to the system load + * average when idle. + */ + if (time) { (void) cv_timedwait_sig(cv, &tx->tx_sync_lock, ddi_get_lbolt() + time); - else + } else { cv_wait_sig(cv, &tx->tx_sync_lock); + } CALLB_CPR_SAFE_END(cpr, &tx->tx_sync_lock); } @@ -689,7 +695,7 @@ txg_wait_synced(dsl_pool_t *dp, uint64_t txg) "tx_synced=%llu waiting=%llu dp=%p\n", tx->tx_synced_txg, tx->tx_sync_txg_waiting, dp); cv_broadcast(&tx->tx_sync_more_cv); - cv_wait(&tx->tx_sync_done_cv, &tx->tx_sync_lock); + cv_wait_io(&tx->tx_sync_done_cv, &tx->tx_sync_lock); } mutex_exit(&tx->tx_sync_lock); } @@ -715,7 +721,17 @@ txg_wait_open(dsl_pool_t *dp, uint64_t txg, boolean_t should_quiesce) txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting); while (tx->tx_open_txg < txg) { cv_broadcast(&tx->tx_quiesce_more_cv); - cv_wait(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock); + /* + * Callers setting should_quiesce will use cv_wait_io() and + * be accounted for as iowait time. Otherwise, the caller is + * understood to be idle and cv_wait_sig() is used to prevent + * incorrectly inflating the system load average. + */ + if (should_quiesce == B_TRUE) { + cv_wait_io(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock); + } else { + cv_wait_sig(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock); + } } mutex_exit(&tx->tx_sync_lock); } |