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 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="gup_test" run_test ./gup_longterm 200 201CATEGORY="userfaultfd" run_test ./uffd-unit-tests 202uffd_stress_bin=./uffd-stress 203CATEGORY="userfaultfd" run_test ${uffd_stress_bin} anon 20 16 204# Hugetlb tests require source and destination huge pages. Pass in half 205# the size ($half_ufd_size_MB), which is used for *each*. 206CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb "$half_ufd_size_MB" 32 207CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb-private "$half_ufd_size_MB" 32 208CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem 20 16 209CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem-private 20 16 210 211#cleanup 212echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages 213 214CATEGORY="compaction" run_test ./compaction_test 215 216CATEGORY="mlock" run_test sudo -u nobody ./on-fault-limit 217 218CATEGORY="mmap" run_test ./map_populate 219 220CATEGORY="mlock" run_test ./mlock-random-test 221 222CATEGORY="mlock" run_test ./mlock2-tests 223 224CATEGORY="process_mrelease" run_test ./mrelease_test 225 226CATEGORY="mremap" run_test ./mremap_test 227 228CATEGORY="hugetlb" run_test ./thuge-gen 229 230if [ $VADDR64 -ne 0 ]; then 231 232 # set overcommit_policy as OVERCOMMIT_ALWAYS so that kernel 233 # allows high virtual address allocation requests independent 234 # of platform's physical memory. 235 236 prev_policy=$(cat /proc/sys/vm/overcommit_memory) 237 echo 1 > /proc/sys/vm/overcommit_memory 238 CATEGORY="hugevm" run_test ./virtual_address_range 239 echo $prev_policy > /proc/sys/vm/overcommit_memory 240 241 # va high address boundary switch test 242 ARCH_ARM64="arm64" 243 prev_nr_hugepages=$(cat /proc/sys/vm/nr_hugepages) 244 if [ "$ARCH" == "$ARCH_ARM64" ]; then 245 echo 6 > /proc/sys/vm/nr_hugepages 246 fi 247 CATEGORY="hugevm" run_test bash ./va_high_addr_switch.sh 248 if [ "$ARCH" == "$ARCH_ARM64" ]; then 249 echo $prev_nr_hugepages > /proc/sys/vm/nr_hugepages 250 fi 251fi # VADDR64 252 253# vmalloc stability smoke test 254CATEGORY="vmalloc" run_test bash ./test_vmalloc.sh smoke 255 256CATEGORY="mremap" run_test ./mremap_dontunmap 257 258CATEGORY="hmm" run_test bash ./test_hmm.sh smoke 259 260# MADV_POPULATE_READ and MADV_POPULATE_WRITE tests 261CATEGORY="madv_populate" run_test ./madv_populate 262 263CATEGORY="memfd_secret" run_test ./memfd_secret 264 265# KSM MADV_MERGEABLE test with 10 identical pages 266CATEGORY="ksm" run_test ./ksm_tests -M -p 10 267# KSM unmerge test 268CATEGORY="ksm" run_test ./ksm_tests -U 269# KSM test with 10 zero pages and use_zero_pages = 0 270CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 0 271# KSM test with 10 zero pages and use_zero_pages = 1 272CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 1 273# KSM test with 2 NUMA nodes and merge_across_nodes = 1 274CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 1 275# KSM test with 2 NUMA nodes and merge_across_nodes = 0 276CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 0 277 278CATEGORY="ksm" run_test ./ksm_functional_tests 279 280run_test ./ksm_functional_tests 281 282# protection_keys tests 283if [ -x ./protection_keys_32 ] 284then 285 CATEGORY="pkey" run_test ./protection_keys_32 286fi 287 288if [ -x ./protection_keys_64 ] 289then 290 CATEGORY="pkey" run_test ./protection_keys_64 291fi 292 293CATEGORY="soft_dirty" run_test ./soft-dirty 294 295# COW tests 296CATEGORY="cow" run_test ./cow 297 298echo "SUMMARY: PASS=${count_pass} SKIP=${count_skip} FAIL=${count_fail}" 299 300exit $exitcode 301