From 050dfc504545e42ab7030dda7e3d3dec5a57a9c5 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 10 Nov 2020 13:39:26 -0500 Subject: [PATCH] Fix dmu_tx_dirty_throttle after arc_c reduction After initial arc_c was reduced to arc_c_min it became possible that on datasets with primarycache=metadata or none dirty data make up most of ARC capacity and easily more than configured 50% of initial arc_c, that causes forced txg commits by arc_tempreserve_space() and periodic very long write delays. This patch makes arc_tempreserve_space() to use arc_c only after ARC warmed up once and arc_c really means something, but use arc_c_max before that. Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Reviewed-by: Matt Macy Signed-off-by: Alexander Motin Sponsored-By: iXsystems, Inc. Closes #11178 --- module/zfs/arc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 554449095..357841f97 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -7070,9 +7070,9 @@ arc_tempreserve_space(spa_t *spa, uint64_t reserve, uint64_t txg) */ uint64_t total_dirty = reserve + arc_tempreserve + anon_size; uint64_t spa_dirty_anon = spa_dirty_data(spa); - - if (total_dirty > arc_c * zfs_arc_dirty_limit_percent / 100 && - anon_size > arc_c * zfs_arc_anon_limit_percent / 100 && + uint64_t rarc_c = arc_warm ? arc_c : arc_c_max; + if (total_dirty > rarc_c * zfs_arc_dirty_limit_percent / 100 && + anon_size > rarc_c * zfs_arc_anon_limit_percent / 100 && spa_dirty_anon > anon_size * zfs_arc_pool_dirty_percent / 100) { #ifdef ZFS_DEBUG uint64_t meta_esize = zfs_refcount_count( @@ -7080,9 +7080,9 @@ arc_tempreserve_space(spa_t *spa, uint64_t reserve, uint64_t txg) uint64_t data_esize = zfs_refcount_count(&arc_anon->arcs_esize[ARC_BUFC_DATA]); dprintf("failing, arc_tempreserve=%lluK anon_meta=%lluK " - "anon_data=%lluK tempreserve=%lluK arc_c=%lluK\n", + "anon_data=%lluK tempreserve=%lluK rarc_c=%lluK\n", arc_tempreserve >> 10, meta_esize >> 10, - data_esize >> 10, reserve >> 10, arc_c >> 10); + data_esize >> 10, reserve >> 10, rarc_c >> 10); #endif DMU_TX_STAT_BUMP(dmu_tx_dirty_throttle); return (SET_ERROR(ERESTART));