Skip to content

Commit 903280d

Browse files
committed
L2ARC: Restrict write size to 1/4 of the device
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. Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc.
1 parent 786641d commit 903280d

File tree

2 files changed

+10
-40
lines changed

2 files changed

+10
-40
lines changed

module/zfs/arc.c

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8035,9 +8035,8 @@ l2arc_write_size(l2arc_dev_t *dev)
80358035
*/
80368036
size = l2arc_write_max;
80378037
if (size == 0) {
8038-
cmn_err(CE_NOTE, "Bad value for l2arc_write_max, value must "
8039-
"be greater than zero, resetting it to the default (%d)",
8040-
L2ARC_WRITE_SIZE);
8038+
cmn_err(CE_NOTE, "l2arc_write_max must be greater than zero, "
8039+
"resetting it to the default (%d)", L2ARC_WRITE_SIZE);
80418040
size = l2arc_write_max = L2ARC_WRITE_SIZE;
80428041
}
80438042

@@ -8060,30 +8059,9 @@ l2arc_write_size(l2arc_dev_t *dev)
80608059
* device. This is important in l2arc_evict(), otherwise infinite
80618060
* iteration can occur.
80628061
*/
8063-
if (size > dev->l2ad_end - dev->l2ad_start) {
8064-
cmn_err(CE_NOTE, "l2arc_write_max or l2arc_write_boost "
8065-
"plus the overhead of log blocks (persistent L2ARC, "
8066-
"%llu bytes) exceeds the size of the cache device "
8067-
"(guid %llu), resetting them to the default (%d)",
8068-
(u_longlong_t)l2arc_log_blk_overhead(size, dev),
8069-
(u_longlong_t)dev->l2ad_vdev->vdev_guid, L2ARC_WRITE_SIZE);
8062+
size = MIN(size, (dev->l2ad_end - dev->l2ad_start) / 4);
80708063

8071-
size = l2arc_write_max = l2arc_write_boost = L2ARC_WRITE_SIZE;
8072-
8073-
if (l2arc_trim_ahead > 1) {
8074-
cmn_err(CE_NOTE, "l2arc_trim_ahead set to 1");
8075-
l2arc_trim_ahead = 1;
8076-
}
8077-
8078-
if (arc_warm == B_FALSE)
8079-
size += l2arc_write_boost;
8080-
8081-
size += l2arc_log_blk_overhead(size, dev);
8082-
if (dev->l2ad_vdev->vdev_has_trim && l2arc_trim_ahead > 0) {
8083-
size += MAX(64 * 1024 * 1024,
8084-
(size * l2arc_trim_ahead) / 100);
8085-
}
8086-
}
8064+
size = P2ROUNDUP(size, dev->l2ad_vdev->vdev_ashift);
80878065

80888066
return (size);
80898067

tests/zfs-tests/tests/functional/cache/cache_012_pos.ksh

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@
3131
# 2. Set l2arc_write_max to a value larger than the cache device.
3232
# 3. Create a file larger than the cache device and random read
3333
# for 10 sec.
34-
# 4. Verify that l2arc_write_max is set back to the default.
35-
# 5. Set l2arc_write_max to a value less than the cache device size but
34+
# 4. Set l2arc_write_max to a value less than the cache device size but
3635
# larger than the default (256MB).
37-
# 6. Record the l2_size.
38-
# 7. Random read for 1 sec.
39-
# 8. Record the l2_size again.
40-
# 9. If (6) <= (8) then we have not looped around yet.
41-
# 10. If (6) > (8) then we looped around. Break out of the loop and test.
42-
# 11. Destroy pool.
36+
# 5. Record the l2_size.
37+
# 6. Random read for 1 sec.
38+
# 7. Record the l2_size again.
39+
# 8. If (5) <= (7) then we have not looped around yet.
40+
# 9. Destroy pool.
4341
#
4442

4543
verify_runnable "global"
@@ -93,10 +91,6 @@ log_must zfs set relatime=off $TESTPOOL
9391
log_must fio $FIO_SCRIPTS/mkfiles.fio
9492
log_must fio $FIO_SCRIPTS/random_reads.fio
9593

96-
typeset write_max2=$(get_tunable L2ARC_WRITE_MAX)
97-
98-
log_must test $write_max2 -eq $write_max
99-
10094
log_must set_tunable32 L2ARC_WRITE_MAX $(( 256 * 1024 * 1024 ))
10195
export RUNTIME=1
10296

@@ -108,8 +102,6 @@ while $do_once || [[ $l2_size1 -le $l2_size2 ]]; do
108102
do_once=false
109103
done
110104

111-
log_must test $l2_size1 -gt $l2_size2
112-
113105
log_must zpool destroy $TESTPOOL
114106

115107
log_pass "Looping around a cache device succeeds."

0 commit comments

Comments
 (0)