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} [ -h | -t "<categories>"] 16 -t: specify specific categories to tests to run 17 -h: display this message 18 19The default behavior is to run all tests. 20 21Alternatively, specific groups tests can be run by passing a string 22to the -t argument containing one or more of the following categories 23separated by spaces: 24- mmap 25 tests for mmap(2) 26- gup_test 27 tests for gup using gup_test interface 28- userfaultfd 29 tests for userfaultfd(2) 30- compaction 31 a test for the patch "Allow compaction of unevictable pages" 32- mlock 33 tests for mlock(2) 34- mremap 35 tests for mremap(2) 36- hugevm 37 tests for very large virtual address space 38- vmalloc 39 vmalloc smoke tests 40- hmm 41 hmm smoke tests 42- madv_populate 43 test memadvise(2) MADV_POPULATE_{READ,WRITE} options 44- memfd_secret 45 test memfd_secret(2) 46- process_mrelease 47 test process_mrelease(2) 48- ksm 49 ksm tests that do not require >=2 NUMA nodes 50- ksm_numa 51 ksm tests that require >=2 NUMA nodes 52- pkey 53 memory protection key tests 54- soft_dirty 55 test soft dirty page bit semantics 56- cow 57 test copy-on-write semantics 58example: ./run_vmtests.sh -t "hmm mmap ksm" 59EOF 60 exit 0 61} 62 63 64while getopts "ht:" OPT; do 65 case ${OPT} in 66 "h") usage ;; 67 "t") VM_SELFTEST_ITEMS=${OPTARG} ;; 68 esac 69done 70shift $((OPTIND -1)) 71 72# default behavior: run all tests 73VM_SELFTEST_ITEMS=${VM_SELFTEST_ITEMS:-default} 74 75test_selected() { 76 if [ "$VM_SELFTEST_ITEMS" == "default" ]; then 77 # If no VM_SELFTEST_ITEMS are specified, run all tests 78 return 0 79 fi 80 # If test selected argument is one of the test items 81 if [[ " ${VM_SELFTEST_ITEMS[*]} " =~ " ${1} " ]]; then 82 return 0 83 else 84 return 1 85 fi 86} 87 88# get huge pagesize and freepages from /proc/meminfo 89while read -r name size unit; do 90 if [ "$name" = "HugePages_Free:" ]; then 91 freepgs="$size" 92 fi 93 if [ "$name" = "Hugepagesize:" ]; then 94 hpgsize_KB="$size" 95 fi 96done < /proc/meminfo 97 98# Simple hugetlbfs tests have a hardcoded minimum requirement of 99# huge pages totaling 256MB (262144KB) in size. The userfaultfd 100# hugetlb test requires a minimum of 2 * nr_cpus huge pages. Take 101# both of these requirements into account and attempt to increase 102# number of huge pages available. 103nr_cpus=$(nproc) 104hpgsize_MB=$((hpgsize_KB / 1024)) 105half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128)) 106needmem_KB=$((half_ufd_size_MB * 2 * 1024)) 107 108# set proper nr_hugepages 109if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then 110 nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages) 111 needpgs=$((needmem_KB / hpgsize_KB)) 112 tries=2 113 while [ "$tries" -gt 0 ] && [ "$freepgs" -lt "$needpgs" ]; do 114 lackpgs=$((needpgs - freepgs)) 115 echo 3 > /proc/sys/vm/drop_caches 116 if ! echo $((lackpgs + nr_hugepgs)) > /proc/sys/vm/nr_hugepages; then 117 echo "Please run this test as root" 118 exit $ksft_skip 119 fi 120 while read -r name size unit; do 121 if [ "$name" = "HugePages_Free:" ]; then 122 freepgs=$size 123 fi 124 done < /proc/meminfo 125 tries=$((tries - 1)) 126 done 127 if [ "$freepgs" -lt "$needpgs" ]; then 128 printf "Not enough huge pages available (%d < %d)\n" \ 129 "$freepgs" "$needpgs" 130 exit 1 131 fi 132else 133 echo "no hugetlbfs support in kernel?" 134 exit 1 135fi 136 137# filter 64bit architectures 138ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sparc64 x86_64" 139if [ -z "$ARCH" ]; then 140 ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/') 141fi 142VADDR64=0 143echo "$ARCH64STR" | grep "$ARCH" &>/dev/null && VADDR64=1 144 145# Usage: run_test [test binary] [arbitrary test arguments...] 146run_test() { 147 if test_selected ${CATEGORY}; then 148 local title="running $*" 149 local sep=$(echo -n "$title" | tr "[:graph:][:space:]" -) 150 printf "%s\n%s\n%s\n" "$sep" "$title" "$sep" 151 152 "$@" 153 local ret=$? 154 if [ $ret -eq 0 ]; then 155 count_pass=$(( count_pass + 1 )) 156 echo "[PASS]" 157 elif [ $ret -eq $ksft_skip ]; then 158 count_skip=$(( count_skip + 1 )) 159 echo "[SKIP]" 160 exitcode=$ksft_skip 161 else 162 count_fail=$(( count_fail + 1 )) 163 echo "[FAIL]" 164 exitcode=1 165 fi 166 fi # test_selected 167} 168 169CATEGORY="hugetlb" run_test ./hugepage-mmap 170 171shmmax=$(cat /proc/sys/kernel/shmmax) 172shmall=$(cat /proc/sys/kernel/shmall) 173echo 268435456 > /proc/sys/kernel/shmmax 174echo 4194304 > /proc/sys/kernel/shmall 175CATEGORY="hugetlb" run_test ./hugepage-shm 176echo "$shmmax" > /proc/sys/kernel/shmmax 177echo "$shmall" > /proc/sys/kernel/shmall 178 179CATEGORY="hugetlb" run_test ./map_hugetlb 180CATEGORY="hugetlb" run_test ./hugepage-mremap 181CATEGORY="hugetlb" run_test ./hugepage-vmemmap 182CATEGORY="hugetlb" run_test ./hugetlb-madvise 183 184if test_selected "hugetlb"; then 185 echo "NOTE: These hugetlb tests provide minimal coverage. Use" 186 echo " https://github.com/libhugetlbfs/libhugetlbfs.git for" 187 echo " hugetlb regression testing." 188fi 189 190CATEGORY="mmap" run_test ./map_fixed_noreplace 191 192# get_user_pages_fast() benchmark 193CATEGORY="gup_test" run_test ./gup_test -u 194# pin_user_pages_fast() benchmark 195CATEGORY="gup_test" run_test ./gup_test -a 196# Dump pages 0, 19, and 4096, using pin_user_pages: 197CATEGORY="gup_test" run_test ./gup_test -ct -F 0x1 0 19 0x1000 198 199CATEGORY="userfaultfd" run_test ./uffd-unit-tests 200uffd_stress_bin=./uffd-stress 201CATEGORY="userfaultfd" run_test ${uffd_stress_bin} anon 20 16 202# Hugetlb tests require source and destination huge pages. Pass in half 203# the size ($half_ufd_size_MB), which is used for *each*. 204CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb "$half_ufd_size_MB" 32 205CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb-private "$half_ufd_size_MB" 32 206CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem 20 16 207CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem-private 20 16 208 209#cleanup 210echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages 211 212CATEGORY="compaction" run_test ./compaction_test 213 214CATEGORY="mlock" run_test sudo -u nobody ./on-fault-limit 215 216CATEGORY="mmap" run_test ./map_populate 217 218CATEGORY="mlock" run_test ./mlock-random-test 219 220CATEGORY="mlock" run_test ./mlock2-tests 221 222CATEGORY="process_mrelease" run_test ./mrelease_test 223 224CATEGORY="mremap" run_test ./mremap_test 225 226CATEGORY="hugetlb" run_test ./thuge-gen 227 228if [ $VADDR64 -ne 0 ]; then 229 230 # set overcommit_policy as OVERCOMMIT_ALWAYS so that kernel 231 # allows high virtual address allocation requests independent 232 # of platform's physical memory. 233 234 prev_policy=$(cat /proc/sys/vm/overcommit_memory) 235 echo 1 > /proc/sys/vm/overcommit_memory 236 CATEGORY="hugevm" run_test ./virtual_address_range 237 echo $prev_policy > /proc/sys/vm/overcommit_memory 238 239 # va high address boundary switch test 240 ARCH_ARM64="arm64" 241 prev_nr_hugepages=$(cat /proc/sys/vm/nr_hugepages) 242 if [ "$ARCH" == "$ARCH_ARM64" ]; then 243 echo 6 > /proc/sys/vm/nr_hugepages 244 fi 245 CATEGORY="hugevm" run_test ./va_high_addr_switch.sh 246 if [ "$ARCH" == "$ARCH_ARM64" ]; then 247 echo $prev_nr_hugepages > /proc/sys/vm/nr_hugepages 248 fi 249fi # VADDR64 250 251# vmalloc stability smoke test 252CATEGORY="vmalloc" run_test ./test_vmalloc.sh smoke 253 254CATEGORY="mremap" run_test ./mremap_dontunmap 255 256CATEGORY="hmm" run_test ./test_hmm.sh smoke 257 258# MADV_POPULATE_READ and MADV_POPULATE_WRITE tests 259CATEGORY="madv_populate" run_test ./madv_populate 260 261CATEGORY="memfd_secret" run_test ./memfd_secret 262 263# KSM MADV_MERGEABLE test with 10 identical pages 264CATEGORY="ksm" run_test ./ksm_tests -M -p 10 265# KSM unmerge test 266CATEGORY="ksm" run_test ./ksm_tests -U 267# KSM test with 10 zero pages and use_zero_pages = 0 268CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 0 269# KSM test with 10 zero pages and use_zero_pages = 1 270CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 1 271# KSM test with 2 NUMA nodes and merge_across_nodes = 1 272CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 1 273# KSM test with 2 NUMA nodes and merge_across_nodes = 0 274CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 0 275 276CATEGORY="ksm" run_test ./ksm_functional_tests 277 278run_test ./ksm_functional_tests 279 280# protection_keys tests 281if [ -x ./protection_keys_32 ] 282then 283 CATEGORY="pkey" run_test ./protection_keys_32 284fi 285 286if [ -x ./protection_keys_64 ] 287then 288 CATEGORY="pkey" run_test ./protection_keys_64 289fi 290 291CATEGORY="soft_dirty" run_test ./soft-dirty 292 293# COW tests 294CATEGORY="cow" run_test ./cow 295 296echo "SUMMARY: PASS=${count_pass} SKIP=${count_skip} FAIL=${count_fail}" 297 298exit $exitcode 299