From acc8a31863eed629632d80590a0c2bb8ca9406e6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 4 Oct 2024 13:56:43 -0400 Subject: [PATCH] ARC: Cache arc_c value during arc_evict() Since arc_evict() run can take some time, arc_c change during it may result in undesired shift in ARC states balance. Primarily in case of arc_c reduction it may cause eviction from MFU data state despite its being below the target already. Instead we should evict as originally planned and if needed do another round after. Reviewed-by: Theera K. Reviewed-by: George Melikov Reviewed-by: Brian Behlendorf Signed-off-by: Alexander Motin Sponsored by: iXsystems, Inc. Closes #16576 Closes #16605 --- module/zfs/arc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/module/zfs/arc.c b/module/zfs/arc.c index f40de4cb9..370500ef0 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -4240,7 +4240,7 @@ arc_evict_adj(uint64_t frac, uint64_t total, uint64_t up, uint64_t down, static uint64_t arc_evict(void) { - uint64_t asize, bytes, total_evicted = 0; + uint64_t bytes, total_evicted = 0; int64_t e, mrud, mrum, mfud, mfum, w; static uint64_t ogrd, ogrm, ogfd, ogfm; static uint64_t gsrd, gsrm, gsfd, gsfm; @@ -4277,8 +4277,9 @@ arc_evict(void) arc_pd = arc_evict_adj(arc_pd, gsrd + gsfd, grd, gfd, 100); arc_pm = arc_evict_adj(arc_pm, gsrm + gsfm, grm, gfm, 100); - asize = aggsum_value(&arc_sums.arcstat_size); - int64_t wt = t - (asize - arc_c); + uint64_t asize = aggsum_value(&arc_sums.arcstat_size); + uint64_t ac = arc_c; + int64_t wt = t - (asize - ac); /* * Try to reduce pinned dnodes if more than 3/4 of wanted metadata @@ -4303,7 +4304,7 @@ arc_evict(void) /* Evict MRU metadata. */ w = wt * (int64_t)(arc_meta * arc_pm >> 48) >> 16; - e = MIN((int64_t)(asize - arc_c), (int64_t)(mrum - w)); + e = MIN((int64_t)(asize - ac), (int64_t)(mrum - w)); bytes = arc_evict_impl(arc_mru, ARC_BUFC_METADATA, e); total_evicted += bytes; mrum -= bytes; @@ -4311,7 +4312,7 @@ arc_evict(void) /* Evict MFU metadata. */ w = wt * (int64_t)(arc_meta >> 16) >> 16; - e = MIN((int64_t)(asize - arc_c), (int64_t)(m - bytes - w)); + e = MIN((int64_t)(asize - ac), (int64_t)(m - bytes - w)); bytes = arc_evict_impl(arc_mfu, ARC_BUFC_METADATA, e); total_evicted += bytes; mfum -= bytes; @@ -4320,14 +4321,14 @@ arc_evict(void) /* Evict MRU data. */ wt -= m - total_evicted; w = wt * (int64_t)(arc_pd >> 16) >> 16; - e = MIN((int64_t)(asize - arc_c), (int64_t)(mrud - w)); + e = MIN((int64_t)(asize - ac), (int64_t)(mrud - w)); bytes = arc_evict_impl(arc_mru, ARC_BUFC_DATA, e); total_evicted += bytes; mrud -= bytes; asize -= bytes; /* Evict MFU data. */ - e = asize - arc_c; + e = asize - ac; bytes = arc_evict_impl(arc_mfu, ARC_BUFC_DATA, e); mfud -= bytes; total_evicted += bytes;