]> git.proxmox.com Git - mirror_zfs.git/commitdiff
L2ARC: Restrict write size to 1/4 of the device
authorAlexander Motin <mav@FreeBSD.org>
Tue, 14 Nov 2023 21:47:57 +0000 (16:47 -0500)
committerGitHub <noreply@github.com>
Tue, 14 Nov 2023 21:47:57 +0000 (13:47 -0800)
PR #15457 exposed weird logic in L2ARC write sizing. If it appeared
bigger than device size, instead of liming write it reset all the
system-wide tunables to their default.  Aside of being excessive,
it did not actually help with the problem, still allowing infinite
loop to happen.

This patch removes the tunables reverting logic, but instead limits
L2ARC writes (or at least eviction/trim) to 1/4 of the capacity.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Amanakis <gamanakis@gmail.com>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Sponsored by: iXsystems, Inc.
Closes #15519

module/zfs/arc.c
tests/zfs-tests/tests/functional/cache/cache_012_pos.ksh

index 2d08cc5e724033fd86f20834247bc071b8ea9ad2..f81beab222ffe23ffc61538284bc5ddf7207c922 100644 (file)
@@ -8035,9 +8035,8 @@ l2arc_write_size(l2arc_dev_t *dev)
         */
        size = l2arc_write_max;
        if (size == 0) {
-               cmn_err(CE_NOTE, "Bad value for l2arc_write_max, value must "
-                   "be greater than zero, resetting it to the default (%d)",
-                   L2ARC_WRITE_SIZE);
+               cmn_err(CE_NOTE, "l2arc_write_max must be greater than zero, "
+                   "resetting it to the default (%d)", L2ARC_WRITE_SIZE);
                size = l2arc_write_max = L2ARC_WRITE_SIZE;
        }
 
@@ -8060,30 +8059,9 @@ l2arc_write_size(l2arc_dev_t *dev)
         * device. This is important in l2arc_evict(), otherwise infinite
         * iteration can occur.
         */
-       if (size > dev->l2ad_end - dev->l2ad_start) {
-               cmn_err(CE_NOTE, "l2arc_write_max or l2arc_write_boost "
-                   "plus the overhead of log blocks (persistent L2ARC, "
-                   "%llu bytes) exceeds the size of the cache device "
-                   "(guid %llu), resetting them to the default (%d)",
-                   (u_longlong_t)l2arc_log_blk_overhead(size, dev),
-                   (u_longlong_t)dev->l2ad_vdev->vdev_guid, L2ARC_WRITE_SIZE);
+       size = MIN(size, (dev->l2ad_end - dev->l2ad_start) / 4);
 
-               size = l2arc_write_max = l2arc_write_boost = L2ARC_WRITE_SIZE;
-
-               if (l2arc_trim_ahead > 1) {
-                       cmn_err(CE_NOTE, "l2arc_trim_ahead set to 1");
-                       l2arc_trim_ahead = 1;
-               }
-
-               if (arc_warm == B_FALSE)
-                       size += l2arc_write_boost;
-
-               size += l2arc_log_blk_overhead(size, dev);
-               if (dev->l2ad_vdev->vdev_has_trim && l2arc_trim_ahead > 0) {
-                       size += MAX(64 * 1024 * 1024,
-                           (size * l2arc_trim_ahead) / 100);
-               }
-       }
+       size = P2ROUNDUP(size, 1ULL << dev->l2ad_vdev->vdev_ashift);
 
        return (size);
 
index 74caa12a9cc468a1b5feb091cfbfb564bc402b9f..945db71bf113e63d5455b32bc3e7ef214872385b 100755 (executable)
 #      2. Set l2arc_write_max to a value larger than the cache device.
 #      3. Create a file larger than the cache device and random read
 #              for 10 sec.
-#      4. Verify that l2arc_write_max is set back to the default.
-#      5. Set l2arc_write_max to a value less than the cache device size but
+#      4. Set l2arc_write_max to a value less than the cache device size but
 #              larger than the default (256MB).
-#      6. Record the l2_size.
-#      7. Random read for 1 sec.
-#      8. Record the l2_size again.
-#      9. If (6) <= (8) then we have not looped around yet.
-#      10. If (6) > (8) then we looped around. Break out of the loop and test.
-#      11. Destroy pool.
+#      5. Record the l2_size.
+#      6. Random read for 1 sec.
+#      7. Record the l2_size again.
+#      8. If (5) <= (7) then we have not looped around yet.
+#      9. Destroy pool.
 #
 
 verify_runnable "global"
@@ -93,10 +91,6 @@ log_must zfs set relatime=off $TESTPOOL
 log_must fio $FIO_SCRIPTS/mkfiles.fio
 log_must fio $FIO_SCRIPTS/random_reads.fio
 
-typeset write_max2=$(get_tunable L2ARC_WRITE_MAX)
-
-log_must test $write_max2 -eq $write_max
-
 log_must set_tunable32 L2ARC_WRITE_MAX $(( 256 * 1024 * 1024 ))
 export RUNTIME=1
 
@@ -108,8 +102,6 @@ while $do_once || [[ $l2_size1 -le $l2_size2 ]]; do
        do_once=false
 done
 
-log_must test $l2_size1 -gt $l2_size2
-
 log_must zpool destroy $TESTPOOL
 
 log_pass "Looping around a cache device succeeds."