Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # This test injects a 10-MB burst of traffic with VLAN tag and 802.1p priority
0005 # of 1. This stream is consistently prioritized as priority 1, is put to PG
0006 # buffer 1, and scheduled at TC 1.
0007 #
0008 # - the stream first ingresses through $swp1, where it is forwarded to $swp3
0009 #
0010 # - then it ingresses through $swp4. Here it is put to a lossless buffer and put
0011 #   to a small pool ("PFC pool"). The traffic is forwarded to $swp2, which is
0012 #   shaped, and thus the PFC pool eventually fills, therefore the headroom
0013 #   fills, and $swp3 is paused.
0014 #
0015 # - since $swp3 now can't send traffic, the traffic ingressing $swp1 is kept at
0016 #   a pool ("overflow pool"). The overflow pool needs to be large enough to
0017 #   contain the whole burst.
0018 #
0019 # - eventually the PFC pool gets some traffic out, headroom therefore gets some
0020 #   traffic to the pool, and $swp3 is unpaused again. This way the traffic is
0021 #   gradually forwarded from the overflow pool, through the PFC pool, out of
0022 #   $swp2, and eventually to $h2.
0023 #
0024 # - if PFC works, all lossless flow packets that ingress through $swp1 should
0025 #   also be seen ingressing $h2. If it doesn't, there will be drops due to
0026 #   discrepancy between the speeds of $swp1 and $h2.
0027 #
0028 # - it should all play out relatively quickly, so that SLL and HLL will not
0029 #   cause drops.
0030 #
0031 # +-----------------------+
0032 # | H1                    |
0033 # |   + $h1.111           |
0034 # |   | 192.0.2.33/28     |
0035 # |   |                   |
0036 # |   + $h1               |
0037 # +---|-------------------+  +--------------------+
0038 #     |                      |                    |
0039 # +---|----------------------|--------------------|---------------------------+
0040 # |   + $swp1          $swp3 +                    + $swp4                     |
0041 # |   | iPOOL1        iPOOL0 |                    | iPOOL2                    |
0042 # |   | ePOOL4        ePOOL5 |                    | ePOOL4                    |
0043 # |   |                1Gbps |                    | 1Gbps                     |
0044 # |   |        PFC:enabled=1 |                    | PFC:enabled=1             |
0045 # | +-|----------------------|-+                +-|------------------------+  |
0046 # | | + $swp1.111  $swp3.111 + |                | + $swp4.111              |  |
0047 # | |                          |                |                          |  |
0048 # | | BR1                      |                | BR2                      |  |
0049 # | |                          |                |                          |  |
0050 # | |                          |                |         + $swp2.111      |  |
0051 # | +--------------------------+                +---------|----------------+  |
0052 # |                                                       |                   |
0053 # | iPOOL0: 500KB dynamic                                 |                   |
0054 # | iPOOL1: 10MB static                                   |                   |
0055 # | iPOOL2: 1MB static                                    + $swp2             |
0056 # | ePOOL4: 500KB dynamic                                 | iPOOL0            |
0057 # | ePOOL5: 10MB static                                   | ePOOL6            |
0058 # | ePOOL6: "infinite" static                             | 200Mbps shaper    |
0059 # +-------------------------------------------------------|-------------------+
0060 #                                                         |
0061 #                                                     +---|-------------------+
0062 #                                                     |   + $h2            H2 |
0063 #                                                     |   |                   |
0064 #                                                     |   + $h2.111           |
0065 #                                                     |     192.0.2.34/28     |
0066 #                                                     +-----------------------+
0067 #
0068 # iPOOL0+ePOOL4 is a helper pool for control traffic etc.
0069 # iPOOL1+ePOOL5 are overflow pools.
0070 # iPOOL2+ePOOL6 are PFC pools.
0071 
0072 ALL_TESTS="
0073         ping_ipv4
0074         test_qos_pfc
0075 "
0076 
0077 lib_dir=$(dirname $0)/../../../net/forwarding
0078 
0079 NUM_NETIFS=6
0080 source $lib_dir/lib.sh
0081 source $lib_dir/devlink_lib.sh
0082 source qos_lib.sh
0083 
0084 _1KB=1000
0085 _100KB=$((100 * _1KB))
0086 _500KB=$((500 * _1KB))
0087 _1MB=$((1000 * _1KB))
0088 _10MB=$((10 * _1MB))
0089 
0090 h1_create()
0091 {
0092         simple_if_init $h1
0093         mtu_set $h1 10000
0094 
0095         vlan_create $h1 111 v$h1 192.0.2.33/28
0096 }
0097 
0098 h1_destroy()
0099 {
0100         vlan_destroy $h1 111
0101 
0102         mtu_restore $h1
0103         simple_if_fini $h1
0104 }
0105 
0106 h2_create()
0107 {
0108         simple_if_init $h2
0109         mtu_set $h2 10000
0110 
0111         vlan_create $h2 111 v$h2 192.0.2.34/28
0112 }
0113 
0114 h2_destroy()
0115 {
0116         vlan_destroy $h2 111
0117 
0118         mtu_restore $h2
0119         simple_if_fini $h2
0120 }
0121 
0122 switch_create()
0123 {
0124         # pools
0125         # -----
0126 
0127         devlink_pool_size_thtype_save 0
0128         devlink_pool_size_thtype_save 4
0129         devlink_pool_size_thtype_save 1
0130         devlink_pool_size_thtype_save 5
0131         devlink_pool_size_thtype_save 2
0132         devlink_pool_size_thtype_save 6
0133 
0134         devlink_port_pool_th_save $swp1 1
0135         devlink_port_pool_th_save $swp2 6
0136         devlink_port_pool_th_save $swp3 5
0137         devlink_port_pool_th_save $swp4 2
0138 
0139         devlink_tc_bind_pool_th_save $swp1 1 ingress
0140         devlink_tc_bind_pool_th_save $swp2 1 egress
0141         devlink_tc_bind_pool_th_save $swp3 1 egress
0142         devlink_tc_bind_pool_th_save $swp4 1 ingress
0143 
0144         # Control traffic pools. Just reduce the size. Keep them dynamic so that
0145         # we don't need to change all the uninteresting quotas.
0146         devlink_pool_size_thtype_set 0 dynamic $_500KB
0147         devlink_pool_size_thtype_set 4 dynamic $_500KB
0148 
0149         # Overflow pools.
0150         devlink_pool_size_thtype_set 1 static $_10MB
0151         devlink_pool_size_thtype_set 5 static $_10MB
0152 
0153         # PFC pools. As per the writ, the size of egress PFC pool should be
0154         # infinice, but actually it just needs to be large enough to not matter
0155         # in practice, so reuse the 10MB limit.
0156         devlink_pool_size_thtype_set 2 static $_1MB
0157         devlink_pool_size_thtype_set 6 static $_10MB
0158 
0159         # $swp1
0160         # -----
0161 
0162         ip link set dev $swp1 up
0163         mtu_set $swp1 10000
0164         vlan_create $swp1 111
0165         ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1
0166 
0167         devlink_port_pool_th_set $swp1 1 $_10MB
0168         devlink_tc_bind_pool_th_set $swp1 1 ingress 1 $_10MB
0169 
0170         # Configure qdisc so that we can configure PG and therefore pool
0171         # assignment.
0172         tc qdisc replace dev $swp1 root handle 1: \
0173            ets bands 8 strict 8 priomap 7 6
0174         dcb buffer set dev $swp1 prio-buffer all:0 1:1
0175 
0176         # $swp2
0177         # -----
0178 
0179         ip link set dev $swp2 up
0180         mtu_set $swp2 10000
0181         vlan_create $swp2 111
0182         ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1
0183 
0184         devlink_port_pool_th_set $swp2 6 $_10MB
0185         devlink_tc_bind_pool_th_set $swp2 1 egress 6 $_10MB
0186 
0187         # prio 0->TC0 (band 7), 1->TC1 (band 6). TC1 is shaped.
0188         tc qdisc replace dev $swp2 root handle 1: \
0189            ets bands 8 strict 8 priomap 7 6
0190         tc qdisc replace dev $swp2 parent 1:7 handle 17: \
0191            tbf rate 200Mbit burst 131072 limit 1M
0192 
0193         # $swp3
0194         # -----
0195 
0196         ip link set dev $swp3 up
0197         mtu_set $swp3 10000
0198         vlan_create $swp3 111
0199         ip link set dev $swp3.111 type vlan egress-qos-map 0:0 1:1
0200 
0201         devlink_port_pool_th_set $swp3 5 $_10MB
0202         devlink_tc_bind_pool_th_set $swp3 1 egress 5 $_10MB
0203 
0204         # prio 0->TC0 (band 7), 1->TC1 (band 6)
0205         tc qdisc replace dev $swp3 root handle 1: \
0206            ets bands 8 strict 8 priomap 7 6
0207 
0208         # Need to enable PFC so that PAUSE takes effect. Therefore need to put
0209         # the lossless prio into a buffer of its own. Don't bother with buffer
0210         # sizes though, there is not going to be any pressure in the "backward"
0211         # direction.
0212         dcb buffer set dev $swp3 prio-buffer all:0 1:1
0213         dcb pfc set dev $swp3 prio-pfc all:off 1:on
0214 
0215         # $swp4
0216         # -----
0217 
0218         ip link set dev $swp4 up
0219         mtu_set $swp4 10000
0220         vlan_create $swp4 111
0221         ip link set dev $swp4.111 type vlan ingress-qos-map 0:0 1:1
0222 
0223         devlink_port_pool_th_set $swp4 2 $_1MB
0224         devlink_tc_bind_pool_th_set $swp4 1 ingress 2 $_1MB
0225 
0226         # Configure qdisc so that we can hand-tune headroom.
0227         tc qdisc replace dev $swp4 root handle 1: \
0228            ets bands 8 strict 8 priomap 7 6
0229         dcb buffer set dev $swp4 prio-buffer all:0 1:1
0230         dcb pfc set dev $swp4 prio-pfc all:off 1:on
0231         # PG0 will get autoconfigured to Xoff, give PG1 arbitrarily 100K, which
0232         # is (-2*MTU) about 80K of delay provision.
0233         dcb buffer set dev $swp4 buffer-size all:0 1:$_100KB
0234 
0235         # bridges
0236         # -------
0237 
0238         ip link add name br1 type bridge vlan_filtering 0
0239         ip link set dev $swp1.111 master br1
0240         ip link set dev $swp3.111 master br1
0241         ip link set dev br1 up
0242 
0243         ip link add name br2 type bridge vlan_filtering 0
0244         ip link set dev $swp2.111 master br2
0245         ip link set dev $swp4.111 master br2
0246         ip link set dev br2 up
0247 }
0248 
0249 switch_destroy()
0250 {
0251         # Do this first so that we can reset the limits to values that are only
0252         # valid for the original static / dynamic setting.
0253         devlink_pool_size_thtype_restore 6
0254         devlink_pool_size_thtype_restore 5
0255         devlink_pool_size_thtype_restore 4
0256         devlink_pool_size_thtype_restore 2
0257         devlink_pool_size_thtype_restore 1
0258         devlink_pool_size_thtype_restore 0
0259 
0260         # bridges
0261         # -------
0262 
0263         ip link set dev br2 down
0264         ip link set dev $swp4.111 nomaster
0265         ip link set dev $swp2.111 nomaster
0266         ip link del dev br2
0267 
0268         ip link set dev br1 down
0269         ip link set dev $swp3.111 nomaster
0270         ip link set dev $swp1.111 nomaster
0271         ip link del dev br1
0272 
0273         # $swp4
0274         # -----
0275 
0276         dcb buffer set dev $swp4 buffer-size all:0
0277         dcb pfc set dev $swp4 prio-pfc all:off
0278         dcb buffer set dev $swp4 prio-buffer all:0
0279         tc qdisc del dev $swp4 root
0280 
0281         devlink_tc_bind_pool_th_restore $swp4 1 ingress
0282         devlink_port_pool_th_restore $swp4 2
0283 
0284         vlan_destroy $swp4 111
0285         mtu_restore $swp4
0286         ip link set dev $swp4 down
0287 
0288         # $swp3
0289         # -----
0290 
0291         dcb pfc set dev $swp3 prio-pfc all:off
0292         dcb buffer set dev $swp3 prio-buffer all:0
0293         tc qdisc del dev $swp3 root
0294 
0295         devlink_tc_bind_pool_th_restore $swp3 1 egress
0296         devlink_port_pool_th_restore $swp3 5
0297 
0298         vlan_destroy $swp3 111
0299         mtu_restore $swp3
0300         ip link set dev $swp3 down
0301 
0302         # $swp2
0303         # -----
0304 
0305         tc qdisc del dev $swp2 parent 1:7
0306         tc qdisc del dev $swp2 root
0307 
0308         devlink_tc_bind_pool_th_restore $swp2 1 egress
0309         devlink_port_pool_th_restore $swp2 6
0310 
0311         vlan_destroy $swp2 111
0312         mtu_restore $swp2
0313         ip link set dev $swp2 down
0314 
0315         # $swp1
0316         # -----
0317 
0318         dcb buffer set dev $swp1 prio-buffer all:0
0319         tc qdisc del dev $swp1 root
0320 
0321         devlink_tc_bind_pool_th_restore $swp1 1 ingress
0322         devlink_port_pool_th_restore $swp1 1
0323 
0324         vlan_destroy $swp1 111
0325         mtu_restore $swp1
0326         ip link set dev $swp1 down
0327 }
0328 
0329 setup_prepare()
0330 {
0331         h1=${NETIFS[p1]}
0332         swp1=${NETIFS[p2]}
0333 
0334         swp2=${NETIFS[p3]}
0335         h2=${NETIFS[p4]}
0336 
0337         swp3=${NETIFS[p5]}
0338         swp4=${NETIFS[p6]}
0339 
0340         h2mac=$(mac_get $h2)
0341 
0342         vrf_prepare
0343 
0344         h1_create
0345         h2_create
0346         switch_create
0347 }
0348 
0349 cleanup()
0350 {
0351         pre_cleanup
0352 
0353         switch_destroy
0354         h2_destroy
0355         h1_destroy
0356 
0357         vrf_cleanup
0358 }
0359 
0360 ping_ipv4()
0361 {
0362         ping_test $h1 192.0.2.34
0363 }
0364 
0365 test_qos_pfc()
0366 {
0367         RET=0
0368 
0369         # 10M pool, each packet is 8K of payload + headers
0370         local pkts=$((_10MB / 8050))
0371         local size=$((pkts * 8050))
0372         local in0=$(ethtool_stats_get $swp1 rx_octets_prio_1)
0373         local out0=$(ethtool_stats_get $swp2 tx_octets_prio_1)
0374 
0375         $MZ $h1 -p 8000 -Q 1:111 -A 192.0.2.33 -B 192.0.2.34 \
0376                 -a own -b $h2mac -c $pkts -t udp -q
0377         sleep 2
0378 
0379         local in1=$(ethtool_stats_get $swp1 rx_octets_prio_1)
0380         local out1=$(ethtool_stats_get $swp2 tx_octets_prio_1)
0381 
0382         local din=$((in1 - in0))
0383         local dout=$((out1 - out0))
0384 
0385         local pct_in=$((din * 100 / size))
0386 
0387         ((pct_in > 95 && pct_in < 105))
0388         check_err $? "Relative ingress out of expected bounds, $pct_in% should be 100%"
0389 
0390         ((dout == din))
0391         check_err $? "$((din - dout)) bytes out of $din ingressed got lost"
0392 
0393         log_test "PFC"
0394 }
0395 
0396 bail_on_lldpad
0397 
0398 trap cleanup EXIT
0399 setup_prepare
0400 setup_wait
0401 tests_run
0402 
0403 exit $EXIT_STATUS