]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Fix txg_wait_open() load average inflation
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 4 Apr 2019 16:44:46 +0000 (09:44 -0700)
committerGitHub <noreply@github.com>
Thu, 4 Apr 2019 16:44:46 +0000 (09:44 -0700)
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

module/zfs/txg.c
module/zfs/zthr.c

index b3f895302e636297c684deada04d41ac8e6119fe..0fcd569e3b4498f7ae2e328af41a50a6a74c166f 100644 (file)
@@ -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);
 }
index dd8505caa5d60befbbcf4c5425e76e0bfd86bac8..532e8ce0f8a257ab0cb5ff6df88c8b30ef796511 100644 (file)
@@ -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 {