diff --git a/qosmngr/files/lib/qos/broadcom.sh b/qosmngr/files/lib/qos/broadcom.sh index 3f4ef9bed..58a5ced16 100755 --- a/qosmngr/files/lib/qos/broadcom.sh +++ b/qosmngr/files/lib/qos/broadcom.sh @@ -7,20 +7,15 @@ BR_RULE="" BR6_RULE="" POLICER_COUNT=0 -INTF_NAME="" Q_COUNT=0 -ITER=0 -PREV_ORDER="" -CURR_ORDER="" -MAX_ORDER="" - +SP_Q_PRIO=7 # Function to handle a queue order and # update total number of queues handle_q_order() { - qid="$1" #queue section ID + local qid="$1" #queue section ID - config_get is_enable "$qid" "enable" + config_get is_enable "$qid" "enable" 1 # No need to configure disabled queues if [ $is_enable == '0' ]; then @@ -36,7 +31,7 @@ handle_q_order() { # Create precedence file containing queue order per # interface. local precedence_file="/tmp/qos/$ifname/q_order" - local q_no=$(cat /tmp/qos/queue_stats/$ifname/q_idx) + local q_no=$(cat /tmp/qos/$ifname/q_idx) config_get precedence "$qid" "precedence" value=${precedence}_q${q_no} @@ -44,71 +39,32 @@ handle_q_order() { # Update the number of queues per interface. q_no=$((q_no + 1)) - echo $q_no > /tmp/qos/queue_stats/$ifname/q_idx + echo $q_no > /tmp/qos/$ifname/q_idx } -# Function to check if values are greater than (total number -# of queue -1) and map them to corresponding value. -configure_precedence_to_file() { - order="$1" - line="$2" - order_file="$3" - - if [ $order == "$PREV_ORDER" ]; then - queue_id=${line#*_} - val=${CURR_ORDER}_${queue_id} - echo $val >> $order_file - else - PREV_ORDER=$order - queue_id=${line#*_} - val=${MAX_ORDER}_${queue_id} - echo $val >> $order_file - CURR_ORDER=$MAX_ORDER - MAX_ORDER=$((MAX_ORDER - 1)) - fi -} - -# Fucntion to map queue precedence per interface -# ranging from 1-X to 0-(no of queues -1) -map_queue_precedence() { +# Sort queue, lower value in uci means higher precedence, so this +# function sorts the precedence in decending order +sort_q_by_precedence() { ifname="$1" - total_q=$(cat /tmp/qos/queue_stats/$ifname/q_idx) - q_no=`expr $total_q - 1` - MAX_ORDER=$q_no - - local precedence_file="/tmp/qos/$ifname/q_precedence" local order_file="/tmp/qos/$ifname/q_order" + local tmp_order_file="/tmp/qos/$ifname/q_order.tmp" - sort -n -r -k1 $order_file >> $precedence_file - rm $order_file - - while read line - do - order=${line%_*} - if [ $order -gt $q_no ]; then - ITER=$((ITER + 1)) - configure_precedence_to_file $order $line $order_file - else - if [ $ITER == '0' ]; then - echo $line >> $order_file - else - configure_precedence_to_file $order $line $order_file - fi - fi - - done < $precedence_file + sort -n -k1 $order_file > $tmp_order_file + cp $tmp_order_file $order_file + rm -f $tmp_order_file } -map_precedence() { +sort_by_precedence() { for interf in $(db -q get hw.board.ethernetPortOrder); do - map_queue_precedence $interf + sort_q_by_precedence $interf done } # function to handle a queue section handle_queue() { - qid="$1" #queue section ID + local qid="$1" #queue section ID + local intf_name="$2" config_get is_enable "$qid" "enable" @@ -124,33 +80,35 @@ handle_queue() { fi # This is to get the qid per interface. - if [ "$INTF_NAME" == $ifname ]; then - Q_COUNT=$((Q_COUNT + 1)) - else - Q_COUNT='0' + if [ "$intf_name" != "$ifname" ]; then + return fi - INTF_NAME=$ifname + local precedence_file="/tmp/qos/$ifname/q_order" - local total_q=$(cat /tmp/qos/queue_stats/$ifname/q_idx) - q_no=`expr $total_q - 1` local - precedence_file="/tmp/qos/$ifname/q_order" + local temp_order=0 + while read -r line; do + line_qid=${line: -1} + if [ "$line_qid" == "$Q_COUNT" ]; then + break + fi + temp_order=$((temp_order + 1)) + done < "$precedence_file" - # TR181 suggests lower the precedence value higher the priority - # but in the chip its the opposite ie lower the value, lower - # the priority of queue on this chip. So we need to reverse the - # precedence value. - precedence="$(grep -i q${Q_COUNT} $precedence_file)" - precedence=${precedence%_*} - order=`expr $q_no - $precedence` + # for sp queue, no matter what the precedence value is configured in the uci file + # broadcom recommends that the highest precedence queue should have priority value + #7, the next priority q 6 and so on. + # Here, we have the index of the queue when sorted by precedence value in the file + # precedence_file so the order is calculated accordingly. + local order=`expr $SP_Q_PRIO - $temp_order` config_get sc_alg "$qid" "scheduling" - config_get wgt "$qid" "weight" + config_get wgt "$qid" "weight" 1 config_get rate "$qid" "rate" config_get bs "$qid" "burst_size" config_get qsize "$qid" "queue_size" 1024 - salg=1 + local salg=1 case "$sc_alg" in "SP") salg=1 @@ -163,31 +121,15 @@ handle_queue() { ;; esac - # ignore precedence value in case of WRR + # ignore precedence value in case of WRR, broadcom recommends that WRR queue should + # always have precedence value set to 0 if [ $salg -eq 2 ]; then order=0 fi # Call tmctl which is a broadcomm command to configure queues on a port. tmctl setqcfg --devtype 0 --if $ifname --qid $Q_COUNT --priority $order --qsize $qsize --weight $wgt --schedmode $salg --shapingrate $rate --burstsize $bs - - # In BCM968 chips, the counters for queues are read, on other model, its read and reset. So, to maintain counter - # value and uniform behaviour, we are storing counter value for each queue in files - local d_name="/tmp/qos/queue_stats/${ifname}/q_${Q_COUNT}" - mkdir $d_name - local f_name="$d_name/txPackets" - touch $f_name - echo 0 > $f_name - f_name="$d_name/txBytes" - touch $f_name - echo 0 > $f_name - f_name="$d_name/droppedPackets" - touch $f_name - echo 0 > $f_name - f_name="$d_name/droppedBytes" - touch $f_name - echo 0 > $f_name - + Q_COUNT=$((Q_COUNT + 1)) } #function to handle a policer section @@ -1092,28 +1034,20 @@ configure_classify() { pre_configure_queue() { # Delete queues - rm -rf /tmp/qos/queue_stats - for intf in $(db get hw.board.ethernetPortOrder); do rm -rf /tmp/qos/$intf - mkdir -p /tmp/qos/queue_stats/$intf - touch /tmp/qos/queue_stats/$intf/q_idx - echo 0 > /tmp/qos/queue_stats/$intf/q_idx + mkdir -p /tmp/qos/$intf + touch /tmp/qos/$intf/q_order + touch /tmp/qos/$intf/q_idx + echo 0 > /tmp/qos/$intf/q_idx -# tm initialization pushing ahead of delcfg as -# porttminit bydefault configures all queue as SP configuration. -# that was causing WRR queue configuration failure. - tmctl porttminit --devtype 0 --if $intf --flag 0 --numqueues 8 + tmctl porttminit --devtype 0 --if $intf --numqueues 8 i=0 for i in 0 1 2 3 4 5 6 7; do tmctl delqcfg --devtype 0 --if $intf --qid $i &>/dev/null done - - mkdir -p /tmp/qos/$intf - touch /tmp/qos/$intf/q_order - touch /tmp/qos/$intf/q_precedence done } @@ -1121,8 +1055,15 @@ configure_queue() { # Load UCI file config_load qos config_foreach handle_q_order queue - map_precedence - config_foreach handle_queue queue + sort_by_precedence + for interf in $(db -q get hw.board.ethernetPortOrder); do + Q_COUNT=0 + # sp queue have max priority value = no. of queue configured on the port + # hence read and update SP_Q_PRIO here + local q_no=$(cat /tmp/qos/$interf/q_idx) + SP_Q_PRIO=`expr $q_no - 1` + config_foreach handle_queue queue $interf + done } configure_policer() {