From 81dd8f8afa1f7e30a67c0761941adc380b352946 Mon Sep 17 00:00:00 2001 From: subramanianc Date: Thu, 28 Sep 2023 15:25:05 +0530 Subject: [PATCH] qosmngr: Fix port shaping for qcm --- qosmngr/files/linux/lib/qos/qos.sh | 77 ++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/qosmngr/files/linux/lib/qos/qos.sh b/qosmngr/files/linux/lib/qos/qos.sh index 5d3c29979..4e673e920 100755 --- a/qosmngr/files/linux/lib/qos/qos.sh +++ b/qosmngr/files/linux/lib/qos/qos.sh @@ -13,6 +13,7 @@ MAJOR="" POLICER_COUNT=0 Q_COUNT=0 SP_Q_PRIO=7 +SOQ_wgt=0 get_rate_per_queue() { echo "1000000" @@ -22,6 +23,22 @@ get_burst_size_per_queue() { echo "1500" } +handle_q_weight() { + local qid="$1" #queue section ID + config_get ifname "$qid" "ifname" + # If ifname is empty that is good enough to break + if [ -z "$ifname" ];then + return + fi + + config_get sc_alg "$qid" "scheduling" + config_get weight "$qid" "weight" + + if [ "$ifname" == "$2" ] && [ "$sc_alg" == "WRR" ]; then + SOQ_wgt=`expr $SOQ_wgt + $weight` + fi +} + # Function to handle a queue order and # update total number of queues handle_q_order() { @@ -80,7 +97,8 @@ handle_queue() { local port_bw="$3" local root="$4" local port_bs="$5" - local priority=0 + local par_class="$6" + local priority=7 config_get is_enable "$qid" "enable" # no need to configure disabled queues @@ -138,16 +156,28 @@ handle_queue() { # ignore precedence value in case of WRR, broadcom recommends that WRR queue should # always have precedence value set to 0 if [ $salg -ne 2 ]; then - priority=$order + priority=`expr $priority - $order` fi - if [ $order -ne 0 ]; then - if [ $salg -eq 2 ]; then - tc class add dev $port parent ${root}: classid ${root}:$order cbq allot $bs bandwidth ${port_bw}kbit rate ${rate}kbit prio $priority weight $wgt avpkt 1500 bounded isolated - else - tc class add dev $port parent ${root}: classid ${root}:$order cbq allot $bs bandwidth ${port_bw}kbit rate ${rate}kbit prio $priority avpkt 1500 bounded isolated - fi - tc filter add dev $port parent ${root}:0 prio $order u32 match mark $order 0xf flowid ${root}:$order + + local ceil_rate=$port_bw + if [ "$rate" -lt "$port_bw" ]; then + ceil_rate=$rate fi + + local cls_priority=`expr $order + 1` + cls_priority=${cls_priority}0 + + if [ $salg -eq 2 ]; then + # maximum quantum value 60000 + # quantum value calculate based on the configured weight value for the queue + quantum=`expr $wgt \* 60000 / $SOQ_wgt` + tc class add dev $port parent ${root}:${par_class} classid ${root}:${cls_priority} htb rate ${rate}kbit prio ${priority} ceil ${ceil_rate}kbit quantum ${quantum} burst $bs + tc qdisc add dev $port parent ${root}:${cls_priority} handle ${cls_priority}: sfq perturb 10 + else + tc class add dev $port parent ${root}:${par_class} classid ${root}:${cls_priority} htb rate ${rate}kbit prio ${priority} ceil ${ceil_rate}kbit burst $bs + fi + tc filter add dev $port parent ${root}:0 prio $order u32 match mark $order 0xf flowid ${root}:${cls_priority} + Q_COUNT=$((Q_COUNT + 1)) } @@ -398,10 +428,18 @@ configure_queue() { fi rate=$(( rate / 1000 )) + + #burst size is either bitrate*0.00025 or max_packat_size in bit whichever is greater + local avg_bs=$(( rate * 25 )) config_get b_size "$sid" "burst_size" - if [ "$b_size" == "0" ]; then + if [ "$b_size" > "0" ]; then bs="$b_size" fi + bs=$(( bs * 8 )) + if [ $avg_bs -gt $bs ]; then + bs="$avg_bs" + fi + bs=$(( bs / 1000 )) } local wanport="$(db -q get hw.board.ethernetWanPort)" for interf in $(db -q get hw.board.ethernetPortOrder); do @@ -420,8 +458,15 @@ configure_queue() { rate=$(( link_rate * 1000 )) fi - # TODO using 1500 as allot and avpkt, if shaper config exist for interf get burst_size of shaper for actual value - tc qdisc add dev $interf root handle ${qdisc_idx}: cbq allot $bs avpkt 1500 bandwidth ${rate}kbit + p_qdisc_idx=`expr $qdisc_idx + 11` + tc qdisc add dev $interf root handle ${p_qdisc_idx}: tbf rate ${rate}kbit burst ${bs}k limit 1M + tc qdisc add dev $interf parent ${p_qdisc_idx}: handle ${qdisc_idx}: htb default 10 + + # port shaper needs to add as parent class and other queue based shaping mapped as child classes + local par_class=1 + tc class add dev $interf parent ${qdisc_idx}: classid ${qdisc_idx}:$par_class htb rate ${rate}kbit prio 8 ceil ${rate}kbit + tc filter add dev $interf parent ${qdisc_idx}:0 matchall flowid ${qdisc_idx}:$par_class + # if qdisc_idx is the index corresponds to WAN port, then # it would be the MAJOR portion of the destination class ID. # under the same qdisc. We are programming for WAN port only. @@ -429,7 +474,11 @@ configure_queue() { MAJOR="$qdisc_idx" fi - config_foreach handle_queue queue $interf $rate $qdisc_idx $bs + #calculate sum of queue weight, to derive the quantum value + SOQ_wgt=0 + config_foreach handle_q_weight queue $interf + + config_foreach handle_queue queue $interf $rate $qdisc_idx $bs $par_class done } @@ -453,11 +502,11 @@ configure_policer() { configure_qos() { pre_configure_queue configure_queue + configure_policer configure_classify if [ -f "/tmp/qos/classify.ebtables" ]; then sh /tmp/qos/classify.ebtables fi - configure_policer } reload_qos() {