Fix txg_sync_thread deadlock
Update two kmem_alloc()'s in dbuf_dirty() to use KM_PUSHPAGE. Because these functions are called from txg_sync_thread we must ensure they don't reenter the zfs filesystem code via the .writepage callback. This would result in a deadlock. This deadlock is rare and has only been observed once under an abusive mmap() write workload. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
f7ef846ea1
commit
beb9826902
|
@ -1095,7 +1095,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
|||
dn->dn_dirtyctx =
|
||||
(dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN);
|
||||
ASSERT(dn->dn_dirtyctx_firstset == NULL);
|
||||
dn->dn_dirtyctx_firstset = kmem_alloc(1, KM_SLEEP);
|
||||
dn->dn_dirtyctx_firstset = kmem_alloc(1, KM_PUSHPAGE);
|
||||
}
|
||||
mutex_exit(&dn->dn_mtx);
|
||||
|
||||
|
@ -1172,7 +1172,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
|||
* to make a copy of it so that the changes we make in this
|
||||
* transaction group won't leak out when we sync the older txg.
|
||||
*/
|
||||
dr = kmem_zalloc(sizeof (dbuf_dirty_record_t), KM_SLEEP);
|
||||
dr = kmem_zalloc(sizeof (dbuf_dirty_record_t), KM_PUSHPAGE);
|
||||
list_link_init(&dr->dr_dirty_node);
|
||||
if (db->db_level == 0) {
|
||||
void *data_old = db->db_buf;
|
||||
|
|
Loading…
Reference in New Issue