summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2019-04-04 09:44:46 -0700
committerGitHub <[email protected]>2019-04-04 09:44:46 -0700
commitf4e35b165c1a3dff5c635fe89e7a52277731ca56 (patch)
tree94e34a8d8edcc0a2613d9ee4438b3f6f4104ec95
parentce4432c5424eb9aa4d00833ee7529cf24491bdde (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
-rw-r--r--module/zfs/txg.c24
-rw-r--r--module/zfs/zthr.c6
2 files changed, 25 insertions, 5 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);
}
diff --git a/module/zfs/zthr.c b/module/zfs/zthr.c
index dd8505caa..532e8ce0f 100644
--- a/module/zfs/zthr.c
+++ b/module/zfs/zthr.c
@@ -234,7 +234,11 @@ zthr_procedure(void *arg)
t->zthr_func(t->zthr_arg, t);
mutex_enter(&t->zthr_state_lock);
} else {
- /* go to sleep */
+ /*
+ * 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 (t->zthr_wait_time == 0) {
cv_wait_sig(&t->zthr_cv, &t->zthr_state_lock);
} else {