1*4882a593Smuzhiyun#!/bin/bash 2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# Copyright (c) 2019 Facebook 5*4882a593Smuzhiyun# 6*4882a593Smuzhiyun# This program is free software; you can redistribute it and/or 7*4882a593Smuzhiyun# modify it under the terms of version 2 of the GNU General Public 8*4882a593Smuzhiyun# License as published by the Free Software Foundation. 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunUsage() { 11*4882a593Smuzhiyun echo "Script for testing HBM (Host Bandwidth Manager) framework." 12*4882a593Smuzhiyun echo "It creates a cgroup to use for testing and load a BPF program to limit" 13*4882a593Smuzhiyun echo "egress or ingress bandwidht. It then uses iperf3 or netperf to create" 14*4882a593Smuzhiyun echo "loads. The output is the goodput in Mbps (unless -D was used)." 15*4882a593Smuzhiyun echo "" 16*4882a593Smuzhiyun echo "USAGE: $name [out] [-b=<prog>|--bpf=<prog>] [-c=<cc>|--cc=<cc>]" 17*4882a593Smuzhiyun echo " [-D] [-d=<delay>|--delay=<delay>] [--debug] [-E] [--edt]" 18*4882a593Smuzhiyun echo " [-f=<#flows>|--flows=<#flows>] [-h] [-i=<id>|--id=<id >]" 19*4882a593Smuzhiyun echo " [-l] [-N] [--no_cn] [-p=<port>|--port=<port>] [-P]" 20*4882a593Smuzhiyun echo " [-q=<qdisc>] [-R] [-s=<server>|--server=<server]" 21*4882a593Smuzhiyun echo " [-S|--stats] -t=<time>|--time=<time>] [-w] [cubic|dctcp]" 22*4882a593Smuzhiyun echo " Where:" 23*4882a593Smuzhiyun echo " out egress (default)" 24*4882a593Smuzhiyun echo " -b or --bpf BPF program filename to load and attach." 25*4882a593Smuzhiyun echo " Default is hbm_out_kern.o for egress," 26*4882a593Smuzhiyun echo " -c or -cc TCP congestion control (cubic or dctcp)" 27*4882a593Smuzhiyun echo " --debug print BPF trace buffer" 28*4882a593Smuzhiyun echo " -d or --delay add a delay in ms using netem" 29*4882a593Smuzhiyun echo " -D In addition to the goodput in Mbps, it also outputs" 30*4882a593Smuzhiyun echo " other detailed information. This information is" 31*4882a593Smuzhiyun echo " test dependent (i.e. iperf3 or netperf)." 32*4882a593Smuzhiyun echo " -E enable ECN (not required for dctcp)" 33*4882a593Smuzhiyun echo " --edt use fq's Earliest Departure Time (requires fq)" 34*4882a593Smuzhiyun echo " -f or --flows number of concurrent flows (default=1)" 35*4882a593Smuzhiyun echo " -i or --id cgroup id (an integer, default is 1)" 36*4882a593Smuzhiyun echo " -N use netperf instead of iperf3" 37*4882a593Smuzhiyun echo " --no_cn Do not return CN notifications" 38*4882a593Smuzhiyun echo " -l do not limit flows using loopback" 39*4882a593Smuzhiyun echo " -h Help" 40*4882a593Smuzhiyun echo " -p or --port iperf3 port (default is 5201)" 41*4882a593Smuzhiyun echo " -P use an iperf3 instance for each flow" 42*4882a593Smuzhiyun echo " -q use the specified qdisc" 43*4882a593Smuzhiyun echo " -r or --rate rate in Mbps (default 1s 1Gbps)" 44*4882a593Smuzhiyun echo " -R Use TCP_RR for netperf. 1st flow has req" 45*4882a593Smuzhiyun echo " size of 10KB, rest of 1MB. Reply in all" 46*4882a593Smuzhiyun echo " cases is 1 byte." 47*4882a593Smuzhiyun echo " More detailed output for each flow can be found" 48*4882a593Smuzhiyun echo " in the files netperf.<cg>.<flow>, where <cg> is the" 49*4882a593Smuzhiyun echo " cgroup id as specified with the -i flag, and <flow>" 50*4882a593Smuzhiyun echo " is the flow id starting at 1 and increasing by 1 for" 51*4882a593Smuzhiyun echo " flow (as specified by -f)." 52*4882a593Smuzhiyun echo " -s or --server hostname of netperf server. Used to create netperf" 53*4882a593Smuzhiyun echo " test traffic between to hosts (default is within host)" 54*4882a593Smuzhiyun echo " netserver must be running on the host." 55*4882a593Smuzhiyun echo " -S or --stats whether to update hbm stats (default is yes)." 56*4882a593Smuzhiyun echo " -t or --time duration of iperf3 in seconds (default=5)" 57*4882a593Smuzhiyun echo " -w Work conserving flag. cgroup can increase its" 58*4882a593Smuzhiyun echo " bandwidth beyond the rate limit specified" 59*4882a593Smuzhiyun echo " while there is available bandwidth. Current" 60*4882a593Smuzhiyun echo " implementation assumes there is only one NIC" 61*4882a593Smuzhiyun echo " (eth0), but can be extended to support multiple" 62*4882a593Smuzhiyun echo " NICs." 63*4882a593Smuzhiyun echo " cubic or dctcp specify which TCP CC to use" 64*4882a593Smuzhiyun echo " " 65*4882a593Smuzhiyun exit 66*4882a593Smuzhiyun} 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun#set -x 69*4882a593Smuzhiyun 70*4882a593Smuzhiyundebug_flag=0 71*4882a593Smuzhiyunargs="$@" 72*4882a593Smuzhiyunname="$0" 73*4882a593Smuzhiyunnetem=0 74*4882a593Smuzhiyuncc=x 75*4882a593Smuzhiyundir="-o" 76*4882a593Smuzhiyundir_name="out" 77*4882a593Smuzhiyundur=5 78*4882a593Smuzhiyunflows=1 79*4882a593Smuzhiyunid=1 80*4882a593Smuzhiyunprog="" 81*4882a593Smuzhiyunport=5201 82*4882a593Smuzhiyunrate=1000 83*4882a593Smuzhiyunmulti_iperf=0 84*4882a593Smuzhiyunflow_cnt=1 85*4882a593Smuzhiyunuse_netperf=0 86*4882a593Smuzhiyunrr=0 87*4882a593Smuzhiyunecn=0 88*4882a593Smuzhiyundetails=0 89*4882a593Smuzhiyunserver="" 90*4882a593Smuzhiyunqdisc="" 91*4882a593Smuzhiyunflags="" 92*4882a593Smuzhiyundo_stats=0 93*4882a593Smuzhiyun 94*4882a593Smuzhiyunfunction start_hbm () { 95*4882a593Smuzhiyun rm -f hbm.out 96*4882a593Smuzhiyun echo "./hbm $dir -n $id -r $rate -t $dur $flags $dbg $prog" > hbm.out 97*4882a593Smuzhiyun echo " " >> hbm.out 98*4882a593Smuzhiyun ./hbm $dir -n $id -r $rate -t $dur $flags $dbg $prog >> hbm.out 2>&1 & 99*4882a593Smuzhiyun echo $! 100*4882a593Smuzhiyun} 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunprocessArgs () { 103*4882a593Smuzhiyun for i in $args ; do 104*4882a593Smuzhiyun case $i in 105*4882a593Smuzhiyun # Support for upcomming ingress rate limiting 106*4882a593Smuzhiyun #in) # support for upcoming ingress rate limiting 107*4882a593Smuzhiyun # dir="-i" 108*4882a593Smuzhiyun # dir_name="in" 109*4882a593Smuzhiyun # ;; 110*4882a593Smuzhiyun out) 111*4882a593Smuzhiyun dir="-o" 112*4882a593Smuzhiyun dir_name="out" 113*4882a593Smuzhiyun ;; 114*4882a593Smuzhiyun -b=*|--bpf=*) 115*4882a593Smuzhiyun prog="${i#*=}" 116*4882a593Smuzhiyun ;; 117*4882a593Smuzhiyun -c=*|--cc=*) 118*4882a593Smuzhiyun cc="${i#*=}" 119*4882a593Smuzhiyun ;; 120*4882a593Smuzhiyun --no_cn) 121*4882a593Smuzhiyun flags="$flags --no_cn" 122*4882a593Smuzhiyun ;; 123*4882a593Smuzhiyun --debug) 124*4882a593Smuzhiyun flags="$flags -d" 125*4882a593Smuzhiyun debug_flag=1 126*4882a593Smuzhiyun ;; 127*4882a593Smuzhiyun -d=*|--delay=*) 128*4882a593Smuzhiyun netem="${i#*=}" 129*4882a593Smuzhiyun ;; 130*4882a593Smuzhiyun -D) 131*4882a593Smuzhiyun details=1 132*4882a593Smuzhiyun ;; 133*4882a593Smuzhiyun -E) 134*4882a593Smuzhiyun ecn=1 135*4882a593Smuzhiyun ;; 136*4882a593Smuzhiyun --edt) 137*4882a593Smuzhiyun flags="$flags --edt" 138*4882a593Smuzhiyun qdisc="fq" 139*4882a593Smuzhiyun ;; 140*4882a593Smuzhiyun -f=*|--flows=*) 141*4882a593Smuzhiyun flows="${i#*=}" 142*4882a593Smuzhiyun ;; 143*4882a593Smuzhiyun -i=*|--id=*) 144*4882a593Smuzhiyun id="${i#*=}" 145*4882a593Smuzhiyun ;; 146*4882a593Smuzhiyun -l) 147*4882a593Smuzhiyun flags="$flags -l" 148*4882a593Smuzhiyun ;; 149*4882a593Smuzhiyun -N) 150*4882a593Smuzhiyun use_netperf=1 151*4882a593Smuzhiyun ;; 152*4882a593Smuzhiyun -p=*|--port=*) 153*4882a593Smuzhiyun port="${i#*=}" 154*4882a593Smuzhiyun ;; 155*4882a593Smuzhiyun -P) 156*4882a593Smuzhiyun multi_iperf=1 157*4882a593Smuzhiyun ;; 158*4882a593Smuzhiyun -q=*) 159*4882a593Smuzhiyun qdisc="${i#*=}" 160*4882a593Smuzhiyun ;; 161*4882a593Smuzhiyun -r=*|--rate=*) 162*4882a593Smuzhiyun rate="${i#*=}" 163*4882a593Smuzhiyun ;; 164*4882a593Smuzhiyun -R) 165*4882a593Smuzhiyun rr=1 166*4882a593Smuzhiyun ;; 167*4882a593Smuzhiyun -s=*|--server=*) 168*4882a593Smuzhiyun server="${i#*=}" 169*4882a593Smuzhiyun ;; 170*4882a593Smuzhiyun -S|--stats) 171*4882a593Smuzhiyun flags="$flags -s" 172*4882a593Smuzhiyun do_stats=1 173*4882a593Smuzhiyun ;; 174*4882a593Smuzhiyun -t=*|--time=*) 175*4882a593Smuzhiyun dur="${i#*=}" 176*4882a593Smuzhiyun ;; 177*4882a593Smuzhiyun -w) 178*4882a593Smuzhiyun flags="$flags -w" 179*4882a593Smuzhiyun ;; 180*4882a593Smuzhiyun cubic) 181*4882a593Smuzhiyun cc=cubic 182*4882a593Smuzhiyun ;; 183*4882a593Smuzhiyun dctcp) 184*4882a593Smuzhiyun cc=dctcp 185*4882a593Smuzhiyun ;; 186*4882a593Smuzhiyun *) 187*4882a593Smuzhiyun echo "Unknown arg:$i" 188*4882a593Smuzhiyun Usage 189*4882a593Smuzhiyun ;; 190*4882a593Smuzhiyun esac 191*4882a593Smuzhiyun done 192*4882a593Smuzhiyun} 193*4882a593Smuzhiyun 194*4882a593SmuzhiyunprocessArgs 195*4882a593Smuzhiyun 196*4882a593Smuzhiyunif [ $debug_flag -eq 1 ] ; then 197*4882a593Smuzhiyun rm -f hbm_out.log 198*4882a593Smuzhiyunfi 199*4882a593Smuzhiyun 200*4882a593Smuzhiyunhbm_pid=$(start_hbm) 201*4882a593Smuzhiyunusleep 100000 202*4882a593Smuzhiyun 203*4882a593Smuzhiyunhost=`hostname` 204*4882a593Smuzhiyuncg_base_dir=/sys/fs/cgroup 205*4882a593Smuzhiyuncg_dir="$cg_base_dir/cgroup-test-work-dir/hbm$id" 206*4882a593Smuzhiyun 207*4882a593Smuzhiyunecho $$ >> $cg_dir/cgroup.procs 208*4882a593Smuzhiyun 209*4882a593Smuzhiyunulimit -l unlimited 210*4882a593Smuzhiyun 211*4882a593Smuzhiyunrm -f ss.out 212*4882a593Smuzhiyunrm -f hbm.[0-9]*.$dir_name 213*4882a593Smuzhiyunif [ $ecn -ne 0 ] ; then 214*4882a593Smuzhiyun sysctl -w -q -n net.ipv4.tcp_ecn=1 215*4882a593Smuzhiyunfi 216*4882a593Smuzhiyun 217*4882a593Smuzhiyunif [ $use_netperf -eq 0 ] ; then 218*4882a593Smuzhiyun cur_cc=`sysctl -n net.ipv4.tcp_congestion_control` 219*4882a593Smuzhiyun if [ "$cc" != "x" ] ; then 220*4882a593Smuzhiyun sysctl -w -q -n net.ipv4.tcp_congestion_control=$cc 221*4882a593Smuzhiyun fi 222*4882a593Smuzhiyunfi 223*4882a593Smuzhiyun 224*4882a593Smuzhiyunif [ "$netem" -ne "0" ] ; then 225*4882a593Smuzhiyun if [ "$qdisc" != "" ] ; then 226*4882a593Smuzhiyun echo "WARNING: Ignoring -q options because -d option used" 227*4882a593Smuzhiyun fi 228*4882a593Smuzhiyun tc qdisc del dev lo root > /dev/null 2>&1 229*4882a593Smuzhiyun tc qdisc add dev lo root netem delay $netem\ms > /dev/null 2>&1 230*4882a593Smuzhiyunelif [ "$qdisc" != "" ] ; then 231*4882a593Smuzhiyun tc qdisc del dev eth0 root > /dev/null 2>&1 232*4882a593Smuzhiyun tc qdisc add dev eth0 root $qdisc > /dev/null 2>&1 233*4882a593Smuzhiyunfi 234*4882a593Smuzhiyun 235*4882a593Smuzhiyunn=0 236*4882a593Smuzhiyunm=$[$dur * 5] 237*4882a593Smuzhiyunhn="::1" 238*4882a593Smuzhiyunif [ $use_netperf -ne 0 ] ; then 239*4882a593Smuzhiyun if [ "$server" != "" ] ; then 240*4882a593Smuzhiyun hn=$server 241*4882a593Smuzhiyun fi 242*4882a593Smuzhiyunfi 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun( ping6 -i 0.2 -c $m $hn > ping.out 2>&1 ) & 245*4882a593Smuzhiyun 246*4882a593Smuzhiyunif [ $use_netperf -ne 0 ] ; then 247*4882a593Smuzhiyun begNetserverPid=`ps ax | grep netserver | grep --invert-match "grep" | \ 248*4882a593Smuzhiyun awk '{ print $1 }'` 249*4882a593Smuzhiyun if [ "$begNetserverPid" == "" ] ; then 250*4882a593Smuzhiyun if [ "$server" == "" ] ; then 251*4882a593Smuzhiyun ( ./netserver > /dev/null 2>&1) & 252*4882a593Smuzhiyun usleep 100000 253*4882a593Smuzhiyun fi 254*4882a593Smuzhiyun fi 255*4882a593Smuzhiyun flow_cnt=1 256*4882a593Smuzhiyun if [ "$server" == "" ] ; then 257*4882a593Smuzhiyun np_server=$host 258*4882a593Smuzhiyun else 259*4882a593Smuzhiyun np_server=$server 260*4882a593Smuzhiyun fi 261*4882a593Smuzhiyun if [ "$cc" == "x" ] ; then 262*4882a593Smuzhiyun np_cc="" 263*4882a593Smuzhiyun else 264*4882a593Smuzhiyun np_cc="-K $cc,$cc" 265*4882a593Smuzhiyun fi 266*4882a593Smuzhiyun replySize=1 267*4882a593Smuzhiyun while [ $flow_cnt -le $flows ] ; do 268*4882a593Smuzhiyun if [ $rr -ne 0 ] ; then 269*4882a593Smuzhiyun reqSize=1M 270*4882a593Smuzhiyun if [ $flow_cnt -eq 1 ] ; then 271*4882a593Smuzhiyun reqSize=10K 272*4882a593Smuzhiyun fi 273*4882a593Smuzhiyun if [ "$dir" == "-i" ] ; then 274*4882a593Smuzhiyun replySize=$reqSize 275*4882a593Smuzhiyun reqSize=1 276*4882a593Smuzhiyun fi 277*4882a593Smuzhiyun ( ./netperf -H $np_server -l $dur -f m -j -t TCP_RR -- -r $reqSize,$replySize $np_cc -k P50_lATENCY,P90_LATENCY,LOCAL_TRANSPORT_RETRANS,REMOTE_TRANSPORT_RETRANS,LOCAL_SEND_THROUGHPUT,LOCAL_RECV_THROUGHPUT,REQUEST_SIZE,RESPONSE_SIZE > netperf.$id.$flow_cnt ) & 278*4882a593Smuzhiyun else 279*4882a593Smuzhiyun if [ "$dir" == "-i" ] ; then 280*4882a593Smuzhiyun ( ./netperf -H $np_server -l $dur -f m -j -t TCP_RR -- -r 1,10M $np_cc -k P50_LATENCY,P90_LATENCY,LOCAL_TRANSPORT_RETRANS,LOCAL_SEND_THROUGHPUT,REMOTE_TRANSPORT_RETRANS,REMOTE_SEND_THROUGHPUT,REQUEST_SIZE,RESPONSE_SIZE > netperf.$id.$flow_cnt ) & 281*4882a593Smuzhiyun else 282*4882a593Smuzhiyun ( ./netperf -H $np_server -l $dur -f m -j -t TCP_STREAM -- $np_cc -k P50_lATENCY,P90_LATENCY,LOCAL_TRANSPORT_RETRANS,LOCAL_SEND_THROUGHPUT,REQUEST_SIZE,RESPONSE_SIZE > netperf.$id.$flow_cnt ) & 283*4882a593Smuzhiyun fi 284*4882a593Smuzhiyun fi 285*4882a593Smuzhiyun flow_cnt=$[flow_cnt+1] 286*4882a593Smuzhiyun done 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun# sleep for duration of test (plus some buffer) 289*4882a593Smuzhiyun n=$[dur+2] 290*4882a593Smuzhiyun sleep $n 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun# force graceful termination of netperf 293*4882a593Smuzhiyun pids=`pgrep netperf` 294*4882a593Smuzhiyun for p in $pids ; do 295*4882a593Smuzhiyun kill -SIGALRM $p 296*4882a593Smuzhiyun done 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun flow_cnt=1 299*4882a593Smuzhiyun rate=0 300*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 301*4882a593Smuzhiyun echo "" 302*4882a593Smuzhiyun echo "Details for HBM in cgroup $id" 303*4882a593Smuzhiyun if [ $do_stats -eq 1 ] ; then 304*4882a593Smuzhiyun if [ -e hbm.$id.$dir_name ] ; then 305*4882a593Smuzhiyun cat hbm.$id.$dir_name 306*4882a593Smuzhiyun fi 307*4882a593Smuzhiyun fi 308*4882a593Smuzhiyun fi 309*4882a593Smuzhiyun while [ $flow_cnt -le $flows ] ; do 310*4882a593Smuzhiyun if [ "$dir" == "-i" ] ; then 311*4882a593Smuzhiyun r=`cat netperf.$id.$flow_cnt | grep -o "REMOTE_SEND_THROUGHPUT=[0-9]*" | grep -o "[0-9]*"` 312*4882a593Smuzhiyun else 313*4882a593Smuzhiyun r=`cat netperf.$id.$flow_cnt | grep -o "LOCAL_SEND_THROUGHPUT=[0-9]*" | grep -o "[0-9]*"` 314*4882a593Smuzhiyun fi 315*4882a593Smuzhiyun echo "rate for flow $flow_cnt: $r" 316*4882a593Smuzhiyun rate=$[rate+r] 317*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 318*4882a593Smuzhiyun echo "-----" 319*4882a593Smuzhiyun echo "Details for cgroup $id, flow $flow_cnt" 320*4882a593Smuzhiyun cat netperf.$id.$flow_cnt 321*4882a593Smuzhiyun fi 322*4882a593Smuzhiyun flow_cnt=$[flow_cnt+1] 323*4882a593Smuzhiyun done 324*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 325*4882a593Smuzhiyun echo "" 326*4882a593Smuzhiyun delay=`grep "avg" ping.out | grep -o "= [0-9.]*/[0-9.]*" | grep -o "[0-9.]*$"` 327*4882a593Smuzhiyun echo "PING AVG DELAY:$delay" 328*4882a593Smuzhiyun echo "AGGREGATE_GOODPUT:$rate" 329*4882a593Smuzhiyun else 330*4882a593Smuzhiyun echo $rate 331*4882a593Smuzhiyun fi 332*4882a593Smuzhiyunelif [ $multi_iperf -eq 0 ] ; then 333*4882a593Smuzhiyun (iperf3 -s -p $port -1 > /dev/null 2>&1) & 334*4882a593Smuzhiyun usleep 100000 335*4882a593Smuzhiyun iperf3 -c $host -p $port -i 0 -P $flows -f m -t $dur > iperf.$id 336*4882a593Smuzhiyun rates=`grep receiver iperf.$id | grep -o "[0-9.]* Mbits" | grep -o "^[0-9]*"` 337*4882a593Smuzhiyun rate=`echo $rates | grep -o "[0-9]*$"` 338*4882a593Smuzhiyun 339*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 340*4882a593Smuzhiyun echo "" 341*4882a593Smuzhiyun echo "Details for HBM in cgroup $id" 342*4882a593Smuzhiyun if [ $do_stats -eq 1 ] ; then 343*4882a593Smuzhiyun if [ -e hbm.$id.$dir_name ] ; then 344*4882a593Smuzhiyun cat hbm.$id.$dir_name 345*4882a593Smuzhiyun fi 346*4882a593Smuzhiyun fi 347*4882a593Smuzhiyun delay=`grep "avg" ping.out | grep -o "= [0-9.]*/[0-9.]*" | grep -o "[0-9.]*$"` 348*4882a593Smuzhiyun echo "PING AVG DELAY:$delay" 349*4882a593Smuzhiyun echo "AGGREGATE_GOODPUT:$rate" 350*4882a593Smuzhiyun else 351*4882a593Smuzhiyun echo $rate 352*4882a593Smuzhiyun fi 353*4882a593Smuzhiyunelse 354*4882a593Smuzhiyun flow_cnt=1 355*4882a593Smuzhiyun while [ $flow_cnt -le $flows ] ; do 356*4882a593Smuzhiyun (iperf3 -s -p $port -1 > /dev/null 2>&1) & 357*4882a593Smuzhiyun ( iperf3 -c $host -p $port -i 0 -P 1 -f m -t $dur | grep receiver | grep -o "[0-9.]* Mbits" | grep -o "^[0-9]*" | grep -o "[0-9]*$" > iperf3.$id.$flow_cnt ) & 358*4882a593Smuzhiyun port=$[port+1] 359*4882a593Smuzhiyun flow_cnt=$[flow_cnt+1] 360*4882a593Smuzhiyun done 361*4882a593Smuzhiyun n=$[dur+1] 362*4882a593Smuzhiyun sleep $n 363*4882a593Smuzhiyun flow_cnt=1 364*4882a593Smuzhiyun rate=0 365*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 366*4882a593Smuzhiyun echo "" 367*4882a593Smuzhiyun echo "Details for HBM in cgroup $id" 368*4882a593Smuzhiyun if [ $do_stats -eq 1 ] ; then 369*4882a593Smuzhiyun if [ -e hbm.$id.$dir_name ] ; then 370*4882a593Smuzhiyun cat hbm.$id.$dir_name 371*4882a593Smuzhiyun fi 372*4882a593Smuzhiyun fi 373*4882a593Smuzhiyun fi 374*4882a593Smuzhiyun 375*4882a593Smuzhiyun while [ $flow_cnt -le $flows ] ; do 376*4882a593Smuzhiyun r=`cat iperf3.$id.$flow_cnt` 377*4882a593Smuzhiyun# echo "rate for flow $flow_cnt: $r" 378*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 379*4882a593Smuzhiyun echo "Rate for cgroup $id, flow $flow_cnt LOCAL_SEND_THROUGHPUT=$r" 380*4882a593Smuzhiyun fi 381*4882a593Smuzhiyun rate=$[rate+r] 382*4882a593Smuzhiyun flow_cnt=$[flow_cnt+1] 383*4882a593Smuzhiyun done 384*4882a593Smuzhiyun if [ $details -ne 0 ] ; then 385*4882a593Smuzhiyun delay=`grep "avg" ping.out | grep -o "= [0-9.]*/[0-9.]*" | grep -o "[0-9.]*$"` 386*4882a593Smuzhiyun echo "PING AVG DELAY:$delay" 387*4882a593Smuzhiyun echo "AGGREGATE_GOODPUT:$rate" 388*4882a593Smuzhiyun else 389*4882a593Smuzhiyun echo $rate 390*4882a593Smuzhiyun fi 391*4882a593Smuzhiyunfi 392*4882a593Smuzhiyun 393*4882a593Smuzhiyunif [ $use_netperf -eq 0 ] ; then 394*4882a593Smuzhiyun sysctl -w -q -n net.ipv4.tcp_congestion_control=$cur_cc 395*4882a593Smuzhiyunfi 396*4882a593Smuzhiyunif [ $ecn -ne 0 ] ; then 397*4882a593Smuzhiyun sysctl -w -q -n net.ipv4.tcp_ecn=0 398*4882a593Smuzhiyunfi 399*4882a593Smuzhiyunif [ "$netem" -ne "0" ] ; then 400*4882a593Smuzhiyun tc qdisc del dev lo root > /dev/null 2>&1 401*4882a593Smuzhiyunfi 402*4882a593Smuzhiyunif [ "$qdisc" != "" ] ; then 403*4882a593Smuzhiyun tc qdisc del dev eth0 root > /dev/null 2>&1 404*4882a593Smuzhiyunfi 405*4882a593Smuzhiyunsleep 2 406*4882a593Smuzhiyun 407*4882a593SmuzhiyunhbmPid=`ps ax | grep "hbm " | grep --invert-match "grep" | awk '{ print $1 }'` 408*4882a593Smuzhiyunif [ "$hbmPid" == "$hbm_pid" ] ; then 409*4882a593Smuzhiyun kill $hbm_pid 410*4882a593Smuzhiyunfi 411*4882a593Smuzhiyun 412*4882a593Smuzhiyunsleep 1 413*4882a593Smuzhiyun 414*4882a593Smuzhiyun# Detach any BPF programs that may have lingered 415*4882a593Smuzhiyunttx=`bpftool cgroup tree | grep hbm` 416*4882a593Smuzhiyunv=2 417*4882a593Smuzhiyunfor x in $ttx ; do 418*4882a593Smuzhiyun if [ "${x:0:36}" == "/sys/fs/cgroup/cgroup-test-work-dir/" ] ; then 419*4882a593Smuzhiyun cg=$x ; v=0 420*4882a593Smuzhiyun else 421*4882a593Smuzhiyun if [ $v -eq 0 ] ; then 422*4882a593Smuzhiyun id=$x ; v=1 423*4882a593Smuzhiyun else 424*4882a593Smuzhiyun if [ $v -eq 1 ] ; then 425*4882a593Smuzhiyun type=$x ; bpftool cgroup detach $cg $type id $id 426*4882a593Smuzhiyun v=0 427*4882a593Smuzhiyun fi 428*4882a593Smuzhiyun fi 429*4882a593Smuzhiyun fi 430*4882a593Smuzhiyundone 431*4882a593Smuzhiyun 432*4882a593Smuzhiyunif [ $use_netperf -ne 0 ] ; then 433*4882a593Smuzhiyun if [ "$server" == "" ] ; then 434*4882a593Smuzhiyun if [ "$begNetserverPid" == "" ] ; then 435*4882a593Smuzhiyun netserverPid=`ps ax | grep netserver | grep --invert-match "grep" | awk '{ print $1 }'` 436*4882a593Smuzhiyun if [ "$netserverPid" != "" ] ; then 437*4882a593Smuzhiyun kill $netserverPid 438*4882a593Smuzhiyun fi 439*4882a593Smuzhiyun fi 440*4882a593Smuzhiyun fi 441*4882a593Smuzhiyunfi 442*4882a593Smuzhiyunexit 443