mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-24 13:40:07 +07:00
Merge branch 'selftests-Add-ethtool-and-scale-tests'
Ido Schimmel says: ==================== selftests: Add ethtool and scale tests This patch set adds generic ethtool tests and a mlxsw-specific router scale test for Spectrum-2. Patches #1-#2 from Danielle add the router scale test for Spectrum-2. It re-uses the same test as Spectrum-1, but it is invoked with a different scale, according to what it is queried from devlink-resource. Patches #3-#5 from Amit are a re-work of the ethtool tests that were posted in the past [1]. Patches #3-#4 add the necessary library routines, whereas patch #5 adds the test itself. The test checks both good and bad flows with autoneg on and off. The test plan it detailed in the commit message. Last time Andrew and Florian (copied) provided very useful feedback that is incorporated in this set. Namely: * Parse the value of the different link modes from /usr/include/linux/ethtool.h * Differentiate between supported and advertised speeds and use the latter in autoneg tests * Make the test generic and move it to net/forwarding/ instead of being mlxsw-specific [1] https://patchwork.ozlabs.org/cover/1112903/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
c4154cffa3
@ -8,6 +8,11 @@ source $lib_dir/lib.sh
|
||||
source $lib_dir/tc_common.sh
|
||||
source $lib_dir/devlink_lib.sh
|
||||
|
||||
if [ "$DEVLINK_VIDDID" != "15b3:cf6c" ]; then
|
||||
echo "SKIP: test is tailored for Mellanox Spectrum-2"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
current_test=""
|
||||
|
||||
cleanup()
|
||||
@ -16,11 +21,13 @@ cleanup()
|
||||
if [ ! -z $current_test ]; then
|
||||
${current_test}_cleanup
|
||||
fi
|
||||
# Need to reload in order to avoid router abort.
|
||||
devlink_reload
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
ALL_TESTS="tc_flower mirror_gre"
|
||||
ALL_TESTS="router tc_flower mirror_gre"
|
||||
for current_test in ${TESTS:-$ALL_TESTS}; do
|
||||
source ${current_test}_scale.sh
|
||||
|
||||
@ -34,6 +41,7 @@ for current_test in ${TESTS:-$ALL_TESTS}; do
|
||||
setup_wait $num_netifs
|
||||
${current_test}_test "$target" "$should_fail"
|
||||
${current_test}_cleanup
|
||||
devlink_reload
|
||||
if [[ "$should_fail" -eq 0 ]]; then
|
||||
log_test "'$current_test' $target"
|
||||
else
|
||||
|
@ -0,0 +1,18 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
source ../router_scale.sh
|
||||
|
||||
router_get_target()
|
||||
{
|
||||
local should_fail=$1
|
||||
local target
|
||||
|
||||
target=$(devlink_resource_size_get kvd)
|
||||
|
||||
if [[ $should_fail -eq 0 ]]; then
|
||||
target=$((target * 85 / 100))
|
||||
else
|
||||
target=$((target + 1))
|
||||
fi
|
||||
|
||||
echo $target
|
||||
}
|
318
tools/testing/selftests/net/forwarding/ethtool.sh
Executable file
318
tools/testing/selftests/net/forwarding/ethtool.sh
Executable file
@ -0,0 +1,318 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ALL_TESTS="
|
||||
same_speeds_autoneg_off
|
||||
different_speeds_autoneg_off
|
||||
combination_of_neg_on_and_off
|
||||
advertise_subset_of_speeds
|
||||
check_highest_speed_is_chosen
|
||||
different_speeds_autoneg_on
|
||||
"
|
||||
NUM_NETIFS=2
|
||||
source lib.sh
|
||||
source ethtool_lib.sh
|
||||
|
||||
h1_create()
|
||||
{
|
||||
simple_if_init $h1 192.0.2.1/24
|
||||
}
|
||||
|
||||
h1_destroy()
|
||||
{
|
||||
simple_if_fini $h1 192.0.2.1/24
|
||||
}
|
||||
|
||||
h2_create()
|
||||
{
|
||||
simple_if_init $h2 192.0.2.2/24
|
||||
}
|
||||
|
||||
h2_destroy()
|
||||
{
|
||||
simple_if_fini $h2 192.0.2.2/24
|
||||
}
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
h1=${NETIFS[p1]}
|
||||
h2=${NETIFS[p2]}
|
||||
|
||||
h1_create
|
||||
h2_create
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
||||
h2_destroy
|
||||
h1_destroy
|
||||
}
|
||||
|
||||
different_speeds_get()
|
||||
{
|
||||
local dev1=$1; shift
|
||||
local dev2=$1; shift
|
||||
local with_mode=$1; shift
|
||||
local adver=$1; shift
|
||||
|
||||
local -a speeds_arr
|
||||
|
||||
speeds_arr=($(common_speeds_get $dev1 $dev2 $with_mode $adver))
|
||||
if [[ ${#speeds_arr[@]} < 2 ]]; then
|
||||
check_err 1 "cannot check different speeds. There are not enough speeds"
|
||||
fi
|
||||
|
||||
echo ${speeds_arr[0]} ${speeds_arr[1]}
|
||||
}
|
||||
|
||||
same_speeds_autoneg_off()
|
||||
{
|
||||
# Check that when each of the reported speeds is forced, the links come
|
||||
# up and are operational.
|
||||
local -a speeds_arr=($(common_speeds_get $h1 $h2 0 0))
|
||||
|
||||
for speed in "${speeds_arr[@]}"; do
|
||||
RET=0
|
||||
ethtool_set $h1 speed $speed autoneg off
|
||||
ethtool_set $h2 speed $speed autoneg off
|
||||
|
||||
setup_wait_dev_with_timeout $h1
|
||||
setup_wait_dev_with_timeout $h2
|
||||
ping_do $h1 192.0.2.2
|
||||
check_err $? "speed $speed autoneg off"
|
||||
log_test "force of same speed autoneg off"
|
||||
log_info "speed = $speed"
|
||||
done
|
||||
|
||||
ethtool -s $h2 autoneg on
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
different_speeds_autoneg_off()
|
||||
{
|
||||
# Test that when we force different speeds, links are not up and ping
|
||||
# fails.
|
||||
RET=0
|
||||
|
||||
local -a speeds_arr=($(different_speeds_get $h1 $h2 0 0))
|
||||
local speed1=${speeds_arr[0]}
|
||||
local speed2=${speeds_arr[1]}
|
||||
|
||||
ethtool_set $h1 speed $speed1 autoneg off
|
||||
ethtool_set $h2 speed $speed2 autoneg off
|
||||
|
||||
setup_wait_dev_with_timeout $h1
|
||||
setup_wait_dev_with_timeout $h2
|
||||
ping_do $h1 192.0.2.2
|
||||
check_fail $? "ping with different speeds"
|
||||
|
||||
log_test "force of different speeds autoneg off"
|
||||
|
||||
ethtool -s $h2 autoneg on
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
combination_of_neg_on_and_off()
|
||||
{
|
||||
# Test that when one device is forced to a speed supported by both
|
||||
# endpoints and the other device is configured to autoneg on, the links
|
||||
# are up and ping passes.
|
||||
local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1))
|
||||
|
||||
for speed in "${speeds_arr[@]}"; do
|
||||
RET=0
|
||||
ethtool_set $h1 speed $speed autoneg off
|
||||
|
||||
setup_wait_dev_with_timeout $h1
|
||||
setup_wait_dev_with_timeout $h2
|
||||
ping_do $h1 192.0.2.2
|
||||
check_err $? "h1-speed=$speed autoneg off, h2 autoneg on"
|
||||
log_test "one side with autoneg off and another with autoneg on"
|
||||
log_info "force speed = $speed"
|
||||
done
|
||||
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
hex_speed_value_get()
|
||||
{
|
||||
local speed=$1; shift
|
||||
|
||||
local shift_size=${speed_values[$speed]}
|
||||
speed=$((0x1 << $"shift_size"))
|
||||
printf "%#x" "$speed"
|
||||
}
|
||||
|
||||
subset_of_common_speeds_get()
|
||||
{
|
||||
local dev1=$1; shift
|
||||
local dev2=$1; shift
|
||||
local adver=$1; shift
|
||||
|
||||
local -a speeds_arr=($(common_speeds_get $dev1 $dev2 0 $adver))
|
||||
local speed_to_advertise=0
|
||||
local speed_to_remove=${speeds_arr[0]}
|
||||
speed_to_remove+='base'
|
||||
|
||||
local -a speeds_mode_arr=($(common_speeds_get $dev1 $dev2 1 $adver))
|
||||
|
||||
for speed in ${speeds_mode_arr[@]}; do
|
||||
if [[ $speed != $speed_to_remove* ]]; then
|
||||
speed=$(hex_speed_value_get $speed)
|
||||
speed_to_advertise=$(($speed_to_advertise | \
|
||||
$speed))
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Convert to hex.
|
||||
printf "%#x" "$speed_to_advertise"
|
||||
}
|
||||
|
||||
speed_to_advertise_get()
|
||||
{
|
||||
# The function returns the hex number that is composed by OR-ing all
|
||||
# the modes corresponding to the provided speed.
|
||||
local speed_without_mode=$1; shift
|
||||
local supported_speeds=("$@"); shift
|
||||
local speed_to_advertise=0
|
||||
|
||||
speed_without_mode+='base'
|
||||
|
||||
for speed in ${supported_speeds[@]}; do
|
||||
if [[ $speed == $speed_without_mode* ]]; then
|
||||
speed=$(hex_speed_value_get $speed)
|
||||
speed_to_advertise=$(($speed_to_advertise | \
|
||||
$speed))
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Convert to hex.
|
||||
printf "%#x" "$speed_to_advertise"
|
||||
}
|
||||
|
||||
advertise_subset_of_speeds()
|
||||
{
|
||||
# Test that when one device advertises a subset of speeds and another
|
||||
# advertises a specific speed (but all modes of this speed), the links
|
||||
# are up and ping passes.
|
||||
RET=0
|
||||
|
||||
local speed_1_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1)
|
||||
ethtool_set $h1 advertise $speed_1_to_advertise
|
||||
|
||||
if [ $RET != 0 ]; then
|
||||
log_test "advertise subset of speeds"
|
||||
return
|
||||
fi
|
||||
|
||||
local -a speeds_arr_without_mode=($(common_speeds_get $h1 $h2 0 1))
|
||||
# Check only speeds that h1 advertised. Remove the first speed.
|
||||
unset speeds_arr_without_mode[0]
|
||||
local -a speeds_arr_with_mode=($(common_speeds_get $h1 $h2 1 1))
|
||||
|
||||
for speed_value in ${speeds_arr_without_mode[@]}; do
|
||||
RET=0
|
||||
local speed_2_to_advertise=$(speed_to_advertise_get $speed_value \
|
||||
"${speeds_arr_with_mode[@]}")
|
||||
ethtool_set $h2 advertise $speed_2_to_advertise
|
||||
|
||||
setup_wait_dev_with_timeout $h1
|
||||
setup_wait_dev_with_timeout $h2
|
||||
ping_do $h1 192.0.2.2
|
||||
check_err $? "h1=$speed_1_to_advertise, h2=$speed_2_to_advertise ($speed_value)"
|
||||
|
||||
log_test "advertise subset of speeds"
|
||||
log_info "h1=$speed_1_to_advertise, h2=$speed_2_to_advertise"
|
||||
done
|
||||
|
||||
ethtool -s $h2 autoneg on
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
check_highest_speed_is_chosen()
|
||||
{
|
||||
# Test that when one device advertises a subset of speeds, the other
|
||||
# chooses the highest speed. This test checks configuration without
|
||||
# traffic.
|
||||
RET=0
|
||||
|
||||
local max_speed
|
||||
local chosen_speed
|
||||
local speed_to_advertise=$(subset_of_common_speeds_get $h1 $h2 1)
|
||||
|
||||
ethtool_set $h1 advertise $speed_to_advertise
|
||||
|
||||
if [ $RET != 0 ]; then
|
||||
log_test "check highest speed"
|
||||
return
|
||||
fi
|
||||
|
||||
local -a speeds_arr=($(common_speeds_get $h1 $h2 0 1))
|
||||
# Remove the first speed, h1 does not advertise this speed.
|
||||
unset speeds_arr[0]
|
||||
|
||||
max_speed=${speeds_arr[0]}
|
||||
for current in ${speeds_arr[@]}; do
|
||||
if [[ $current -gt $max_speed ]]; then
|
||||
max_speed=$current
|
||||
fi
|
||||
done
|
||||
|
||||
setup_wait_dev_with_timeout $h1
|
||||
setup_wait_dev_with_timeout $h2
|
||||
chosen_speed=$(ethtool $h1 | grep 'Speed:')
|
||||
chosen_speed=${chosen_speed%"Mb/s"*}
|
||||
chosen_speed=${chosen_speed#*"Speed: "}
|
||||
((chosen_speed == max_speed))
|
||||
check_err $? "h1 advertise $speed_to_advertise, h2 sync to speed $chosen_speed"
|
||||
|
||||
log_test "check highest speed"
|
||||
|
||||
ethtool -s $h2 autoneg on
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
different_speeds_autoneg_on()
|
||||
{
|
||||
# Test that when we configure links to advertise different speeds,
|
||||
# links are not up and ping fails.
|
||||
RET=0
|
||||
|
||||
local -a speeds=($(different_speeds_get $h1 $h2 1 1))
|
||||
local speed1=${speeds[0]}
|
||||
local speed2=${speeds[1]}
|
||||
|
||||
speed1=$(hex_speed_value_get $speed1)
|
||||
speed2=$(hex_speed_value_get $speed2)
|
||||
|
||||
ethtool_set $h1 advertise $speed1
|
||||
ethtool_set $h2 advertise $speed2
|
||||
|
||||
if (($RET)); then
|
||||
setup_wait_dev_with_timeout $h1
|
||||
setup_wait_dev_with_timeout $h2
|
||||
ping_do $h1 192.0.2.2
|
||||
check_fail $? "ping with different speeds autoneg on"
|
||||
fi
|
||||
|
||||
log_test "advertise different speeds autoneg on"
|
||||
|
||||
ethtool -s $h2 autoneg on
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
||||
setup_wait
|
||||
|
||||
declare -gA speed_values
|
||||
eval "speed_values=($(speeds_arr_get))"
|
||||
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
69
tools/testing/selftests/net/forwarding/ethtool_lib.sh
Executable file
69
tools/testing/selftests/net/forwarding/ethtool_lib.sh
Executable file
@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
speeds_arr_get()
|
||||
{
|
||||
cmd='/ETHTOOL_LINK_MODE_[^[:space:]]*_BIT[[:space:]]+=[[:space:]]+/ \
|
||||
{sub(/,$/, "") \
|
||||
sub(/ETHTOOL_LINK_MODE_/,"") \
|
||||
sub(/_BIT/,"") \
|
||||
sub(/_Full/,"/Full") \
|
||||
sub(/_Half/,"/Half");\
|
||||
print "["$1"]="$3}'
|
||||
|
||||
awk "${cmd}" /usr/include/linux/ethtool.h
|
||||
}
|
||||
|
||||
ethtool_set()
|
||||
{
|
||||
local cmd="$@"
|
||||
local out=$(ethtool -s $cmd 2>&1 | wc -l)
|
||||
|
||||
check_err $out "error in configuration. $cmd"
|
||||
}
|
||||
|
||||
dev_speeds_get()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local with_mode=$1; shift
|
||||
local adver=$1; shift
|
||||
local speeds_str
|
||||
|
||||
if (($adver)); then
|
||||
mode="Advertised link modes"
|
||||
else
|
||||
mode="Supported link modes"
|
||||
fi
|
||||
|
||||
speeds_str=$(ethtool "$dev" | \
|
||||
# Snip everything before the link modes section.
|
||||
sed -n '/'"$mode"':/,$p' | \
|
||||
# Quit processing the rest at the start of the next section.
|
||||
# When checking, skip the header of this section (hence the 2,).
|
||||
sed -n '2,${/^[\t][^ \t]/q};p' | \
|
||||
# Drop the section header of the current section.
|
||||
cut -d':' -f2)
|
||||
|
||||
local -a speeds_arr=($speeds_str)
|
||||
if [[ $with_mode -eq 0 ]]; then
|
||||
for ((i=0; i<${#speeds_arr[@]}; i++)); do
|
||||
speeds_arr[$i]=${speeds_arr[$i]%base*}
|
||||
done
|
||||
fi
|
||||
echo ${speeds_arr[@]}
|
||||
}
|
||||
|
||||
common_speeds_get()
|
||||
{
|
||||
dev1=$1; shift
|
||||
dev2=$1; shift
|
||||
with_mode=$1; shift
|
||||
adver=$1; shift
|
||||
|
||||
local -a dev1_speeds=($(dev_speeds_get $dev1 $with_mode $adver))
|
||||
local -a dev2_speeds=($(dev_speeds_get $dev2 $with_mode $adver))
|
||||
|
||||
comm -12 \
|
||||
<(printf '%s\n' "${dev1_speeds[@]}" | sort -u) \
|
||||
<(printf '%s\n' "${dev2_speeds[@]}" | sort -u)
|
||||
}
|
@ -18,6 +18,8 @@ NETIF_CREATE=${NETIF_CREATE:=yes}
|
||||
MCD=${MCD:=smcrouted}
|
||||
MC_CLI=${MC_CLI:=smcroutectl}
|
||||
PING_TIMEOUT=${PING_TIMEOUT:=5}
|
||||
WAIT_TIMEOUT=${WAIT_TIMEOUT:=20}
|
||||
INTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600}
|
||||
|
||||
relative_path="${BASH_SOURCE%/*}"
|
||||
if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then
|
||||
@ -226,24 +228,45 @@ log_info()
|
||||
setup_wait_dev()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local wait_time=${1:-$WAIT_TIME}; shift
|
||||
|
||||
while true; do
|
||||
setup_wait_dev_with_timeout "$dev" $INTERFACE_TIMEOUT $wait_time
|
||||
|
||||
if (($?)); then
|
||||
check_err 1
|
||||
log_test setup_wait_dev ": Interface $dev does not come up."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
setup_wait_dev_with_timeout()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local max_iterations=${1:-$WAIT_TIMEOUT}; shift
|
||||
local wait_time=${1:-$WAIT_TIME}; shift
|
||||
local i
|
||||
|
||||
for ((i = 1; i <= $max_iterations; ++i)); do
|
||||
ip link show dev $dev up \
|
||||
| grep 'state UP' &> /dev/null
|
||||
if [[ $? -ne 0 ]]; then
|
||||
sleep 1
|
||||
else
|
||||
break
|
||||
sleep $wait_time
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
setup_wait()
|
||||
{
|
||||
local num_netifs=${1:-$NUM_NETIFS}
|
||||
local i
|
||||
|
||||
for ((i = 1; i <= num_netifs; ++i)); do
|
||||
setup_wait_dev ${NETIFS[p$i]}
|
||||
setup_wait_dev ${NETIFS[p$i]} 0
|
||||
done
|
||||
|
||||
# Make sure links are ready.
|
||||
|
Loading…
Reference in New Issue
Block a user