Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'selftests-net-introduce-deferred-commands'

Petr Machata says:

====================
selftests: net: Introduce deferred commands

Recently, a defer helper was added to Python selftests. The idea is to keep
cleanup commands close to their dirtying counterparts, thereby making it
more transparent what is cleaning up what, making it harder to miss a
cleanup, and make the whole cleanup business exception safe. All these
benefits are applicable to bash as well, exception safety can be
interpreted in terms of safety vs. a SIGINT.

This patchset therefore introduces a framework of several helpers that
serve to schedule cleanups in bash selftests.

- Patch #1 has more details about the primitives being introduced.
Patch #2 adds a fallback cleanup() function to lib.sh, because ideally
selftests wouldn't need to introduce a dedicated cleanup function at all.

- Patch #3 adds a parameter to stop_traffic(), which makes it possible to
start other background processes after the traffic is started without
confusing the cleanup.

- Patches #4 to #10 convert a number of selftests.

The goal was to convert all tests that use start_traffic / stop_traffic
to the defer framework. Leftover traffic generators are a particularly
painful sort of a missed cleanup. Normal unfinished cleanups can usually
be cleaned up simply by rerunning the test and interrupting it early to
let the cleanups run again / in full. This does not work with
stop_traffic, because it is only issued at the end of the test case that
starts the traffic. At the same time, leftover traffic generators
influence follow-up test runs, and are hard to notice.

The tests were however converted whole-sale, not just their traffic bits.
Thus they form a proof of concept of the defer framework.
====================

Link: https://patch.msgid.link/cover.1729157566.git.petrm@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+597 -615
+85 -82
tools/testing/selftests/drivers/net/mlxsw/qos_ets_strict.sh
··· 58 58 h1_create() 59 59 { 60 60 simple_if_init $h1 61 + defer simple_if_fini $h1 62 + 61 63 mtu_set $h1 10000 64 + defer mtu_restore $h1 62 65 63 66 vlan_create $h1 111 v$h1 192.0.2.33/28 67 + defer vlan_destroy $h1 111 64 68 ip link set dev $h1.111 type vlan egress-qos-map 0:1 65 - } 66 - 67 - h1_destroy() 68 - { 69 - vlan_destroy $h1 111 70 - 71 - mtu_restore $h1 72 - simple_if_fini $h1 73 69 } 74 70 75 71 h2_create() 76 72 { 77 73 simple_if_init $h2 74 + defer simple_if_fini $h2 75 + 78 76 mtu_set $h2 10000 77 + defer mtu_restore $h2 79 78 80 79 vlan_create $h2 222 v$h2 192.0.2.65/28 80 + defer vlan_destroy $h2 222 81 81 ip link set dev $h2.222 type vlan egress-qos-map 0:2 82 - } 83 - 84 - h2_destroy() 85 - { 86 - vlan_destroy $h2 222 87 - 88 - mtu_restore $h2 89 - simple_if_fini $h2 90 82 } 91 83 92 84 h3_create() 93 85 { 94 86 simple_if_init $h3 87 + defer simple_if_fini $h3 88 + 95 89 mtu_set $h3 10000 90 + defer mtu_restore $h3 96 91 97 92 vlan_create $h3 111 v$h3 192.0.2.34/28 93 + defer vlan_destroy $h3 111 94 + 98 95 vlan_create $h3 222 v$h3 192.0.2.66/28 99 - } 100 - 101 - h3_destroy() 102 - { 103 - vlan_destroy $h3 222 104 - vlan_destroy $h3 111 105 - 106 - mtu_restore $h3 107 - simple_if_fini $h3 96 + defer vlan_destroy $h3 222 108 97 } 109 98 110 99 switch_create() 111 100 { 112 101 ip link set dev $swp1 up 102 + defer ip link set dev $swp1 down 103 + 113 104 mtu_set $swp1 10000 105 + defer mtu_restore $swp1 114 106 115 107 ip link set dev $swp2 up 108 + defer ip link set dev $swp2 down 109 + 116 110 mtu_set $swp2 10000 111 + defer mtu_restore $swp2 117 112 118 113 # prio n -> TC n, strict scheduling 119 114 lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7 115 + 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 116 + 120 117 lldptool -T -i $swp3 -V ETS-CFG tsa=$( 121 118 )"0:strict,"$( 122 119 )"1:strict,"$( ··· 126 129 sleep 1 127 130 128 131 ip link set dev $swp3 up 132 + defer ip link set dev $swp3 down 133 + 129 134 mtu_set $swp3 10000 135 + defer mtu_restore $swp3 136 + 130 137 tc qdisc replace dev $swp3 root handle 101: tbf rate 1gbit \ 131 138 burst 128K limit 1G 139 + defer tc qdisc del dev $swp3 root handle 101: 132 140 133 141 vlan_create $swp1 111 142 + defer vlan_destroy $swp1 111 143 + 134 144 vlan_create $swp2 222 145 + defer vlan_destroy $swp2 222 146 + 135 147 vlan_create $swp3 111 148 + defer vlan_destroy $swp3 111 149 + 136 150 vlan_create $swp3 222 151 + defer vlan_destroy $swp3 222 137 152 138 153 ip link add name br111 type bridge vlan_filtering 0 154 + defer ip link del dev br111 139 155 ip link set dev br111 addrgenmode none 156 + 140 157 ip link set dev br111 up 158 + defer ip link set dev br111 down 159 + 141 160 ip link set dev $swp1.111 master br111 161 + defer ip link set dev $swp1.111 nomaster 162 + 142 163 ip link set dev $swp3.111 master br111 164 + defer ip link set dev $swp3.111 nomaster 143 165 144 166 ip link add name br222 type bridge vlan_filtering 0 167 + defer ip link del dev br222 145 168 ip link set dev br222 addrgenmode none 169 + 146 170 ip link set dev br222 up 171 + defer ip link set dev br222 down 172 + 147 173 ip link set dev $swp2.222 master br222 174 + defer ip link set dev $swp2.222 nomaster 175 + 148 176 ip link set dev $swp3.222 master br222 177 + defer ip link set dev $swp3.222 nomaster 149 178 150 179 # Make sure that ingress quotas are smaller than egress so that there is 151 180 # room for both streams of traffic to be admitted to shared buffer. 152 181 devlink_pool_size_thtype_save 0 153 182 devlink_pool_size_thtype_set 0 dynamic 10000000 183 + defer devlink_pool_size_thtype_restore 0 184 + 154 185 devlink_pool_size_thtype_save 4 155 186 devlink_pool_size_thtype_set 4 dynamic 10000000 187 + defer devlink_pool_size_thtype_restore 4 156 188 157 189 devlink_port_pool_th_save $swp1 0 158 190 devlink_port_pool_th_set $swp1 0 6 191 + defer devlink_port_pool_th_restore $swp1 0 192 + 159 193 devlink_tc_bind_pool_th_save $swp1 1 ingress 160 194 devlink_tc_bind_pool_th_set $swp1 1 ingress 0 6 195 + defer devlink_tc_bind_pool_th_restore $swp1 1 ingress 161 196 162 197 devlink_port_pool_th_save $swp2 0 163 198 devlink_port_pool_th_set $swp2 0 6 199 + defer devlink_port_pool_th_restore $swp2 0 200 + 164 201 devlink_tc_bind_pool_th_save $swp2 2 ingress 165 202 devlink_tc_bind_pool_th_set $swp2 2 ingress 0 6 203 + defer devlink_tc_bind_pool_th_restore $swp2 2 ingress 166 204 167 205 devlink_tc_bind_pool_th_save $swp3 1 egress 168 206 devlink_tc_bind_pool_th_set $swp3 1 egress 4 7 207 + defer devlink_tc_bind_pool_th_restore $swp3 1 egress 208 + 169 209 devlink_tc_bind_pool_th_save $swp3 2 egress 170 210 devlink_tc_bind_pool_th_set $swp3 2 egress 4 7 211 + defer devlink_tc_bind_pool_th_restore $swp3 2 egress 212 + 171 213 devlink_port_pool_th_save $swp3 4 172 214 devlink_port_pool_th_set $swp3 4 7 173 - } 174 - 175 - switch_destroy() 176 - { 177 - devlink_port_pool_th_restore $swp3 4 178 - devlink_tc_bind_pool_th_restore $swp3 2 egress 179 - devlink_tc_bind_pool_th_restore $swp3 1 egress 180 - 181 - devlink_tc_bind_pool_th_restore $swp2 2 ingress 182 - devlink_port_pool_th_restore $swp2 0 183 - 184 - devlink_tc_bind_pool_th_restore $swp1 1 ingress 185 - devlink_port_pool_th_restore $swp1 0 186 - 187 - devlink_pool_size_thtype_restore 4 188 - devlink_pool_size_thtype_restore 0 189 - 190 - ip link del dev br222 191 - ip link del dev br111 192 - 193 - vlan_destroy $swp3 222 194 - vlan_destroy $swp3 111 195 - vlan_destroy $swp2 222 196 - vlan_destroy $swp1 111 197 - 198 - tc qdisc del dev $swp3 root handle 101: 199 - mtu_restore $swp3 200 - ip link set dev $swp3 down 201 - lldptool -T -i $swp3 -V ETS-CFG up2tc=0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0 202 - 203 - mtu_restore $swp2 204 - ip link set dev $swp2 down 205 - 206 - mtu_restore $swp1 207 - ip link set dev $swp1 down 215 + defer devlink_port_pool_th_restore $swp3 4 208 216 } 209 217 210 218 setup_prepare() ··· 226 224 h3mac=$(mac_get $h3) 227 225 228 226 vrf_prepare 227 + defer vrf_cleanup 229 228 230 229 h1_create 231 230 h2_create 232 231 h3_create 233 232 switch_create 234 - } 235 - 236 - cleanup() 237 - { 238 - pre_cleanup 239 - 240 - switch_destroy 241 - h3_destroy 242 - h2_destroy 243 - h1_destroy 244 - 245 - vrf_cleanup 246 233 } 247 234 248 235 ping_ipv4() ··· 252 261 " 253 262 } 254 263 264 + __run_hi_measure_rate() 265 + { 266 + local what=$1; shift 267 + local -a uc_rate 268 + 269 + start_traffic $h2.222 192.0.2.65 192.0.2.66 $h3mac 270 + defer stop_traffic $! 271 + 272 + uc_rate=($(measure_rate $swp2 $h3 rx_octets_prio_2 "$what")) 273 + check_err $? "Could not get high enough $what ingress rate" 274 + 275 + echo ${uc_rate[@]} 276 + } 277 + 278 + run_hi_measure_rate() 279 + { 280 + in_defer_scope __run_hi_measure_rate "$@" 281 + } 282 + 255 283 test_ets_strict() 256 284 { 257 285 RET=0 258 286 259 287 # Run high-prio traffic on its own. 260 - start_traffic $h2.222 192.0.2.65 192.0.2.66 $h3mac 261 288 local -a rate_2 262 - rate_2=($(measure_rate $swp2 $h3 rx_octets_prio_2 "prio 2")) 263 - check_err $? "Could not get high enough prio-2 ingress rate" 289 + rate_2=($(run_hi_measure_rate "prio 2")) 264 290 local rate_2_in=${rate_2[0]} 265 291 local rate_2_eg=${rate_2[1]} 266 - stop_traffic # $h2.222 267 292 268 293 # Start low-prio stream. 269 294 start_traffic $h1.111 192.0.2.33 192.0.2.34 $h3mac 295 + defer stop_traffic $! 270 296 271 297 local -a rate_1 272 298 rate_1=($(measure_rate $swp1 $h3 rx_octets_prio_1 "prio 1")) ··· 298 290 check_err $(bc <<< "$rel21 > 105") 299 291 300 292 # Start the high-prio stream--now both streams run. 301 - start_traffic $h2.222 192.0.2.65 192.0.2.66 $h3mac 302 - rate_3=($(measure_rate $swp2 $h3 rx_octets_prio_2 "prio 2 w/ 1")) 303 - check_err $? "Could not get high enough prio-2 ingress rate with prio-1" 293 + rate_3=($(run_hi_measure_rate "prio 2+1")) 304 294 local rate_3_in=${rate_3[0]} 305 295 local rate_3_eg=${rate_3[1]} 306 - stop_traffic # $h2.222 307 - 308 - stop_traffic # $h1.111 309 296 310 297 # High-prio should have about the same throughput whether or not 311 298 # low-prio is in the system.
+41 -77
tools/testing/selftests/drivers/net/mlxsw/qos_max_descriptors.sh
··· 69 69 h1_create() 70 70 { 71 71 simple_if_init $h1 72 + defer simple_if_fini $h1 72 73 73 74 vlan_create $h1 111 v$h1 192.0.2.33/28 75 + defer vlan_destroy $h1 111 74 76 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 77 } 83 78 84 79 h2_create() 85 80 { 86 81 simple_if_init $h2 82 + defer simple_if_fini $h2 87 83 88 84 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 85 + defer vlan_destroy $h2 111 96 86 } 97 87 98 88 switch_create() 99 89 { 100 90 # pools 101 91 # ----- 92 + # devlink_pool_size_thtype_restore needs to be done first so that we can 93 + # reset the various limits to values that are only valid for the 94 + # original static / dynamic setting. 102 95 103 96 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 97 devlink_pool_size_thtype_set 1 dynamic $MAX_POOL_SIZE 98 + defer_prio devlink_pool_size_thtype_restore 1 99 + 100 + devlink_pool_size_thtype_save 6 113 101 devlink_pool_size_thtype_set 6 static $MAX_POOL_SIZE 102 + defer_prio devlink_pool_size_thtype_restore 6 114 103 115 104 # $swp1 116 105 # ----- 117 106 118 107 ip link set dev $swp1 up 108 + defer ip link set dev $swp1 down 109 + 119 110 vlan_create $swp1 111 111 + defer vlan_destroy $swp1 111 120 112 ip link set dev $swp1.111 type vlan ingress-qos-map 0:0 1:1 121 113 114 + devlink_port_pool_th_save $swp1 1 122 115 devlink_port_pool_th_set $swp1 1 16 116 + defer devlink_tc_bind_pool_th_restore $swp1 1 ingress 117 + 118 + devlink_tc_bind_pool_th_save $swp1 1 ingress 123 119 devlink_tc_bind_pool_th_set $swp1 1 ingress 1 16 120 + defer devlink_port_pool_th_restore $swp1 1 124 121 125 122 tc qdisc replace dev $swp1 root handle 1: \ 126 123 ets bands 8 strict 8 priomap 7 6 124 + defer tc qdisc del dev $swp1 root 125 + 127 126 dcb buffer set dev $swp1 prio-buffer all:0 1:1 127 + defer dcb buffer set dev $swp1 prio-buffer all:0 128 128 129 129 # $swp2 130 130 # ----- 131 131 132 132 ip link set dev $swp2 up 133 + defer ip link set dev $swp2 down 134 + 133 135 vlan_create $swp2 111 136 + defer vlan_destroy $swp2 111 134 137 ip link set dev $swp2.111 type vlan egress-qos-map 0:0 1:1 135 138 139 + devlink_port_pool_th_save $swp2 6 136 140 devlink_port_pool_th_set $swp2 6 $MAX_POOL_SIZE 141 + defer devlink_tc_bind_pool_th_restore $swp2 1 egress 142 + 143 + devlink_tc_bind_pool_th_save $swp2 1 egress 137 144 devlink_tc_bind_pool_th_set $swp2 1 egress 6 $MAX_POOL_SIZE 145 + defer devlink_port_pool_th_restore $swp2 6 138 146 139 147 tc qdisc replace dev $swp2 root handle 1: tbf rate $SHAPER_RATE \ 140 148 burst 128K limit 500M 149 + defer tc qdisc del dev $swp2 root 150 + 141 151 tc qdisc replace dev $swp2 parent 1:1 handle 11: \ 142 152 ets bands 8 strict 8 priomap 7 6 153 + defer tc qdisc del dev $swp2 parent 1:1 handle 11: 143 154 144 155 # bridge 145 156 # ------ 146 157 147 158 ip link add name br1 type bridge vlan_filtering 0 159 + defer ip link del dev br1 160 + 148 161 ip link set dev $swp1.111 master br1 162 + defer ip link set dev $swp1.111 nomaster 163 + 149 164 ip link set dev br1 up 165 + defer ip link set dev br1 down 150 166 151 167 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 168 + defer ip link set dev $swp2.111 nomaster 193 169 } 194 170 195 171 setup_prepare() ··· 179 203 h2mac=$(mac_get $h2) 180 204 181 205 vrf_prepare 206 + defer vrf_cleanup 182 207 183 208 h1_create 184 209 h2_create 185 210 switch_create 186 - } 187 - 188 - cleanup() 189 - { 190 - pre_cleanup 191 - 192 - switch_destroy 193 - h2_destroy 194 - h1_destroy 195 - 196 - vrf_cleanup 197 211 } 198 212 199 213 ping_ipv4() ··· 217 251 218 252 log_info "Send many small packets, packet size = $pktsize bytes" 219 253 start_traffic_pktsize $pktsize $h1.111 192.0.2.33 192.0.2.34 $h2mac 254 + defer stop_traffic $! 220 255 221 256 # Sleep to wait for congestion. 222 257 sleep 5 ··· 234 267 235 268 check_err $(bc <<< "$perc_used < $exp_perc_used") \ 236 269 "Expected > $exp_perc_used% of descriptors, handle $perc_used%" 237 - 238 - stop_traffic 239 - sleep 1 240 270 241 271 log_test "Maximum descriptors usage. The percentage used is $perc_used%" 242 272 }
+67 -77
tools/testing/selftests/drivers/net/mlxsw/qos_mc_aware.sh
··· 73 73 h1_create() 74 74 { 75 75 simple_if_init $h1 192.0.2.65/28 76 - mtu_set $h1 10000 77 - } 76 + defer simple_if_fini $h1 192.0.2.65/28 78 77 79 - h1_destroy() 80 - { 81 - mtu_restore $h1 82 - simple_if_fini $h1 192.0.2.65/28 78 + mtu_set $h1 10000 79 + defer mtu_restore $h1 83 80 } 84 81 85 82 h2_create() 86 83 { 87 84 simple_if_init $h2 85 + defer simple_if_fini $h2 86 + 88 87 mtu_set $h2 10000 88 + defer mtu_restore $h2 89 89 90 90 vlan_create $h2 111 v$h2 192.0.2.129/28 91 + defer vlan_destroy $h2 111 91 92 ip link set dev $h2.111 type vlan egress-qos-map 0:1 92 - } 93 - 94 - h2_destroy() 95 - { 96 - vlan_destroy $h2 111 97 - 98 - mtu_restore $h2 99 - simple_if_fini $h2 100 93 } 101 94 102 95 h3_create() 103 96 { 104 97 simple_if_init $h3 192.0.2.66/28 98 + defer simple_if_fini $h3 192.0.2.66/28 99 + 105 100 mtu_set $h3 10000 101 + defer mtu_restore $h3 106 102 107 103 vlan_create $h3 111 v$h3 192.0.2.130/28 108 - } 109 - 110 - h3_destroy() 111 - { 112 - vlan_destroy $h3 111 113 - 114 - mtu_restore $h3 115 - simple_if_fini $h3 192.0.2.66/28 104 + defer vlan_destroy $h3 111 116 105 } 117 106 118 107 switch_create() 119 108 { 120 109 ip link set dev $swp1 up 110 + defer ip link set dev $swp1 down 111 + 121 112 mtu_set $swp1 10000 113 + defer mtu_restore $swp1 122 114 123 115 ip link set dev $swp2 up 116 + defer ip link set dev $swp2 down 117 + 124 118 mtu_set $swp2 10000 119 + defer mtu_restore $swp2 125 120 126 121 ip link set dev $swp3 up 122 + defer ip link set dev $swp3 down 123 + 127 124 mtu_set $swp3 10000 125 + defer mtu_restore $swp3 128 126 129 127 vlan_create $swp2 111 128 + defer vlan_destroy $swp2 111 129 + 130 130 vlan_create $swp3 111 131 + defer vlan_destroy $swp3 111 131 132 132 133 tc qdisc replace dev $swp3 root handle 3: tbf rate 1gbit \ 133 134 burst 128K limit 1G 135 + defer tc qdisc del dev $swp3 root handle 3: 136 + 134 137 tc qdisc replace dev $swp3 parent 3:3 handle 33: \ 135 138 prio bands 8 priomap 7 7 7 7 7 7 7 7 139 + defer tc qdisc del dev $swp3 parent 3:3 handle 33: 136 140 137 141 ip link add name br1 type bridge vlan_filtering 0 142 + defer ip link del dev br1 138 143 ip link set dev br1 addrgenmode none 139 144 ip link set dev br1 up 145 + 140 146 ip link set dev $swp1 master br1 147 + defer ip link set dev $swp1 nomaster 148 + 141 149 ip link set dev $swp3 master br1 150 + defer ip link set dev $swp3 nomaster 142 151 143 152 ip link add name br111 type bridge vlan_filtering 0 153 + defer ip link del dev br111 144 154 ip link set dev br111 addrgenmode none 145 155 ip link set dev br111 up 156 + 146 157 ip link set dev $swp2.111 master br111 158 + defer ip link set dev $swp2.111 nomaster 159 + 147 160 ip link set dev $swp3.111 master br111 161 + defer ip link set dev $swp3.111 nomaster 148 162 149 163 # Make sure that ingress quotas are smaller than egress so that there is 150 164 # room for both streams of traffic to be admitted to shared buffer. 151 165 devlink_port_pool_th_save $swp1 0 152 166 devlink_port_pool_th_set $swp1 0 5 167 + defer devlink_port_pool_th_restore $swp1 0 168 + 153 169 devlink_tc_bind_pool_th_save $swp1 0 ingress 154 170 devlink_tc_bind_pool_th_set $swp1 0 ingress 0 5 171 + defer devlink_tc_bind_pool_th_restore $swp1 0 ingress 155 172 156 173 devlink_port_pool_th_save $swp2 0 157 174 devlink_port_pool_th_set $swp2 0 5 175 + defer devlink_port_pool_th_restore $swp2 0 176 + 158 177 devlink_tc_bind_pool_th_save $swp2 1 ingress 159 178 devlink_tc_bind_pool_th_set $swp2 1 ingress 0 5 179 + defer devlink_tc_bind_pool_th_restore $swp2 1 ingress 160 180 161 181 devlink_port_pool_th_save $swp3 4 162 182 devlink_port_pool_th_set $swp3 4 12 163 - } 164 - 165 - switch_destroy() 166 - { 167 - devlink_port_pool_th_restore $swp3 4 168 - 169 - devlink_tc_bind_pool_th_restore $swp2 1 ingress 170 - devlink_port_pool_th_restore $swp2 0 171 - 172 - devlink_tc_bind_pool_th_restore $swp1 0 ingress 173 - devlink_port_pool_th_restore $swp1 0 174 - 175 - ip link del dev br111 176 - ip link del dev br1 177 - 178 - tc qdisc del dev $swp3 parent 3:3 handle 33: 179 - tc qdisc del dev $swp3 root handle 3: 180 - 181 - vlan_destroy $swp3 111 182 - vlan_destroy $swp2 111 183 - 184 - mtu_restore $swp3 185 - ip link set dev $swp3 down 186 - 187 - mtu_restore $swp2 188 - ip link set dev $swp2 down 189 - 190 - mtu_restore $swp1 191 - ip link set dev $swp1 down 183 + defer devlink_port_pool_th_restore $swp3 4 192 184 } 193 185 194 186 setup_prepare() ··· 197 205 h3mac=$(mac_get $h3) 198 206 199 207 vrf_prepare 208 + defer vrf_cleanup 200 209 201 210 h1_create 202 211 h2_create ··· 205 212 switch_create 206 213 } 207 214 208 - cleanup() 209 - { 210 - pre_cleanup 211 - 212 - switch_destroy 213 - h3_destroy 214 - h2_destroy 215 - h1_destroy 216 - 217 - vrf_cleanup 218 - } 219 - 220 215 ping_ipv4() 221 216 { 222 217 ping_test $h2 192.0.2.130 218 + } 219 + 220 + __run_uc_measure_rate() 221 + { 222 + local what=$1; shift 223 + local -a uc_rate 224 + 225 + start_traffic $h2.111 192.0.2.129 192.0.2.130 $h3mac 226 + defer stop_traffic $! 227 + 228 + uc_rate=($(measure_rate $swp2 $h3 rx_octets_prio_1 "$what")) 229 + check_err $? "Could not get high enough $what ingress rate" 230 + 231 + echo ${uc_rate[@]} 232 + } 233 + 234 + run_uc_measure_rate() 235 + { 236 + in_defer_scope __run_uc_measure_rate "$@" 223 237 } 224 238 225 239 test_mc_aware() 226 240 { 227 241 RET=0 228 242 229 - local -a uc_rate 230 - start_traffic $h2.111 192.0.2.129 192.0.2.130 $h3mac 231 - uc_rate=($(measure_rate $swp2 $h3 rx_octets_prio_1 "UC-only")) 232 - check_err $? "Could not get high enough UC-only ingress rate" 233 - stop_traffic 243 + local -a uc_rate=($(run_uc_measure_rate "UC-only")) 234 244 local ucth1=${uc_rate[1]} 235 245 236 246 start_traffic $h1 192.0.2.65 bc bc 247 + defer stop_traffic $! 237 248 238 249 local d0=$(date +%s) 239 250 local t0=$(ethtool_stats_get $h3 rx_octets_prio_0) 240 251 local u0=$(ethtool_stats_get $swp1 rx_octets_prio_0) 241 252 242 - local -a uc_rate_2 243 - start_traffic $h2.111 192.0.2.129 192.0.2.130 $h3mac 244 - uc_rate_2=($(measure_rate $swp2 $h3 rx_octets_prio_1 "UC+MC")) 245 - check_err $? "Could not get high enough UC+MC ingress rate" 246 - stop_traffic 253 + local -a uc_rate_2=($(run_uc_measure_rate "UC+MC")) 247 254 local ucth2=${uc_rate_2[1]} 248 255 249 256 local d1=$(date +%s) ··· 264 271 local interval=$((d1 - d0)) 265 272 local mc_ir=$(rate $u0 $u1 $interval) 266 273 local mc_er=$(rate $t0 $t1 $interval) 267 - 268 - stop_traffic 269 274 270 275 log_test "UC performance under MC overload" 271 276 ··· 288 297 RET=0 289 298 290 299 start_traffic $h2.111 192.0.2.129 192.0.2.130 $h3mac 300 + defer stop_traffic $! 291 301 292 302 local d0=$(date +%s) 293 303 local t0=$(ethtool_stats_get $h3 rx_octets_prio_1) ··· 317 325 318 326 ((attempts == passes)) 319 327 check_err $? 320 - 321 - stop_traffic 322 328 323 329 log_test "MC performance under UC overload" 324 330 echo " ingress UC throughput $(humanize ${uc_ir})"
+12 -14
tools/testing/selftests/drivers/net/mlxsw/sch_ets.sh
··· 21 21 # Create a bottleneck so that the DWRR process can kick in. 22 22 tc qdisc replace dev $swp2 root handle 3: tbf rate 1gbit \ 23 23 burst 128K limit 1G 24 + defer tc qdisc del dev $swp2 root handle 3: 24 25 25 26 ets_switch_create 26 27 ··· 31 30 # for the DWRR process. 32 31 devlink_port_pool_th_save $swp1 0 33 32 devlink_port_pool_th_set $swp1 0 12 33 + defer devlink_port_pool_th_restore $swp1 0 34 + 34 35 devlink_tc_bind_pool_th_save $swp1 0 ingress 35 36 devlink_tc_bind_pool_th_set $swp1 0 ingress 0 12 37 + defer devlink_tc_bind_pool_th_restore $swp1 0 ingress 38 + 36 39 devlink_port_pool_th_save $swp2 4 37 40 devlink_port_pool_th_set $swp2 4 12 41 + defer devlink_port_pool_th_restore $swp2 4 42 + 38 43 devlink_tc_bind_pool_th_save $swp2 7 egress 39 44 devlink_tc_bind_pool_th_set $swp2 7 egress 4 5 45 + defer devlink_tc_bind_pool_th_restore $swp2 7 egress 46 + 40 47 devlink_tc_bind_pool_th_save $swp2 6 egress 41 48 devlink_tc_bind_pool_th_set $swp2 6 egress 4 5 49 + defer devlink_tc_bind_pool_th_restore $swp2 6 egress 50 + 42 51 devlink_tc_bind_pool_th_save $swp2 5 egress 43 52 devlink_tc_bind_pool_th_set $swp2 5 egress 4 5 53 + defer devlink_tc_bind_pool_th_restore $swp2 5 egress 44 54 45 55 # Note: sch_ets_core.sh uses VLAN ingress-qos-map to assign packet 46 56 # priorities at $swp1 based on their 802.1p headers. ingress-qos-map is 47 57 # not offloaded by mlxsw as of this writing, but the mapping used is 48 58 # 1:1, which is the mapping currently hard-coded by the driver. 49 - } 50 - 51 - switch_destroy() 52 - { 53 - devlink_tc_bind_pool_th_restore $swp2 5 egress 54 - devlink_tc_bind_pool_th_restore $swp2 6 egress 55 - devlink_tc_bind_pool_th_restore $swp2 7 egress 56 - devlink_port_pool_th_restore $swp2 4 57 - devlink_tc_bind_pool_th_restore $swp1 0 ingress 58 - devlink_port_pool_th_restore $swp1 0 59 - 60 - ets_switch_destroy 61 - 62 - tc qdisc del dev $swp2 root handle 3: 63 59 } 64 60 65 61 # Callback from sch_ets_tests.sh
+95 -96
tools/testing/selftests/drivers/net/mlxsw/sch_red_core.sh
··· 75 75 source $lib_dir/devlink_lib.sh 76 76 source mlxsw_lib.sh 77 77 78 + stop_traffic_sleep() 79 + { 80 + local pid=$1; shift 81 + 82 + # Issuing a kill still leaves a bunch of packets lingering in the 83 + # buffers. This traffic then arrives at the point where a follow-up test 84 + # is already running, and can confuse the test. Therefore sleep after 85 + # stopping traffic to flush any leftover packets. 86 + stop_traffic "$pid" 87 + sleep 1 88 + } 89 + 78 90 ipaddr() 79 91 { 80 92 local host=$1; shift ··· 101 89 local host=$1; shift 102 90 103 91 simple_if_init $dev 92 + defer simple_if_fini $dev 93 + 104 94 mtu_set $dev 10000 95 + defer mtu_restore $dev 105 96 106 97 vlan_create $dev 10 v$dev $(ipaddr $host 10)/28 98 + defer vlan_destroy $dev 10 107 99 ip link set dev $dev.10 type vlan egress 0:0 108 100 109 101 vlan_create $dev 11 v$dev $(ipaddr $host 11)/28 102 + defer vlan_destroy $dev 11 110 103 ip link set dev $dev.11 type vlan egress 0:1 111 - } 112 - 113 - host_destroy() 114 - { 115 - local dev=$1; shift 116 - 117 - vlan_destroy $dev 11 118 - vlan_destroy $dev 10 119 - mtu_restore $dev 120 - simple_if_fini $dev 121 104 } 122 105 123 106 h1_create() ··· 120 113 host_create $h1 1 121 114 } 122 115 123 - h1_destroy() 124 - { 125 - host_destroy $h1 126 - } 127 - 128 116 h2_create() 129 117 { 130 118 host_create $h2 2 119 + 131 120 tc qdisc add dev $h2 clsact 121 + defer tc qdisc del dev $h2 clsact 132 122 133 123 # Some of the tests in this suite use multicast traffic. As this traffic 134 124 # enters BR2_10 resp. BR2_11, it is flooded to all other ports. Thus ··· 143 139 144 140 tc qdisc replace dev $h2 root handle 10: tbf rate 200mbit \ 145 141 burst 128K limit 1G 146 - } 147 - 148 - h2_destroy() 149 - { 150 - tc qdisc del dev $h2 root handle 10: 151 - tc qdisc del dev $h2 clsact 152 - host_destroy $h2 142 + defer tc qdisc del dev $h2 root handle 10: 153 143 } 154 144 155 145 h3_create() 156 146 { 157 147 host_create $h3 3 158 - } 159 - 160 - h3_destroy() 161 - { 162 - host_destroy $h3 163 148 } 164 149 165 150 switch_create() ··· 157 164 local vlan 158 165 159 166 ip link add dev br1_10 type bridge 167 + defer ip link del dev br1_10 168 + 160 169 ip link add dev br1_11 type bridge 170 + defer ip link del dev br1_11 161 171 162 172 ip link add dev br2_10 type bridge 173 + defer ip link del dev br2_10 174 + 163 175 ip link add dev br2_11 type bridge 176 + defer ip link del dev br2_11 164 177 165 178 for intf in $swp1 $swp2 $swp3 $swp4 $swp5; do 166 179 ip link set dev $intf up 180 + defer ip link set dev $intf down 181 + 167 182 mtu_set $intf 10000 183 + defer mtu_restore $intf 168 184 done 169 185 170 186 for intf in $swp1 $swp4; do 171 187 for vlan in 10 11; do 172 188 vlan_create $intf $vlan 189 + defer vlan_destroy $intf $vlan 190 + 173 191 ip link set dev $intf.$vlan master br1_$vlan 192 + defer ip link set dev $intf.$vlan nomaster 193 + 174 194 ip link set dev $intf.$vlan up 195 + defer ip link set dev $intf.$vlan up 175 196 done 176 197 done 177 198 178 199 for intf in $swp2 $swp3 $swp5; do 179 200 for vlan in 10 11; do 180 201 vlan_create $intf $vlan 202 + defer vlan_destroy $intf $vlan 203 + 181 204 ip link set dev $intf.$vlan master br2_$vlan 205 + defer ip link set dev $intf.$vlan nomaster 206 + 182 207 ip link set dev $intf.$vlan up 208 + defer ip link set dev $intf.$vlan up 183 209 done 184 210 done 185 211 ··· 213 201 for intf in $swp3 $swp4; do 214 202 tc qdisc replace dev $intf root handle 1: tbf rate 200mbit \ 215 203 burst 128K limit 1G 204 + defer tc qdisc del dev $intf root handle 1: 216 205 done 217 206 218 207 ip link set dev br1_10 up 208 + defer ip link set dev br1_10 down 209 + 219 210 ip link set dev br1_11 up 211 + defer ip link set dev br1_11 down 212 + 220 213 ip link set dev br2_10 up 214 + defer ip link set dev br2_10 down 215 + 221 216 ip link set dev br2_11 up 217 + defer ip link set dev br2_11 down 222 218 223 219 local size=$(devlink_pool_size_thtype 0 | cut -d' ' -f 1) 224 220 devlink_port_pool_th_save $swp3 8 225 221 devlink_port_pool_th_set $swp3 8 $size 226 - } 227 - 228 - switch_destroy() 229 - { 230 - local intf 231 - local vlan 232 - 233 - devlink_port_pool_th_restore $swp3 8 234 - 235 - ip link set dev br2_11 down 236 - ip link set dev br2_10 down 237 - ip link set dev br1_11 down 238 - ip link set dev br1_10 down 239 - 240 - for intf in $swp4 $swp3; do 241 - tc qdisc del dev $intf root handle 1: 242 - done 243 - 244 - for intf in $swp5 $swp3 $swp2 $swp4 $swp1; do 245 - for vlan in 11 10; do 246 - ip link set dev $intf.$vlan down 247 - ip link set dev $intf.$vlan nomaster 248 - vlan_destroy $intf $vlan 249 - done 250 - 251 - mtu_restore $intf 252 - ip link set dev $intf down 253 - done 254 - 255 - ip link del dev br2_11 256 - ip link del dev br2_10 257 - ip link del dev br1_11 258 - ip link del dev br1_10 222 + defer devlink_port_pool_th_restore $swp3 8 259 223 } 260 224 261 225 setup_prepare() ··· 251 263 h3_mac=$(mac_get $h3) 252 264 253 265 vrf_prepare 266 + defer vrf_cleanup 254 267 255 268 h1_create 256 269 h2_create 257 270 h3_create 258 271 switch_create 259 - } 260 - 261 - cleanup() 262 - { 263 - pre_cleanup 264 - 265 - switch_destroy 266 - h3_destroy 267 - h2_destroy 268 - h1_destroy 269 - 270 - vrf_cleanup 271 272 } 272 273 273 274 ping_ipv4() ··· 427 450 428 451 start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \ 429 452 $h3_mac tos=0x01 453 + defer stop_traffic_sleep $! 430 454 sleep 1 431 455 432 456 ecn_test_common "$name" "$get_nmarked" $vlan $limit ··· 439 461 build_backlog $vlan $((2 * limit)) udp >/dev/null 440 462 check_fail $? "UDP traffic went into backlog instead of being early-dropped" 441 463 log_test "TC $((vlan - 10)): $name backlog > limit: UDP early-dropped" 442 - 443 - stop_traffic 444 - sleep 1 445 464 } 446 465 447 466 do_ecn_test() ··· 446 471 local vlan=$1; shift 447 472 local limit=$1; shift 448 473 449 - __do_ecn_test get_nmarked "$vlan" "$limit" 474 + in_defer_scope \ 475 + __do_ecn_test get_nmarked "$vlan" "$limit" 450 476 } 451 477 452 478 do_ecn_test_perband() ··· 456 480 local limit=$1; shift 457 481 458 482 mlxsw_only_on_spectrum 3+ || return 459 - __do_ecn_test get_qdisc_nmarked "$vlan" "$limit" "per-band ECN" 483 + in_defer_scope \ 484 + __do_ecn_test get_qdisc_nmarked "$vlan" "$limit" "per-band ECN" 460 485 } 461 486 462 - do_ecn_nodrop_test() 487 + __do_ecn_nodrop_test() 463 488 { 464 489 local vlan=$1; shift 465 490 local limit=$1; shift ··· 468 491 469 492 start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \ 470 493 $h3_mac tos=0x01 494 + defer stop_traffic_sleep $! 471 495 sleep 1 472 496 473 497 ecn_test_common "$name" get_nmarked $vlan $limit ··· 480 502 build_backlog $vlan $((2 * limit)) udp >/dev/null 481 503 check_err $? "UDP traffic was early-dropped instead of getting into backlog" 482 504 log_test "TC $((vlan - 10)): $name backlog > limit: UDP not dropped" 483 - 484 - stop_traffic 485 - sleep 1 486 505 } 487 506 488 - do_red_test() 507 + do_ecn_nodrop_test() 508 + { 509 + in_defer_scope \ 510 + __do_ecn_nodrop_test "$@" 511 + } 512 + 513 + __do_red_test() 489 514 { 490 515 local vlan=$1; shift 491 516 local limit=$1; shift ··· 499 518 # is above limit. 500 519 start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \ 501 520 $h3_mac tos=0x01 521 + defer stop_traffic_sleep $! 502 522 503 523 # Pushing below the queue limit should work. 504 524 RET=0 ··· 521 539 ((-15 <= pct && pct <= 15)) 522 540 check_err $? "backlog $backlog / $limit expected <= 15% distance" 523 541 log_test "TC $((vlan - 10)): RED backlog > limit" 524 - 525 - stop_traffic 526 - sleep 1 527 542 } 528 543 529 - do_mc_backlog_test() 544 + do_red_test() 545 + { 546 + in_defer_scope \ 547 + __do_red_test "$@" 548 + } 549 + 550 + __do_mc_backlog_test() 530 551 { 531 552 local vlan=$1; shift 532 553 local limit=$1; shift ··· 539 554 RET=0 540 555 541 556 start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) bc 557 + defer stop_traffic_sleep $! 558 + 542 559 start_tcp_traffic $h2.$vlan $(ipaddr 2 $vlan) $(ipaddr 3 $vlan) bc 560 + defer stop_traffic_sleep $! 543 561 544 562 qbl=$(busywait 5000 until_counter_is ">= 500000" \ 545 563 get_qdisc_backlog $vlan) ··· 555 567 get_mc_transmit_queue $vlan) 556 568 check_err $? "MC backlog reported by qdisc not visible in ethtool" 557 569 558 - stop_traffic 559 - stop_traffic 560 - 561 570 log_test "TC $((vlan - 10)): Qdisc reports MC backlog" 562 571 } 563 572 564 - do_mark_test() 573 + do_mc_backlog_test() 574 + { 575 + in_defer_scope \ 576 + __do_mc_backlog_test "$@" 577 + } 578 + 579 + __do_mark_test() 565 580 { 566 581 local vlan=$1; shift 567 582 local limit=$1; shift ··· 579 588 580 589 start_tcp_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) \ 581 590 $h3_mac tos=0x01 591 + defer stop_traffic_sleep $! 582 592 583 593 # Create a bit of a backlog and observe no mirroring due to marks. 584 594 qevent_rule_install_$subtest ··· 609 617 else 610 618 log_test "TC $((vlan - 10)): marked packets $subtest'd" 611 619 fi 612 - 613 - stop_traffic 614 - sleep 1 615 620 } 616 621 617 - do_drop_test() 622 + do_mark_test() 623 + { 624 + in_defer_scope \ 625 + __do_mark_test "$@" 626 + } 627 + 628 + __do_drop_test() 618 629 { 619 630 local vlan=$1; shift 620 631 local limit=$1; shift ··· 632 637 RET=0 633 638 634 639 start_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 3 $vlan) $h3_mac 640 + defer stop_traffic_sleep $! 635 641 636 642 # Create a bit of a backlog and observe no mirroring due to drops. 637 643 qevent_rule_install_$subtest ··· 667 671 check_fail $? "$((now - base)) spurious packets observed after uninstall" 668 672 669 673 log_test "TC $((vlan - 10)): ${trigger}ped packets $subtest'd" 674 + } 670 675 671 - stop_traffic 672 - sleep 1 676 + do_drop_test() 677 + { 678 + in_defer_scope \ 679 + __do_drop_test "$@" 673 680 } 674 681 675 682 qevent_rule_install_mirror()
+8 -16
tools/testing/selftests/drivers/net/mlxsw/sch_red_ets.sh
··· 80 80 ecn_test() 81 81 { 82 82 install_qdisc ecn 83 + defer uninstall_qdisc 83 84 84 85 do_ecn_test 10 $BACKLOG1 85 86 do_ecn_test 11 $BACKLOG2 86 - 87 - uninstall_qdisc 88 87 } 89 88 90 89 ecn_test_perband() 91 90 { 92 91 install_qdisc ecn 92 + defer uninstall_qdisc 93 93 94 94 do_ecn_test_perband 10 $BACKLOG1 95 95 do_ecn_test_perband 11 $BACKLOG2 96 - 97 - uninstall_qdisc 98 96 } 99 97 100 98 ecn_nodrop_test() 101 99 { 102 100 install_qdisc ecn nodrop 101 + defer uninstall_qdisc 103 102 104 103 do_ecn_nodrop_test 10 $BACKLOG1 105 104 do_ecn_nodrop_test 11 $BACKLOG2 106 - 107 - uninstall_qdisc 108 105 } 109 106 110 107 red_test() 111 108 { 112 109 install_qdisc 110 + defer uninstall_qdisc 113 111 114 112 # Make sure that we get the non-zero value if there is any. 115 113 local cur=$(busywait 1100 until_counter_is "> 0" \ ··· 118 120 119 121 do_red_test 10 $BACKLOG1 120 122 do_red_test 11 $BACKLOG2 121 - 122 - uninstall_qdisc 123 123 } 124 124 125 125 mc_backlog_test() 126 126 { 127 127 install_qdisc 128 + defer uninstall_qdisc 128 129 129 130 # Note that the backlog numbers here do not correspond to RED 130 131 # configuration, but are arbitrary. 131 132 do_mc_backlog_test 10 $BACKLOG1 132 133 do_mc_backlog_test 11 $BACKLOG2 133 - 134 - uninstall_qdisc 135 134 } 136 135 137 136 red_mirror_test() 138 137 { 139 138 install_qdisc qevent early_drop block 10 139 + defer uninstall_qdisc 140 140 141 141 do_drop_mirror_test 10 $BACKLOG1 early_drop 142 142 do_drop_mirror_test 11 $BACKLOG2 early_drop 143 - 144 - uninstall_qdisc 145 143 } 146 144 147 145 red_trap_test() 148 146 { 149 147 install_qdisc qevent early_drop block 10 148 + defer uninstall_qdisc 150 149 151 150 do_drop_trap_test 10 $BACKLOG1 early_drop 152 151 do_drop_trap_test 11 $BACKLOG2 early_drop 153 - 154 - uninstall_qdisc 155 152 } 156 153 157 154 ecn_mirror_test() 158 155 { 159 156 install_qdisc ecn qevent mark block 10 157 + defer uninstall_qdisc 160 158 161 159 do_mark_mirror_test 10 $BACKLOG1 162 160 do_mark_mirror_test 11 $BACKLOG2 163 - 164 - uninstall_qdisc 165 161 } 166 162 167 163 bail_on_lldpad "configure DCB" "configure Qdiscs"
+12 -6
tools/testing/selftests/drivers/net/mlxsw/sch_red_root.sh
··· 32 32 ecn_test() 33 33 { 34 34 install_qdisc ecn 35 + defer uninstall_qdisc 36 + 35 37 do_ecn_test 10 $BACKLOG 36 - uninstall_qdisc 37 38 } 38 39 39 40 ecn_test_perband() 40 41 { 41 42 install_qdisc ecn 43 + defer uninstall_qdisc 44 + 42 45 do_ecn_test_perband 10 $BACKLOG 43 - uninstall_qdisc 44 46 } 45 47 46 48 ecn_nodrop_test() 47 49 { 48 50 install_qdisc ecn nodrop 51 + defer uninstall_qdisc 52 + 49 53 do_ecn_nodrop_test 10 $BACKLOG 50 - uninstall_qdisc 51 54 } 52 55 53 56 red_test() 54 57 { 55 58 install_qdisc 59 + defer uninstall_qdisc 60 + 56 61 do_red_test 10 $BACKLOG 57 - uninstall_qdisc 58 62 } 59 63 60 64 mc_backlog_test() 61 65 { 62 66 install_qdisc 67 + defer uninstall_qdisc 68 + 63 69 # Note that the backlog value here does not correspond to RED 64 70 # configuration, but is arbitrary. 65 71 do_mc_backlog_test 10 $BACKLOG 66 - uninstall_qdisc 67 72 } 68 73 69 74 red_mirror_test() 70 75 { 71 76 install_qdisc qevent early_drop block 10 77 + defer uninstall_qdisc 78 + 72 79 do_drop_mirror_test 10 $BACKLOG 73 - uninstall_qdisc 74 80 } 75 81 76 82 bail_on_lldpad "configure DCB" "configure Qdiscs"
+11 -2
tools/testing/selftests/net/forwarding/lib.sh
··· 1403 1403 local current_test 1404 1404 1405 1405 for current_test in ${TESTS:-$ALL_TESTS}; do 1406 - $current_test 1406 + in_defer_scope \ 1407 + $current_test 1407 1408 done 1409 + } 1410 + 1411 + cleanup() 1412 + { 1413 + pre_cleanup 1414 + defer_scopes_cleanup 1408 1415 } 1409 1416 1410 1417 multipath_eval() ··· 1768 1761 1769 1762 stop_traffic() 1770 1763 { 1764 + local pid=${1-%%}; shift 1765 + 1771 1766 # Suppress noise from killing mausezahn. 1772 - { kill %% && wait %%; } 2>/dev/null 1767 + { kill $pid && wait $pid; } 2>/dev/null 1773 1768 } 1774 1769 1775 1770 declare -A cappid
+1 -6
tools/testing/selftests/net/forwarding/sch_ets.sh
··· 24 24 # Create a bottleneck so that the DWRR process can kick in. 25 25 tc qdisc add dev $swp2 root handle 1: tbf \ 26 26 rate 1Gbit burst 1Mbit latency 100ms 27 + defer tc qdisc del dev $swp2 root 27 28 PARENT="parent 1:" 28 - } 29 - 30 - switch_destroy() 31 - { 32 - ets_switch_destroy 33 - tc qdisc del dev $swp2 root 34 29 } 35 30 36 31 # Callback from sch_ets_tests.sh
+30 -51
tools/testing/selftests/net/forwarding/sch_ets_core.sh
··· 166 166 local i; 167 167 168 168 simple_if_init $h1 169 + defer simple_if_fini $h1 170 + 169 171 mtu_set $h1 9900 172 + defer mtu_restore $h1 173 + 170 174 for i in {0..2}; do 171 175 vlan_create $h1 1$i v$h1 $(sip $i)/28 176 + defer vlan_destroy $h1 1$i 172 177 ip link set dev $h1.1$i type vlan egress 0:$i 173 178 done 174 - } 175 - 176 - h1_destroy() 177 - { 178 - local i 179 - 180 - for i in {0..2}; do 181 - vlan_destroy $h1 1$i 182 - done 183 - mtu_restore $h1 184 - simple_if_fini $h1 185 179 } 186 180 187 181 h2_create() ··· 183 189 local i 184 190 185 191 simple_if_init $h2 192 + defer simple_if_fini $h2 193 + 186 194 mtu_set $h2 9900 195 + defer mtu_restore $h2 196 + 187 197 for i in {0..2}; do 188 198 vlan_create $h2 1$i v$h2 $(dip $i)/28 199 + defer vlan_destroy $h2 1$i 189 200 done 190 - } 191 - 192 - h2_destroy() 193 - { 194 - local i 195 - 196 - for i in {0..2}; do 197 - vlan_destroy $h2 1$i 198 - done 199 - mtu_restore $h2 200 - simple_if_fini $h2 201 201 } 202 202 203 203 ets_switch_create() ··· 199 211 local i 200 212 201 213 ip link set dev $swp1 up 214 + defer ip link set dev $swp1 down 215 + 202 216 mtu_set $swp1 9900 217 + defer mtu_restore $swp1 203 218 204 219 ip link set dev $swp2 up 220 + defer ip link set dev $swp2 down 221 + 205 222 mtu_set $swp2 9900 223 + defer mtu_restore $swp2 206 224 207 225 for i in {0..2}; do 208 226 vlan_create $swp1 1$i 227 + defer vlan_destroy $swp1 1$i 209 228 ip link set dev $swp1.1$i type vlan ingress 0:0 1:1 2:2 210 229 211 230 vlan_create $swp2 1$i 231 + defer vlan_destroy $swp2 1$i 212 232 213 233 ip link add dev br1$i type bridge 234 + defer ip link del dev br1$i 235 + 214 236 ip link set dev $swp1.1$i master br1$i 237 + defer ip link set dev $swp1.1$i nomaster 238 + 215 239 ip link set dev $swp2.1$i master br1$i 240 + defer ip link set dev $swp2.1$i nomaster 216 241 217 242 ip link set dev br1$i up 243 + defer ip link set dev br1$i down 244 + 218 245 ip link set dev $swp1.1$i up 246 + defer ip link set dev $swp1.1$i down 247 + 219 248 ip link set dev $swp2.1$i up 220 - done 221 - } 222 - 223 - ets_switch_destroy() 224 - { 225 - local i 226 - 227 - ets_delete_qdisc 228 - 229 - for i in {0..2}; do 230 - ip link del dev br1$i 231 - vlan_destroy $swp2 1$i 232 - vlan_destroy $swp1 1$i 249 + defer ip link set dev $swp2.1$i down 233 250 done 234 251 235 - mtu_restore $swp2 236 - ip link set dev $swp2 down 237 - 238 - mtu_restore $swp1 239 - ip link set dev $swp1 down 252 + defer ets_delete_qdisc 240 253 } 241 254 242 255 setup_prepare() ··· 252 263 hut=$h2 253 264 254 265 vrf_prepare 266 + defer vrf_cleanup 255 267 256 268 h1_create 257 269 h2_create 258 270 switch_create 259 - } 260 - 261 - cleanup() 262 - { 263 - pre_cleanup 264 - 265 - switch_destroy 266 - h2_destroy 267 - h1_destroy 268 - 269 - vrf_cleanup 270 271 } 271 272 272 273 ping_ipv4()
+7 -7
tools/testing/selftests/net/forwarding/sch_ets_tests.sh
··· 90 90 91 91 for stream in ${streams[@]}; do 92 92 ets_start_traffic $stream 93 + defer stop_traffic $! 93 94 done 94 95 95 96 sleep 10 ··· 121 120 ${d[0]} ${d[$i]} 122 121 fi 123 122 done 124 - 125 - for stream in ${streams[@]}; do 126 - stop_traffic 127 - done 128 123 } 129 124 130 125 ets_dwrr_test_012() 131 126 { 132 - __ets_dwrr_test 0 1 2 127 + in_defer_scope \ 128 + __ets_dwrr_test 0 1 2 133 129 } 134 130 135 131 ets_dwrr_test_01() 136 132 { 137 - __ets_dwrr_test 0 1 133 + in_defer_scope \ 134 + __ets_dwrr_test 0 1 138 135 } 139 136 140 137 ets_dwrr_test_12() 141 138 { 142 - __ets_dwrr_test 1 2 139 + in_defer_scope \ 140 + __ets_dwrr_test 1 2 143 141 } 144 142 145 143 ets_qdisc_setup()
+37 -66
tools/testing/selftests/net/forwarding/sch_red.sh
··· 53 53 h1_create() 54 54 { 55 55 simple_if_init $h1 192.0.2.1/28 56 + defer simple_if_fini $h1 192.0.2.1/28 57 + 56 58 mtu_set $h1 10000 59 + defer mtu_restore $h1 60 + 57 61 tc qdisc replace dev $h1 root handle 1: tbf \ 58 62 rate 10Mbit burst 10K limit 1M 59 - } 60 - 61 - h1_destroy() 62 - { 63 - tc qdisc del dev $h1 root 64 - mtu_restore $h1 65 - simple_if_fini $h1 192.0.2.1/28 63 + defer tc qdisc del dev $h1 root 66 64 } 67 65 68 66 h2_create() 69 67 { 70 68 simple_if_init $h2 192.0.2.2/28 71 - mtu_set $h2 10000 72 - } 69 + defer simple_if_fini $h2 192.0.2.2/28 73 70 74 - h2_destroy() 75 - { 76 - mtu_restore $h2 77 - simple_if_fini $h2 192.0.2.2/28 71 + mtu_set $h2 10000 72 + defer mtu_restore $h2 78 73 } 79 74 80 75 h3_create() 81 76 { 82 77 simple_if_init $h3 192.0.2.3/28 83 - mtu_set $h3 10000 84 - } 78 + defer simple_if_fini $h3 192.0.2.3/28 85 79 86 - h3_destroy() 87 - { 88 - mtu_restore $h3 89 - simple_if_fini $h3 192.0.2.3/28 80 + mtu_set $h3 10000 81 + defer mtu_restore $h3 90 82 } 91 83 92 84 switch_create() 93 85 { 94 86 ip link add dev br up type bridge 87 + defer ip link del dev br 88 + 95 89 ip link set dev $swp1 up master br 90 + defer ip link set dev $swp1 down nomaster 91 + 96 92 ip link set dev $swp2 up master br 93 + defer ip link set dev $swp2 down nomaster 94 + 97 95 ip link set dev $swp3 up master br 96 + defer ip link set dev $swp3 down nomaster 98 97 99 98 mtu_set $swp1 10000 99 + defer mtu_restore $h1 100 + 100 101 mtu_set $swp2 10000 102 + defer mtu_restore $h2 103 + 101 104 mtu_set $swp3 10000 105 + defer mtu_restore $h3 102 106 103 107 tc qdisc replace dev $swp3 root handle 1: tbf \ 104 108 rate 10Mbit burst 10K limit 1M 109 + defer tc qdisc del dev $swp3 root 110 + 105 111 ip link add name _drop_test up type dummy 106 - } 107 - 108 - switch_destroy() 109 - { 110 - ip link del dev _drop_test 111 - tc qdisc del dev $swp3 root 112 - 113 - mtu_restore $h3 114 - mtu_restore $h2 115 - mtu_restore $h1 116 - 117 - ip link set dev $swp3 down nomaster 118 - ip link set dev $swp2 down nomaster 119 - ip link set dev $swp1 down nomaster 120 - ip link del dev br 112 + defer ip link del dev _drop_test 121 113 } 122 114 123 115 setup_prepare() ··· 126 134 h3_mac=$(mac_get $h3) 127 135 128 136 vrf_prepare 137 + defer vrf_cleanup 129 138 130 139 h1_create 131 140 h2_create 132 141 h3_create 133 142 switch_create 134 - } 135 - 136 - cleanup() 137 - { 138 - pre_cleanup 139 - 140 - switch_destroy 141 - h3_destroy 142 - h2_destroy 143 - h1_destroy 144 - 145 - vrf_cleanup 146 143 } 147 144 148 145 ping_ipv4() ··· 268 287 269 288 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \ 270 289 -a own -b $h3_mac -t tcp -q tos=0x01 & 290 + defer stop_traffic $! 271 291 sleep 1 272 292 273 293 ecn_test_common "$name" $limit ··· 280 298 build_backlog $((2 * limit)) udp >/dev/null 281 299 check_fail $? "UDP traffic went into backlog instead of being early-dropped" 282 300 log_test "$name backlog > limit: UDP early-dropped" 283 - 284 - stop_traffic 285 - sleep 1 286 301 } 287 302 288 303 do_ecn_nodrop_test() ··· 289 310 290 311 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \ 291 312 -a own -b $h3_mac -t tcp -q tos=0x01 & 313 + defer stop_traffic $! 292 314 sleep 1 293 315 294 316 ecn_test_common "$name" $limit ··· 301 321 build_backlog $((2 * limit)) udp >/dev/null 302 322 check_err $? "UDP traffic was early-dropped instead of getting into backlog" 303 323 log_test "$name backlog > limit: UDP not dropped" 304 - 305 - stop_traffic 306 - sleep 1 307 324 } 308 325 309 326 do_red_test() ··· 313 336 # is above limit. 314 337 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \ 315 338 -a own -b $h3_mac -t tcp -q tos=0x01 & 339 + defer stop_traffic $! 316 340 317 341 # Pushing below the queue limit should work. 318 342 RET=0 ··· 330 352 pct=$(check_marking "== 0") 331 353 check_err $? "backlog $backlog / $limit Got $pct% marked packets, expected == 0." 332 354 log_test "RED backlog > limit" 333 - 334 - stop_traffic 335 - sleep 1 336 355 } 337 356 338 357 do_red_qevent_test() ··· 344 369 345 370 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \ 346 371 -a own -b $h3_mac -t udp -q & 372 + defer stop_traffic $! 347 373 sleep 1 348 374 349 375 tc filter add block 10 pref 1234 handle 102 matchall skip_hw \ ··· 372 396 check_err $? "Dropped packets still observed: 0 expected, $((now - base)) seen" 373 397 374 398 log_test "RED early_dropped packets mirrored" 375 - 376 - stop_traffic 377 - sleep 1 378 399 } 379 400 380 401 do_ecn_qevent_test() ··· 383 410 384 411 $MZ $h1 -p $PKTSZ -A 192.0.2.1 -B 192.0.2.3 -c 0 \ 385 412 -a own -b $h3_mac -t tcp -q tos=0x01 & 413 + defer stop_traffic $! 386 414 sleep 1 387 415 388 416 tc filter add block 10 pref 1234 handle 102 matchall skip_hw \ ··· 402 428 tc filter del block 10 pref 1234 handle 102 matchall 403 429 404 430 log_test "ECN marked packets mirrored" 405 - 406 - stop_traffic 407 - sleep 1 408 431 } 409 432 410 433 install_qdisc() ··· 422 451 ecn_test() 423 452 { 424 453 install_qdisc ecn 454 + defer uninstall_qdisc 425 455 xfail_on_slow do_ecn_test $BACKLOG 426 - uninstall_qdisc 427 456 } 428 457 429 458 ecn_nodrop_test() 430 459 { 431 460 install_qdisc ecn nodrop 461 + defer uninstall_qdisc 432 462 xfail_on_slow do_ecn_nodrop_test $BACKLOG 433 - uninstall_qdisc 434 463 } 435 464 436 465 red_test() 437 466 { 438 467 install_qdisc 468 + defer uninstall_qdisc 439 469 xfail_on_slow do_red_test $BACKLOG 440 - uninstall_qdisc 441 470 } 442 471 443 472 red_qevent_test() 444 473 { 445 474 install_qdisc qevent early_drop block 10 475 + defer uninstall_qdisc 446 476 xfail_on_slow do_red_qevent_test $BACKLOG 447 - uninstall_qdisc 448 477 } 449 478 450 479 ecn_qevent_test() 451 480 { 452 481 install_qdisc ecn qevent mark block 10 482 + defer uninstall_qdisc 453 483 xfail_on_slow do_ecn_qevent_test $BACKLOG 454 - uninstall_qdisc 455 484 } 456 485 457 486 trap cleanup EXIT
+30 -61
tools/testing/selftests/net/forwarding/sch_tbf_core.sh
··· 60 60 local host=$1; shift 61 61 62 62 simple_if_init $dev 63 + defer simple_if_fini $dev 64 + 63 65 mtu_set $dev 10000 66 + defer mtu_restore $dev 64 67 65 68 vlan_create $dev 10 v$dev $(ipaddr $host 10)/28 69 + defer vlan_destroy $dev 10 66 70 ip link set dev $dev.10 type vlan egress 0:0 67 71 68 72 vlan_create $dev 11 v$dev $(ipaddr $host 11)/28 73 + defer vlan_destroy $dev 11 69 74 ip link set dev $dev.11 type vlan egress 0:1 70 - } 71 - 72 - host_destroy() 73 - { 74 - local dev=$1; shift 75 - 76 - vlan_destroy $dev 11 77 - vlan_destroy $dev 10 78 - mtu_restore $dev 79 - simple_if_fini $dev 80 75 } 81 76 82 77 h1_create() ··· 79 84 host_create $h1 1 80 85 } 81 86 82 - h1_destroy() 83 - { 84 - host_destroy $h1 85 - } 86 - 87 87 h2_create() 88 88 { 89 89 host_create $h2 2 90 90 91 91 tc qdisc add dev $h2 clsact 92 + defer tc qdisc del dev $h2 clsact 93 + 92 94 tc filter add dev $h2 ingress pref 1010 prot 802.1q \ 93 95 flower $TCFLAGS vlan_id 10 action pass 94 96 tc filter add dev $h2 ingress pref 1011 prot 802.1q \ 95 97 flower $TCFLAGS vlan_id 11 action pass 96 - } 97 - 98 - h2_destroy() 99 - { 100 - tc qdisc del dev $h2 clsact 101 - host_destroy $h2 102 98 } 103 99 104 100 switch_create() ··· 98 112 local vlan 99 113 100 114 ip link add dev br10 type bridge 115 + defer ip link del dev br10 116 + 101 117 ip link add dev br11 type bridge 118 + defer ip link del dev br11 102 119 103 120 for intf in $swp1 $swp2; do 104 121 ip link set dev $intf up 122 + defer ip link set dev $intf down 123 + 105 124 mtu_set $intf 10000 125 + defer mtu_restore $intf 106 126 107 127 for vlan in 10 11; do 108 128 vlan_create $intf $vlan 129 + defer vlan_destroy $intf $vlan 130 + 109 131 ip link set dev $intf.$vlan master br$vlan 132 + defer ip link set dev $intf.$vlan nomaster 133 + 110 134 ip link set dev $intf.$vlan up 135 + defer ip link set dev $intf.$vlan down 111 136 done 112 137 done 113 138 ··· 127 130 done 128 131 129 132 ip link set dev br10 up 133 + defer ip link set dev br10 down 134 + 130 135 ip link set dev br11 up 131 - } 132 - 133 - switch_destroy() 134 - { 135 - local intf 136 - local vlan 137 - 138 - # A test may have been interrupted mid-run, with Qdisc installed. Delete 139 - # it here. 140 - tc qdisc del dev $swp2 root 2>/dev/null 141 - 142 - ip link set dev br11 down 143 - ip link set dev br10 down 144 - 145 - for intf in $swp2 $swp1; do 146 - for vlan in 11 10; do 147 - ip link set dev $intf.$vlan down 148 - ip link set dev $intf.$vlan nomaster 149 - vlan_destroy $intf $vlan 150 - done 151 - 152 - mtu_restore $intf 153 - ip link set dev $intf down 154 - done 155 - 156 - ip link del dev br11 157 - ip link del dev br10 136 + defer ip link set dev br11 down 158 137 } 159 138 160 139 setup_prepare() ··· 150 177 h2_mac=$(mac_get $h2) 151 178 152 179 vrf_prepare 180 + defer vrf_cleanup 153 181 154 182 h1_create 155 183 h2_create 156 184 switch_create 157 - } 158 - 159 - cleanup() 160 - { 161 - pre_cleanup 162 - 163 - switch_destroy 164 - h2_destroy 165 - h1_destroy 166 - 167 - vrf_cleanup 168 185 } 169 186 170 187 ping_ipv4() ··· 170 207 tc_rule_stats_get $h2 10$vlan ingress .bytes 171 208 } 172 209 173 - do_tbf_test() 210 + __tbf_test() 174 211 { 175 212 local vlan=$1; shift 176 213 local mbit=$1; shift 177 214 178 215 start_traffic $h1.$vlan $(ipaddr 1 $vlan) $(ipaddr 2 $vlan) $h2_mac 216 + defer stop_traffic $! 179 217 sleep 5 # Wait for the burst to dwindle 180 218 181 219 local t2=$(busywait_for_counter 1000 +1 tbf_get_counter $vlan) 182 220 sleep 10 183 221 local t3=$(tbf_get_counter $vlan) 184 - stop_traffic 185 222 186 223 RET=0 187 224 ··· 193 230 xfail_on_slow check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-5%." 194 231 195 232 log_test "TC $((vlan - 10)): TBF rate ${mbit}Mbit" 233 + } 234 + 235 + do_tbf_test() 236 + { 237 + in_defer_scope \ 238 + __tbf_test "$@" 196 239 }
+4 -3
tools/testing/selftests/net/forwarding/sch_tbf_etsprio.sh
··· 30 30 # This test is used for both ETS and PRIO. Even though we only need two 31 31 # bands, PRIO demands a minimum of three. 32 32 tc qdisc add dev $swp2 root handle 10: $QDISC 3 priomap 2 1 0 33 + defer tc qdisc del dev $swp2 root 34 + 33 35 tbf_test_one 128K 34 - tc qdisc del dev $swp2 root 35 36 } 36 37 37 38 tbf_root_test() ··· 43 42 44 43 tc qdisc replace dev $swp2 root handle 1: \ 45 44 tbf rate 400Mbit burst $bs limit 1M 45 + defer tc qdisc del dev $swp2 root 46 + 46 47 tc qdisc replace dev $swp2 parent 1:1 handle 10: \ 47 48 $QDISC 3 priomap 2 1 0 48 49 tc qdisc replace dev $swp2 parent 10:3 handle 103: \ ··· 56 53 57 54 do_tbf_test 10 400 $bs 58 55 do_tbf_test 11 400 $bs 59 - 60 - tc qdisc del dev $swp2 root 61 56 } 62 57 63 58 if type -t sch_tbf_pre_hook >/dev/null; then
+2 -1
tools/testing/selftests/net/forwarding/sch_tbf_root.sh
··· 14 14 15 15 tc qdisc replace dev $swp2 root handle 108: tbf \ 16 16 rate 400Mbit burst $bs limit 1M 17 + defer tc qdisc del dev $swp2 root 18 + 17 19 do_tbf_test 10 400 $bs 18 20 } 19 21 20 22 tbf_test() 21 23 { 22 24 tbf_test_one 128K 23 - tc qdisc del dev $swp2 root 24 25 } 25 26 26 27 if type -t sch_tbf_pre_hook >/dev/null; then
+3
tools/testing/selftests/net/lib.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 + net_dir=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 5 + source "$net_dir/lib/sh/defer.sh" 6 + 4 7 ############################################################################## 5 8 # Defines 6 9
+1 -1
tools/testing/selftests/net/lib/Makefile
··· 10 10 11 11 TEST_GEN_FILES += csum 12 12 13 - TEST_INCLUDES := $(wildcard py/*.py) 13 + TEST_INCLUDES := $(wildcard py/*.py sh/*.sh) 14 14 15 15 include ../../lib.mk
+115
tools/testing/selftests/net/lib/sh/defer.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # map[(scope_id,track,cleanup_id) -> cleanup_command] 5 + # track={d=default | p=priority} 6 + declare -A __DEFER__JOBS 7 + 8 + # map[(scope_id,track) -> # cleanup_commands] 9 + declare -A __DEFER__NJOBS 10 + 11 + # scope_id of the topmost scope. 12 + __DEFER__SCOPE_ID=0 13 + 14 + __defer__ndefer_key() 15 + { 16 + local track=$1; shift 17 + 18 + echo $__DEFER__SCOPE_ID,$track 19 + } 20 + 21 + __defer__defer_key() 22 + { 23 + local track=$1; shift 24 + local defer_ix=$1; shift 25 + 26 + echo $__DEFER__SCOPE_ID,$track,$defer_ix 27 + } 28 + 29 + __defer__ndefers() 30 + { 31 + local track=$1; shift 32 + 33 + echo ${__DEFER__NJOBS[$(__defer__ndefer_key $track)]} 34 + } 35 + 36 + __defer__run() 37 + { 38 + local track=$1; shift 39 + local defer_ix=$1; shift 40 + local defer_key=$(__defer__defer_key $track $defer_ix) 41 + 42 + ${__DEFER__JOBS[$defer_key]} 43 + unset __DEFER__JOBS[$defer_key] 44 + } 45 + 46 + __defer__schedule() 47 + { 48 + local track=$1; shift 49 + local ndefers=$(__defer__ndefers $track) 50 + local ndefers_key=$(__defer__ndefer_key $track) 51 + local defer_key=$(__defer__defer_key $track $ndefers) 52 + local defer="$@" 53 + 54 + __DEFER__JOBS[$defer_key]="$defer" 55 + __DEFER__NJOBS[$ndefers_key]=$((ndefers + 1)) 56 + } 57 + 58 + __defer__scope_wipe() 59 + { 60 + __DEFER__NJOBS[$(__defer__ndefer_key d)]=0 61 + __DEFER__NJOBS[$(__defer__ndefer_key p)]=0 62 + } 63 + 64 + defer_scope_push() 65 + { 66 + ((__DEFER__SCOPE_ID++)) 67 + __defer__scope_wipe 68 + } 69 + 70 + defer_scope_pop() 71 + { 72 + local defer_ix 73 + 74 + for ((defer_ix=$(__defer__ndefers p); defer_ix-->0; )); do 75 + __defer__run p $defer_ix 76 + done 77 + 78 + for ((defer_ix=$(__defer__ndefers d); defer_ix-->0; )); do 79 + __defer__run d $defer_ix 80 + done 81 + 82 + __defer__scope_wipe 83 + ((__DEFER__SCOPE_ID--)) 84 + } 85 + 86 + defer() 87 + { 88 + __defer__schedule d "$@" 89 + } 90 + 91 + defer_prio() 92 + { 93 + __defer__schedule p "$@" 94 + } 95 + 96 + defer_scopes_cleanup() 97 + { 98 + while ((__DEFER__SCOPE_ID >= 0)); do 99 + defer_scope_pop 100 + done 101 + } 102 + 103 + in_defer_scope() 104 + { 105 + local ret 106 + 107 + defer_scope_push 108 + "$@" 109 + ret=$? 110 + defer_scope_pop 111 + 112 + return $ret 113 + } 114 + 115 + __defer__scope_wipe