xref: /linux/tools/testing/selftests/mm/run_vmtests.sh (revision 247dbcdbf790c52fc76cf8e327cd0a5778e41e66)
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
312CATEGORY="memfd_secret" run_test ./memfd_secret
313
314# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100
315CATEGORY="ksm" run_test ./ksm_tests -H -s 100
316# KSM KSM_MERGE_TIME test with size of 100
317CATEGORY="ksm" run_test ./ksm_tests -P -s 100
318# KSM MADV_MERGEABLE test with 10 identical pages
319CATEGORY="ksm" run_test ./ksm_tests -M -p 10
320# KSM unmerge test
321CATEGORY="ksm" run_test ./ksm_tests -U
322# KSM test with 10 zero pages and use_zero_pages = 0
323CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 0
324# KSM test with 10 zero pages and use_zero_pages = 1
325CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 1
326# KSM test with 2 NUMA nodes and merge_across_nodes = 1
327CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 1
328# KSM test with 2 NUMA nodes and merge_across_nodes = 0
329CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 0
330
331CATEGORY="ksm" run_test ./ksm_functional_tests
332
333run_test ./ksm_functional_tests
334
335# protection_keys tests
336if [ -x ./protection_keys_32 ]
337then
338	CATEGORY="pkey" run_test ./protection_keys_32
339fi
340
341if [ -x ./protection_keys_64 ]
342then
343	CATEGORY="pkey" run_test ./protection_keys_64
344fi
345
346if [ -x ./soft-dirty ]
347then
348	CATEGORY="soft_dirty" run_test ./soft-dirty
349fi
350
351CATEGORY="pagemap" run_test ./pagemap_ioctl
352
353# COW tests
354CATEGORY="cow" run_test ./cow
355
356CATEGORY="thp" run_test ./khugepaged
357
358CATEGORY="thp" run_test ./transhuge-stress -d 20
359
360CATEGORY="thp" run_test ./split_huge_page_test
361
362CATEGORY="migration" run_test ./migration
363
364CATEGORY="mkdirty" run_test ./mkdirty
365
366CATEGORY="mdwe" run_test ./mdwe_test
367
368echo "SUMMARY: PASS=${count_pass} SKIP=${count_skip} FAIL=${count_fail}"
369
370exit $exitcode
371