mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-14 12:10:26 +03:00
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 <tim@chase2k.com> Reviewed-by: Olaf Faaland <faaland1@llnl.gov> Reviewed-by: Matt Ahrens <mahrens@delphix.com> Reviewed-by: George Melikov <mail@gmelikov.ru> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #8550 Closes #8558
This commit is contained in:
parent
ce4432c542
commit
f4e35b165c
@ -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);
|
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,
|
(void) cv_timedwait_sig(cv, &tx->tx_sync_lock,
|
||||||
ddi_get_lbolt() + time);
|
ddi_get_lbolt() + time);
|
||||||
else
|
} else {
|
||||||
cv_wait_sig(cv, &tx->tx_sync_lock);
|
cv_wait_sig(cv, &tx->tx_sync_lock);
|
||||||
|
}
|
||||||
|
|
||||||
CALLB_CPR_SAFE_END(cpr, &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_synced=%llu waiting=%llu dp=%p\n",
|
||||||
tx->tx_synced_txg, tx->tx_sync_txg_waiting, dp);
|
tx->tx_synced_txg, tx->tx_sync_txg_waiting, dp);
|
||||||
cv_broadcast(&tx->tx_sync_more_cv);
|
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);
|
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);
|
txg, tx->tx_quiesce_txg_waiting, tx->tx_sync_txg_waiting);
|
||||||
while (tx->tx_open_txg < txg) {
|
while (tx->tx_open_txg < txg) {
|
||||||
cv_broadcast(&tx->tx_quiesce_more_cv);
|
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);
|
mutex_exit(&tx->tx_sync_lock);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,11 @@ zthr_procedure(void *arg)
|
|||||||
t->zthr_func(t->zthr_arg, t);
|
t->zthr_func(t->zthr_arg, t);
|
||||||
mutex_enter(&t->zthr_state_lock);
|
mutex_enter(&t->zthr_state_lock);
|
||||||
} else {
|
} 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) {
|
if (t->zthr_wait_time == 0) {
|
||||||
cv_wait_sig(&t->zthr_cv, &t->zthr_state_lock);
|
cv_wait_sig(&t->zthr_cv, &t->zthr_state_lock);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user