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