1*d9ccb18fSOmid Ehtemam-Haghighi#!/bin/bash 2*d9ccb18fSOmid Ehtemam-Haghighi# SPDX-License-Identifier: GPL-2.0 3*d9ccb18fSOmid Ehtemam-Haghighi# 4*d9ccb18fSOmid Ehtemam-Haghighi# Testing for potential kernel soft lockup during IPv6 routing table 5*d9ccb18fSOmid Ehtemam-Haghighi# refresh under heavy outgoing IPv6 traffic. If a kernel soft lockup 6*d9ccb18fSOmid Ehtemam-Haghighi# occurs, a kernel panic will be triggered to prevent associated issues. 7*d9ccb18fSOmid Ehtemam-Haghighi# 8*d9ccb18fSOmid Ehtemam-Haghighi# 9*d9ccb18fSOmid Ehtemam-Haghighi# Test Environment Layout 10*d9ccb18fSOmid Ehtemam-Haghighi# 11*d9ccb18fSOmid Ehtemam-Haghighi# ┌----------------┐ ┌----------------┐ 12*d9ccb18fSOmid Ehtemam-Haghighi# | SOURCE_NS | | SINK_NS | 13*d9ccb18fSOmid Ehtemam-Haghighi# | NAMESPACE | | NAMESPACE | 14*d9ccb18fSOmid Ehtemam-Haghighi# |(iperf3 clients)| |(iperf3 servers)| 15*d9ccb18fSOmid Ehtemam-Haghighi# | | | | 16*d9ccb18fSOmid Ehtemam-Haghighi# | | | | 17*d9ccb18fSOmid Ehtemam-Haghighi# | ┌-----------| nexthops |---------┐ | 18*d9ccb18fSOmid Ehtemam-Haghighi# | |veth_source|<--------------------------------------->|veth_sink|<┐ | 19*d9ccb18fSOmid Ehtemam-Haghighi# | └-----------|2001:0DB8:1::0:1/96 2001:0DB8:1::1:1/96 |---------┘ | | 20*d9ccb18fSOmid Ehtemam-Haghighi# | | ^ 2001:0DB8:1::1:2/96 | | | 21*d9ccb18fSOmid Ehtemam-Haghighi# | | . . | fwd | | 22*d9ccb18fSOmid Ehtemam-Haghighi# | ┌---------┐ | . . | | | 23*d9ccb18fSOmid Ehtemam-Haghighi# | | IPv6 | | . . | V | 24*d9ccb18fSOmid Ehtemam-Haghighi# | | routing | | . 2001:0DB8:1::1:80/96| ┌-----┐ | 25*d9ccb18fSOmid Ehtemam-Haghighi# | | table | | . | | lo | | 26*d9ccb18fSOmid Ehtemam-Haghighi# | | nexthop | | . └--------┴-----┴-┘ 27*d9ccb18fSOmid Ehtemam-Haghighi# | | update | | ............................> 2001:0DB8:2::1:1/128 28*d9ccb18fSOmid Ehtemam-Haghighi# | └-------- ┘ | 29*d9ccb18fSOmid Ehtemam-Haghighi# └----------------┘ 30*d9ccb18fSOmid Ehtemam-Haghighi# 31*d9ccb18fSOmid Ehtemam-Haghighi# The test script sets up two network namespaces, source_ns and sink_ns, 32*d9ccb18fSOmid Ehtemam-Haghighi# connected via a veth link. Within source_ns, it continuously updates the 33*d9ccb18fSOmid Ehtemam-Haghighi# IPv6 routing table by flushing and inserting IPV6_NEXTHOP_ADDR_COUNT nexthop 34*d9ccb18fSOmid Ehtemam-Haghighi# IPs destined for SINK_LOOPBACK_IP_ADDR in sink_ns. This refresh occurs at a 35*d9ccb18fSOmid Ehtemam-Haghighi# rate of 1/ROUTING_TABLE_REFRESH_PERIOD per second for TEST_DURATION seconds. 36*d9ccb18fSOmid Ehtemam-Haghighi# 37*d9ccb18fSOmid Ehtemam-Haghighi# Simultaneously, multiple iperf3 clients within source_ns generate heavy 38*d9ccb18fSOmid Ehtemam-Haghighi# outgoing IPv6 traffic. Each client is assigned a unique port number starting 39*d9ccb18fSOmid Ehtemam-Haghighi# at 5000 and incrementing sequentially. Each client targets a unique iperf3 40*d9ccb18fSOmid Ehtemam-Haghighi# server running in sink_ns, connected to the SINK_LOOPBACK_IFACE interface 41*d9ccb18fSOmid Ehtemam-Haghighi# using the same port number. 42*d9ccb18fSOmid Ehtemam-Haghighi# 43*d9ccb18fSOmid Ehtemam-Haghighi# The number of iperf3 servers and clients is set to half of the total 44*d9ccb18fSOmid Ehtemam-Haghighi# available cores on each machine. 45*d9ccb18fSOmid Ehtemam-Haghighi# 46*d9ccb18fSOmid Ehtemam-Haghighi# NOTE: We have tested this script on machines with various CPU specifications, 47*d9ccb18fSOmid Ehtemam-Haghighi# ranging from lower to higher performance as listed below. The test script 48*d9ccb18fSOmid Ehtemam-Haghighi# effectively triggered a kernel soft lockup on machines running an unpatched 49*d9ccb18fSOmid Ehtemam-Haghighi# kernel in under a minute: 50*d9ccb18fSOmid Ehtemam-Haghighi# 51*d9ccb18fSOmid Ehtemam-Haghighi# - 1x Intel Xeon E-2278G 8-Core Processor @ 3.40GHz 52*d9ccb18fSOmid Ehtemam-Haghighi# - 1x Intel Xeon E-2378G Processor 8-Core @ 2.80GHz 53*d9ccb18fSOmid Ehtemam-Haghighi# - 1x AMD EPYC 7401P 24-Core Processor @ 2.00GHz 54*d9ccb18fSOmid Ehtemam-Haghighi# - 1x AMD EPYC 7402P 24-Core Processor @ 2.80GHz 55*d9ccb18fSOmid Ehtemam-Haghighi# - 2x Intel Xeon Gold 5120 14-Core Processor @ 2.20GHz 56*d9ccb18fSOmid Ehtemam-Haghighi# - 1x Ampere Altra Q80-30 80-Core Processor @ 3.00GHz 57*d9ccb18fSOmid Ehtemam-Haghighi# - 2x Intel Xeon Gold 5120 14-Core Processor @ 2.20GHz 58*d9ccb18fSOmid Ehtemam-Haghighi# - 2x Intel Xeon Silver 4214 24-Core Processor @ 2.20GHz 59*d9ccb18fSOmid Ehtemam-Haghighi# - 1x AMD EPYC 7502P 32-Core @ 2.50GHz 60*d9ccb18fSOmid Ehtemam-Haghighi# - 1x Intel Xeon Gold 6314U 32-Core Processor @ 2.30GHz 61*d9ccb18fSOmid Ehtemam-Haghighi# - 2x Intel Xeon Gold 6338 32-Core Processor @ 2.00GHz 62*d9ccb18fSOmid Ehtemam-Haghighi# 63*d9ccb18fSOmid Ehtemam-Haghighi# On less performant machines, you may need to increase the TEST_DURATION 64*d9ccb18fSOmid Ehtemam-Haghighi# parameter to enhance the likelihood of encountering a race condition leading 65*d9ccb18fSOmid Ehtemam-Haghighi# to a kernel soft lockup and avoid a false negative result. 66*d9ccb18fSOmid Ehtemam-Haghighi# 67*d9ccb18fSOmid Ehtemam-Haghighi# NOTE: The test may not produce the expected result in virtualized 68*d9ccb18fSOmid Ehtemam-Haghighi# environments (e.g., qemu) due to differences in timing and CPU handling, 69*d9ccb18fSOmid Ehtemam-Haghighi# which can affect the conditions needed to trigger a soft lockup. 70*d9ccb18fSOmid Ehtemam-Haghighi 71*d9ccb18fSOmid Ehtemam-Haghighisource lib.sh 72*d9ccb18fSOmid Ehtemam-Haghighisource net_helper.sh 73*d9ccb18fSOmid Ehtemam-Haghighi 74*d9ccb18fSOmid Ehtemam-HaghighiTEST_DURATION=300 75*d9ccb18fSOmid Ehtemam-HaghighiROUTING_TABLE_REFRESH_PERIOD=0.01 76*d9ccb18fSOmid Ehtemam-Haghighi 77*d9ccb18fSOmid Ehtemam-HaghighiIPERF3_BITRATE="300m" 78*d9ccb18fSOmid Ehtemam-Haghighi 79*d9ccb18fSOmid Ehtemam-Haghighi 80*d9ccb18fSOmid Ehtemam-HaghighiIPV6_NEXTHOP_ADDR_COUNT="128" 81*d9ccb18fSOmid Ehtemam-HaghighiIPV6_NEXTHOP_ADDR_MASK="96" 82*d9ccb18fSOmid Ehtemam-HaghighiIPV6_NEXTHOP_PREFIX="2001:0DB8:1" 83*d9ccb18fSOmid Ehtemam-Haghighi 84*d9ccb18fSOmid Ehtemam-Haghighi 85*d9ccb18fSOmid Ehtemam-HaghighiSOURCE_TEST_IFACE="veth_source" 86*d9ccb18fSOmid Ehtemam-HaghighiSOURCE_TEST_IP_ADDR="2001:0DB8:1::0:1/96" 87*d9ccb18fSOmid Ehtemam-Haghighi 88*d9ccb18fSOmid Ehtemam-HaghighiSINK_TEST_IFACE="veth_sink" 89*d9ccb18fSOmid Ehtemam-Haghighi# ${SINK_TEST_IFACE} is populated with the following range of IPv6 addresses: 90*d9ccb18fSOmid Ehtemam-Haghighi# 2001:0DB8:1::1:1 to 2001:0DB8:1::1:${IPV6_NEXTHOP_ADDR_COUNT} 91*d9ccb18fSOmid Ehtemam-HaghighiSINK_LOOPBACK_IFACE="lo" 92*d9ccb18fSOmid Ehtemam-HaghighiSINK_LOOPBACK_IP_MASK="128" 93*d9ccb18fSOmid Ehtemam-HaghighiSINK_LOOPBACK_IP_ADDR="2001:0DB8:2::1:1" 94*d9ccb18fSOmid Ehtemam-Haghighi 95*d9ccb18fSOmid Ehtemam-Haghighinexthop_ip_list="" 96*d9ccb18fSOmid Ehtemam-Haghighitermination_signal="" 97*d9ccb18fSOmid Ehtemam-Haghighikernel_softlokup_panic_prev_val="" 98*d9ccb18fSOmid Ehtemam-Haghighi 99*d9ccb18fSOmid Ehtemam-Haghighiterminate_ns_processes_by_pattern() { 100*d9ccb18fSOmid Ehtemam-Haghighi local ns=$1 101*d9ccb18fSOmid Ehtemam-Haghighi local pattern=$2 102*d9ccb18fSOmid Ehtemam-Haghighi 103*d9ccb18fSOmid Ehtemam-Haghighi for pid in $(ip netns pids ${ns}); do 104*d9ccb18fSOmid Ehtemam-Haghighi [ -e /proc/$pid/cmdline ] && grep -qe "${pattern}" /proc/$pid/cmdline && kill -9 $pid 105*d9ccb18fSOmid Ehtemam-Haghighi done 106*d9ccb18fSOmid Ehtemam-Haghighi} 107*d9ccb18fSOmid Ehtemam-Haghighi 108*d9ccb18fSOmid Ehtemam-Haghighicleanup() { 109*d9ccb18fSOmid Ehtemam-Haghighi echo "info: cleaning up namespaces and terminating all processes within them..." 110*d9ccb18fSOmid Ehtemam-Haghighi 111*d9ccb18fSOmid Ehtemam-Haghighi 112*d9ccb18fSOmid Ehtemam-Haghighi # Terminate iperf3 instances running in the source_ns. To avoid race 113*d9ccb18fSOmid Ehtemam-Haghighi # conditions, first iterate over the PIDs and terminate those 114*d9ccb18fSOmid Ehtemam-Haghighi # associated with the bash shells running the 115*d9ccb18fSOmid Ehtemam-Haghighi # `while true; do iperf3 -c ...; done` loops. In a second iteration, 116*d9ccb18fSOmid Ehtemam-Haghighi # terminate the individual `iperf3 -c ...` instances. 117*d9ccb18fSOmid Ehtemam-Haghighi terminate_ns_processes_by_pattern ${source_ns} while 118*d9ccb18fSOmid Ehtemam-Haghighi terminate_ns_processes_by_pattern ${source_ns} iperf3 119*d9ccb18fSOmid Ehtemam-Haghighi 120*d9ccb18fSOmid Ehtemam-Haghighi # Repeat the same process for sink_ns 121*d9ccb18fSOmid Ehtemam-Haghighi terminate_ns_processes_by_pattern ${sink_ns} while 122*d9ccb18fSOmid Ehtemam-Haghighi terminate_ns_processes_by_pattern ${sink_ns} iperf3 123*d9ccb18fSOmid Ehtemam-Haghighi 124*d9ccb18fSOmid Ehtemam-Haghighi # Check if any iperf3 instances are still running. This could happen 125*d9ccb18fSOmid Ehtemam-Haghighi # if a core has entered an infinite loop and the timeout for detecting 126*d9ccb18fSOmid Ehtemam-Haghighi # the soft lockup has not expired, but either the test interval has 127*d9ccb18fSOmid Ehtemam-Haghighi # already elapsed or the test was terminated manually (e.g., with ^C) 128*d9ccb18fSOmid Ehtemam-Haghighi for pid in $(ip netns pids ${source_ns}); do 129*d9ccb18fSOmid Ehtemam-Haghighi if [ -e /proc/$pid/cmdline ] && grep -qe 'iperf3' /proc/$pid/cmdline; then 130*d9ccb18fSOmid Ehtemam-Haghighi echo "FAIL: unable to terminate some iperf3 instances. Soft lockup is underway. A kernel panic is on the way!" 131*d9ccb18fSOmid Ehtemam-Haghighi exit ${ksft_fail} 132*d9ccb18fSOmid Ehtemam-Haghighi fi 133*d9ccb18fSOmid Ehtemam-Haghighi done 134*d9ccb18fSOmid Ehtemam-Haghighi 135*d9ccb18fSOmid Ehtemam-Haghighi if [ "$termination_signal" == "SIGINT" ]; then 136*d9ccb18fSOmid Ehtemam-Haghighi echo "SKIP: Termination due to ^C (SIGINT)" 137*d9ccb18fSOmid Ehtemam-Haghighi elif [ "$termination_signal" == "SIGALRM" ]; then 138*d9ccb18fSOmid Ehtemam-Haghighi echo "PASS: No kernel soft lockup occurred during this ${TEST_DURATION} second test" 139*d9ccb18fSOmid Ehtemam-Haghighi fi 140*d9ccb18fSOmid Ehtemam-Haghighi 141*d9ccb18fSOmid Ehtemam-Haghighi cleanup_ns ${source_ns} ${sink_ns} 142*d9ccb18fSOmid Ehtemam-Haghighi 143*d9ccb18fSOmid Ehtemam-Haghighi sysctl -qw kernel.softlockup_panic=${kernel_softlokup_panic_prev_val} 144*d9ccb18fSOmid Ehtemam-Haghighi} 145*d9ccb18fSOmid Ehtemam-Haghighi 146*d9ccb18fSOmid Ehtemam-Haghighisetup_prepare() { 147*d9ccb18fSOmid Ehtemam-Haghighi setup_ns source_ns sink_ns 148*d9ccb18fSOmid Ehtemam-Haghighi 149*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${source_ns} link add name ${SOURCE_TEST_IFACE} type veth peer name ${SINK_TEST_IFACE} netns ${sink_ns} 150*d9ccb18fSOmid Ehtemam-Haghighi 151*d9ccb18fSOmid Ehtemam-Haghighi # Setting up the Source namespace 152*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${source_ns} addr add ${SOURCE_TEST_IP_ADDR} dev ${SOURCE_TEST_IFACE} 153*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${source_ns} link set dev ${SOURCE_TEST_IFACE} qlen 10000 154*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${source_ns} link set dev ${SOURCE_TEST_IFACE} up 155*d9ccb18fSOmid Ehtemam-Haghighi ip netns exec ${source_ns} sysctl -qw net.ipv6.fib_multipath_hash_policy=1 156*d9ccb18fSOmid Ehtemam-Haghighi 157*d9ccb18fSOmid Ehtemam-Haghighi # Setting up the Sink namespace 158*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${sink_ns} addr add ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK} dev ${SINK_LOOPBACK_IFACE} 159*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${sink_ns} link set dev ${SINK_LOOPBACK_IFACE} up 160*d9ccb18fSOmid Ehtemam-Haghighi ip netns exec ${sink_ns} sysctl -qw net.ipv6.conf.${SINK_LOOPBACK_IFACE}.forwarding=1 161*d9ccb18fSOmid Ehtemam-Haghighi 162*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${sink_ns} link set ${SINK_TEST_IFACE} up 163*d9ccb18fSOmid Ehtemam-Haghighi ip netns exec ${sink_ns} sysctl -qw net.ipv6.conf.${SINK_TEST_IFACE}.forwarding=1 164*d9ccb18fSOmid Ehtemam-Haghighi 165*d9ccb18fSOmid Ehtemam-Haghighi 166*d9ccb18fSOmid Ehtemam-Haghighi # Populate nexthop IPv6 addresses on the test interface in the sink_ns 167*d9ccb18fSOmid Ehtemam-Haghighi echo "info: populating ${IPV6_NEXTHOP_ADDR_COUNT} IPv6 addresses on the ${SINK_TEST_IFACE} interface ..." 168*d9ccb18fSOmid Ehtemam-Haghighi for IP in $(seq 1 ${IPV6_NEXTHOP_ADDR_COUNT}); do 169*d9ccb18fSOmid Ehtemam-Haghighi ip -n ${sink_ns} addr add ${IPV6_NEXTHOP_PREFIX}::$(printf "1:%x" "${IP}")/${IPV6_NEXTHOP_ADDR_MASK} dev ${SINK_TEST_IFACE}; 170*d9ccb18fSOmid Ehtemam-Haghighi done 171*d9ccb18fSOmid Ehtemam-Haghighi 172*d9ccb18fSOmid Ehtemam-Haghighi # Preparing list of nexthops 173*d9ccb18fSOmid Ehtemam-Haghighi for IP in $(seq 1 ${IPV6_NEXTHOP_ADDR_COUNT}); do 174*d9ccb18fSOmid Ehtemam-Haghighi nexthop_ip_list=$nexthop_ip_list" nexthop via ${IPV6_NEXTHOP_PREFIX}::$(printf "1:%x" $IP) dev ${SOURCE_TEST_IFACE} weight 1" 175*d9ccb18fSOmid Ehtemam-Haghighi done 176*d9ccb18fSOmid Ehtemam-Haghighi} 177*d9ccb18fSOmid Ehtemam-Haghighi 178*d9ccb18fSOmid Ehtemam-Haghighi 179*d9ccb18fSOmid Ehtemam-Haghighitest_soft_lockup_during_routing_table_refresh() { 180*d9ccb18fSOmid Ehtemam-Haghighi # Start num_of_iperf_servers iperf3 servers in the sink_ns namespace, 181*d9ccb18fSOmid Ehtemam-Haghighi # each listening on ports starting at 5001 and incrementing 182*d9ccb18fSOmid Ehtemam-Haghighi # sequentially. Since iperf3 instances may terminate unexpectedly, a 183*d9ccb18fSOmid Ehtemam-Haghighi # while loop is used to automatically restart them in such cases. 184*d9ccb18fSOmid Ehtemam-Haghighi echo "info: starting ${num_of_iperf_servers} iperf3 servers in the sink_ns namespace ..." 185*d9ccb18fSOmid Ehtemam-Haghighi for i in $(seq 1 ${num_of_iperf_servers}); do 186*d9ccb18fSOmid Ehtemam-Haghighi cmd="iperf3 --bind ${SINK_LOOPBACK_IP_ADDR} -s -p $(printf '5%03d' ${i}) --rcv-timeout 200 &>/dev/null" 187*d9ccb18fSOmid Ehtemam-Haghighi ip netns exec ${sink_ns} bash -c "while true; do ${cmd}; done &" &>/dev/null 188*d9ccb18fSOmid Ehtemam-Haghighi done 189*d9ccb18fSOmid Ehtemam-Haghighi 190*d9ccb18fSOmid Ehtemam-Haghighi # Wait for the iperf3 servers to be ready 191*d9ccb18fSOmid Ehtemam-Haghighi for i in $(seq ${num_of_iperf_servers}); do 192*d9ccb18fSOmid Ehtemam-Haghighi port=$(printf '5%03d' ${i}); 193*d9ccb18fSOmid Ehtemam-Haghighi wait_local_port_listen ${sink_ns} ${port} tcp 194*d9ccb18fSOmid Ehtemam-Haghighi done 195*d9ccb18fSOmid Ehtemam-Haghighi 196*d9ccb18fSOmid Ehtemam-Haghighi # Continuously refresh the routing table in the background within 197*d9ccb18fSOmid Ehtemam-Haghighi # the source_ns namespace 198*d9ccb18fSOmid Ehtemam-Haghighi ip netns exec ${source_ns} bash -c " 199*d9ccb18fSOmid Ehtemam-Haghighi while \$(ip netns list | grep -q ${source_ns}); do 200*d9ccb18fSOmid Ehtemam-Haghighi ip -6 route add ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK} ${nexthop_ip_list}; 201*d9ccb18fSOmid Ehtemam-Haghighi sleep ${ROUTING_TABLE_REFRESH_PERIOD}; 202*d9ccb18fSOmid Ehtemam-Haghighi ip -6 route delete ${SINK_LOOPBACK_IP_ADDR}/${SINK_LOOPBACK_IP_MASK}; 203*d9ccb18fSOmid Ehtemam-Haghighi done &" 204*d9ccb18fSOmid Ehtemam-Haghighi 205*d9ccb18fSOmid Ehtemam-Haghighi # Start num_of_iperf_servers iperf3 clients in the source_ns namespace, 206*d9ccb18fSOmid Ehtemam-Haghighi # each sending TCP traffic on sequential ports starting at 5001. 207*d9ccb18fSOmid Ehtemam-Haghighi # Since iperf3 instances may terminate unexpectedly (e.g., if the route 208*d9ccb18fSOmid Ehtemam-Haghighi # to the server is deleted in the background during a route refresh), a 209*d9ccb18fSOmid Ehtemam-Haghighi # while loop is used to automatically restart them in such cases. 210*d9ccb18fSOmid Ehtemam-Haghighi echo "info: starting ${num_of_iperf_servers} iperf3 clients in the source_ns namespace ..." 211*d9ccb18fSOmid Ehtemam-Haghighi for i in $(seq 1 ${num_of_iperf_servers}); do 212*d9ccb18fSOmid Ehtemam-Haghighi cmd="iperf3 -c ${SINK_LOOPBACK_IP_ADDR} -p $(printf '5%03d' ${i}) --length 64 --bitrate ${IPERF3_BITRATE} -t 0 --connect-timeout 150 &>/dev/null" 213*d9ccb18fSOmid Ehtemam-Haghighi ip netns exec ${source_ns} bash -c "while true; do ${cmd}; done &" &>/dev/null 214*d9ccb18fSOmid Ehtemam-Haghighi done 215*d9ccb18fSOmid Ehtemam-Haghighi 216*d9ccb18fSOmid Ehtemam-Haghighi echo "info: IPv6 routing table is being updated at the rate of $(echo "1/${ROUTING_TABLE_REFRESH_PERIOD}" | bc)/s for ${TEST_DURATION} seconds ..." 217*d9ccb18fSOmid Ehtemam-Haghighi echo "info: A kernel soft lockup, if detected, results in a kernel panic!" 218*d9ccb18fSOmid Ehtemam-Haghighi 219*d9ccb18fSOmid Ehtemam-Haghighi wait 220*d9ccb18fSOmid Ehtemam-Haghighi} 221*d9ccb18fSOmid Ehtemam-Haghighi 222*d9ccb18fSOmid Ehtemam-Haghighi# Make sure 'iperf3' is installed, skip the test otherwise 223*d9ccb18fSOmid Ehtemam-Haghighiif [ ! -x "$(command -v "iperf3")" ]; then 224*d9ccb18fSOmid Ehtemam-Haghighi echo "SKIP: 'iperf3' is not installed. Skipping the test." 225*d9ccb18fSOmid Ehtemam-Haghighi exit ${ksft_skip} 226*d9ccb18fSOmid Ehtemam-Haghighifi 227*d9ccb18fSOmid Ehtemam-Haghighi 228*d9ccb18fSOmid Ehtemam-Haghighi# Determine the number of cores on the machine 229*d9ccb18fSOmid Ehtemam-Haghighinum_of_iperf_servers=$(( $(nproc)/2 )) 230*d9ccb18fSOmid Ehtemam-Haghighi 231*d9ccb18fSOmid Ehtemam-Haghighi# Check if we are running on a multi-core machine, skip the test otherwise 232*d9ccb18fSOmid Ehtemam-Haghighiif [ "${num_of_iperf_servers}" -eq 0 ]; then 233*d9ccb18fSOmid Ehtemam-Haghighi echo "SKIP: This test is not valid on a single core machine!" 234*d9ccb18fSOmid Ehtemam-Haghighi exit ${ksft_skip} 235*d9ccb18fSOmid Ehtemam-Haghighifi 236*d9ccb18fSOmid Ehtemam-Haghighi 237*d9ccb18fSOmid Ehtemam-Haghighi# Since the kernel soft lockup we're testing causes at least one core to enter 238*d9ccb18fSOmid Ehtemam-Haghighi# an infinite loop, destabilizing the host and likely affecting subsequent 239*d9ccb18fSOmid Ehtemam-Haghighi# tests, we trigger a kernel panic instead of reporting a failure and 240*d9ccb18fSOmid Ehtemam-Haghighi# continuing 241*d9ccb18fSOmid Ehtemam-Haghighikernel_softlokup_panic_prev_val=$(sysctl -n kernel.softlockup_panic) 242*d9ccb18fSOmid Ehtemam-Haghighisysctl -qw kernel.softlockup_panic=1 243*d9ccb18fSOmid Ehtemam-Haghighi 244*d9ccb18fSOmid Ehtemam-Haghighihandle_sigint() { 245*d9ccb18fSOmid Ehtemam-Haghighi termination_signal="SIGINT" 246*d9ccb18fSOmid Ehtemam-Haghighi cleanup 247*d9ccb18fSOmid Ehtemam-Haghighi exit ${ksft_skip} 248*d9ccb18fSOmid Ehtemam-Haghighi} 249*d9ccb18fSOmid Ehtemam-Haghighi 250*d9ccb18fSOmid Ehtemam-Haghighihandle_sigalrm() { 251*d9ccb18fSOmid Ehtemam-Haghighi termination_signal="SIGALRM" 252*d9ccb18fSOmid Ehtemam-Haghighi cleanup 253*d9ccb18fSOmid Ehtemam-Haghighi exit ${ksft_pass} 254*d9ccb18fSOmid Ehtemam-Haghighi} 255*d9ccb18fSOmid Ehtemam-Haghighi 256*d9ccb18fSOmid Ehtemam-Haghighitrap handle_sigint SIGINT 257*d9ccb18fSOmid Ehtemam-Haghighitrap handle_sigalrm SIGALRM 258*d9ccb18fSOmid Ehtemam-Haghighi 259*d9ccb18fSOmid Ehtemam-Haghighi(sleep ${TEST_DURATION} && kill -s SIGALRM $$)& 260*d9ccb18fSOmid Ehtemam-Haghighi 261*d9ccb18fSOmid Ehtemam-Haghighisetup_prepare 262*d9ccb18fSOmid Ehtemam-Haghighitest_soft_lockup_during_routing_table_refresh 263