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;
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));
#ifdef _KERNEL
/*
- * Disable the normal reclaim path for the txg_sync thread. This
- * ensures the thread will never enter dmu_tx_assign() which can
- * otherwise occur due to direct reclaim. If this is allowed to
- * happen the system can deadlock. Direct reclaim call path:
- *
- * ->shrink_icache_memory->prune_icache->dispose_list->
- * clear_inode->zpl_clear_inode->zfs_inactive->dmu_tx_assign
+ * 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_MEMALLOC;
+ current->flags |= PF_NOFS;
#endif /* _KERNEL */
txg_thread_enter(tx, &cpr);