Make zfs_immediate_write_sz a module paramater
[zfs.git] / module / zfs / txg.c
index 5afb139..e14bff2 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);
 }
@@ -218,9 +218,19 @@ uint64_t
 txg_hold_open(dsl_pool_t *dp, txg_handle_t *th)
 {
        tx_state_t *tx = &dp->dp_tx;
-       tx_cpu_t *tc = &tx->tx_cpu[CPU_SEQID];
+       tx_cpu_t *tc;
        uint64_t txg;
 
+       /*
+        * It appears the processor id is simply used as a "random"
+        * number to index into the array, and there isn't any other
+        * significance to the chosen tx_cpu. Because.. Why not use
+        * the current cpu to index into the array?
+        */
+       kpreempt_disable();
+       tc = &tx->tx_cpu[CPU_SEQID];
+       kpreempt_enable();
+
        mutex_enter(&tc->tc_lock);
 
        txg = tx->tx_open_txg;
@@ -339,7 +349,7 @@ txg_dispatch_callbacks(dsl_pool_t *dp, uint64_t txg)
                            TASKQ_THREADS_CPU_PCT | TASKQ_PREPOPULATE);
                }
 
-               cb_list = kmem_alloc(sizeof (list_t), KM_SLEEP);
+               cb_list = kmem_alloc(sizeof (list_t), KM_PUSHPAGE);
                list_create(cb_list, sizeof (dmu_tx_callback_t),
                    offsetof(dmu_tx_callback_t, dcb_node));
 
@@ -372,6 +382,15 @@ txg_sync_thread(dsl_pool_t *dp)
        callb_cpr_t cpr;
        uint64_t start, delta;
 
+#ifdef _KERNEL
+       /*
+        * Annotate this process with a flag that indicates that it is
+        * unsafe to use KM_SLEEP during memory allocations due to the
+        * potential for a deadlock.  KM_PUSHPAGE should be used instead.
+        */
+       current->flags |= PF_NOFS;
+#endif /* _KERNEL */
+
        txg_thread_enter(tx, &cpr);
 
        start = delta = 0;
@@ -493,7 +512,7 @@ void
 txg_delay(dsl_pool_t *dp, uint64_t txg, int ticks)
 {
        tx_state_t *tx = &dp->dp_tx;
-       int timeout = ddi_get_lbolt() + ticks;
+       clock_t timeout = ddi_get_lbolt() + ticks;
 
        /* don't delay if this txg could transition to quiesing immediately */
        if (tx->tx_open_txg > txg ||
@@ -511,6 +530,8 @@ txg_delay(dsl_pool_t *dp, uint64_t txg, int ticks)
                (void) cv_timedwait(&tx->tx_quiesce_more_cv, &tx->tx_sync_lock,
                    timeout);
 
+       DMU_TX_STAT_BUMP(dmu_tx_delay);
+
        mutex_exit(&tx->tx_sync_lock);
 }