16d05d3cbSAllison Henderson#! /bin/bash 26d05d3cbSAllison Henderson# SPDX-License-Identifier: GPL-2.0 36d05d3cbSAllison Henderson 46d05d3cbSAllison Hendersonset -e 56d05d3cbSAllison Hendersonset -u 66d05d3cbSAllison Henderson 76d05d3cbSAllison Hendersonunset KBUILD_OUTPUT 86d05d3cbSAllison Henderson 96d05d3cbSAllison Hendersoncurrent_dir="$(realpath "$(dirname "$0")")" 106d05d3cbSAllison Hendersonbuild_dir="$current_dir" 116d05d3cbSAllison Henderson 126d05d3cbSAllison Hendersonbuild_include="$current_dir/include.sh" 136d05d3cbSAllison Hendersonif test -f "$build_include"; then 146d05d3cbSAllison Henderson # this include will define "$mk_build_dir" as the location the test was 156d05d3cbSAllison Henderson # built. We will need this if the tests are installed in a location 166d05d3cbSAllison Henderson # other than the kernel source 176d05d3cbSAllison Henderson 186d05d3cbSAllison Henderson source "$build_include" 196d05d3cbSAllison Henderson build_dir="$mk_build_dir" 206d05d3cbSAllison Hendersonfi 216d05d3cbSAllison Henderson 226d05d3cbSAllison Henderson# Source settings for timeout value (also used by ksft runner) 236d05d3cbSAllison Hendersonsource "$current_dir"/settings 246d05d3cbSAllison Henderson 256d05d3cbSAllison Henderson# This test requires kernel source and the *.gcda data therein 266d05d3cbSAllison Henderson# Locate the top level of the kernel source, and the net/rds 276d05d3cbSAllison Henderson# subfolder with the appropriate *.gcno object files 286d05d3cbSAllison Hendersonksrc_dir="$(realpath "$build_dir"/../../../../../)" 296d05d3cbSAllison Hendersonkconfig="$ksrc_dir/.config" 306d05d3cbSAllison Hendersonobj_dir="$ksrc_dir/net/rds" 316d05d3cbSAllison Henderson 326d05d3cbSAllison HendersonGCOV_CMD=gcov 336d05d3cbSAllison Henderson 346d05d3cbSAllison Henderson#check to see if the host has the required packages to generate a gcov report 356d05d3cbSAllison Hendersoncheck_gcov_env() 366d05d3cbSAllison Henderson{ 376d05d3cbSAllison Henderson if ! which "$GCOV_CMD" > /dev/null 2>&1; then 386d05d3cbSAllison Henderson echo "# Warning: Could not find gcov. " 396d05d3cbSAllison Henderson GENERATE_GCOV_REPORT=0 406d05d3cbSAllison Henderson return 416d05d3cbSAllison Henderson fi 426d05d3cbSAllison Henderson 436d05d3cbSAllison Henderson # the gcov version must match the gcc version 446d05d3cbSAllison Henderson GCC_VER=$(gcc -dumpfullversion) 456d05d3cbSAllison Henderson GCOV_VER=$($GCOV_CMD -v | grep gcov | awk '{print $3}'| awk 'BEGIN {FS="-"}{print $1}') 466d05d3cbSAllison Henderson if [ "$GCOV_VER" != "$GCC_VER" ]; then 476d05d3cbSAllison Henderson #attempt to find a matching gcov version 486d05d3cbSAllison Henderson GCOV_CMD=gcov-$(gcc -dumpversion) 496d05d3cbSAllison Henderson 506d05d3cbSAllison Henderson if ! which "$GCOV_CMD" > /dev/null 2>&1; then 516d05d3cbSAllison Henderson echo "# Warning: Could not find an appropriate gcov installation. \ 526d05d3cbSAllison Henderson gcov version must match gcc version" 536d05d3cbSAllison Henderson GENERATE_GCOV_REPORT=0 546d05d3cbSAllison Henderson return 556d05d3cbSAllison Henderson fi 566d05d3cbSAllison Henderson 576d05d3cbSAllison Henderson #recheck version number of found gcov executable 586d05d3cbSAllison Henderson GCOV_VER=$($GCOV_CMD -v | grep gcov | awk '{print $3}'| \ 596d05d3cbSAllison Henderson awk 'BEGIN {FS="-"}{print $1}') 606d05d3cbSAllison Henderson if [ "$GCOV_VER" != "$GCC_VER" ]; then 616d05d3cbSAllison Henderson echo "# Warning: Could not find an appropriate gcov installation. \ 626d05d3cbSAllison Henderson gcov version must match gcc version" 636d05d3cbSAllison Henderson GENERATE_GCOV_REPORT=0 646d05d3cbSAllison Henderson else 656d05d3cbSAllison Henderson echo "# Warning: Mismatched gcc and gcov detected. Using $GCOV_CMD" 666d05d3cbSAllison Henderson fi 676d05d3cbSAllison Henderson fi 686d05d3cbSAllison Henderson} 696d05d3cbSAllison Henderson 706d05d3cbSAllison Henderson# Check to see if the kconfig has the required configs to generate a coverage report 716d05d3cbSAllison Hendersoncheck_gcov_conf() 726d05d3cbSAllison Henderson{ 736d05d3cbSAllison Henderson if ! grep -x "CONFIG_GCOV_PROFILE_RDS=y" "$kconfig" > /dev/null 2>&1; then 746d05d3cbSAllison Henderson echo "# INFO: CONFIG_GCOV_PROFILE_RDS should be enabled for coverage reports" 756d05d3cbSAllison Henderson GENERATE_GCOV_REPORT=0 766d05d3cbSAllison Henderson fi 776d05d3cbSAllison Henderson if ! grep -x "CONFIG_GCOV_KERNEL=y" "$kconfig" > /dev/null 2>&1; then 786d05d3cbSAllison Henderson echo "# INFO: CONFIG_GCOV_KERNEL should be enabled for coverage reports" 796d05d3cbSAllison Henderson GENERATE_GCOV_REPORT=0 806d05d3cbSAllison Henderson fi 816d05d3cbSAllison Henderson if grep -x "CONFIG_GCOV_PROFILE_ALL=y" "$kconfig" > /dev/null 2>&1; then 826d05d3cbSAllison Henderson echo "# INFO: CONFIG_GCOV_PROFILE_ALL should be disabled for coverage reports" 836d05d3cbSAllison Henderson GENERATE_GCOV_REPORT=0 846d05d3cbSAllison Henderson fi 856d05d3cbSAllison Henderson 866d05d3cbSAllison Henderson if [ "$GENERATE_GCOV_REPORT" -eq 0 ]; then 876d05d3cbSAllison Henderson echo "# To enable gcov reports, please run "\ 886d05d3cbSAllison Henderson "\"tools/testing/selftests/net/rds/config.sh -g\" and rebuild the kernel" 896d05d3cbSAllison Henderson else 906d05d3cbSAllison Henderson # if we have the required kernel configs, proceed to check the environment to 916d05d3cbSAllison Henderson # ensure we have the required gcov packages 926d05d3cbSAllison Henderson check_gcov_env 936d05d3cbSAllison Henderson fi 946d05d3cbSAllison Henderson} 956d05d3cbSAllison Henderson 96c5eb1376SAllison Henderson# Checks if a kconfig is enabled (set to =y or =m) 97c5eb1376SAllison Henderson# $1: kconfig symbol to check 98c5eb1376SAllison Henderson# $2: (optional) module name backing $1 99c5eb1376SAllison Henderson# Ex: check_conf_enabled CONFIG_RDS_TCP rds_tcp 100c5eb1376SAllison Henderson# Modules for configs set to =m will be probed 101c5eb1376SAllison Henderson# If omitted, only a built-in (=y) config is accepted. 102c5eb1376SAllison Henderson# Returns on success. exits 4 on failure 1036d05d3cbSAllison Henderson# Kselftest framework requirement - SKIP code is 4. 1046d05d3cbSAllison Hendersoncheck_conf_enabled() { 105c5eb1376SAllison Henderson if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then 106c5eb1376SAllison Henderson return 1076d05d3cbSAllison Henderson fi 108c5eb1376SAllison Henderson if [ -n "${2:-}" ] && grep -x "$1=m" "$kconfig" > /dev/null 2>&1; then 109c5eb1376SAllison Henderson probe_module "$2" 110c5eb1376SAllison Henderson return 111c5eb1376SAllison Henderson fi 112c5eb1376SAllison Henderson echo "selftests: [SKIP] This test requires $1 enabled" 113c5eb1376SAllison Henderson echo "Please run" \ 114c5eb1376SAllison Henderson "tools/testing/selftests/net/rds/config.sh and rebuild the kernel" 115c5eb1376SAllison Henderson exit 4 1166d05d3cbSAllison Henderson} 1176d05d3cbSAllison Henderson 1186d05d3cbSAllison Hendersoncheck_rdma_conf_enabled() { 119c5eb1376SAllison Henderson if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then 120c5eb1376SAllison Henderson return 121c5eb1376SAllison Henderson fi 122c5eb1376SAllison Henderson if [ -n "${2:-}" ] && grep -x "$1=m" "$kconfig" > /dev/null 2>&1; then 123c5eb1376SAllison Henderson probe_module "$2" 124c5eb1376SAllison Henderson return 125c5eb1376SAllison Henderson fi 126*e3ab0affSAllison Henderson echo "selftests: [XFAIL] rdma transport requires $1 enabled" 1276d05d3cbSAllison Henderson echo "To enable, run" \ 1286d05d3cbSAllison Henderson "tools/testing/selftests/net/rds/config.sh -r and rebuild" 129*e3ab0affSAllison Henderson exit 2 1306d05d3cbSAllison Henderson} 1316d05d3cbSAllison Henderson 132c5eb1376SAllison Henderson# Load the module backing a config that is built as a loadable module 133c5eb1376SAllison Henderson# (=m). Built-in (=y) configs are already available and don't reach 134c5eb1376SAllison Henderson# here. Exits with the SKIP code if a required module cannot be loaded. 135c5eb1376SAllison Hendersonprobe_module() { 136c5eb1376SAllison Henderson if ! modprobe -q "$1"; then 137c5eb1376SAllison Henderson echo "selftests: [SKIP] could not load required module $1" 1386d05d3cbSAllison Henderson exit 4 1396d05d3cbSAllison Henderson fi 1406d05d3cbSAllison Henderson} 141c5eb1376SAllison Henderson 1426d05d3cbSAllison Hendersoncheck_conf() { 143c5eb1376SAllison Henderson check_conf_enabled CONFIG_NET_SCH_NETEM sch_netem 144c5eb1376SAllison Henderson check_conf_enabled CONFIG_VETH veth 1456d05d3cbSAllison Henderson check_conf_enabled CONFIG_NET_NS 146c5eb1376SAllison Henderson check_conf_enabled CONFIG_RDS_TCP rds_tcp 147c5eb1376SAllison Henderson check_conf_enabled CONFIG_RDS rds 1486d05d3cbSAllison Henderson} 1496d05d3cbSAllison Henderson 1506d05d3cbSAllison Henderson# Check kernel config and host environment for RDS-RDMA support. 151*e3ab0affSAllison Henderson# Exits with XFAIL (2) if the user requested rdma but prerequisites 1526d05d3cbSAllison Henderson# are not met. 1536d05d3cbSAllison Hendersoncheck_rdma_conf() 1546d05d3cbSAllison Henderson{ 1556d05d3cbSAllison Henderson case "$TRANSPORT" in 1566d05d3cbSAllison Henderson *rdma*) ;; 1576d05d3cbSAllison Henderson *) return ;; 1586d05d3cbSAllison Henderson esac 1596d05d3cbSAllison Henderson 1606d05d3cbSAllison Henderson # Kconfig will enforce CONFIG_INFINIBAND_* as dependencies 1616d05d3cbSAllison Henderson # of CONFIG_RDMA_RXE 162c5eb1376SAllison Henderson check_rdma_conf_enabled CONFIG_RDMA_RXE rdma_rxe 163c5eb1376SAllison Henderson check_rdma_conf_enabled CONFIG_RDS_RDMA rds_rdma 1646d05d3cbSAllison Henderson 1656d05d3cbSAllison Henderson if ! which rdma > /dev/null 2>&1; then 166*e3ab0affSAllison Henderson echo "selftests: [XFAIL] rdma transport requires the 'rdma'" \ 1676d05d3cbSAllison Henderson "tool (iproute2)" 168*e3ab0affSAllison Henderson exit 2 1696d05d3cbSAllison Henderson fi 1706d05d3cbSAllison Henderson} 1716d05d3cbSAllison Henderson 1726d05d3cbSAllison Hendersoncheck_env() 1736d05d3cbSAllison Henderson{ 1746d05d3cbSAllison Henderson if ! test -d "$obj_dir"; then 1756d05d3cbSAllison Henderson echo "selftests: [SKIP] This test requires a kernel source tree" 1766d05d3cbSAllison Henderson exit 4 1776d05d3cbSAllison Henderson fi 1786d05d3cbSAllison Henderson if ! test -e "$kconfig"; then 1796d05d3cbSAllison Henderson echo "selftests: [SKIP] This test requires a configured kernel source tree" 1806d05d3cbSAllison Henderson exit 4 1816d05d3cbSAllison Henderson fi 1826d05d3cbSAllison Henderson if ! which strace > /dev/null 2>&1; then 1836d05d3cbSAllison Henderson echo "selftests: [SKIP] Could not run test without strace" 1846d05d3cbSAllison Henderson exit 4 1856d05d3cbSAllison Henderson fi 1866d05d3cbSAllison Henderson if ! which tcpdump > /dev/null 2>&1; then 1876d05d3cbSAllison Henderson echo "selftests: [SKIP] Could not run test without tcpdump" 1886d05d3cbSAllison Henderson exit 4 1896d05d3cbSAllison Henderson fi 1906d05d3cbSAllison Henderson 1916d05d3cbSAllison Henderson if ! which python3 > /dev/null 2>&1; then 1926d05d3cbSAllison Henderson echo "selftests: [SKIP] Could not run test without python3" 1936d05d3cbSAllison Henderson exit 4 1946d05d3cbSAllison Henderson fi 1956d05d3cbSAllison Henderson 1966d05d3cbSAllison Henderson python_major=$(python3 -c "import sys; print(sys.version_info[0])") 1976d05d3cbSAllison Henderson python_minor=$(python3 -c "import sys; print(sys.version_info[1])") 1986d05d3cbSAllison Henderson if [[ python_major -lt 3 || ( python_major -eq 3 && python_minor -lt 9 ) ]] ; then 1996d05d3cbSAllison Henderson echo "selftests: [SKIP] Could not run test without at least python3.9" 2006d05d3cbSAllison Henderson python3 -V 2016d05d3cbSAllison Henderson exit 4 2026d05d3cbSAllison Henderson fi 2036d05d3cbSAllison Henderson} 2046d05d3cbSAllison Henderson 2056d05d3cbSAllison HendersonLOG_DIR="${RDS_LOG_DIR:-}" 2066d05d3cbSAllison HendersonTIMEOUT=$timeout 2076d05d3cbSAllison HendersonGENERATE_GCOV_REPORT=1 2086d05d3cbSAllison HendersonTRANSPORT=tcp 2096d05d3cbSAllison HendersonFLAGS=() 2106d05d3cbSAllison Henderson 2116d05d3cbSAllison Hendersonwhile getopts "d:l:c:u:t:T:" opt; do 2126d05d3cbSAllison Henderson case ${opt} in 2136d05d3cbSAllison Henderson d) 2146d05d3cbSAllison Henderson LOG_DIR=${OPTARG} 2156d05d3cbSAllison Henderson ;; 2166d05d3cbSAllison Henderson l) 2176d05d3cbSAllison Henderson FLAGS+=("-l" "${OPTARG}") 2186d05d3cbSAllison Henderson ;; 2196d05d3cbSAllison Henderson c) 2206d05d3cbSAllison Henderson FLAGS+=("-c" "${OPTARG}") 2216d05d3cbSAllison Henderson ;; 2226d05d3cbSAllison Henderson t) 2236d05d3cbSAllison Henderson TIMEOUT=${OPTARG} 2246d05d3cbSAllison Henderson ;; 2256d05d3cbSAllison Henderson u) 2266d05d3cbSAllison Henderson FLAGS+=("-u" "${OPTARG}") 2276d05d3cbSAllison Henderson ;; 2286d05d3cbSAllison Henderson T) 2296d05d3cbSAllison Henderson TRANSPORT=${OPTARG} 2306d05d3cbSAllison Henderson ;; 2316d05d3cbSAllison Henderson :) 2326d05d3cbSAllison Henderson echo "USAGE: rds_run.sh [-d logdir] [-l packet_loss]" \ 2336d05d3cbSAllison Henderson "[-c packet_corruption] [-u packet_duplicate] [-t timeout]" \ 2346d05d3cbSAllison Henderson "[-T tcp|rdma|tcp,rdma]" 2356d05d3cbSAllison Henderson exit 1 2366d05d3cbSAllison Henderson ;; 2376d05d3cbSAllison Henderson ?) 2386d05d3cbSAllison Henderson echo "Invalid option: -${OPTARG}." 2396d05d3cbSAllison Henderson exit 1 2406d05d3cbSAllison Henderson ;; 2416d05d3cbSAllison Henderson esac 2426d05d3cbSAllison Hendersondone 2436d05d3cbSAllison Henderson 2446d05d3cbSAllison Henderson# Validate transport tokens 2456d05d3cbSAllison HendersonIFS=',' read -ra transports <<< "$TRANSPORT" 2466d05d3cbSAllison Hendersonfor t in "${transports[@]}"; do 2476d05d3cbSAllison Henderson if [ "$t" != "tcp" ] && [ "$t" != "rdma" ]; then 2486d05d3cbSAllison Henderson echo "rds_run.sh: unknown transport '$t' (expected tcp or rdma)" 2496d05d3cbSAllison Henderson exit 1 2506d05d3cbSAllison Henderson fi 2516d05d3cbSAllison Hendersondone 2526d05d3cbSAllison Henderson 2536d05d3cbSAllison HendersonFLAGS+=("--transport" "${TRANSPORT}") 2546d05d3cbSAllison Henderson 2556d05d3cbSAllison Hendersoncheck_env 2566d05d3cbSAllison Hendersoncheck_conf 2576d05d3cbSAllison Hendersoncheck_gcov_conf 2586d05d3cbSAllison Hendersoncheck_rdma_conf 2596d05d3cbSAllison Henderson 2606d05d3cbSAllison HendersonTRACE_CMD=() 2616d05d3cbSAllison Hendersonif [[ -n "$LOG_DIR" ]]; then 2626d05d3cbSAllison Henderson FLAGS+=("-d" "$LOG_DIR") 2636d05d3cbSAllison Henderson 2646d05d3cbSAllison Henderson TRACE_FILE="${LOG_DIR}/rds-strace.txt" 2656d05d3cbSAllison Henderson COVR_DIR="${LOG_DIR}/coverage/" 2666d05d3cbSAllison Henderson DMESG_FILE="${LOG_DIR}/rds-dmesg.out" 2676d05d3cbSAllison Henderson 2686d05d3cbSAllison Henderson mkdir -p "$LOG_DIR" 2696d05d3cbSAllison Henderson mkdir -p "$COVR_DIR" 2706d05d3cbSAllison Henderson 2716d05d3cbSAllison Henderson rm -f "$TRACE_FILE" 2726d05d3cbSAllison Henderson rm -f "$DMESG_FILE" 2736d05d3cbSAllison Henderson rm -f "$LOG_DIR"/rds-*.pcap 2746d05d3cbSAllison Henderson rm -f "$COVR_DIR"/gcovr* 2756d05d3cbSAllison Henderson 2766d05d3cbSAllison Henderson echo "# Traces will be logged to ${TRACE_FILE}" 2776d05d3cbSAllison Henderson TRACE_CMD=(strace -T -tt -o "${TRACE_FILE}") 2786d05d3cbSAllison Hendersonfi 2796d05d3cbSAllison Henderson 2806d05d3cbSAllison Hendersonset +e 2816d05d3cbSAllison Hendersonecho "# running RDS tests..." 2826d05d3cbSAllison Henderson"${TRACE_CMD[@]}" python3 "$(dirname "$0")/test.py" "${FLAGS[@]}" -t "$TIMEOUT" 2836d05d3cbSAllison Henderson 2846d05d3cbSAllison Hendersontest_rc=$? 2856d05d3cbSAllison Henderson 2866d05d3cbSAllison Hendersonif [[ -n "$LOG_DIR" ]]; then 2876d05d3cbSAllison Henderson dmesg > "${DMESG_FILE}" 2886d05d3cbSAllison Hendersonfi 2896d05d3cbSAllison Henderson 2906d05d3cbSAllison Hendersonif [[ -n "$LOG_DIR" ]] && [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then 2916d05d3cbSAllison Henderson echo "# saving coverage data..." 2926d05d3cbSAllison Henderson 2936d05d3cbSAllison Henderson # Ensure debugfs is mounted before reading gcov data. 2946d05d3cbSAllison Henderson if ! mountpoint -q /sys/kernel/debug 2>/dev/null; then 2956d05d3cbSAllison Henderson mount -t debugfs debugfs /sys/kernel/debug 2>/dev/null || true 2966d05d3cbSAllison Henderson fi 2976d05d3cbSAllison Henderson 2986d05d3cbSAllison Henderson (set +x; cd /sys/kernel/debug/gcov; find ./* -name '*.gcda' | \ 2996d05d3cbSAllison Henderson while read -r f 3006d05d3cbSAllison Henderson do 3016d05d3cbSAllison Henderson cat < "/sys/kernel/debug/gcov/$f" > "/$f" 3026d05d3cbSAllison Henderson done) 3036d05d3cbSAllison Henderson 3046d05d3cbSAllison Henderson echo "# running gcovr..." 3056d05d3cbSAllison Henderson gcovr -s --html-details --gcov-executable "$GCOV_CMD" --gcov-ignore-parse-errors \ 3066d05d3cbSAllison Henderson --root "${ksrc_dir}" -o "${COVR_DIR}/gcovr" "${ksrc_dir}/net/rds/" \ 3076d05d3cbSAllison Henderson > "${LOG_DIR}/gcovr.log" 2>&1 3086d05d3cbSAllison Henderson echo "# gcovr log: ${LOG_DIR}/gcovr.log" 3096d05d3cbSAllison Hendersonelse 3106d05d3cbSAllison Henderson echo "# Coverage report will be skipped" 3116d05d3cbSAllison Hendersonfi 3126d05d3cbSAllison Henderson 3136d05d3cbSAllison Hendersonif [ "$test_rc" -eq 0 ]; then 3146d05d3cbSAllison Henderson echo "# PASS: Test completed successfully" 3156d05d3cbSAllison Hendersonelse 3166d05d3cbSAllison Henderson echo "# FAIL: Test failed" 3176d05d3cbSAllison Hendersonfi 3186d05d3cbSAllison Henderson 3196d05d3cbSAllison Hendersonexit "$test_rc" 320