selftests: net: veth: add tests for set_channel
authorPaolo Abeni <pabeni@redhat.com>
Tue, 20 Jul 2021 08:41:52 +0000 (10:41 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 20 Jul 2021 13:11:18 +0000 (06:11 -0700)
Simple functional test for the newly exposed features.

Also add an optional stress test for the channel number
update under flood.

RFC v1 -> RFC v2:
 - add the stress test

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
tools/testing/selftests/net/veth.sh

index 11d7cdb..19eac3e 100755 (executable)
@@ -13,7 +13,7 @@ readonly NS_DST=$BASE$DST
 readonly BM_NET_V4=192.168.1.
 readonly BM_NET_V6=2001:db8::
 
-readonly NPROCS=`nproc`
+readonly CPUS=`nproc`
 ret=0
 
 cleanup() {
@@ -75,6 +75,29 @@ chk_tso_flag() {
        __chk_flag "$1" $2 $3 tcp-segmentation-offload
 }
 
+chk_channels() {
+       local msg="$1"
+       local target=$2
+       local rx=$3
+       local tx=$4
+
+       local dev=veth$target
+
+       local cur_rx=`ip netns exec $BASE$target ethtool -l $dev |\
+               grep RX: | tail -n 1 | awk '{print $2}' `
+               local cur_tx=`ip netns exec $BASE$target ethtool -l $dev |\
+               grep TX: | tail -n 1 | awk '{print $2}'`
+       local cur_combined=`ip netns exec $BASE$target ethtool -l $dev |\
+               grep Combined: | tail -n 1 | awk '{print $2}'`
+
+       printf "%-60s" "$msg"
+       if [ "$cur_rx" = "$rx" -a "$cur_tx" = "$tx" -a "$cur_combined" = "n/a" ]; then
+               echo " ok "
+       else
+               echo " fail rx:$rx:$cur_rx tx:$tx:$cur_tx combined:n/a:$cur_combined"
+       fi
+}
+
 chk_gro() {
        local msg="$1"
        local expected=$2
@@ -107,11 +130,100 @@ chk_gro() {
        fi
 }
 
+__change_channels()
+{
+       local cur_cpu
+       local end=$1
+       local cur
+       local i
+
+       while true; do
+               printf -v cur '%(%s)T'
+               [ $cur -le $end ] || break
+
+               for i in `seq 1 $CPUS`; do
+                       ip netns exec $NS_SRC ethtool -L veth$SRC rx $i tx $i
+                       ip netns exec $NS_DST ethtool -L veth$DST rx $i tx $i
+               done
+
+               for i in `seq 1 $((CPUS - 1))`; do
+                       cur_cpu=$((CPUS - $i))
+                       ip netns exec $NS_SRC ethtool -L veth$SRC rx $cur_cpu tx $cur_cpu
+                       ip netns exec $NS_DST ethtool -L veth$DST rx $cur_cpu tx $cur_cpu
+               done
+       done
+}
+
+__send_data() {
+       local end=$1
+
+       while true; do
+               printf -v cur '%(%s)T'
+               [ $cur -le $end ] || break
+
+               ip netns exec $NS_SRC ./udpgso_bench_tx -4 -s 1000 -M 300 -D $BM_NET_V4$DST
+       done
+}
+
+do_stress() {
+       local end
+       printf -v end '%(%s)T'
+       end=$((end + $STRESS))
+
+       ip netns exec $NS_SRC ethtool -L veth$SRC rx 3 tx 3
+       ip netns exec $NS_DST ethtool -L veth$DST rx 3 tx 3
+
+       ip netns exec $NS_DST ./udpgso_bench_rx &
+       local rx_pid=$!
+
+       echo "Running stress test for $STRESS seconds..."
+       __change_channels $end &
+       local ch_pid=$!
+       __send_data $end &
+       local data_pid_1=$!
+       __send_data $end &
+       local data_pid_2=$!
+       __send_data $end &
+       local data_pid_3=$!
+       __send_data $end &
+       local data_pid_4=$!
+
+       wait $ch_pid $data_pid_1 $data_pid_2 $data_pid_3 $data_pid_4
+       kill -9 $rx_pid
+       echo "done"
+
+       # restore previous setting
+       ip netns exec $NS_SRC ethtool -L veth$SRC rx 2 tx 2
+       ip netns exec $NS_DST ethtool -L veth$DST rx 2 tx 1
+}
+
+usage() {
+       echo "Usage: $0 [-h] [-s <seconds>]"
+       echo -e "\t-h: show this help"
+       echo -e "\t-s: run optional stress tests for the given amount of seconds"
+}
+
+STRESS=0
+while getopts "hs:" option; do
+       case "$option" in
+       "h")
+               usage $0
+               exit 0
+               ;;
+       "s")
+               STRESS=$OPTARG
+               ;;
+       esac
+done
+
 if [ ! -f ../bpf/xdp_dummy.o ]; then
        echo "Missing xdp_dummy helper. Build bpf selftest first"
        exit 1
 fi
 
+[ $CPUS -lt 2 ] && echo "Only one CPU available, some tests will be skipped"
+[ $STRESS -gt 0 -a $CPUS -lt 3 ] && echo " stress test will be skipped, too"
+
 create_ns
 chk_gro_flag "default - gro flag" $SRC off
 chk_gro_flag "        - peer gro flag" $DST off
@@ -134,6 +246,8 @@ chk_gro "        - aggregation with TSO off" 1
 cleanup
 
 create_ns
+chk_channels "default channels" $DST 1 1
+
 ip -n $NS_DST link set dev veth$DST down
 ip netns exec $NS_DST ethtool -K veth$DST gro on
 chk_gro_flag "with gro enabled on link down - gro flag" $DST on
@@ -147,6 +261,56 @@ chk_gro "        - aggregation with TSO off" 1
 cleanup
 
 create_ns
+
+CUR_TX=1
+CUR_RX=1
+if [ $CPUS -gt 1 ]; then
+       ip netns exec $NS_DST ethtool -L veth$DST tx 2
+       chk_channels "setting tx channels" $DST 1 2
+       CUR_TX=2
+fi
+
+if [ $CPUS -gt 2 ]; then
+       ip netns exec $NS_DST ethtool -L veth$DST rx 3 tx 3
+       chk_channels "setting both rx and tx channels" $DST 3 3
+       CUR_RX=3
+       CUR_TX=3
+fi
+
+ip netns exec $NS_DST ethtool -L veth$DST combined 2 2>/dev/null
+chk_channels "bad setting: combined channels" $DST $CUR_RX $CUR_TX
+
+ip netns exec $NS_DST ethtool -L veth$DST tx $((CPUS + 1)) 2>/dev/null
+chk_channels "setting invalid channels nr" $DST $CUR_RX $CUR_TX
+
+if [ $CPUS -gt 1 ]; then
+       # this also tests queues nr reduction
+       ip netns exec $NS_DST ethtool -L veth$DST rx 1 tx 2 2>/dev/null
+       ip netns exec $NS_SRC ethtool -L veth$SRC rx 1 tx 2 2>/dev/null
+       printf "%-60s" "bad setting: XDP with RX nr less than TX"
+       ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
+               section xdp_dummy 2>/dev/null &&\
+               echo "fail - set operation successful ?!?" || echo " ok "
+
+       # the following tests will run with multiple channels active
+       ip netns exec $NS_SRC ethtool -L veth$SRC rx 2
+       ip netns exec $NS_DST ethtool -L veth$DST rx 2
+       ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
+               section xdp_dummy 2>/dev/null
+       printf "%-60s" "bad setting: reducing RX nr below peer TX with XDP set"
+       ip netns exec $NS_DST ethtool -L veth$DST rx 1 2>/dev/null &&\
+               echo "fail - set operation successful ?!?" || echo " ok "
+       CUR_RX=2
+       CUR_TX=2
+fi
+
+if [ $CPUS -gt 2 ]; then
+       printf "%-60s" "bad setting: increasing peer TX nr above RX with XDP set"
+       ip netns exec $NS_SRC ethtool -L veth$SRC tx 3 2>/dev/null &&\
+               echo "fail - set operation successful ?!?" || echo " ok "
+       chk_channels "setting invalid channels nr" $DST 2 2
+fi
+
 ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
 chk_gro_flag "with xdp attached - gro flag" $DST on
 chk_gro_flag "        - peer gro flag" $SRC off
@@ -167,10 +331,27 @@ chk_gro_flag "        - after gro on xdp off, gro flag" $DST on
 chk_gro_flag "        - peer gro flag" $SRC off
 chk_tso_flag "        - tso flag" $SRC on
 chk_tso_flag "        - peer tso flag" $DST on
+
+if [ $CPUS -gt 1 ]; then
+       ip netns exec $NS_DST ethtool -L veth$DST tx 1
+       chk_channels "decreasing tx channels with device down" $DST 2 1
+fi
+
 ip -n $NS_DST link set dev veth$DST up
 ip -n $NS_SRC link set dev veth$SRC up
 chk_gro "        - aggregation" 1
 
+if [ $CPUS -gt 1 ]; then
+       [ $STRESS -gt 0 -a $CPUS -gt 2 ] && do_stress
+
+       ip -n $NS_DST link set dev veth$DST down
+       ip -n $NS_SRC link set dev veth$SRC down
+       ip netns exec $NS_DST ethtool -L veth$DST tx 2
+       chk_channels "increasing tx channels with device down" $DST 2 2
+       ip -n $NS_DST link set dev veth$DST up
+       ip -n $NS_SRC link set dev veth$SRC up
+fi
+
 ip netns exec $NS_DST ethtool -K veth$DST gro off
 ip netns exec $NS_SRC ethtool -K veth$SRC tx-udp-segmentation off
 chk_gro "aggregation again with default and TSO off" 10