Skip to content

Commit 666aa69

Browse files
authored
Non-l2arc pool reads shouldn't be l2arc misses
The current l2_misses accounting behavior treats all reads to pools without a configured l2arc as an l2arc miss, IFF there is at least one other pool on the system which does have an l2arc configured. This makes it extremely hard to tune for an improved l2arc hit/miss ratio because this ratio will be modulated by reads from pools which do not (and should not) have l2arc devices; its upper limit will depend on the ratio of reads from l2arc'd pools and non-l2arc'd pools. This PR prevents ARC reads affecting l2arc stats (n.b. l2_misses is the only relevant one) where the target spa doesn't have an l2arc. Includes new test - l2arc_l2miss_pos.ksh Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: George Amanakis <[email protected]> Signed-off-by: Adam Moss <[email protected]> Closes #10921
1 parent 241c62b commit 666aa69

File tree

6 files changed

+119
-9
lines changed

6 files changed

+119
-9
lines changed

module/zfs/arc.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6305,7 +6305,11 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
63056305
metadata, misses);
63066306
}
63076307

6308-
if (vd != NULL && l2arc_ndev != 0 && !(l2arc_norw && devw)) {
6308+
/* Check if the spa even has l2 configured */
6309+
const boolean_t spa_has_l2 = l2arc_ndev != 0 &&
6310+
spa->spa_l2cache.sav_count > 0;
6311+
6312+
if (vd != NULL && spa_has_l2 && !(l2arc_norw && devw)) {
63096313
/*
63106314
* Read from the L2ARC if the following are true:
63116315
* 1. The L2ARC vdev was previously cached.
@@ -6406,15 +6410,24 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
64066410
} else {
64076411
if (vd != NULL)
64086412
spa_config_exit(spa, SCL_L2ARC, vd);
6413+
64096414
/*
6410-
* Skip ARC stat bump for block pointers with
6411-
* embedded data. The data are read from the blkptr
6412-
* itself via decode_embedded_bp_compressed().
6415+
* Only a spa with l2 should contribute to l2
6416+
* miss stats. (Including the case of having a
6417+
* faulted cache device - that's also a miss.)
64136418
*/
6414-
if (l2arc_ndev != 0 && !embedded_bp) {
6415-
DTRACE_PROBE1(l2arc__miss,
6416-
arc_buf_hdr_t *, hdr);
6417-
ARCSTAT_BUMP(arcstat_l2_misses);
6419+
if (spa_has_l2) {
6420+
/*
6421+
* Skip ARC stat bump for block pointers with
6422+
* embedded data. The data are read from the
6423+
* blkptr itself via
6424+
* decode_embedded_bp_compressed().
6425+
*/
6426+
if (!embedded_bp) {
6427+
DTRACE_PROBE1(l2arc__miss,
6428+
arc_buf_hdr_t *, hdr);
6429+
ARCSTAT_BUMP(arcstat_l2_misses);
6430+
}
64186431
}
64196432
}
64206433

tests/runfiles/common.run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ post =
899899
tags = ['functional', 'log_spacemap']
900900

901901
[tests/functional/l2arc]
902-
tests = ['l2arc_arcstats_pos', 'l2arc_mfuonly_pos',
902+
tests = ['l2arc_arcstats_pos', 'l2arc_mfuonly_pos', 'l2arc_l2miss_pos',
903903
'persist_l2arc_001_pos', 'persist_l2arc_002_pos',
904904
'persist_l2arc_003_neg', 'persist_l2arc_004_pos', 'persist_l2arc_005_pos',
905905
'persist_l2arc_006_pos', 'persist_l2arc_007_pos', 'persist_l2arc_008_pos']

tests/zfs-tests/tests/functional/l2arc/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ dist_pkgdata_SCRIPTS = \
33
cleanup.ksh \
44
setup.ksh \
55
l2arc_arcstats_pos.ksh \
6+
l2arc_l2miss_pos.ksh \
67
l2arc_mfuonly_pos.ksh \
78
persist_l2arc_001_pos.ksh \
89
persist_l2arc_002_pos.ksh \

tests/zfs-tests/tests/functional/l2arc/l2arc.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export SIZE=1G
2424
export VDIR=$TESTDIR/disk.l2arc
2525
export VDEV="$VDIR/a"
2626
export VDEV_CACHE="$VDIR/b"
27+
export VDEV1="$VDIR/c"
2728

2829
# fio options
2930
export DIRECTORY=/$TESTPOOL
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/bin/ksh -p
2+
#
3+
# CDDL HEADER START
4+
#
5+
# This file and its contents are supplied under the terms of the
6+
# Common Development and Distribution License ("CDDL"), version 1.0.
7+
# You may only use this file in accordance with the terms of version
8+
# 1.0 of the CDDL.
9+
#
10+
# A full copy of the text of the CDDL should have accompanied this
11+
# source. A copy of the CDDL is also available via the Internet at
12+
# http://www.illumos.org/license/CDDL.
13+
#
14+
# CDDL HEADER END
15+
#
16+
17+
#
18+
# Copyright (c) 2020, Adam Moss. All rights reserved.
19+
#
20+
21+
. $STF_SUITE/include/libtest.shlib
22+
. $STF_SUITE/tests/functional/l2arc/l2arc.cfg
23+
24+
#
25+
# DESCRIPTION:
26+
# l2arc_misses does not increment upon reads from a pool without l2arc
27+
#
28+
# STRATEGY:
29+
# 1. Create pool with a cache device.
30+
# 2. Create pool without a cache device.
31+
# 3. Create a random file in the no-cache-device pool,
32+
# and random read for 10 sec.
33+
# 4. Check that l2arc_misses hasn't risen
34+
# 5. Create a random file in the pool with the cache device,
35+
# and random read for 10 sec.
36+
# 6. Check that l2arc_misses has risen
37+
#
38+
39+
verify_runnable "global"
40+
41+
log_assert "l2arc_misses does not increment upon reads from a pool without l2arc."
42+
43+
function cleanup
44+
{
45+
if poolexists $TESTPOOL ; then
46+
destroy_pool $TESTPOOL
47+
fi
48+
if poolexists $TESTPOOL1 ; then
49+
destroy_pool $TESTPOOL1
50+
fi
51+
}
52+
log_onexit cleanup
53+
54+
typeset fill_mb=800
55+
typeset cache_sz=$(( 1.4 * $fill_mb ))
56+
export FILE_SIZE=$(( floor($fill_mb / $NUMJOBS) ))M
57+
58+
log_must truncate -s ${cache_sz}M $VDEV_CACHE
59+
60+
log_must zpool create -O compression=off -f $TESTPOOL $VDEV cache $VDEV_CACHE
61+
log_must zpool create -O compression=off -f $TESTPOOL1 $VDEV1
62+
63+
# I/O to pool without l2arc - expect that l2_misses stays constant
64+
export DIRECTORY=/$TESTPOOL1
65+
log_must fio $FIO_SCRIPTS/mkfiles.fio
66+
log_must fio $FIO_SCRIPTS/random_reads.fio
67+
# attempt to remove entries for pool from ARC so we would try
68+
# to hit the nonexistent L2ARC for subsequent reads
69+
log_must zpool export $TESTPOOL1
70+
log_must zpool import $TESTPOOL1 -d $VDEV1
71+
72+
typeset starting_miss_count=$(get_arcstat l2_misses)
73+
74+
log_must fio $FIO_SCRIPTS/random_reads.fio
75+
log_must test $(get_arcstat l2_misses) -eq $starting_miss_count
76+
77+
# I/O to pool with l2arc - expect that l2_misses rises
78+
export DIRECTORY=/$TESTPOOL
79+
log_must fio $FIO_SCRIPTS/mkfiles.fio
80+
log_must fio $FIO_SCRIPTS/random_reads.fio
81+
# wait for L2ARC writes to actually happen
82+
arcstat_quiescence_noecho l2_size
83+
# attempt to remove entries for pool from ARC so we would try
84+
# to hit L2ARC for subsequent reads
85+
log_must zpool export $TESTPOOL
86+
log_must zpool import $TESTPOOL -d $VDEV
87+
88+
log_must fio $FIO_SCRIPTS/random_reads.fio
89+
log_must test $(get_arcstat l2_misses) -gt $starting_miss_count
90+
91+
log_must zpool destroy -f $TESTPOOL
92+
log_must zpool destroy -f $TESTPOOL1
93+
94+
log_pass "l2arc_misses does not increment upon reads from a pool without l2arc."

tests/zfs-tests/tests/functional/l2arc/setup.ksh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ verify_runnable "global"
2525
log_must rm -rf $VDIR
2626
log_must mkdir -p $VDIR
2727
log_must mkfile $SIZE $VDEV
28+
log_must mkfile $SIZE $VDEV1
2829

2930
log_pass

0 commit comments

Comments
 (0)