xref: /linux/tools/testing/selftests/mm/run_vmtests.sh (revision 3d0fe49454652117522f60bfbefb978ba0e5300b)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# Please run as root
4
5# Kselftest framework requirement - SKIP code is 4.
6ksft_skip=4
7
8count_pass=0
9count_fail=0
10count_skip=0
11exitcode=0
12
13usage() {
14	cat <<EOF
15usage: ${BASH_SOURCE[0]:-$0} [ options ]
16
17  -a: run all tests, including extra ones
18  -t: specify specific categories to tests to run
19  -h: display this message
20
21The default behavior is to run required tests only.  If -a is specified,
22will run all tests.
23
24Alternatively, specific groups tests can be run by passing a string
25to the -t argument containing one or more of the following categories
26separated by spaces:
27- mmap
28	tests for mmap(2)
29- gup_test
30	tests for gup
31- userfaultfd
32	tests for  userfaultfd(2)
33- compaction
34	a test for the patch "Allow compaction of unevictable pages"
35- mlock
36	tests for mlock(2)
37- mremap
38	tests for mremap(2)
39- hugevm
40	tests for very large virtual address space
41- vmalloc
42	vmalloc smoke tests
43- hmm
44	hmm smoke tests
45- madv_populate
46	test memadvise(2) MADV_POPULATE_{READ,WRITE} options
47- memfd_secret
48	test memfd_secret(2)
49- process_mrelease
50	test process_mrelease(2)
51- ksm
52	ksm tests that do not require >=2 NUMA nodes
53- ksm_numa
54	ksm tests that require >=2 NUMA nodes
55- pkey
56	memory protection key tests
57- soft_dirty
58	test soft dirty page bit semantics
59- pagemap
60	test pagemap_scan IOCTL
61- cow
62	test copy-on-write semantics
63- thp
64	test transparent huge pages
65- migration
66	invoke move_pages(2) to exercise the migration entry code
67	paths in the kernel
68- mkdirty
69	test handling of code that might set PTE/PMD dirty in
70	read-only VMAs
71- mdwe
72	test prctl(PR_SET_MDWE, ...)
73
74example: ./run_vmtests.sh -t "hmm mmap ksm"
75EOF
76	exit 0
77}
78
79RUN_ALL=false
80
81while getopts "aht:" OPT; do
82	case ${OPT} in
83		"a") RUN_ALL=true ;;
84		"h") usage ;;
85		"t") VM_SELFTEST_ITEMS=${OPTARG} ;;
86	esac
87done
88shift $((OPTIND -1))
89
90# default behavior: run all tests
91VM_SELFTEST_ITEMS=${VM_SELFTEST_ITEMS:-default}
92
93test_selected() {
94	if [ "$VM_SELFTEST_ITEMS" == "default" ]; then
95		# If no VM_SELFTEST_ITEMS are specified, run all tests
96		return 0
97	fi
98	# If test selected argument is one of the test items
99	if [[ " ${VM_SELFTEST_ITEMS[*]} " =~ " ${1} " ]]; then
100	        return 0
101	else
102	        return 1
103	fi
104}
105
106run_gup_matrix() {
107    # -t: thp=on, -T: thp=off, -H: hugetlb=on
108    local hugetlb_mb=$(( needmem_KB / 1024 ))
109
110    for huge in -t -T "-H -m $hugetlb_mb"; do
111        # -u: gup-fast, -U: gup-basic, -a: pin-fast, -b: pin-basic, -L: pin-longterm
112        for test_cmd in -u -U -a -b -L; do
113            # -w: write=1, -W: write=0
114            for write in -w -W; do
115                # -S: shared
116                for share in -S " "; do
117                    # -n: How many pages to fetch together?  512 is special
118                    # because it's default thp size (or 2M on x86), 123 to
119                    # just test partial gup when hit a huge in whatever form
120                    for num in "-n 1" "-n 512" "-n 123"; do
121                        CATEGORY="gup_test" run_test ./gup_test \
122                                $huge $test_cmd $write $share $num
123                    done
124                done
125            done
126        done
127    done
128}
129
130# get huge pagesize and freepages from /proc/meminfo
131while read -r name size unit; do
132	if [ "$name" = "HugePages_Free:" ]; then
133		freepgs="$size"
134	fi
135	if [ "$name" = "Hugepagesize:" ]; then
136		hpgsize_KB="$size"
137	fi
138done < /proc/meminfo
139
140# Simple hugetlbfs tests have a hardcoded minimum requirement of
141# huge pages totaling 256MB (262144KB) in size.  The userfaultfd
142# hugetlb test requires a minimum of 2 * nr_cpus huge pages.  Take
143# both of these requirements into account and attempt to increase
144# number of huge pages available.
145nr_cpus=$(nproc)
146hpgsize_MB=$((hpgsize_KB / 1024))
147half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128))
148needmem_KB=$((half_ufd_size_MB * 2 * 1024))
149
150# set proper nr_hugepages
151if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
152	nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
153	needpgs=$((needmem_KB / hpgsize_KB))
154	tries=2
155	while [ "$tries" -gt 0 ] && [ "$freepgs" -lt "$needpgs" ]; do
156		lackpgs=$((needpgs - freepgs))
157		echo 3 > /proc/sys/vm/drop_caches
158		if ! echo $((lackpgs + nr_hugepgs)) > /proc/sys/vm/nr_hugepages; then
159			echo "Please run this test as root"
160			exit $ksft_skip
161		fi
162		while read -r name size unit; do
163			if [ "$name" = "HugePages_Free:" ]; then
164				freepgs=$size
165			fi
166		done < /proc/meminfo
167		tries=$((tries - 1))
168	done
169	if [ "$freepgs" -lt "$needpgs" ]; then
170		printf "Not enough huge pages available (%d < %d)\n" \
171		       "$freepgs" "$needpgs"
172		exit 1
173	fi
174else
175	echo "no hugetlbfs support in kernel?"
176	exit 1
177fi
178
179# filter 64bit architectures
180ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sparc64 x86_64"
181if [ -z "$ARCH" ]; then
182	ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/')
183fi
184VADDR64=0
185echo "$ARCH64STR" | grep "$ARCH" &>/dev/null && VADDR64=1
186
187# Usage: run_test [test binary] [arbitrary test arguments...]
188run_test() {
189	if test_selected ${CATEGORY}; then
190		local title="running $*"
191		local sep=$(echo -n "$title" | tr "[:graph:][:space:]" -)
192		printf "%s\n%s\n%s\n" "$sep" "$title" "$sep"
193
194		"$@"
195		local ret=$?
196		if [ $ret -eq 0 ]; then
197			count_pass=$(( count_pass + 1 ))
198			echo "[PASS]"
199		elif [ $ret -eq $ksft_skip ]; then
200			count_skip=$(( count_skip + 1 ))
201			echo "[SKIP]"
202			exitcode=$ksft_skip
203		else
204			count_fail=$(( count_fail + 1 ))
205			echo "[FAIL]"
206			exitcode=1
207		fi
208	fi # test_selected
209}
210
211CATEGORY="hugetlb" run_test ./hugepage-mmap
212
213shmmax=$(cat /proc/sys/kernel/shmmax)
214shmall=$(cat /proc/sys/kernel/shmall)
215echo 268435456 > /proc/sys/kernel/shmmax
216echo 4194304 > /proc/sys/kernel/shmall
217CATEGORY="hugetlb" run_test ./hugepage-shm
218echo "$shmmax" > /proc/sys/kernel/shmmax
219echo "$shmall" > /proc/sys/kernel/shmall
220
221CATEGORY="hugetlb" run_test ./map_hugetlb
222CATEGORY="hugetlb" run_test ./hugepage-mremap
223CATEGORY="hugetlb" run_test ./hugepage-vmemmap
224CATEGORY="hugetlb" run_test ./hugetlb-madvise
225
226# For this test, we need one and just one huge page
227echo 1 > /proc/sys/vm/nr_hugepages
228CATEGORY="hugetlb" run_test ./hugetlb_fault_after_madv
229
230if test_selected "hugetlb"; then
231	echo "NOTE: These hugetlb tests provide minimal coverage.  Use"
232	echo "      https://github.com/libhugetlbfs/libhugetlbfs.git for"
233	echo "      hugetlb regression testing."
234fi
235
236CATEGORY="mmap" run_test ./map_fixed_noreplace
237
238if $RUN_ALL; then
239    run_gup_matrix
240else
241    # get_user_pages_fast() benchmark
242    CATEGORY="gup_test" run_test ./gup_test -u
243    # pin_user_pages_fast() benchmark
244    CATEGORY="gup_test" run_test ./gup_test -a
245fi
246# Dump pages 0, 19, and 4096, using pin_user_pages:
247CATEGORY="gup_test" run_test ./gup_test -ct -F 0x1 0 19 0x1000
248CATEGORY="gup_test" run_test ./gup_longterm
249
250CATEGORY="userfaultfd" run_test ./uffd-unit-tests
251uffd_stress_bin=./uffd-stress
252CATEGORY="userfaultfd" run_test ${uffd_stress_bin} anon 20 16
253# Hugetlb tests require source and destination huge pages. Pass in half
254# the size ($half_ufd_size_MB), which is used for *each*.
255CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb "$half_ufd_size_MB" 32
256CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb-private "$half_ufd_size_MB" 32
257CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem 20 16
258CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem-private 20 16
259
260#cleanup
261echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
262
263CATEGORY="compaction" run_test ./compaction_test
264
265CATEGORY="mlock" run_test sudo -u nobody ./on-fault-limit
266
267CATEGORY="mmap" run_test ./map_populate
268
269CATEGORY="mlock" run_test ./mlock-random-test
270
271CATEGORY="mlock" run_test ./mlock2-tests
272
273CATEGORY="process_mrelease" run_test ./mrelease_test
274
275CATEGORY="mremap" run_test ./mremap_test
276
277CATEGORY="hugetlb" run_test ./thuge-gen
278
279if [ $VADDR64 -ne 0 ]; then
280
281	# set overcommit_policy as OVERCOMMIT_ALWAYS so that kernel
282	# allows high virtual address allocation requests independent
283	# of platform's physical memory.
284
285	prev_policy=$(cat /proc/sys/vm/overcommit_memory)
286	echo 1 > /proc/sys/vm/overcommit_memory
287	CATEGORY="hugevm" run_test ./virtual_address_range
288	echo $prev_policy > /proc/sys/vm/overcommit_memory
289
290	# va high address boundary switch test
291	ARCH_ARM64="arm64"
292	prev_nr_hugepages=$(cat /proc/sys/vm/nr_hugepages)
293	if [ "$ARCH" == "$ARCH_ARM64" ]; then
294		echo 6 > /proc/sys/vm/nr_hugepages
295	fi
296	CATEGORY="hugevm" run_test bash ./va_high_addr_switch.sh
297	if [ "$ARCH" == "$ARCH_ARM64" ]; then
298		echo $prev_nr_hugepages > /proc/sys/vm/nr_hugepages
299	fi
300fi # VADDR64
301
302# vmalloc stability smoke test
303CATEGORY="vmalloc" run_test bash ./test_vmalloc.sh smoke
304
305CATEGORY="mremap" run_test ./mremap_dontunmap
306
307CATEGORY="hmm" run_test bash ./test_hmm.sh smoke
308
309# MADV_POPULATE_READ and MADV_POPULATE_WRITE tests
310CATEGORY="madv_populate" run_test ./madv_populate
311
312echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
313CATEGORY="memfd_secret" run_test ./memfd_secret
314
315# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100
316CATEGORY="ksm" run_test ./ksm_tests -H -s 100
317# KSM KSM_MERGE_TIME test with size of 100
318CATEGORY="ksm" run_test ./ksm_tests -P -s 100
319# KSM MADV_MERGEABLE test with 10 identical pages
320CATEGORY="ksm" run_test ./ksm_tests -M -p 10
321# KSM unmerge test
322CATEGORY="ksm" run_test ./ksm_tests -U
323# KSM test with 10 zero pages and use_zero_pages = 0
324CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 0
325# KSM test with 10 zero pages and use_zero_pages = 1
326CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 1
327# KSM test with 2 NUMA nodes and merge_across_nodes = 1
328CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 1
329# KSM test with 2 NUMA nodes and merge_across_nodes = 0
330CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 0
331
332CATEGORY="ksm" run_test ./ksm_functional_tests
333
334run_test ./ksm_functional_tests
335
336# protection_keys tests
337if [ -x ./protection_keys_32 ]
338then
339	CATEGORY="pkey" run_test ./protection_keys_32
340fi
341
342if [ -x ./protection_keys_64 ]
343then
344	CATEGORY="pkey" run_test ./protection_keys_64
345fi
346
347if [ -x ./soft-dirty ]
348then
349	CATEGORY="soft_dirty" run_test ./soft-dirty
350fi
351
352CATEGORY="pagemap" run_test ./pagemap_ioctl
353
354# COW tests
355CATEGORY="cow" run_test ./cow
356
357CATEGORY="thp" run_test ./khugepaged
358
359CATEGORY="thp" run_test ./transhuge-stress -d 20
360
361CATEGORY="thp" run_test ./split_huge_page_test
362
363CATEGORY="migration" run_test ./migration
364
365CATEGORY="mkdirty" run_test ./mkdirty
366
367CATEGORY="mdwe" run_test ./mdwe_test
368
369echo "SUMMARY: PASS=${count_pass} SKIP=${count_skip} FAIL=${count_fail}"
370
371exit $exitcode
372