1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4ALL_TESTS=" 5 test_defaults 6 test_dcb_ets 7 test_mtu 8 test_pfc 9 test_int_buf 10 test_tc_priomap 11 test_tc_mtu 12 test_tc_sizes 13 test_tc_int_buf 14" 15 16lib_dir=$(dirname $0)/../../../net/forwarding 17 18NUM_NETIFS=0 19source $lib_dir/lib.sh 20source $lib_dir/devlink_lib.sh 21 22swp=$NETIF_NO_CABLE 23 24cleanup() 25{ 26 pre_cleanup 27} 28 29get_prio_pg() 30{ 31 # Produces a string of numbers "<B0> <B1> ... <B7> ", where BX is number 32 # of buffer that priority X is mapped to. 33 dcb -j buffer show dev $swp | 34 jq -r '[.prio_buffer | .[] | tostring + " "] | add' 35} 36 37get_prio_pfc() 38{ 39 # Produces a string of numbers "<P0> <P1> ... <P7> ", where PX denotes 40 # whether priority X has PFC enabled (the value is 1) or disabled (0). 41 dcb -j pfc show dev $swp | 42 jq -r '[.prio_pfc | .[] | if . then "1 " else "0 " end] | add' 43} 44 45get_prio_tc() 46{ 47 # Produces a string of numbers "<T0> <T1> ... <T7> ", where TC is number 48 # of TC that priority X is mapped to. 49 dcb -j ets show dev $swp | 50 jq -r '[.prio_tc | .[] | tostring + " "] | add' 51} 52 53get_buf_size() 54{ 55 local idx=$1; shift 56 57 dcb -j buffer show dev $swp | jq ".buffer_size[$idx]" 58} 59 60get_tot_size() 61{ 62 dcb -j buffer show dev $swp | jq '.total_size' 63} 64 65check_prio_pg() 66{ 67 local expect=$1; shift 68 69 local current=$(get_prio_pg) 70 test "$current" = "$expect" 71 check_err $? "prio2buffer is '$current', expected '$expect'" 72} 73 74check_prio_pfc() 75{ 76 local expect=$1; shift 77 78 local current=$(get_prio_pfc) 79 test "$current" = "$expect" 80 check_err $? "prio PFC is '$current', expected '$expect'" 81} 82 83check_prio_tc() 84{ 85 local expect=$1; shift 86 87 local current=$(get_prio_tc) 88 test "$current" = "$expect" 89 check_err $? "prio_tc is '$current', expected '$expect'" 90} 91 92__check_buf_size() 93{ 94 local idx=$1; shift 95 local expr=$1; shift 96 local what=$1; shift 97 98 local current=$(get_buf_size $idx) 99 ((current $expr)) 100 check_err $? "${what}buffer $idx size is '$current', expected '$expr'" 101 echo $current 102} 103 104check_buf_size() 105{ 106 __check_buf_size "$@" > /dev/null 107} 108 109test_defaults() 110{ 111 RET=0 112 113 check_prio_pg "0 0 0 0 0 0 0 0 " 114 check_prio_tc "0 0 0 0 0 0 0 0 " 115 check_prio_pfc "0 0 0 0 0 0 0 0 " 116 117 log_test "Default headroom configuration" 118} 119 120test_dcb_ets() 121{ 122 RET=0 123 124 dcb ets set dev $swp prio-tc 0:0 1:2 2:4 3:6 4:1 5:3 6:5 7:7 125 126 check_prio_pg "0 2 4 6 1 3 5 7 " 127 check_prio_tc "0 2 4 6 1 3 5 7 " 128 check_prio_pfc "0 0 0 0 0 0 0 0 " 129 130 dcb ets set dev $swp prio-tc all:0 131 132 check_prio_pg "0 0 0 0 0 0 0 0 " 133 check_prio_tc "0 0 0 0 0 0 0 0 " 134 135 dcb buffer set dev $swp prio-buffer 0:1 1:3 2:5 3:7 4:0 5:2 6:4 7:6 2>/dev/null 136 check_fail $? "prio2buffer accepted in DCB mode" 137 138 log_test "Configuring headroom through ETS" 139} 140 141test_mtu() 142{ 143 local what=$1; shift 144 local buf0size_2 145 local buf0size 146 147 RET=0 148 buf0size=$(__check_buf_size 0 "> 0") 149 150 mtu_set $swp 3000 151 buf0size_2=$(__check_buf_size 0 "> $buf0size" "MTU 3000: ") 152 mtu_restore $swp 153 154 mtu_set $swp 6000 155 check_buf_size 0 "> $buf0size_2" "MTU 6000: " 156 mtu_restore $swp 157 158 check_buf_size 0 "== $buf0size" 159 160 log_test "${what}MTU impacts buffer size" 161} 162 163test_tc_mtu() 164{ 165 # In TC mode, MTU still impacts the threshold below which a buffer is 166 # not permitted to go. 167 168 tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M 169 test_mtu "TC: " 170 tc qdisc delete dev $swp root 171} 172 173test_pfc() 174{ 175 RET=0 176 177 dcb ets set dev $swp prio-tc all:0 5:1 6:2 7:3 178 179 local buf0size=$(get_buf_size 0) 180 local buf1size=$(get_buf_size 1) 181 local buf2size=$(get_buf_size 2) 182 local buf3size=$(get_buf_size 3) 183 check_buf_size 0 "> 0" 184 check_buf_size 1 "> 0" 185 check_buf_size 2 "> 0" 186 check_buf_size 3 "> 0" 187 check_buf_size 4 "== 0" 188 check_buf_size 5 "== 0" 189 check_buf_size 6 "== 0" 190 check_buf_size 7 "== 0" 191 192 log_test "Buffer size sans PFC" 193 194 RET=0 195 196 dcb pfc set dev $swp prio-pfc all:off 5:on 6:on 7:on delay 0 197 198 check_prio_pg "0 0 0 0 0 1 2 3 " 199 check_prio_pfc "0 0 0 0 0 1 1 1 " 200 check_buf_size 0 "== $buf0size" 201 check_buf_size 1 "> $buf1size" 202 check_buf_size 2 "> $buf2size" 203 check_buf_size 3 "> $buf3size" 204 205 local buf1size=$(get_buf_size 1) 206 check_buf_size 2 "== $buf1size" 207 check_buf_size 3 "== $buf1size" 208 209 log_test "PFC: Cable length 0" 210 211 RET=0 212 213 dcb pfc set dev $swp delay 1000 214 215 check_buf_size 0 "== $buf0size" 216 check_buf_size 1 "> $buf1size" 217 check_buf_size 2 "> $buf1size" 218 check_buf_size 3 "> $buf1size" 219 220 log_test "PFC: Cable length 1000" 221 222 RET=0 223 224 dcb pfc set dev $swp prio-pfc all:off delay 0 225 dcb ets set dev $swp prio-tc all:0 226 227 check_prio_pg "0 0 0 0 0 0 0 0 " 228 check_prio_tc "0 0 0 0 0 0 0 0 " 229 check_buf_size 0 "> 0" 230 check_buf_size 1 "== 0" 231 check_buf_size 2 "== 0" 232 check_buf_size 3 "== 0" 233 check_buf_size 4 "== 0" 234 check_buf_size 5 "== 0" 235 check_buf_size 6 "== 0" 236 check_buf_size 7 "== 0" 237 238 log_test "PFC: Restore defaults" 239} 240 241test_tc_priomap() 242{ 243 RET=0 244 245 dcb ets set dev $swp prio-tc 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7 246 check_prio_pg "0 1 2 3 4 5 6 7 " 247 248 tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M 249 check_prio_pg "0 0 0 0 0 0 0 0 " 250 251 dcb buffer set dev $swp prio-buffer 0:1 1:3 2:5 3:7 4:0 5:2 6:4 7:6 252 check_prio_pg "1 3 5 7 0 2 4 6 " 253 254 tc qdisc delete dev $swp root 255 check_prio_pg "0 1 2 3 4 5 6 7 " 256 257 # Clean up. 258 tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M 259 dcb buffer set dev $swp prio-buffer all:0 260 tc qdisc delete dev $swp root 261 dcb ets set dev $swp prio-tc all:0 262 263 log_test "TC: priomap" 264} 265 266test_tc_sizes() 267{ 268 local cell_size=$(devlink_cell_size_get) 269 local size=$((cell_size * 1000)) 270 271 RET=0 272 273 dcb buffer set dev $swp buffer-size all:0 0:$size 2>/dev/null 274 check_fail $? "buffer_size should fail before qdisc is added" 275 276 tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M 277 278 dcb buffer set dev $swp buffer-size all:0 0:$size 279 check_err $? "buffer_size should pass after qdisc is added" 280 check_buf_size 0 "== $size" "set size: " 281 282 mtu_set $swp 6000 283 check_buf_size 0 "== $size" "set MTU: " 284 mtu_restore $swp 285 286 dcb buffer set dev $swp buffer-size all:0 287 288 # After replacing the qdisc for the same kind, buffer_size still has to 289 # work. 290 tc qdisc replace dev $swp root handle 1: bfifo limit 1M 291 292 dcb buffer set dev $swp buffer-size all:0 0:$size 293 check_buf_size 0 "== $size" "post replace, set size: " 294 295 dcb buffer set dev $swp buffer-size all:0 296 297 # Likewise after replacing for a different kind. 298 tc qdisc replace dev $swp root handle 2: prio bands 8 299 300 dcb buffer set dev $swp buffer-size all:0 0:$size 301 check_buf_size 0 "== $size" "post replace different kind, set size: " 302 303 tc qdisc delete dev $swp root 304 305 dcb buffer set dev $swp buffer-size all:0 0:$size 2>/dev/null 306 check_fail $? "buffer_size should fail after qdisc is deleted" 307 308 log_test "TC: buffer size" 309} 310 311test_int_buf() 312{ 313 local what=$1; shift 314 315 RET=0 316 317 local buf0size=$(get_buf_size 0) 318 local tot_size=$(get_tot_size) 319 320 # Size of internal buffer and buffer 9. 321 local dsize=$((tot_size - buf0size)) 322 323 tc qdisc add dev $swp clsact 324 tc filter add dev $swp egress matchall skip_sw action mirred egress mirror dev $swp 325 326 local buf0size_2=$(get_buf_size 0) 327 local tot_size_2=$(get_tot_size) 328 local dsize_2=$((tot_size_2 - buf0size_2)) 329 330 # Egress SPAN should have added to the "invisible" buffer configuration. 331 ((dsize_2 > dsize)) 332 check_err $? "Invisible buffers account for '$dsize_2', expected '> $dsize'" 333 334 mtu_set $swp 3000 335 336 local buf0size_3=$(get_buf_size 0) 337 local tot_size_3=$(get_tot_size) 338 local dsize_3=$((tot_size_3 - buf0size_3)) 339 340 # MTU change might change buffer 0, which will show at total, but the 341 # hidden buffers should stay the same size. 342 ((dsize_3 == dsize_2)) 343 check_err $? "MTU change: Invisible buffers account for '$dsize_3', expected '== $dsize_2'" 344 345 mtu_restore $swp 346 tc qdisc del dev $swp clsact 347 348 # After SPAN removal, hidden buffers should be back to the original sizes. 349 local buf0size_4=$(get_buf_size 0) 350 local tot_size_4=$(get_tot_size) 351 local dsize_4=$((tot_size_4 - buf0size_4)) 352 ((dsize_4 == dsize)) 353 check_err $? "SPAN removed: Invisible buffers account for '$dsize_4', expected '== $dsize'" 354 355 log_test "${what}internal buffer size" 356} 357 358test_tc_int_buf() 359{ 360 local cell_size=$(devlink_cell_size_get) 361 local size=$((cell_size * 1000)) 362 363 tc qdisc replace dev $swp root handle 1: bfifo limit 1.5M 364 test_int_buf "TC: " 365 366 dcb buffer set dev $swp buffer-size all:0 0:$size 367 test_int_buf "TC+buffsize: " 368 369 dcb buffer set dev $swp buffer-size all:0 370 tc qdisc delete dev $swp root 371} 372 373bail_on_lldpad "configure DCB" "configure Qdiscs" 374 375trap cleanup EXIT 376setup_wait 377tests_run 378 379exit $EXIT_STATUS 380