Fix inflated load average
[zfs.git] / module / zfs / txg.c
index 382a2a9..00c1c7d 100644 (file)
@@ -166,10 +166,10 @@ txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, uint64_t time)
        CALLB_CPR_SAFE_BEGIN(cpr);
 
        if (time)
-               (void) cv_timedwait(cv, &tx->tx_sync_lock,
+               (void) cv_timedwait_interruptible(cv, &tx->tx_sync_lock,
                    ddi_get_lbolt() + time);
        else
-               cv_wait(cv, &tx->tx_sync_lock);
+               cv_wait_interruptible(cv, &tx->tx_sync_lock);
 
        CALLB_CPR_SAFE_END(cpr, &tx->tx_sync_lock);
 }
@@ -350,6 +350,20 @@ txg_dispatch_callbacks(dsl_pool_t *dp, uint64_t txg)
        }
 }
 
+/*
+ * Wait for pending commit callbacks of already-synced transactions to finish
+ * processing.
+ * Calling this function from within a commit callback will deadlock.
+ */
+void
+txg_wait_callbacks(dsl_pool_t *dp)
+{
+       tx_state_t *tx = &dp->dp_tx;
+
+       if (tx->tx_commit_cb_taskq != NULL)
+               taskq_wait(tx->tx_commit_cb_taskq);
+}
+
 static void
 txg_sync_thread(dsl_pool_t *dp)
 {
@@ -735,6 +749,7 @@ EXPORT_SYMBOL(txg_register_callbacks);
 EXPORT_SYMBOL(txg_delay);
 EXPORT_SYMBOL(txg_wait_synced);
 EXPORT_SYMBOL(txg_wait_open);
+EXPORT_SYMBOL(txg_wait_callbacks);
 EXPORT_SYMBOL(txg_stalled);
 EXPORT_SYMBOL(txg_sync_waiting);
 #endif