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.com
Signed-off-by: Joel 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: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Joel Savitz 2022-10-18 19:12:22 -04:00 committed by Andrew Morton
parent 3b91010500
commit 85463321e7
1 changed files with 143 additions and 62 deletions

View File

@ -1,13 +1,88 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#please run as root
# Please run as root
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
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
if [ "$name" = "HugePages_Free:" ]; then
freepgs="$size"
@ -27,7 +102,7 @@ hpgsize_MB=$((hpgsize_KB / 1024))
half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128))
needmem_KB=$((half_ufd_size_MB * 2 * 1024))
#set proper nr_hugepages
# set proper nr_hugepages
if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
needpgs=$((needmem_KB / hpgsize_KB))
@ -56,136 +131,142 @@ else
exit 1
fi
#filter 64bit architectures
# filter 64bit architectures
ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64"
if [ -z "$ARCH" ]; then
ARCH=$(uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/')
fi
VADDR64=0
echo "$ARCH64STR" | grep "$ARCH" && VADDR64=1
echo "$ARCH64STR" | grep "$ARCH" &>/dev/null && VADDR64=1
# Usage: run_test [test binary] [arbitrary test arguments...]
run_test() {
local title="running $*"
local sep=$(echo -n "$title" | tr "[:graph:][:space:]" -)
printf "%s\n%s\n%s\n" "$sep" "$title" "$sep"
if test_selected ${CATEGORY}; then
local title="running $*"
local sep=$(echo -n "$title" | tr "[:graph:][:space:]" -)
printf "%s\n%s\n%s\n" "$sep" "$title" "$sep"
"$@"
local ret=$?
if [ $ret -eq 0 ]; then
echo "[PASS]"
elif [ $ret -eq $ksft_skip ]; then
echo "[SKIP]"
exitcode=$ksft_skip
else
echo "[FAIL]"
exitcode=1
fi
"$@"
local ret=$?
if [ $ret -eq 0 ]; then
echo "[PASS]"
elif [ $ret -eq $ksft_skip ]; then
echo "[SKIP]"
exitcode=$ksft_skip
else
echo "[FAIL]"
exitcode=1
fi
fi # test_selected
}
run_test ./hugepage-mmap
CATEGORY="hugetlb" run_test ./hugepage-mmap
shmmax=$(cat /proc/sys/kernel/shmmax)
shmall=$(cat /proc/sys/kernel/shmall)
echo 268435456 > /proc/sys/kernel/shmmax
echo 4194304 > /proc/sys/kernel/shmall
run_test ./hugepage-shm
CATEGORY="hugetlb" run_test ./hugepage-shm
echo "$shmmax" > /proc/sys/kernel/shmmax
echo "$shmall" > /proc/sys/kernel/shmall
run_test ./map_hugetlb
run_test ./hugepage-mremap
run_test ./hugepage-vmemmap
run_test ./hugetlb-madvise
CATEGORY="hugetlb" run_test ./map_hugetlb
CATEGORY="hugetlb" run_test ./hugepage-mremap
CATEGORY="hugetlb" run_test ./hugepage-vmemmap
CATEGORY="hugetlb" run_test ./hugetlb-madvise
echo "NOTE: The above hugetlb tests provide minimal coverage. Use"
echo " https://github.com/libhugetlbfs/libhugetlbfs.git for"
echo " hugetlb regression testing."
if test_selected "hugetlb"; then
echo "NOTE: These hugetlb tests provide minimal coverage. Use"
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
run_test ./gup_test -u
CATEGORY="gup_test" run_test ./gup_test -u
# 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:
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")
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
# the size ($half_ufd_size_MB), which is used for *each*.
run_test ./userfaultfd hugetlb${mod} "$half_ufd_size_MB" 32
run_test ./userfaultfd hugetlb_shared${mod} "$half_ufd_size_MB" 32
run_test ./userfaultfd shmem${mod} 20 16
CATEGORY="userfaultfd" run_test ./userfaultfd hugetlb${mod} "$half_ufd_size_MB" 32
CATEGORY="userfaultfd" run_test ./userfaultfd hugetlb_shared${mod} "$half_ufd_size_MB" 32
CATEGORY="userfaultfd" run_test ./userfaultfd shmem${mod} 20 16
done
#cleanup
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
run_test ./virtual_address_range
CATEGORY="hugevm" run_test ./virtual_address_range
# virtual address 128TB switch test
run_test ./va_128TBswitch.sh
CATEGORY="hugevm" run_test ./va_128TBswitch.sh
fi # VADDR64
# 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
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
run_test ./ksm_tests -M -p 10
CATEGORY="ksm" run_test ./ksm_tests -M -p 10
# 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
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
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
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
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
if [ -x ./protection_keys_32 ]
then
run_test ./protection_keys_32
CATEGORY="pkey" run_test ./protection_keys_32
fi
if [ -x ./protection_keys_64 ]
then
run_test ./protection_keys_64
CATEGORY="pkey" run_test ./protection_keys_64
fi
run_test ./soft-dirty
CATEGORY="soft_dirty" run_test ./soft-dirty
# COW tests for anonymous memory
run_test ./cow
# COW tests
CATEGORY="cow" run_test ./cow
exit $exitcode