Commit 85463321 authored by Joel Savitz's avatar Joel Savitz Committed by Andrew Morton

selftests/vm: enable running select groups of tests

Our memory management kernel CI testing at Red Hat uses the VM
selftests and we have run into two problems:

First, our LTP tests overlap with the VM selftests.

We want to avoid unhelpful redundancy in our testing practices.

Second, we have observed the current run_vmtests.sh to report overall
failure/ambiguous results in the case that a machine lacks the necessary
hardware to perform one or more of the tests. E.g. ksm tests that
require more than one numa node.

We want to be able to run the vm selftests suitable to particular hardware.

Add the ability to run one or more groups of vm tests via run_vmtests.sh
instead of simply all-or-none in order to solve these problems.

Preserve existing default behavior of running all tests when the script
is invoked with no arguments.

Documentation of test groups is included in the patch as follows:

    # ./run_vmtests.sh [ -h || --help ]

    usage: ./tools/testing/selftests/vm/run_vmtests.sh [ -h | -t "<categories>"]
      -t: specify specific categories to tests to run
      -h: display this message

    The default behavior is to run all tests.

    Alternatively, specific groups tests can be run by passing a string
    to the -t argument containing one or more of the following categories
    separated by spaces:
    - mmap
	    tests for mmap(2)
    - gup_test
	    tests for gup using gup_test interface
    - userfaultfd
	    tests for  userfaultfd(2)
    - compaction
	    a test for the patch "Allow compaction of unevictable pages"
    - mlock
	    tests for mlock(2)
    - mremap
	    tests for mremap(2)
    - hugevm
	    tests for very large virtual address space
    - vmalloc
	    vmalloc smoke tests
    - hmm
	    hmm smoke tests
    - madv_populate
	    test memadvise(2) MADV_POPULATE_{READ,WRITE} options
    - memfd_secret
	    test memfd_secret(2)
    - process_mrelease
	    test process_mrelease(2)
    - ksm
	    ksm tests that do not require >=2 NUMA nodes
    - ksm_numa
	    ksm tests that require >=2 NUMA nodes
    - pkey
	    memory protection key tests
    - soft_dirty
    	    test soft dirty page bit semantics
    - anon_cow
            test anonymous copy-on-write semantics
    example: ./run_vmtests.sh -t "hmm mmap ksm"

Link: https://lkml.kernel.org/r/20221018231222.1884715-1-jsavitz@redhat.comSigned-off-by: default avatarJoel Savitz <jsavitz@redhat.com>
Cc: Joel Savitz <jsavitz@redhat.com>
Cc: Nico Pache <npache@redhat.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 3b910105
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
#please run as root # Please run as root
# Kselftest framework requirement - SKIP code is 4. # Kselftest framework requirement - SKIP code is 4.
ksft_skip=4 ksft_skip=4
exitcode=0 exitcode=0
#get huge pagesize and freepages from /proc/meminfo usage() {
cat <<EOF
usage: ${BASH_SOURCE[0]:-$0} [ -h | -t "<categories>"]
-t: specify specific categories to tests to run
-h: display this message
The default behavior is to run all tests.
Alternatively, specific groups tests can be run by passing a string
to the -t argument containing one or more of the following categories
separated by spaces:
- mmap
tests for mmap(2)
- gup_test
tests for gup using gup_test interface
- userfaultfd
tests for userfaultfd(2)
- compaction
a test for the patch "Allow compaction of unevictable pages"
- mlock
tests for mlock(2)
- mremap
tests for mremap(2)
- hugevm
tests for very large virtual address space
- vmalloc
vmalloc smoke tests
- hmm
hmm smoke tests
- madv_populate
test memadvise(2) MADV_POPULATE_{READ,WRITE} options
- memfd_secret
test memfd_secret(2)
- process_mrelease
test process_mrelease(2)
- ksm
ksm tests that do not require >=2 NUMA nodes
- ksm_numa
ksm tests that require >=2 NUMA nodes
- pkey
memory protection key tests
- soft_dirty
test soft dirty page bit semantics
- cow
test copy-on-write semantics
example: ./run_vmtests.sh -t "hmm mmap ksm"
EOF
exit 0
}
while getopts "ht:" OPT; do
case ${OPT} in
"h") usage ;;
"t") VM_SELFTEST_ITEMS=${OPTARG} ;;
esac
done
shift $((OPTIND -1))
# default behavior: run all tests
VM_SELFTEST_ITEMS=${VM_SELFTEST_ITEMS:-default}
test_selected() {
if [ "$VM_SELFTEST_ITEMS" == "default" ]; then
# If no VM_SELFTEST_ITEMS are specified, run all tests
return 0
fi
# If test selected argument is one of the test items
if [[ " ${VM_SELFTEST_ITEMS[*]} " =~ " ${1} " ]]; then
return 0
else
return 1
fi
}
# get huge pagesize and freepages from /proc/meminfo
while read -r name size unit; do while read -r name size unit; do
if [ "$name" = "HugePages_Free:" ]; then if [ "$name" = "HugePages_Free:" ]; then
freepgs="$size" freepgs="$size"
...@@ -27,7 +102,7 @@ hpgsize_MB=$((hpgsize_KB / 1024)) ...@@ -27,7 +102,7 @@ hpgsize_MB=$((hpgsize_KB / 1024))
half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128)) half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128))
needmem_KB=$((half_ufd_size_MB * 2 * 1024)) needmem_KB=$((half_ufd_size_MB * 2 * 1024))
#set proper nr_hugepages # set proper nr_hugepages
if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages) nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
needpgs=$((needmem_KB / hpgsize_KB)) needpgs=$((needmem_KB / hpgsize_KB))
...@@ -56,16 +131,17 @@ else ...@@ -56,16 +131,17 @@ else
exit 1 exit 1
fi fi
#filter 64bit architectures # filter 64bit architectures
ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64" ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64"
if [ -z "$ARCH" ]; then if [ -z "$ARCH" ]; then
ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/') ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/')
fi fi
VADDR64=0 VADDR64=0
echo "$ARCH64STR" | grep "$ARCH" && VADDR64=1 echo "$ARCH64STR" | grep "$ARCH" &>/dev/null && VADDR64=1
# Usage: run_test [test binary] [arbitrary test arguments...] # Usage: run_test [test binary] [arbitrary test arguments...]
run_test() { run_test() {
if test_selected ${CATEGORY}; then
local title="running $*" local title="running $*"
local sep=$(echo -n "$title" | tr "[:graph:][:space:]" -) local sep=$(echo -n "$title" | tr "[:graph:][:space:]" -)
printf "%s\n%s\n%s\n" "$sep" "$title" "$sep" printf "%s\n%s\n%s\n" "$sep" "$title" "$sep"
...@@ -81,111 +157,116 @@ run_test() { ...@@ -81,111 +157,116 @@ run_test() {
echo "[FAIL]" echo "[FAIL]"
exitcode=1 exitcode=1
fi fi
fi # test_selected
} }
run_test ./hugepage-mmap CATEGORY="hugetlb" run_test ./hugepage-mmap
shmmax=$(cat /proc/sys/kernel/shmmax) shmmax=$(cat /proc/sys/kernel/shmmax)
shmall=$(cat /proc/sys/kernel/shmall) shmall=$(cat /proc/sys/kernel/shmall)
echo 268435456 > /proc/sys/kernel/shmmax echo 268435456 > /proc/sys/kernel/shmmax
echo 4194304 > /proc/sys/kernel/shmall echo 4194304 > /proc/sys/kernel/shmall
run_test ./hugepage-shm CATEGORY="hugetlb" run_test ./hugepage-shm
echo "$shmmax" > /proc/sys/kernel/shmmax echo "$shmmax" > /proc/sys/kernel/shmmax
echo "$shmall" > /proc/sys/kernel/shmall echo "$shmall" > /proc/sys/kernel/shmall
run_test ./map_hugetlb CATEGORY="hugetlb" run_test ./map_hugetlb
run_test ./hugepage-mremap CATEGORY="hugetlb" run_test ./hugepage-mremap
run_test ./hugepage-vmemmap CATEGORY="hugetlb" run_test ./hugepage-vmemmap
run_test ./hugetlb-madvise CATEGORY="hugetlb" run_test ./hugetlb-madvise
echo "NOTE: The above hugetlb tests provide minimal coverage. Use" if test_selected "hugetlb"; then
echo " https://github.com/libhugetlbfs/libhugetlbfs.git for" echo "NOTE: These hugetlb tests provide minimal coverage. Use"
echo " hugetlb regression testing." echo " https://github.com/libhugetlbfs/libhugetlbfs.git for"
echo " hugetlb regression testing."
fi
run_test ./map_fixed_noreplace CATEGORY="mmap" run_test ./map_fixed_noreplace
# get_user_pages_fast() benchmark # get_user_pages_fast() benchmark
run_test ./gup_test -u CATEGORY="gup_test" run_test ./gup_test -u
# pin_user_pages_fast() benchmark # pin_user_pages_fast() benchmark
run_test ./gup_test -a CATEGORY="gup_test" run_test ./gup_test -a
# Dump pages 0, 19, and 4096, using pin_user_pages: # Dump pages 0, 19, and 4096, using pin_user_pages:
run_test ./gup_test -ct -F 0x1 0 19 0x1000 CATEGORY="gup_test" run_test ./gup_test -ct -F 0x1 0 19 0x1000
uffd_mods=("" ":dev") uffd_mods=("" ":dev")
for mod in "${uffd_mods[@]}"; do for mod in "${uffd_mods[@]}"; do
run_test ./userfaultfd anon${mod} 20 16 CATEGORY="userfaultfd" run_test ./userfaultfd anon${mod} 20 16
# Hugetlb tests require source and destination huge pages. Pass in half # Hugetlb tests require source and destination huge pages. Pass in half
# the size ($half_ufd_size_MB), which is used for *each*. # the size ($half_ufd_size_MB), which is used for *each*.
run_test ./userfaultfd hugetlb${mod} "$half_ufd_size_MB" 32 CATEGORY="userfaultfd" run_test ./userfaultfd hugetlb${mod} "$half_ufd_size_MB" 32
run_test ./userfaultfd hugetlb_shared${mod} "$half_ufd_size_MB" 32 CATEGORY="userfaultfd" run_test ./userfaultfd hugetlb_shared${mod} "$half_ufd_size_MB" 32
run_test ./userfaultfd shmem${mod} 20 16 CATEGORY="userfaultfd" run_test ./userfaultfd shmem${mod} 20 16
done done
#cleanup #cleanup
echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
run_test ./compaction_test CATEGORY="compaction" run_test ./compaction_test
run_test sudo -u nobody ./on-fault-limit CATEGORY="mlock" run_test sudo -u nobody ./on-fault-limit
run_test ./map_populate CATEGORY="mmap" run_test ./map_populate
run_test ./mlock-random-test CATEGORY="mlock" run_test ./mlock-random-test
run_test ./mlock2-tests CATEGORY="mlock" run_test ./mlock2-tests
run_test ./mrelease_test CATEGORY="process_mrelease" run_test ./mrelease_test
run_test ./mremap_test CATEGORY="mremap" run_test ./mremap_test
run_test ./thuge-gen CATEGORY="hugetlb" run_test ./thuge-gen
if [ $VADDR64 -ne 0 ]; then if [ $VADDR64 -ne 0 ]; then
run_test ./virtual_address_range CATEGORY="hugevm" run_test ./virtual_address_range
# virtual address 128TB switch test # virtual address 128TB switch test
run_test ./va_128TBswitch.sh CATEGORY="hugevm" run_test ./va_128TBswitch.sh
fi # VADDR64 fi # VADDR64
# vmalloc stability smoke test # vmalloc stability smoke test
run_test ./test_vmalloc.sh smoke CATEGORY="vmalloc" run_test ./test_vmalloc.sh smoke
run_test ./mremap_dontunmap CATEGORY="mremap" run_test ./mremap_dontunmap
run_test ./test_hmm.sh smoke CATEGORY="hmm" run_test ./test_hmm.sh smoke
# MADV_POPULATE_READ and MADV_POPULATE_WRITE tests # MADV_POPULATE_READ and MADV_POPULATE_WRITE tests
run_test ./madv_populate CATEGORY="madv_populate" run_test ./madv_populate
run_test ./memfd_secret CATEGORY="memfd_secret" run_test ./memfd_secret
# KSM MADV_MERGEABLE test with 10 identical pages # KSM MADV_MERGEABLE test with 10 identical pages
run_test ./ksm_tests -M -p 10 CATEGORY="ksm" run_test ./ksm_tests -M -p 10
# KSM unmerge test # KSM unmerge test
run_test ./ksm_tests -U CATEGORY="ksm" run_test ./ksm_tests -U
# KSM test with 10 zero pages and use_zero_pages = 0 # KSM test with 10 zero pages and use_zero_pages = 0
run_test ./ksm_tests -Z -p 10 -z 0 CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 0
# KSM test with 10 zero pages and use_zero_pages = 1 # KSM test with 10 zero pages and use_zero_pages = 1
run_test ./ksm_tests -Z -p 10 -z 1 CATEGORY="ksm" run_test ./ksm_tests -Z -p 10 -z 1
# KSM test with 2 NUMA nodes and merge_across_nodes = 1 # KSM test with 2 NUMA nodes and merge_across_nodes = 1
run_test ./ksm_tests -N -m 1 CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 1
# KSM test with 2 NUMA nodes and merge_across_nodes = 0 # KSM test with 2 NUMA nodes and merge_across_nodes = 0
run_test ./ksm_tests -N -m 0 CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 0
CATEGORY="ksm" run_test ./ksm_functional_tests
# protection_keys tests # protection_keys tests
if [ -x ./protection_keys_32 ] if [ -x ./protection_keys_32 ]
then then
run_test ./protection_keys_32 CATEGORY="pkey" run_test ./protection_keys_32
fi fi
if [ -x ./protection_keys_64 ] if [ -x ./protection_keys_64 ]
then then
run_test ./protection_keys_64 CATEGORY="pkey" run_test ./protection_keys_64
fi fi
run_test ./soft-dirty CATEGORY="soft_dirty" run_test ./soft-dirty
# COW tests for anonymous memory # COW tests
run_test ./cow CATEGORY="cow" run_test ./cow
exit $exitcode exit $exitcode
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment