selftests: mlxsw: Add QOS test for maximum use of descriptors
[platform/kernel/linux-starfive.git] / tools / testing / selftests / drivers / net / mlxsw / qos_max_descriptors.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # This test sends many small packets (size is less than cell size) through the
5 # switch. A shaper is used in $swp2, so the traffic is limited there. Packets
6 # are queued till they will be sent.
7 #
8 # The idea is to verify that the switch can handle at least 85% of maximum
9 # supported descrpitors by hardware. Then, we verify that the driver configures
10 # firmware to allow infinite size of egress descriptor pool, and does not use a
11 # lower limitation. Increase the size of the relevant pools such that the pool's
12 # size does not limit the traffic.
13
14 # +-----------------------+
15 # | H1                    |
16 # |   + $h1.111           |
17 # |   | 192.0.2.33/28     |
18 # |   |                   |
19 # |   + $h1               |
20 # +---|-------------------+
21 #     |
22 # +---|-----------------------------+
23 # |   + $swp1                       |
24 # |   | iPOOL1                      |
25 # |   |                             |
26 # | +-|------------------------+    |
27 # | | + $swp1.111              |    |
28 # | |                          |    |
29 # | | BR1                      |    |
30 # | |                          |    |
31 # | | + $swp2.111              |    |
32 # | +-|------------------------+    |
33 # |   |                             |
34 # |   + $swp2                       |
35 # |   | ePOOL6                      |
36 # |   | 1mbit                       |
37 # +---+-----------------------------+
38 #     |
39 # +---|-------------------+
40 # |   + $h2            H2 |
41 # |   |                   |
42 # |   + $h2.111           |
43 # |     192.0.2.34/28     |
44 # +-----------------------+
45 #
46
47 ALL_TESTS="
48         ping_ipv4
49         max_descriptors
50 "
51
52 lib_dir=$(dirname $0)/../../../net/forwarding
53
54 NUM_NETIFS=4
55 source $lib_dir/lib.sh
56 source $lib_dir/devlink_lib.sh
57 source mlxsw_lib.sh
58
59 MAX_POOL_SIZE=$(devlink_pool_size_get)
60 SHAPER_RATE=1mbit
61
62 # The current TBF qdisc interface does not allow us to configure the shaper to
63 # flat zero. The ASIC shaper is guaranteed to work with a granularity of
64 # 200Mbps. On Spectrum-2, writing a value close to zero instead of zero works
65 # well, but the performance on Spectrum-1 is unpredictable. Thus, do not run the
66 # test on Spectrum-1.
67 mlxsw_only_on_spectrum 2+ || exit
68
69 h1_create()
70 {
71         simple_if_init $h1
72
73         vlan_create $h1 111 v$h1 192.0.2.33/28
74         ip link set dev $h1.111 type vlan egress-qos-map 0:1
75 }
76
77 h1_destroy()
78 {
79         vlan_destroy $h1 111
80
81         simple_if_fini $h1
82 }
83
84 h2_create()
85 {
86         simple_if_init $h2
87
88         vlan_create $h2 111 v$h2 192.0.2.34/28
89 }
90
91 h2_destroy()
92 {
93         vlan_destroy $h2 111
94
95         simple_if_fini $h2
96 }
97
98 switch_create()
99 {
100         # pools
101         # -----
102
103         devlink_pool_size_thtype_save 1
104         devlink_pool_size_thtype_save 6
105
106         devlink_port_pool_th_save $swp1 1
107         devlink_port_pool_th_save $swp2 6
108
109         devlink_tc_bind_pool_th_save $swp1 1 ingress
110         devlink_tc_bind_pool_th_save $swp2 1 egress
111
112         devlink_pool_size_thtype_set 1 dynamic $MAX_POOL_SIZE
113         devlink_pool_size_thtype_set 6 static $MAX_POOL_SIZE
114
115         # $swp1
116         # -----
117
118         ip link set dev $swp1 up
119         vlan_create $swp1 111
120         ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1
121
122         devlink_port_pool_th_set $swp1 1 16
123         devlink_tc_bind_pool_th_set $swp1 1 ingress 1 16
124
125         tc qdisc replace dev $swp1 root handle 1: \
126            ets bands 8 strict 8 priomap 7 6
127         dcb buffer set dev $swp1 prio-buffer all:0 1:1
128
129         # $swp2
130         # -----
131
132         ip link set dev $swp2 up
133         vlan_create $swp2 111
134         ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1
135
136         devlink_port_pool_th_set $swp2 6 $MAX_POOL_SIZE
137         devlink_tc_bind_pool_th_set $swp2 1 egress 6 $MAX_POOL_SIZE
138
139         tc qdisc replace dev $swp2 root handle 1: tbf rate $SHAPER_RATE \
140                 burst 128K limit 500M
141         tc qdisc replace dev $swp2 parent 1:1 handle 11: \
142                 ets bands 8 strict 8 priomap 7 6
143
144         # bridge
145         # ------
146
147         ip link add name br1 type bridge vlan_filtering 0
148         ip link set dev $swp1.111 master br1
149         ip link set dev br1 up
150
151         ip link set dev $swp2.111 master br1
152 }
153
154 switch_destroy()
155 {
156         # Do this first so that we can reset the limits to values that are only
157         # valid for the original static / dynamic setting.
158         devlink_pool_size_thtype_restore 6
159         devlink_pool_size_thtype_restore 1
160
161         # bridge
162         # ------
163
164         ip link set dev $swp2.111 nomaster
165
166         ip link set dev br1 down
167         ip link set dev $swp1.111 nomaster
168         ip link del dev br1
169
170         # $swp2
171         # -----
172
173         tc qdisc del dev $swp2 parent 1:1 handle 11:
174         tc qdisc del dev $swp2 root
175
176         devlink_tc_bind_pool_th_restore $swp2 1 egress
177         devlink_port_pool_th_restore $swp2 6
178
179         vlan_destroy $swp2 111
180         ip link set dev $swp2 down
181
182         # $swp1
183         # -----
184
185         dcb buffer set dev $swp1 prio-buffer all:0
186         tc qdisc del dev $swp1 root
187
188         devlink_tc_bind_pool_th_restore $swp1 1 ingress
189         devlink_port_pool_th_restore $swp1 1
190
191         vlan_destroy $swp1 111
192         ip link set dev $swp1 down
193 }
194
195 setup_prepare()
196 {
197         h1=${NETIFS[p1]}
198         swp1=${NETIFS[p2]}
199
200         swp2=${NETIFS[p3]}
201         h2=${NETIFS[p4]}
202
203         h2mac=$(mac_get $h2)
204
205         vrf_prepare
206
207         h1_create
208         h2_create
209         switch_create
210 }
211
212 cleanup()
213 {
214         pre_cleanup
215
216         switch_destroy
217         h2_destroy
218         h1_destroy
219
220         vrf_cleanup
221 }
222
223 ping_ipv4()
224 {
225         ping_test $h1 192.0.2.34 " h1->h2"
226 }
227
228 percentage_used()
229 {
230         local num_packets=$1; shift
231         local max_packets=$1; shift
232
233         bc <<< "
234             scale=2
235             100 * $num_packets / $max_packets
236         "
237 }
238
239 max_descriptors()
240 {
241         local cell_size=$(devlink_cell_size_get)
242         local exp_perc_used=85
243         local max_descriptors
244         local pktsize=30
245
246         RET=0
247
248         max_descriptors=$(mlxsw_max_descriptors_get) || exit 1
249
250         local d0=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1)
251
252         log_info "Send many small packets, packet size = $pktsize bytes"
253         start_traffic_pktsize $pktsize $h1.111 192.0.2.33 192.0.2.34 $h2mac
254
255         # Sleep to wait for congestion.
256         sleep 5
257
258         local d1=$(ethtool_stats_get $swp2 tc_no_buffer_discard_uc_tc_1)
259         ((d1 == d0))
260         check_err $? "Drops seen on egress port: $d0 -> $d1 ($((d1 - d0)))"
261
262         # Check how many packets the switch can handle, the limitation is
263         # maximum descriptors.
264         local pkts_bytes=$(ethtool_stats_get $swp2 tc_transmit_queue_tc_1)
265         local pkts_num=$((pkts_bytes / cell_size))
266         local perc_used=$(percentage_used $pkts_num $max_descriptors)
267
268         check_err $(bc <<< "$perc_used < $exp_perc_used") \
269                 "Expected > $exp_perc_used% of descriptors, handle $perc_used%"
270
271         stop_traffic
272         sleep 1
273
274         log_test "Maximum descriptors usage. The percentage used is $perc_used%"
275 }
276
277 trap cleanup EXIT
278 setup_prepare
279 setup_wait
280 tests_run
281
282 exit $EXIT_STATUS