X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Ftxg.c;h=e14bff269b3e77a5c3421255f7a77ba89f2aebb5;hb=49d39798f286cce2497a87fc06d78c051ca87570;hp=d0d2b1716e88688df4d05857f537d2af7f0feb39;hpb=cddafdcbc55a38cdbdd3dc8c58f447b22bd847ee;p=zfs.git diff --git a/module/zfs/txg.c b/module/zfs/txg.c index d0d2b17..e14bff2 100644 --- a/module/zfs/txg.c +++ b/module/zfs/txg.c @@ -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)); @@ -374,15 +384,11 @@ txg_sync_thread(dsl_pool_t *dp) #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); @@ -524,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); }