mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	This patch fixes a spelling typo in do_hbm_test.sh Signed-off-by: Masanari Iida <standby24x7@gmail.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20210315124454.1744594-1-standby24x7@gmail.com
		
			
				
	
	
		
			438 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			438 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
#!/bin/bash
 | 
						|
# SPDX-License-Identifier: GPL-2.0
 | 
						|
#
 | 
						|
# Copyright (c) 2019 Facebook
 | 
						|
#
 | 
						|
# This program is free software; you can redistribute it and/or
 | 
						|
# modify it under the terms of version 2 of the GNU General Public
 | 
						|
# License as published by the Free Software Foundation.
 | 
						|
 | 
						|
Usage() {
 | 
						|
  echo "Script for testing HBM (Host Bandwidth Manager) framework."
 | 
						|
  echo "It creates a cgroup to use for testing and load a BPF program to limit"
 | 
						|
  echo "egress or ingress bandwidth. It then uses iperf3 or netperf to create"
 | 
						|
  echo "loads. The output is the goodput in Mbps (unless -D was used)."
 | 
						|
  echo ""
 | 
						|
  echo "USAGE: $name [out] [-b=<prog>|--bpf=<prog>] [-c=<cc>|--cc=<cc>]"
 | 
						|
  echo "             [-D] [-d=<delay>|--delay=<delay>] [--debug] [-E] [--edt]"
 | 
						|
  echo "             [-f=<#flows>|--flows=<#flows>] [-h] [-i=<id>|--id=<id >]"
 | 
						|
  echo "             [-l] [-N] [--no_cn] [-p=<port>|--port=<port>] [-P]"
 | 
						|
  echo "             [-q=<qdisc>] [-R] [-s=<server>|--server=<server]"
 | 
						|
  echo "             [-S|--stats] -t=<time>|--time=<time>] [-w] [cubic|dctcp]"
 | 
						|
  echo "  Where:"
 | 
						|
  echo "    out               egress (default)"
 | 
						|
  echo "    -b or --bpf       BPF program filename to load and attach."
 | 
						|
  echo "                      Default is hbm_out_kern.o for egress,"
 | 
						|
  echo "    -c or -cc         TCP congestion control (cubic or dctcp)"
 | 
						|
  echo "    --debug           print BPF trace buffer"
 | 
						|
  echo "    -d or --delay     add a delay in ms using netem"
 | 
						|
  echo "    -D                In addition to the goodput in Mbps, it also outputs"
 | 
						|
  echo "                      other detailed information. This information is"
 | 
						|
  echo "                      test dependent (i.e. iperf3 or netperf)."
 | 
						|
  echo "    -E                enable ECN (not required for dctcp)"
 | 
						|
  echo "    --edt             use fq's Earliest Departure Time (requires fq)"
 | 
						|
  echo "    -f or --flows     number of concurrent flows (default=1)"
 | 
						|
  echo "    -i or --id        cgroup id (an integer, default is 1)"
 | 
						|
  echo "    -N                use netperf instead of iperf3"
 | 
						|
  echo "    --no_cn           Do not return CN notifications"
 | 
						|
  echo "    -l                do not limit flows using loopback"
 | 
						|
  echo "    -h                Help"
 | 
						|
  echo "    -p or --port      iperf3 port (default is 5201)"
 | 
						|
  echo "    -P                use an iperf3 instance for each flow"
 | 
						|
  echo "    -q                use the specified qdisc"
 | 
						|
  echo "    -r or --rate      rate in Mbps (default 1s 1Gbps)"
 | 
						|
  echo "    -R                Use TCP_RR for netperf. 1st flow has req"
 | 
						|
  echo "                      size of 10KB, rest of 1MB. Reply in all"
 | 
						|
  echo "                      cases is 1 byte."
 | 
						|
  echo "                      More detailed output for each flow can be found"
 | 
						|
  echo "                      in the files netperf.<cg>.<flow>, where <cg> is the"
 | 
						|
  echo "                      cgroup id as specified with the -i flag, and <flow>"
 | 
						|
  echo "                      is the flow id starting at 1 and increasing by 1 for"
 | 
						|
  echo "                      flow (as specified by -f)."
 | 
						|
  echo "    -s or --server    hostname of netperf server. Used to create netperf"
 | 
						|
  echo "                      test traffic between to hosts (default is within host)"
 | 
						|
  echo "                      netserver must be running on the host."
 | 
						|
  echo "    -S or --stats     whether to update hbm stats (default is yes)."
 | 
						|
  echo "    -t or --time      duration of iperf3 in seconds (default=5)"
 | 
						|
  echo "    -w                Work conserving flag. cgroup can increase its"
 | 
						|
  echo "                      bandwidth beyond the rate limit specified"
 | 
						|
  echo "                      while there is available bandwidth. Current"
 | 
						|
  echo "                      implementation assumes there is only one NIC"
 | 
						|
  echo "                      (eth0), but can be extended to support multiple"
 | 
						|
  echo "                       NICs."
 | 
						|
  echo "    cubic or dctcp    specify which TCP CC to use"
 | 
						|
  echo " "
 | 
						|
  exit
 | 
						|
}
 | 
						|
 | 
						|
#set -x
 | 
						|
 | 
						|
debug_flag=0
 | 
						|
args="$@"
 | 
						|
name="$0"
 | 
						|
netem=0
 | 
						|
cc=x
 | 
						|
dir="-o"
 | 
						|
dir_name="out"
 | 
						|
dur=5
 | 
						|
flows=1
 | 
						|
id=1
 | 
						|
prog=""
 | 
						|
port=5201
 | 
						|
rate=1000
 | 
						|
multi_iperf=0
 | 
						|
flow_cnt=1
 | 
						|
use_netperf=0
 | 
						|
rr=0
 | 
						|
ecn=0
 | 
						|
details=0
 | 
						|
server=""
 | 
						|
qdisc=""
 | 
						|
flags=""
 | 
						|
do_stats=0
 | 
						|
 | 
						|
BPFFS=/sys/fs/bpf
 | 
						|
function config_bpffs () {
 | 
						|
	if mount | grep $BPFFS > /dev/null; then
 | 
						|
		echo "bpffs already mounted"
 | 
						|
	else
 | 
						|
		echo "bpffs not mounted. Mounting..."
 | 
						|
		mount -t bpf none $BPFFS
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
function start_hbm () {
 | 
						|
  rm -f hbm.out
 | 
						|
  echo "./hbm $dir -n $id -r $rate -t $dur $flags $dbg $prog" > hbm.out
 | 
						|
  echo " " >> hbm.out
 | 
						|
  ./hbm $dir -n $id -r $rate -t $dur $flags $dbg $prog >> hbm.out 2>&1  &
 | 
						|
  echo $!
 | 
						|
}
 | 
						|
 | 
						|
processArgs () {
 | 
						|
  for i in $args ; do
 | 
						|
    case $i in
 | 
						|
    # Support for upcomming ingress rate limiting
 | 
						|
    #in)         # support for upcoming ingress rate limiting
 | 
						|
    #  dir="-i"
 | 
						|
    #  dir_name="in"
 | 
						|
    #  ;;
 | 
						|
    out)
 | 
						|
      dir="-o"
 | 
						|
      dir_name="out"
 | 
						|
      ;;
 | 
						|
    -b=*|--bpf=*)
 | 
						|
      prog="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -c=*|--cc=*)
 | 
						|
      cc="${i#*=}"
 | 
						|
      ;;
 | 
						|
    --no_cn)
 | 
						|
      flags="$flags --no_cn"
 | 
						|
      ;;
 | 
						|
    --debug)
 | 
						|
      flags="$flags -d"
 | 
						|
      debug_flag=1
 | 
						|
      ;;
 | 
						|
    -d=*|--delay=*)
 | 
						|
      netem="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -D)
 | 
						|
      details=1
 | 
						|
      ;;
 | 
						|
    -E)
 | 
						|
      ecn=1
 | 
						|
      ;;
 | 
						|
    --edt)
 | 
						|
      flags="$flags --edt"
 | 
						|
      qdisc="fq"
 | 
						|
     ;;
 | 
						|
    -f=*|--flows=*)
 | 
						|
      flows="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -i=*|--id=*)
 | 
						|
      id="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -l)
 | 
						|
      flags="$flags -l"
 | 
						|
      ;;
 | 
						|
    -N)
 | 
						|
      use_netperf=1
 | 
						|
      ;;
 | 
						|
    -p=*|--port=*)
 | 
						|
      port="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -P)
 | 
						|
      multi_iperf=1
 | 
						|
      ;;
 | 
						|
    -q=*)
 | 
						|
      qdisc="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -r=*|--rate=*)
 | 
						|
      rate="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -R)
 | 
						|
      rr=1
 | 
						|
      ;;
 | 
						|
    -s=*|--server=*)
 | 
						|
      server="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -S|--stats)
 | 
						|
      flags="$flags -s"
 | 
						|
      do_stats=1
 | 
						|
      ;;
 | 
						|
    -t=*|--time=*)
 | 
						|
      dur="${i#*=}"
 | 
						|
      ;;
 | 
						|
    -w)
 | 
						|
      flags="$flags -w"
 | 
						|
      ;;
 | 
						|
    cubic)
 | 
						|
      cc=cubic
 | 
						|
      ;;
 | 
						|
    dctcp)
 | 
						|
      cc=dctcp
 | 
						|
      ;;
 | 
						|
    *)
 | 
						|
      echo "Unknown arg:$i"
 | 
						|
      Usage
 | 
						|
      ;;
 | 
						|
    esac
 | 
						|
  done
 | 
						|
}
 | 
						|
 | 
						|
processArgs
 | 
						|
config_bpffs
 | 
						|
 | 
						|
if [ $debug_flag -eq 1 ] ; then
 | 
						|
  rm -f hbm_out.log
 | 
						|
fi
 | 
						|
 | 
						|
hbm_pid=$(start_hbm)
 | 
						|
usleep 100000
 | 
						|
 | 
						|
host=`hostname`
 | 
						|
cg_base_dir=/sys/fs/cgroup/unified
 | 
						|
cg_dir="$cg_base_dir/cgroup-test-work-dir/hbm$id"
 | 
						|
 | 
						|
echo $$ >> $cg_dir/cgroup.procs
 | 
						|
 | 
						|
ulimit -l unlimited
 | 
						|
 | 
						|
rm -f ss.out
 | 
						|
rm -f hbm.[0-9]*.$dir_name
 | 
						|
if [ $ecn -ne 0 ] ; then
 | 
						|
  sysctl -w -q -n net.ipv4.tcp_ecn=1
 | 
						|
fi
 | 
						|
 | 
						|
if [ $use_netperf -eq 0 ] ; then
 | 
						|
  cur_cc=`sysctl -n net.ipv4.tcp_congestion_control`
 | 
						|
  if [ "$cc" != "x" ] ; then
 | 
						|
    sysctl -w -q -n net.ipv4.tcp_congestion_control=$cc
 | 
						|
  fi
 | 
						|
fi
 | 
						|
 | 
						|
if [ "$netem" -ne "0" ] ; then
 | 
						|
  if [ "$qdisc" != "" ] ; then
 | 
						|
    echo "WARNING: Ignoring -q options because -d option used"
 | 
						|
  fi
 | 
						|
  tc qdisc del dev lo root > /dev/null 2>&1
 | 
						|
  tc qdisc add dev lo root netem delay $netem\ms > /dev/null 2>&1
 | 
						|
elif [ "$qdisc" != "" ] ; then
 | 
						|
  tc qdisc del dev eth0 root > /dev/null 2>&1
 | 
						|
  tc qdisc add dev eth0 root $qdisc > /dev/null 2>&1
 | 
						|
fi
 | 
						|
 | 
						|
n=0
 | 
						|
m=$[$dur * 5]
 | 
						|
hn="::1"
 | 
						|
if [ $use_netperf -ne 0 ] ; then
 | 
						|
  if [ "$server" != "" ] ; then
 | 
						|
    hn=$server
 | 
						|
  fi
 | 
						|
fi
 | 
						|
 | 
						|
( ping6 -i 0.2 -c $m $hn > ping.out 2>&1 ) &
 | 
						|
 | 
						|
if [ $use_netperf -ne 0 ] ; then
 | 
						|
  begNetserverPid=`ps ax | grep netserver | grep --invert-match "grep" | \
 | 
						|
                   awk '{ print $1 }'`
 | 
						|
  if [ "$begNetserverPid" == "" ] ; then
 | 
						|
    if [ "$server" == "" ] ; then
 | 
						|
      ( ./netserver > /dev/null 2>&1) &
 | 
						|
      usleep 100000
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
  flow_cnt=1
 | 
						|
  if [ "$server" == "" ] ; then
 | 
						|
    np_server=$host
 | 
						|
  else
 | 
						|
    np_server=$server
 | 
						|
  fi
 | 
						|
  if [ "$cc" == "x" ] ; then
 | 
						|
    np_cc=""
 | 
						|
  else
 | 
						|
    np_cc="-K $cc,$cc"
 | 
						|
  fi
 | 
						|
  replySize=1
 | 
						|
  while [ $flow_cnt -le $flows ] ; do
 | 
						|
    if [ $rr -ne 0 ] ; then
 | 
						|
      reqSize=1M
 | 
						|
      if [ $flow_cnt -eq 1 ] ; then
 | 
						|
        reqSize=10K
 | 
						|
      fi
 | 
						|
      if [ "$dir" == "-i" ] ; then
 | 
						|
        replySize=$reqSize
 | 
						|
        reqSize=1
 | 
						|
      fi
 | 
						|
      ( ./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 ) &
 | 
						|
    else
 | 
						|
      if [ "$dir" == "-i" ] ; then
 | 
						|
        ( ./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 ) &
 | 
						|
      else
 | 
						|
        ( ./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 ) &
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
    flow_cnt=$[flow_cnt+1]
 | 
						|
  done
 | 
						|
 | 
						|
# sleep for duration of test (plus some buffer)
 | 
						|
  n=$[dur+2]
 | 
						|
  sleep $n
 | 
						|
 | 
						|
# force graceful termination of netperf
 | 
						|
  pids=`pgrep netperf`
 | 
						|
  for p in $pids ; do
 | 
						|
    kill -SIGALRM $p
 | 
						|
  done
 | 
						|
 | 
						|
  flow_cnt=1
 | 
						|
  rate=0
 | 
						|
  if [ $details -ne 0 ] ; then
 | 
						|
    echo ""
 | 
						|
    echo "Details for HBM in cgroup $id"
 | 
						|
    if [ $do_stats -eq 1 ] ; then
 | 
						|
      if [ -e hbm.$id.$dir_name ] ; then
 | 
						|
        cat hbm.$id.$dir_name
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
  while [ $flow_cnt -le $flows ] ; do
 | 
						|
    if [ "$dir" == "-i" ] ; then
 | 
						|
      r=`cat netperf.$id.$flow_cnt | grep -o "REMOTE_SEND_THROUGHPUT=[0-9]*" | grep -o "[0-9]*"`
 | 
						|
    else
 | 
						|
      r=`cat netperf.$id.$flow_cnt | grep -o "LOCAL_SEND_THROUGHPUT=[0-9]*" | grep -o "[0-9]*"`
 | 
						|
    fi
 | 
						|
    echo "rate for flow $flow_cnt: $r"
 | 
						|
    rate=$[rate+r]
 | 
						|
    if [ $details -ne 0 ] ; then
 | 
						|
      echo "-----"
 | 
						|
      echo "Details for cgroup $id, flow $flow_cnt"
 | 
						|
      cat netperf.$id.$flow_cnt
 | 
						|
    fi
 | 
						|
    flow_cnt=$[flow_cnt+1]
 | 
						|
  done
 | 
						|
  if [ $details -ne 0 ] ; then
 | 
						|
    echo ""
 | 
						|
    delay=`grep "avg" ping.out | grep -o "= [0-9.]*/[0-9.]*" | grep -o "[0-9.]*$"`
 | 
						|
    echo "PING AVG DELAY:$delay"
 | 
						|
    echo "AGGREGATE_GOODPUT:$rate"
 | 
						|
  else
 | 
						|
    echo $rate
 | 
						|
  fi
 | 
						|
elif [ $multi_iperf -eq 0 ] ; then
 | 
						|
  (iperf3 -s -p $port -1 > /dev/null 2>&1) &
 | 
						|
  usleep 100000
 | 
						|
  iperf3 -c $host -p $port -i 0 -P $flows -f m -t $dur > iperf.$id
 | 
						|
  rates=`grep receiver iperf.$id | grep -o "[0-9.]* Mbits" | grep -o "^[0-9]*"`
 | 
						|
  rate=`echo $rates | grep -o "[0-9]*$"`
 | 
						|
 | 
						|
  if [ $details -ne 0 ] ; then
 | 
						|
    echo ""
 | 
						|
    echo "Details for HBM in cgroup $id"
 | 
						|
    if [ $do_stats -eq 1 ] ; then
 | 
						|
      if [ -e hbm.$id.$dir_name ] ; then
 | 
						|
        cat hbm.$id.$dir_name
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
    delay=`grep "avg" ping.out | grep -o "= [0-9.]*/[0-9.]*" | grep -o "[0-9.]*$"`
 | 
						|
    echo "PING AVG DELAY:$delay"
 | 
						|
    echo "AGGREGATE_GOODPUT:$rate"
 | 
						|
  else
 | 
						|
    echo $rate
 | 
						|
  fi
 | 
						|
else
 | 
						|
  flow_cnt=1
 | 
						|
  while [ $flow_cnt -le $flows ] ; do
 | 
						|
    (iperf3 -s -p $port -1 > /dev/null 2>&1) &
 | 
						|
    ( 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 ) &
 | 
						|
    port=$[port+1]
 | 
						|
    flow_cnt=$[flow_cnt+1]
 | 
						|
  done
 | 
						|
  n=$[dur+1]
 | 
						|
  sleep $n
 | 
						|
  flow_cnt=1
 | 
						|
  rate=0
 | 
						|
  if [ $details -ne 0 ] ; then
 | 
						|
    echo ""
 | 
						|
    echo "Details for HBM in cgroup $id"
 | 
						|
    if [ $do_stats -eq 1 ] ; then
 | 
						|
      if [ -e hbm.$id.$dir_name ] ; then
 | 
						|
        cat hbm.$id.$dir_name
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
 | 
						|
  while [ $flow_cnt -le $flows ] ; do
 | 
						|
    r=`cat iperf3.$id.$flow_cnt`
 | 
						|
#    echo "rate for flow $flow_cnt: $r"
 | 
						|
  if [ $details -ne 0 ] ; then
 | 
						|
    echo "Rate for cgroup $id, flow $flow_cnt LOCAL_SEND_THROUGHPUT=$r"
 | 
						|
  fi
 | 
						|
    rate=$[rate+r]
 | 
						|
    flow_cnt=$[flow_cnt+1]
 | 
						|
  done
 | 
						|
  if [ $details -ne 0 ] ; then
 | 
						|
    delay=`grep "avg" ping.out | grep -o "= [0-9.]*/[0-9.]*" | grep -o "[0-9.]*$"`
 | 
						|
    echo "PING AVG DELAY:$delay"
 | 
						|
    echo "AGGREGATE_GOODPUT:$rate"
 | 
						|
  else
 | 
						|
    echo $rate
 | 
						|
  fi
 | 
						|
fi
 | 
						|
 | 
						|
if [ $use_netperf -eq 0 ] ; then
 | 
						|
  sysctl -w -q -n net.ipv4.tcp_congestion_control=$cur_cc
 | 
						|
fi
 | 
						|
if [ $ecn -ne 0 ] ; then
 | 
						|
  sysctl -w -q -n net.ipv4.tcp_ecn=0
 | 
						|
fi
 | 
						|
if [ "$netem" -ne "0" ] ; then
 | 
						|
  tc qdisc del dev lo root > /dev/null 2>&1
 | 
						|
fi
 | 
						|
if [ "$qdisc" != "" ] ; then
 | 
						|
  tc qdisc del dev eth0 root > /dev/null 2>&1
 | 
						|
fi
 | 
						|
sleep 2
 | 
						|
 | 
						|
hbmPid=`ps ax | grep "hbm " | grep --invert-match "grep" | awk '{ print $1 }'`
 | 
						|
if [ "$hbmPid" == "$hbm_pid" ] ; then
 | 
						|
  kill $hbm_pid
 | 
						|
fi
 | 
						|
 | 
						|
sleep 1
 | 
						|
 | 
						|
# Detach any pinned BPF programs that may have lingered
 | 
						|
rm -rf $BPFFS/hbm*
 | 
						|
 | 
						|
if [ $use_netperf -ne 0 ] ; then
 | 
						|
  if [ "$server" == "" ] ; then
 | 
						|
    if [ "$begNetserverPid" == "" ] ; then
 | 
						|
      netserverPid=`ps ax | grep netserver | grep --invert-match "grep" | awk '{ print $1 }'`
 | 
						|
      if [ "$netserverPid" != "" ] ; then
 | 
						|
        kill $netserverPid
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
  fi
 | 
						|
fi
 | 
						|
exit
 |