Skip to content

Commit 77f842a

Browse files
committed
ZTS: Add L2ARC DWPD and parallel writes tests
Add four new functional tests to validate L2ARC DWPD rate limiting and parallel write features: - l2arc_dwpd_pos: Verifies DWPD rate limiting ordering (0>100>10>1) - l2arc_dwpd_multidev_pos: Verifies per-device DWPD budgets - l2arc_dwpd_persist_pos: Verifies DWPD works after pool export/import - l2arc_parallel_writes_pos: Verifies parallel write throughput scales with device count (~32MB/s per device) Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
1 parent 973a210 commit 77f842a

9 files changed

Lines changed: 490 additions & 2 deletions

File tree

tests/runfiles/common.run

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,8 @@ tags = ['functional', 'log_spacemap']
11281128

11291129
[tests/functional/l2arc]
11301130
tests = ['l2arc_arcstats_pos', 'l2arc_mfuonly_pos', 'l2arc_l2miss_pos',
1131-
'persist_l2arc_001_pos', 'persist_l2arc_002_pos',
1131+
'l2arc_dwpd_pos', 'l2arc_dwpd_multidev_pos', 'l2arc_dwpd_persist_pos',
1132+
'l2arc_parallel_writes_pos', 'persist_l2arc_001_pos', 'persist_l2arc_002_pos',
11321133
'persist_l2arc_003_neg', 'persist_l2arc_004_pos', 'persist_l2arc_005_pos']
11331134
tags = ['functional', 'l2arc']
11341135

tests/zfs-tests/include/tunables.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ INITIALIZE_CHUNK_SIZE initialize_chunk_size zfs_initialize_chunk_size
4646
INITIALIZE_VALUE initialize_value zfs_initialize_value
4747
KEEP_LOG_SPACEMAPS_AT_EXPORT keep_log_spacemaps_at_export zfs_keep_log_spacemaps_at_export
4848
LUA_MAX_MEMLIMIT lua.max_memlimit zfs_lua_max_memlimit
49+
L2ARC_DWPD_LIMIT l2arc.dwpd_limit l2arc_dwpd_limit
4950
L2ARC_MFUONLY l2arc.mfuonly l2arc_mfuonly
5051
L2ARC_NOPREFETCH l2arc.noprefetch l2arc_noprefetch
5152
L2ARC_REBUILD_BLOCKS_MIN_L2SIZE l2arc.rebuild_blocks_min_l2size l2arc_rebuild_blocks_min_l2size

tests/zfs-tests/tests/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,10 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
16571657
functional/l2arc/l2arc_arcstats_pos.ksh \
16581658
functional/l2arc/l2arc_l2miss_pos.ksh \
16591659
functional/l2arc/l2arc_mfuonly_pos.ksh \
1660+
functional/l2arc/l2arc_dwpd_pos.ksh \
1661+
functional/l2arc/l2arc_dwpd_multidev_pos.ksh \
1662+
functional/l2arc/l2arc_dwpd_persist_pos.ksh \
1663+
functional/l2arc/l2arc_parallel_writes_pos.ksh \
16601664
functional/l2arc/persist_l2arc_001_pos.ksh \
16611665
functional/l2arc/persist_l2arc_002_pos.ksh \
16621666
functional/l2arc/persist_l2arc_003_neg.ksh \

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ function cleanup
5555

5656
log_must set_tunable32 L2ARC_WRITE_MAX $write_max
5757
log_must set_tunable32 L2ARC_NOPREFETCH $noprefetch
58+
log_must set_tunable32 L2ARC_DWPD_LIMIT $dwpd_limit
5859
}
5960
log_onexit cleanup
6061

6162
typeset write_max=$(get_tunable L2ARC_WRITE_MAX)
6263
typeset noprefetch=$(get_tunable L2ARC_NOPREFETCH)
64+
typeset dwpd_limit=$(get_tunable L2ARC_DWPD_LIMIT)
6365
log_must set_tunable32 L2ARC_NOPREFETCH 0
66+
log_must set_tunable32 L2ARC_DWPD_LIMIT 0
6467

6568
typeset VDEV="$VDIR/vdev.disk"
6669
typeset VDEV_SZ=$(( 4 * 1024 * 1024 * 1024 ))
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/bin/ksh -p
2+
# SPDX-License-Identifier: CDDL-1.0
3+
#
4+
# CDDL HEADER START
5+
#
6+
# This file and its contents are supplied under the terms of the
7+
# Common Development and Distribution License ("CDDL"), version 1.0.
8+
# You may only use this file in accordance with the terms of version
9+
# 1.0 of the CDDL.
10+
#
11+
# A full copy of the text of the CDDL should have accompanied this
12+
# source. A copy of the CDDL is also available via the Internet at
13+
# http://www.illumos.org/license/CDDL.
14+
#
15+
# CDDL HEADER END
16+
#
17+
18+
#
19+
# Copyright (c) 2024. All rights reserved.
20+
#
21+
22+
. $STF_SUITE/include/libtest.shlib
23+
. $STF_SUITE/tests/functional/l2arc/l2arc.cfg
24+
25+
#
26+
# DESCRIPTION:
27+
# L2ARC DWPD rate limiting works independently per device.
28+
#
29+
# STRATEGY:
30+
# 1. Set DWPD limit before creating pool.
31+
# 2. Create pool with two cache devices, measure total writes.
32+
# 3. Recreate pool with one cache device, measure total writes.
33+
# 4. Verify dual-device writes exceed single-device writes.
34+
#
35+
36+
verify_runnable "global"
37+
38+
log_assert "L2ARC DWPD rate limiting works independently per device."
39+
40+
function cleanup
41+
{
42+
if poolexists $TESTPOOL ; then
43+
destroy_pool $TESTPOOL
44+
fi
45+
46+
log_must set_tunable32 L2ARC_WRITE_MAX $write_max
47+
log_must set_tunable32 L2ARC_NOPREFETCH $noprefetch
48+
log_must set_tunable32 L2ARC_DWPD_LIMIT $dwpd_limit
49+
log_must set_tunable64 ARC_MIN $arc_min
50+
log_must set_tunable64 ARC_MAX $arc_max
51+
}
52+
log_onexit cleanup
53+
54+
# Save original tunables
55+
typeset write_max=$(get_tunable L2ARC_WRITE_MAX)
56+
typeset noprefetch=$(get_tunable L2ARC_NOPREFETCH)
57+
typeset dwpd_limit=$(get_tunable L2ARC_DWPD_LIMIT)
58+
typeset arc_min=$(get_tunable ARC_MIN)
59+
typeset arc_max=$(get_tunable ARC_MAX)
60+
61+
# Test parameters
62+
typeset cache_sz=200
63+
typeset fill_mb=500
64+
typeset test_time=10
65+
typeset VDEV_CACHE2="$VDIR/cache2"
66+
67+
# Set DWPD before pool creation
68+
log_must set_tunable32 L2ARC_DWPD_LIMIT 100
69+
70+
# Configure arc_max = 1.5 * total_cache_size
71+
log_must set_tunable64 ARC_MIN $((cache_sz * 2 * 3 / 4 * 1024 * 1024))
72+
log_must set_tunable64 ARC_MAX $((cache_sz * 2 * 3 / 2 * 1024 * 1024))
73+
log_must set_tunable32 L2ARC_NOPREFETCH 0
74+
log_must set_tunable32 L2ARC_WRITE_MAX $((100 * 1024 * 1024))
75+
76+
# Create two cache devices
77+
log_must truncate -s ${cache_sz}M $VDEV_CACHE
78+
log_must truncate -s ${cache_sz}M $VDEV_CACHE2
79+
80+
log_must zpool create -f $TESTPOOL $VDEV cache $VDEV_CACHE $VDEV_CACHE2
81+
82+
# Fill first pass on both devices
83+
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=1M count=$fill_mb
84+
log_must sleep 6
85+
86+
# Measure writes with two devices
87+
typeset start=$(kstat arcstats.l2_write_bytes)
88+
log_must dd if=/dev/urandom of=/$TESTPOOL/file2 bs=1M count=100
89+
log_must sleep $test_time
90+
typeset end=$(kstat arcstats.l2_write_bytes)
91+
typeset dual_writes=$((end - start))
92+
93+
log_note "Dual-device writes: $((dual_writes / 1024))KB"
94+
95+
# Recreate with single device for comparison
96+
# Adjust arc_max so persist_threshold < single cache size
97+
log_must zpool destroy $TESTPOOL
98+
log_must set_tunable64 ARC_MIN $((cache_sz * 3 / 4 * 1024 * 1024))
99+
log_must set_tunable64 ARC_MAX $((cache_sz * 3 / 2 * 1024 * 1024))
100+
log_must zpool create -f $TESTPOOL $VDEV cache $VDEV_CACHE
101+
102+
# Fill first pass
103+
log_must dd if=/dev/urandom of=/$TESTPOOL/file3 bs=1M count=$fill_mb
104+
log_must sleep 6
105+
106+
# Measure writes with single device
107+
start=$(kstat arcstats.l2_write_bytes)
108+
log_must dd if=/dev/urandom of=/$TESTPOOL/file4 bs=1M count=100
109+
log_must sleep $test_time
110+
end=$(kstat arcstats.l2_write_bytes)
111+
typeset single_writes=$((end - start))
112+
113+
log_note "Single-device writes: $((single_writes / 1024))KB"
114+
115+
# Dual devices should write more than single (each has own DWPD budget)
116+
if [[ $dual_writes -le $single_writes ]]; then
117+
log_fail "Dual-device ($dual_writes) should exceed" \
118+
"single-device ($single_writes)"
119+
fi
120+
121+
log_must zpool destroy $TESTPOOL
122+
123+
log_pass "L2ARC DWPD rate limiting works independently per device."
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/ksh -p
2+
# SPDX-License-Identifier: CDDL-1.0
3+
#
4+
# CDDL HEADER START
5+
#
6+
# This file and its contents are supplied under the terms of the
7+
# Common Development and Distribution License ("CDDL"), version 1.0.
8+
# You may only use this file in accordance with the terms of version
9+
# 1.0 of the CDDL.
10+
#
11+
# A full copy of the text of the CDDL should have accompanied this
12+
# source. A copy of the CDDL is also available via the Internet at
13+
# http://www.illumos.org/license/CDDL.
14+
#
15+
# CDDL HEADER END
16+
#
17+
18+
#
19+
# Copyright (c) 2024. All rights reserved.
20+
#
21+
22+
. $STF_SUITE/include/libtest.shlib
23+
. $STF_SUITE/tests/functional/l2arc/l2arc.cfg
24+
25+
#
26+
# DESCRIPTION:
27+
# L2ARC DWPD rate limiting works after pool export/import.
28+
#
29+
# STRATEGY:
30+
# 1. Set DWPD limit before creating pool.
31+
# 2. Create pool with cache device.
32+
# 3. Fill L2ARC to complete first pass.
33+
# 4. Measure writes with rate limiting active.
34+
# 5. Export and import pool.
35+
# 6. Measure writes again.
36+
# 7. Verify rate limiting still works after import.
37+
#
38+
39+
verify_runnable "global"
40+
41+
log_assert "L2ARC DWPD rate limiting works after pool export/import."
42+
43+
function cleanup
44+
{
45+
if poolexists $TESTPOOL ; then
46+
destroy_pool $TESTPOOL
47+
fi
48+
49+
log_must set_tunable32 L2ARC_WRITE_MAX $write_max
50+
log_must set_tunable32 L2ARC_NOPREFETCH $noprefetch
51+
log_must set_tunable32 L2ARC_DWPD_LIMIT $dwpd_limit
52+
log_must set_tunable32 L2ARC_REBUILD_BLOCKS_MIN_L2SIZE $rebuild_min
53+
log_must set_tunable64 ARC_MIN $arc_min
54+
log_must set_tunable64 ARC_MAX $arc_max
55+
}
56+
log_onexit cleanup
57+
58+
# Save original tunables
59+
typeset write_max=$(get_tunable L2ARC_WRITE_MAX)
60+
typeset noprefetch=$(get_tunable L2ARC_NOPREFETCH)
61+
typeset dwpd_limit=$(get_tunable L2ARC_DWPD_LIMIT)
62+
typeset rebuild_min=$(get_tunable L2ARC_REBUILD_BLOCKS_MIN_L2SIZE)
63+
typeset arc_min=$(get_tunable ARC_MIN)
64+
typeset arc_max=$(get_tunable ARC_MAX)
65+
66+
# Test parameters (total writes must fit in 1GB vdev)
67+
typeset cache_sz=400
68+
typeset fill_mb=300
69+
typeset test_time=10
70+
71+
# Set DWPD before pool creation
72+
log_must set_tunable32 L2ARC_DWPD_LIMIT 100
73+
log_must set_tunable32 L2ARC_REBUILD_BLOCKS_MIN_L2SIZE 0
74+
75+
# Configure arc_max = 1.5 * cache_size
76+
log_must set_tunable64 ARC_MIN $((cache_sz * 3 / 4 * 1024 * 1024))
77+
log_must set_tunable64 ARC_MAX $((cache_sz * 3 / 2 * 1024 * 1024))
78+
log_must set_tunable32 L2ARC_NOPREFETCH 0
79+
log_must set_tunable32 L2ARC_WRITE_MAX $((100 * 1024 * 1024))
80+
81+
log_must truncate -s ${cache_sz}M $VDEV_CACHE
82+
83+
log_must zpool create -f $TESTPOOL $VDEV cache $VDEV_CACHE
84+
85+
# Fill first pass
86+
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=1M count=$fill_mb
87+
log_must sleep 6
88+
89+
# Measure writes before export
90+
typeset start1=$(kstat arcstats.l2_write_bytes)
91+
log_must dd if=/dev/urandom of=/$TESTPOOL/file2 bs=1M count=100
92+
log_must sleep $test_time
93+
typeset end1=$(kstat arcstats.l2_write_bytes)
94+
typeset writes_before=$((end1 - start1))
95+
96+
log_note "Writes before export: $((writes_before / 1024))KB"
97+
98+
# Export and import pool
99+
log_must zpool export $TESTPOOL
100+
log_must zpool import -d $VDIR $TESTPOOL
101+
102+
# Wait for rebuild to complete
103+
arcstat_quiescence_noecho l2_size
104+
105+
# Fill again to complete first pass after import
106+
log_must dd if=/dev/urandom of=/$TESTPOOL/file3 bs=1M count=$fill_mb
107+
log_must sleep 6
108+
109+
# Measure writes after import
110+
typeset start2=$(kstat arcstats.l2_write_bytes)
111+
log_must dd if=/dev/urandom of=/$TESTPOOL/file4 bs=1M count=100
112+
log_must sleep $test_time
113+
typeset end2=$(kstat arcstats.l2_write_bytes)
114+
typeset writes_after=$((end2 - start2))
115+
116+
log_note "Writes after import: $((writes_after / 1024))KB"
117+
118+
# Verify rate limiting works after import (writes should be similar)
119+
# Allow 3x variance due to timing differences
120+
if [[ $writes_after -eq 0 ]]; then
121+
log_fail "No writes after import - rate limiting may be broken"
122+
fi
123+
124+
if [[ $writes_after -gt $((writes_before * 3)) ]]; then
125+
log_fail "Writes after import too high - rate limiting may not be active"
126+
fi
127+
128+
log_must zpool destroy $TESTPOOL
129+
130+
log_pass "L2ARC DWPD rate limiting works after pool export/import."

0 commit comments

Comments
 (0)