Browse Source

Add dynamic burst calculation to HTB for higher bandwidths w/ UCI option

Signed-off-by: Eric Luehrsen <ericluehrsen@users.noreply.github.com>
Eric Luehrsen 8 years ago
parent
commit
8bbd578d60
5 changed files with 77 additions and 16 deletions
  1. 1 0
      src/defaults.sh
  2. 55 1
      src/functions.sh
  3. 1 1
      src/run-openwrt.sh
  4. 13 10
      src/simple.qos
  5. 7 4
      src/simplest.qos

+ 1 - 0
src/defaults.sh

@@ -34,6 +34,7 @@
 #sm: *_CAKE_OPTS should contain the diffserv keyword for cake
 [ -z "$INGRESS_CAKE_OPTS" ] && INGRESS_CAKE_OPTS="diffserv4"
 [ -z "$EGRESS_CAKE_OPTS" ] && EGRESS_CAKE_OPTS="diffserv4"
+[ -z "$SHAPER_BURST" ] && SHAPER_BURST="0"
 
 # Logging verbosity
 VERBOSITY_SILENT=0

+ 55 - 1
src/functions.sh

@@ -1,8 +1,25 @@
+################################################################################
+# (sqm) functions.sh
+#
+# These are all helper functions for various parts of SQM scripts. If you want
+# to play around with your own shaper-qdisc-filter configuration look here for
+# ready made tools, or examples start of on your own.
+#
+# Please note the SQM logger function is broken down into levels of logging.
+# Use only levels appropriate to touch points in your script and realize the
+# potential to overflow SYSLOG.
+#
+################################################################################
+#
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 as
 # published by the Free Software Foundation.
 #
-#       Copyright (C) 2012-2016 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+#   Copyright (C) 2012-6
+#       Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
+#       Eric Luehrsen
+#
+################################################################################
 
 sqm_logger() {
     case $1 in
@@ -302,6 +319,43 @@ get_htb_quantum() {
     echo $CUR_QUANTUM
 }
 
+# Create optional burst parameters to leap over CPU interupts when the CPU is
+# severly loaded. We need to be conservative though.
+get_htb_burst() {
+    HTB_MTU=$( get_mtu $1 )
+    BANDWIDTH=$2
+
+    if [ -n "${HTB_MTU}" -a "${SHAPER_BURST}" -eq "1" ] ; then
+        # 10 MTU burst can itself create delay under CPU load.
+        # It will need to all wait for a hardware commit.
+        BANDWIDTH_L=$(( ${HTB_MTU} *  2 * 8 ))
+        BANDWIDTH_H=$(( ${HTB_MTU} * 10 * 8 ))
+
+
+        if [ ${BANDWIDTH} -gt ${BANDWIDTH_H} ] ; then
+            HTB_BURST=$(( ${HTB_MTU} * 10 ))
+
+            sqm_debug "CUR_HTB_BURST: ${HTB_BURST}, BANDWIDTH: ${BANDWIDTH}"
+
+            echo burst ${HTB_BURST} cburst ${HTB_BURST}
+
+        elif [ ${BANDWIDTH} -gt ${BANDWIDTH_L} ] ; then
+            # Start with 1ms buffer 2x MTU, and lean out the mixture at higher rates
+            HTB_BURST=$(( ${BANDWIDTH} - ${BANDWIDTH_L} ))
+            HTB_BURST=$(( ${HTB_BURST} / 16 ))
+            HTB_BURST=$(( ${HTB_BURST} / ${HTB_MTU} ))
+            HTB_BURST=$(( ${HTB_BURST} * ${HTB_MTU} ))
+            HTB_BURST=$(( ${HTB_BURST} + ${HTB_MTU} * 2 ))
+
+            sqm_debug "CUR_HTB_BURST: ${HTB_BURST}, BANDWIDTH: ${BANDWIDTH}"
+
+            echo burst ${HTB_BURST} cburst ${HTB_BURST}
+
+        else
+            sqm_debug "Default Burst, HTB will use MTU plus shipping and handling"
+        fi
+    fi
+}
 
 # For a default PPPoE link this returns 1492 just as expected but I fear we
 # actually need the wire size of the whole thing not so much the MTU

+ 1 - 1
src/run-openwrt.sh

@@ -55,7 +55,7 @@ run_sqm_scripts() {
     export TARGET=$(config_get "$section" target)
     export SQUASH_DSCP=$(config_get "$section" squash_dscp)
     export SQUASH_INGRESS=$(config_get "$section" squash_ingress)
-
+    export SHAPER_BURST=$(config_get "$section" shaper_burst)
     export QDISC=$(config_get "$section" qdisc)
     export SCRIPT=$(config_get "$section" script)
 

+ 13 - 10
src/simple.qos

@@ -106,18 +106,20 @@ egress() {
     BE_CEIL=`expr $CEIL - 16`  # A little slop at the top
 
     LQ="quantum `get_htb_quantum $IFACE $CEIL`"
+    BURST="`get_htb_burst $IFACE $CEIL`"
 
     $TC qdisc del dev $IFACE root 2> /dev/null
+
     case $QDISC in
         cake*) cake_egress; return;;
     esac
 
     $TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 12
-    $TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit `get_htb_adsll_string`
-    $TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 `get_htb_adsll_string`
+    $TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit $BURST `get_htb_adsll_string`
+    $TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit $BURST prio 0 `get_htb_adsll_string`
     $TC class add dev $IFACE parent 1:1 classid 1:11 htb $LQ rate 128kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string`
-    $TC class add dev $IFACE parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
-    $TC class add dev $IFACE parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+    $TC class add dev $IFACE parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 2 `get_htb_adsll_string`
+    $TC class add dev $IFACE parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 3 `get_htb_adsll_string`
 
     $TC qdisc add dev $IFACE parent 1:11 handle 110: $QDISC \
         `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_quantum 300` `get_flows ${PRIO_RATE}` ${EQDISC_OPTS}
@@ -182,6 +184,7 @@ ingress() {
     BE_CEIL=`expr $CEIL - 16`  # A little slop at the top
 
     LQ="quantum `get_htb_quantum $IFACE $CEIL`"
+    BURST="`get_htb_burst $IFACE $CEIL`"
 
     $TC qdisc del dev $IFACE handle ffff: ingress 2> /dev/null
     $TC qdisc add dev $IFACE handle ffff: ingress
@@ -195,18 +198,18 @@ ingress() {
     if [ "$SQUASH_INGRESS" = "1" ]; then
         sqm_debug "Do not perform DSCP based filtering on ingress. (1-tier classification)"
         $TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10
-        $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit `get_htb_adsll_string`
-        $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit prio 0 `get_htb_adsll_string`
+        $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST `get_htb_adsll_string`
+        $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST prio 0 `get_htb_adsll_string`
         $TC qdisc add dev $DEV parent 1:10 handle 110: $QDISC \
             `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_flows ${DOWNLINK}` ${IQDISC_OPTS}
     else
         sqm_debug "Perform DSCP based filtering on ingress. (3-tier classification)"
         $TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 12
-        $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit `get_htb_adsll_string`
-        $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit prio 0 `get_htb_adsll_string`
+        $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit $BURST `get_htb_adsll_string`
+        $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${CEIL}kbit ceil ${CEIL}kbit $BURST prio 0 `get_htb_adsll_string`
         $TC class add dev $DEV parent 1:1 classid 1:11 htb $LQ rate 32kbit ceil ${PRIO_RATE}kbit prio 1 `get_htb_adsll_string`
-        $TC class add dev $DEV parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit prio 2 `get_htb_adsll_string`
-        $TC class add dev $DEV parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit prio 3 `get_htb_adsll_string`
+        $TC class add dev $DEV parent 1:1 classid 1:12 htb $LQ rate ${BE_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 2 `get_htb_adsll_string`
+        $TC class add dev $DEV parent 1:1 classid 1:13 htb $LQ rate ${BK_RATE}kbit ceil ${BE_CEIL}kbit $BURST prio 3 `get_htb_adsll_string`
 
         $TC qdisc add dev $DEV parent 1:11 handle 110: $QDISC \
             `get_limit ${ILIMIT}` `get_target "${ITARGET}" ${DOWNLINK}` `get_ecn ${IECN}` `get_quantum 500` `get_flows ${PRIO_RATE}` ${IQDISC_OPTS}

+ 7 - 4
src/simplest.qos

@@ -35,15 +35,17 @@ cake_egress()
 egress() {
 
     LQ="quantum `get_htb_quantum $IFACE ${UPLINK}`"
+    BURST="`get_htb_burst $IFACE ${UPLINK}`"
 
     $TC qdisc del dev $IFACE root 2>/dev/null
+
     case $QDISC in
         cake*) cake_egress; return ;;
     esac
 
     $TC qdisc add dev $IFACE root handle 1: `get_stab_string` htb default 10
-    $TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit `get_htb_adsll_string`
-    $TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit prio 0 `get_htb_adsll_string`
+    $TC class add dev $IFACE parent 1: classid 1:1 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit $BURST `get_htb_adsll_string`
+    $TC class add dev $IFACE parent 1:1 classid 1:10 htb $LQ rate ${UPLINK}kbit ceil ${UPLINK}kbit $BURST prio 0 `get_htb_adsll_string`
     $TC qdisc add dev $IFACE parent 1:10 handle 110: $QDISC \
         `get_limit ${ELIMIT}` `get_target "${ETARGET}" ${UPLINK}` `get_ecn ${EECN}` `get_flows ${UPLINK}` ${EQDISC_OPTS}
 
@@ -66,6 +68,7 @@ ingress() {
     $TC qdisc add dev $IFACE handle ffff: ingress
 
     LQ="quantum `get_htb_quantum $IFACE ${DOWNLINK}`"
+    BURST="`get_htb_burst $IFACE ${DOWNLINK}`"
 
     $TC qdisc del dev $DEV root 2>/dev/null
 
@@ -74,8 +77,8 @@ ingress() {
     esac
 
     $TC qdisc add dev $DEV root handle 1: `get_stab_string` htb default 10
-    $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit `get_htb_adsll_string`
-    $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit prio 0 `get_htb_adsll_string`
+    $TC class add dev $DEV parent 1: classid 1:1 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST `get_htb_adsll_string`
+    $TC class add dev $DEV parent 1:1 classid 1:10 htb $LQ rate ${DOWNLINK}kbit ceil ${DOWNLINK}kbit $BURST prio 0 `get_htb_adsll_string`
 
     # FIXME: I'd prefer to use a pre-nat filter but we need to detect if nat is on this interface
     # AND we need to permute by a random number which we can't do from userspace filters