--- a/module/zfs/dbuf.c 2026-04-24 14:20:12.565390796 -0400 +++ b/module/zfs/dbuf.c 2026-04-24 14:20:40.711198653 -0400 @@ -864,23 +864,16 @@ dbuf_evict_notify(uint64_t size) { /* - * We check if we should evict without holding the dbuf_evict_lock, - * because it's OK to occasionally make the wrong decision here, - * and grabbing the lock results in massive lock contention. + * Wake the dedicated eviction thread when the cache + * exceeds target. Inline eviction from write-completion + * context is intentionally avoided: it adds a second + * multilist sublist lock to every write, and when + * kmem_cache_free is slow (__free_frozen_pages zone lock + * contention on 6.14+), the cascade stalls txg_sync. + * See openzfs#18426. */ - if (size > dbuf_cache_target_bytes()) { - /* - * Avoid calling dbuf_evict_one() from memory reclaim context - * (e.g. Linux kswapd, FreeBSD pagedaemon) to prevent deadlocks. - * Memory reclaim threads can get stuck waiting for the dbuf - * hash lock. - */ - if (size > dbuf_cache_hiwater_bytes() && - !current_is_reclaim_thread()) { - dbuf_evict_one(); - } + if (size > dbuf_cache_target_bytes()) cv_signal(&dbuf_evict_cv); - } } /*