linux/tools/testing/selftests/net/gro.sh
Kevin Krakauer 51bef03e1a selftests/net: deflake GRO tests
GRO tests are timing dependent and can easily flake. This is partially
mitigated in gro.sh by giving each subtest 3 chances to pass. However,
this still flakes on some machines. Reduce the flakiness by:

- Bumping retries to 6.
- Setting napi_defer_hard_irqs to 1 to reduce the chance that GRO is
  flushed prematurely. This also lets us reduce the gro_flush_timeout
  from 1ms to 100us.

Tested: Ran `gro.sh -t large` 1000 times. There were no failures with
this change. Ran inside strace to increase flakiness.

Signed-off-by: Kevin Krakauer <krakauer@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20250226192725.621969-4-krakauer@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-02-27 18:38:23 -08:00

105 lines
2.3 KiB
Bash
Executable file

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
readonly SERVER_MAC="aa:00:00:00:00:02"
readonly CLIENT_MAC="aa:00:00:00:00:01"
readonly TESTS=("data" "ack" "flags" "tcp" "ip" "large")
readonly PROTOS=("ipv4" "ipv6")
dev=""
test="all"
proto="ipv4"
run_test() {
local server_pid=0
local exit_code=0
local protocol=$1
local test=$2
local ARGS=( "--${protocol}" "--dmac" "${SERVER_MAC}" \
"--smac" "${CLIENT_MAC}" "--test" "${test}" "--verbose" )
setup_ns
# Each test is run 6 times to deflake, because given the receive timing,
# not all packets that should coalesce will be considered in the same flow
# on every try.
for tries in {1..6}; do
# Actual test starts here
ip netns exec $server_ns ./gro "${ARGS[@]}" "--rx" "--iface" "server" \
1>>log.txt &
server_pid=$!
sleep 0.5 # to allow for socket init
ip netns exec $client_ns ./gro "${ARGS[@]}" "--iface" "client" \
1>>log.txt
wait "${server_pid}"
exit_code=$?
if [[ ${test} == "large" && -n "${KSFT_MACHINE_SLOW}" && \
${exit_code} -ne 0 ]]; then
echo "Ignoring errors due to slow environment" 1>&2
exit_code=0
fi
if [[ "${exit_code}" -eq 0 ]]; then
break;
fi
done
cleanup_ns
echo ${exit_code}
}
run_all_tests() {
local failed_tests=()
for proto in "${PROTOS[@]}"; do
for test in "${TESTS[@]}"; do
echo "running test ${proto} ${test}" >&2
exit_code=$(run_test $proto $test)
if [[ "${exit_code}" -ne 0 ]]; then
failed_tests+=("${proto}_${test}")
fi;
done;
done
if [[ ${#failed_tests[@]} -ne 0 ]]; then
echo "failed tests: ${failed_tests[*]}. \
Please see log.txt for more logs"
exit 1
else
echo "All Tests Succeeded!"
fi;
}
usage() {
echo "Usage: $0 \
[-i <DEV>] \
[-t data|ack|flags|tcp|ip|large] \
[-p <ipv4|ipv6>]" 1>&2;
exit 1;
}
while getopts "i:t:p:" opt; do
case "${opt}" in
i)
dev="${OPTARG}"
;;
t)
test="${OPTARG}"
;;
p)
proto="${OPTARG}"
;;
*)
usage
;;
esac
done
if [ -n "$dev" ]; then
source setup_loopback.sh
else
source setup_veth.sh
fi
setup
trap cleanup EXIT
if [[ "${test}" == "all" ]]; then
run_all_tests
else
exit_code=$(run_test "${proto}" "${test}")
exit $exit_code
fi;