xref: /linux/tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh (revision 8a5f956a9fb7d74fff681145082acfad5afa6bb8)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# A test for strict prioritization of traffic in the switch. Run two streams of
5# traffic, each through a different ingress port, one tagged with PCP of 1, the
6# other with PCP of 2. Both streams converge at one egress port, where they are
7# assigned TC of, respectively, 1 and 2, with strict priority configured between
8# them. In H3, we expect to see (almost) exclusively the high-priority traffic.
9#
10# Please see qos_mc_aware.sh for an explanation of why we use mausezahn and
11# counters instead of just running iperf3.
12#
13# +---------------------------+                 +-----------------------------+
14# | H1                        |                 |                          H2 |
15# |         $h1.111 +         |                 |         + $h2.222           |
16# |   192.0.2.33/28 |         |                 |         | 192.0.2.65/28     |
17# |   e-qos-map 0:1 |         |                 |         | e-qos-map 0:2     |
18# |                 |         |                 |         |                   |
19# |             $h1 +         |                 |         + $h2               |
20# +-----------------|---------+                 +---------|-------------------+
21#                   |                                     |
22# +-----------------|-------------------------------------|-------------------+
23# |           $swp1 +                                     + $swp2             |
24# |          >1Gbps |                                     | >1Gbps            |
25# | +---------------|-----------+              +----------|----------------+  |
26# | |     $swp1.111 +           |              |          + $swp2.222      |  |
27# | |                     BR111 |       SW     | BR222                     |  |
28# | |     $swp3.111 +           |              |          + $swp3.222      |  |
29# | +---------------|-----------+              +----------|----------------+  |
30# |                 \_____________________________________/                   |
31# |                                    |                                      |
32# |                                    + $swp3                                |
33# |                                    | 1Gbps bottleneck                     |
34# |                                    | ETS: (up n->tc n for n in 0..7)      |
35# |                                    |      strict priority                 |
36# +------------------------------------|--------------------------------------+
37#                                      |
38#                 +--------------------|--------------------+
39#                 |                    + $h3             H3 |
40#                 |                   / \                   |
41#                 |                  /   \                  |
42#                 |         $h3.111 +     + $h3.222         |
43#                 |  192.0.2.34/28          192.0.2.66/28   |
44#                 +-----------------------------------------+
45
46ALL_TESTS="
47	ping_ipv4
48	test_ets_strict
49"
50
51lib_dir=$(dirname $0)/../../../net/forwarding
52
53NUM_NETIFS=6
54source $lib_dir/lib.sh
55source $lib_dir/devlink_lib.sh
56source qos_lib.sh
57
58h1_create()
59{
60	adf_simple_if_init $h1
61
62	mtu_set $h1 10000
63	defer mtu_restore $h1
64
65	vlan_create $h1 111 v$h1 192.0.2.33/28
66	defer vlan_destroy $h1 111
67	ip link set dev $h1.111 type vlan egress-qos-map 0:1
68}
69
70h2_create()
71{
72	adf_simple_if_init $h2
73
74	mtu_set $h2 10000
75	defer mtu_restore $h2
76
77	vlan_create $h2 222 v$h2 192.0.2.65/28
78	defer vlan_destroy $h2 222
79	ip link set dev $h2.222 type vlan egress-qos-map 0:2
80}
81
82h3_create()
83{
84	adf_simple_if_init $h3
85
86	mtu_set $h3 10000
87	defer mtu_restore $h3
88
89	vlan_create $h3 111 v$h3 192.0.2.34/28
90	defer vlan_destroy $h3 111
91
92	vlan_create $h3 222 v$h3 192.0.2.66/28
93	defer vlan_destroy $h3 222
94}
95
96switch_create()
97{
98	ip link set dev $swp1 up
99	defer ip link set dev $swp1 down
100
101	mtu_set $swp1 10000
102	defer mtu_restore $swp1
103
104	ip link set dev $swp2 up
105	defer ip link set dev $swp2 down
106
107	mtu_set $swp2 10000
108	defer mtu_restore $swp2
109
110	# prio n -> TC n, strict scheduling
111	lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7
112	defer lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0
113
114	lldptool -T -i $swp3 -V ETS-CFG tsa=$(
115			)"0:strict,"$(
116			)"1:strict,"$(
117			)"2:strict,"$(
118			)"3:strict,"$(
119			)"4:strict,"$(
120			)"5:strict,"$(
121			)"6:strict,"$(
122			)"7:strict"
123	sleep 1
124
125	ip link set dev $swp3 up
126	defer ip link set dev $swp3 down
127
128	mtu_set $swp3 10000
129	defer mtu_restore $swp3
130
131	tc qdisc replace dev $swp3 root handle 101: tbf rate 1gbit \
132		burst 128K limit 1G
133	defer tc qdisc del dev $swp3 root handle 101:
134
135	vlan_create $swp1 111
136	defer vlan_destroy $swp1 111
137
138	vlan_create $swp2 222
139	defer vlan_destroy $swp2 222
140
141	vlan_create $swp3 111
142	defer vlan_destroy $swp3 111
143
144	vlan_create $swp3 222
145	defer vlan_destroy $swp3 222
146
147	ip link add name br111 type bridge vlan_filtering 0
148	defer ip link del dev br111
149	ip link set dev br111 addrgenmode none
150
151	ip link set dev br111 up
152	defer ip link set dev br111 down
153
154	ip link set dev $swp1.111 master br111
155	defer ip link set dev $swp1.111 nomaster
156
157	ip link set dev $swp3.111 master br111
158	defer ip link set dev $swp3.111 nomaster
159
160	ip link add name br222 type bridge vlan_filtering 0
161	defer ip link del dev br222
162	ip link set dev br222 addrgenmode none
163
164	ip link set dev br222 up
165	defer ip link set dev br222 down
166
167	ip link set dev $swp2.222 master br222
168	defer ip link set dev $swp2.222 nomaster
169
170	ip link set dev $swp3.222 master br222
171	defer ip link set dev $swp3.222 nomaster
172
173	# Make sure that ingress quotas are smaller than egress so that there is
174	# room for both streams of traffic to be admitted to shared buffer.
175	devlink_pool_size_thtype_save 0
176	devlink_pool_size_thtype_set 0 dynamic 10000000
177	defer devlink_pool_size_thtype_restore 0
178
179	devlink_pool_size_thtype_save 4
180	devlink_pool_size_thtype_set 4 dynamic 10000000
181	defer devlink_pool_size_thtype_restore 4
182
183	devlink_port_pool_th_save $swp1 0
184	devlink_port_pool_th_set $swp1 0 6
185	defer devlink_port_pool_th_restore $swp1 0
186
187	devlink_tc_bind_pool_th_save $swp1 1 ingress
188	devlink_tc_bind_pool_th_set $swp1 1 ingress 0 6
189	defer devlink_tc_bind_pool_th_restore $swp1 1 ingress
190
191	devlink_port_pool_th_save $swp2 0
192	devlink_port_pool_th_set $swp2 0 6
193	defer devlink_port_pool_th_restore $swp2 0
194
195	devlink_tc_bind_pool_th_save $swp2 2 ingress
196	devlink_tc_bind_pool_th_set $swp2 2 ingress 0 6
197	defer devlink_tc_bind_pool_th_restore $swp2 2 ingress
198
199	devlink_tc_bind_pool_th_save $swp3 1 egress
200	devlink_tc_bind_pool_th_set $swp3 1 egress 4 7
201	defer devlink_tc_bind_pool_th_restore $swp3 1 egress
202
203	devlink_tc_bind_pool_th_save $swp3 2 egress
204	devlink_tc_bind_pool_th_set $swp3 2 egress 4 7
205	defer devlink_tc_bind_pool_th_restore $swp3 2 egress
206
207	devlink_port_pool_th_save $swp3 4
208	devlink_port_pool_th_set $swp3 4 7
209	defer devlink_port_pool_th_restore $swp3 4
210}
211
212setup_prepare()
213{
214	h1=${NETIFS[p1]}
215	swp1=${NETIFS[p2]}
216
217	swp2=${NETIFS[p3]}
218	h2=${NETIFS[p4]}
219
220	swp3=${NETIFS[p5]}
221	h3=${NETIFS[p6]}
222
223	h3mac=$(mac_get $h3)
224
225	adf_vrf_prepare
226
227	h1_create
228	h2_create
229	h3_create
230	switch_create
231}
232
233ping_ipv4()
234{
235	ping_test $h1 192.0.2.34 " from H1"
236	ping_test $h2 192.0.2.66 " from H2"
237}
238
239rel()
240{
241	local old=$1; shift
242	local new=$1; shift
243
244	bc <<< "
245	    scale=2
246	    ret = 100 * $new / $old
247	    if (ret > 0) { ret } else { 0 }
248	"
249}
250
251__run_hi_measure_rate()
252{
253	local what=$1; shift
254	local -a uc_rate
255
256	start_traffic $h2.222 192.0.2.65 192.0.2.66 $h3mac
257	defer stop_traffic $!
258
259	uc_rate=($(measure_rate $swp2 $h3 rx_octets_prio_2 "$what"))
260	check_err $? "Could not get high enough $what ingress rate"
261
262	echo ${uc_rate[@]}
263}
264
265run_hi_measure_rate()
266{
267	in_defer_scope __run_hi_measure_rate "$@"
268}
269
270test_ets_strict()
271{
272	RET=0
273
274	# Run high-prio traffic on its own.
275	local -a rate_2
276	rate_2=($(run_hi_measure_rate "prio 2"))
277	local rate_2_in=${rate_2[0]}
278	local rate_2_eg=${rate_2[1]}
279
280	# Start low-prio stream.
281	start_traffic $h1.111 192.0.2.33 192.0.2.34 $h3mac
282	defer stop_traffic $!
283
284	local -a rate_1
285	rate_1=($(measure_rate $swp1 $h3 rx_octets_prio_1 "prio 1"))
286	check_err $? "Could not get high enough prio-1 ingress rate"
287	local rate_1_in=${rate_1[0]}
288	local rate_1_eg=${rate_1[1]}
289
290	# High-prio and low-prio on their own should have about the same
291	# throughput.
292	local rel21=$(rel $rate_1_eg $rate_2_eg)
293	check_err $(bc <<< "$rel21 < 95")
294	check_err $(bc <<< "$rel21 > 105")
295
296	# Start the high-prio stream--now both streams run.
297	rate_3=($(run_hi_measure_rate "prio 2+1"))
298	local rate_3_in=${rate_3[0]}
299	local rate_3_eg=${rate_3[1]}
300
301	# High-prio should have about the same throughput whether or not
302	# low-prio is in the system.
303	local rel32=$(rel $rate_2_eg $rate_3_eg)
304	check_err $(bc <<< "$rel32 < 95")
305
306	log_test "strict priority"
307	echo "Ingress to switch:"
308	echo "  p1 in rate            $(humanize $rate_1_in)"
309	echo "  p2 in rate            $(humanize $rate_2_in)"
310	echo "  p2 in rate w/ p1      $(humanize $rate_3_in)"
311	echo "Egress from switch:"
312	echo "  p1 eg rate            $(humanize $rate_1_eg)"
313	echo "  p2 eg rate            $(humanize $rate_2_eg) ($rel21% of p1)"
314	echo "  p2 eg rate w/ p1      $(humanize $rate_3_eg) ($rel32% of p2)"
315}
316
317trap cleanup EXIT
318
319setup_prepare
320setup_wait
321
322tests_run
323
324exit $EXIT_STATUS
325