#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # # This test sends many small packets (size is less than cell size) through the # switch. A shaper is used in $swp2, so the traffic is limited there. Packets # are queued till they will be sent. # # The idea is to verify that the switch can handle at least 85% of maximum # supported descrpitors by hardware. Then, we verify that the driver configures # firmware to allow infinite size of egress descriptor pool, and does not use a # lower limitation. Increase the size of the relevant pools such that the pool's # size does not limit the traffic. # +-----------------------+ # | H1 | # | + $h1.111 | # | | 192.0.2.33/28 | # | | | # | + $h1 | # +---|-------------------+ # | # +---|-----------------------------+ # | + $swp1 | # | | iPOOL1 | # | | | # | +-|------------------------+ | # | | + $swp1.111 | | # | | | | # | | BR1 | | # | | | | # | | + $swp2.111 | | # | +-|------------------------+ | # | | | # | + $swp2 | # | | ePOOL6 | # | | 1mbit | # +---+-----------------------------+ # | # +---|-------------------+ # | + $h2 H2 | # | | | # | + $h2.111 | # | 192.0.2.34/28 | # +-----------------------+ # ALL_TESTS=" ping_ipv4 max_descriptors " lib_dir=$(dirname $0)/../../../net/forwarding NUM_NETIFS=4 source $lib_dir/lib.sh source $lib_dir/devlink_lib.sh source mlxsw_lib.sh MAX_POOL_SIZE=$(devlink_pool_size_get) SHAPER_RATE=1mbit # The current TBF qdisc interface does not allow us to configure the shaper to # flat zero. The ASIC shaper is guaranteed to work with a granularity of # 200Mbps. On Spectrum-2, writing a value close to zero instead of zero works # well, but the performance on Spectrum-1 is unpredictable. Thus, do not run the # test on Spectrum-1. mlxsw_only_on_spectrum 2+ || exit h1_create() { simple_if_init $h1 vlan_create $h1 111 v$h1 192.0.2.33/28 ip link set dev $h1.111 type vlan egress-qos-map 0:1 } h1_destroy() { vlan_destroy $h1 111 simple_if_fini $h1 } h2_create() { simple_if_init $h2 vlan_create $h2 111 v$h2 192.0.2.34/28 } h2_destroy() { vlan_destroy $h2 111 simple_if_fini $h2 } switch_create() { # pools # ----- devlink_pool_size_thtype_save 1 devlink_pool_size_thtype_save 6 devlink_port_pool_th_save $swp1 1 devlink_port_pool_th_save $swp2 6 devlink_tc_bind_pool_th_save $swp1 1 ingress devlink_tc_bind_pool_th_save $swp2 1 egress devlink_pool_size_thtype_set 1 dynamic $MAX_POOL_SIZE devlink_pool_size_thtype_set 6 static $MAX_POOL_SIZE # $swp1 # ----- ip link set dev $swp1 up vlan_create $swp1 111 ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1 devlink_port_pool_th_set $swp1 1 16 devlink_tc_bind_pool_th_set $swp1 1 ingress 1 16 tc qdisc replace dev $swp1 root handle 1: \ ets bands 8 strict 8 priomap 7 6 dcb buffer set dev $swp1 prio-buffer all:0 1:1 # $swp2 # ----- ip link set dev $swp2 up vlan_create $swp2 111 ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1 devlink_port_pool_th_set $swp2 6 $MAX_POOL_SIZE devlink_tc_bind_pool_th_set $swp2 1 egress 6 $MAX_POOL_SIZE tc qdisc replace dev $swp2 root handle 1: tbf rate $SHAPER_RATE \ burst 128K limit 500M tc qdisc replace dev $swp2 parent 1:1 handle 11: \ ets bands 8 strict 8 priomap 7 6 # bridge # ------ ip link add name br1 type bridge vlan_filtering 0 ip link set dev $swp1.111 master br1 ip link set dev br1 up ip link set dev $swp2.111 master br1 } switch_destroy() { # Do this first so that we can reset the limits to values that are only # valid for the original static / dynamic setting. devlink_pool_size_thtype_restore 6 devlink_pool_size_thtype_restore 1 # bridge # ------ ip link set dev $swp2.111 nomaster ip link set dev br1 down ip link set dev $swp1.111 nomaster ip link del dev br1 # $swp2 # ----- tc qdisc del dev $swp2 parent 1:1 handle 11: tc qdisc del dev $swp2 root devlink_tc_bind_pool_th_restore $swp2 1 egress devlink_port_pool_th_restore $swp2 6 vlan_destroy $swp2 111 ip link set dev $swp2 down # $swp1 # ----- dcb buffer set dev $swp1 prio-buffer all:0 tc qdisc del dev $swp1 root devlink_tc_bind_pool_th_restore $swp1 1 ingress devlink_port_pool_th_restore $swp1 1 vlan_destroy $swp1 111 ip link set dev $swp1 down } setup_prepare() { h1=${NETIFS[p1]} swp1=${NETIFS[p2]} swp2=${NETIFS[p3]} h2=${NETIFS[p4]} h2mac=$(mac_get $h2) vrf_prepare h1_create h2_create switch_create } cleanup() { pre_cleanup switch_destroy h2_destroy h1_destroy vrf_cleanup } ping_ipv4() { ping_test $h1 192.0.2.34 " h1->h2" } percentage_used() { local num_packets=$1; shift local max_packets=$1; shift bc <<< " scale=2 100 * $num_packets / $max_packets " } max_descriptors() { local cell_size=$(devlink_cell_size_get) local exp_perc_used=85 local max_descriptors local pktsize=30 RET=0 max_descriptors=$(mlxsw_max_descriptors_get) || exit 1 local d0=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1) log_info "Send many small packets, packet size = $pktsize bytes" start_traffic_pktsize $pktsize $h1.111 192.0.2.33 192.0.2.34 $h2mac # Sleep to wait for congestion. sleep 5 local d1=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1) ((d1 == d0)) check_err $? "Drops seen on egress port: $d0 -> $d1 ($((d1 - d0)))" # Check how many packets the switch can handle, the limitation is # maximum descriptors. local pkts_bytes=$(ethtool_stats_get $swp2 tc_transmit_queue_tc_1) local pkts_num=$((pkts_bytes / cell_size)) local perc_used=$(percentage_used $pkts_num $max_descriptors) check_err $(bc <<< "$perc_used < $exp_perc_used") \ "Expected > $exp_perc_used% of descriptors, handle $perc_used%" stop_traffic sleep 1 log_test "Maximum descriptors usage. The percentage used is $perc_used%" } trap cleanup EXIT setup_prepare setup_wait tests_run exit $EXIT_STATUS