]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Minimize aggsum_compare(&arc_size, arc_c) calls.
authorAlexander Motin <mav@FreeBSD.org>
Fri, 14 Jun 2019 21:07:34 +0000 (17:07 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 14 Jun 2019 21:07:33 +0000 (14:07 -0700)
For busy ARC situation when arc_size close to arc_c is desired.  But
then it is quite likely that aggsum_compare(&arc_size, arc_c) will need
to flush per-CPU buckets to find exact comparison result.  Doing that
often in a hot path penalizes whole idea of aggsum usage there, since it
replaces few simple atomic additions with dozens of lock acquisitions.

Replacing aggsum_compare() with aggsum_upper_bound() in code increasing
arc_p when ARC is growing (arc_size < arc_c) according to PMC profiles
allows to save ~5% of CPU time in aggsum code during sequential write
to 12 ZVOLs with 16KB block size on large dual-socket system.

I suppose there some minor arc_p behavior change due to lower precision
of the new code, but I don't think it is a big deal, since it should
affect only very small window in time (aggsum buckets are flushed every
second) and in ARC size (buckets are limited to 10 average ARC blocks
per CPU).

Reviewed-by: Chris Dunlop <chris@onthe.net.au>
Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Allan Jude <allanjude@freebsd.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Closes #8901

module/zfs/arc.c

index 28a6c93c5a5f171916ed429947ef76f50cee11c6..bd2aafc2c21c8680bbb0171ac7c32b01cf961187 100644 (file)
@@ -5613,7 +5613,7 @@ arc_get_data_impl(arc_buf_hdr_t *hdr, uint64_t size, void *tag)
                 * If we are growing the cache, and we are adding anonymous
                 * data, and we have outgrown arc_p, update arc_p
                 */
-               if (aggsum_compare(&arc_size, arc_c) < 0 &&
+               if (aggsum_upper_bound(&arc_size) < arc_c &&
                    hdr->b_l1hdr.b_state == arc_anon &&
                    (zfs_refcount_count(&arc_anon->arcs_size) +
                    zfs_refcount_count(&arc_mru->arcs_size) > arc_p))