Skip to content

Commit

Permalink
sonic-utilities: WRED stats feature changes on sonic-utilities
Browse files Browse the repository at this point in the history
* New script for wredstat CLI commands
* portstat script updated to accomodate WRED port stats
* counterpoll script updated to support wredport and wredqueue counters
* CLi to script mapping changes
* UT for the new script changes

Signed-off-by: rpmarvell <[email protected]>
  • Loading branch information
rpmarvell committed Apr 30, 2023
1 parent 7443b9e commit a22be8b
Show file tree
Hide file tree
Showing 9 changed files with 2,263 additions and 5 deletions.
6 changes: 6 additions & 0 deletions clear/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ def clear_wm_q_all():
command = ['watermarkstat', '-c', '-t', 'q_shared_all']
run_command(command)

@queue.group(name='wredcounters')
def wredcounters():
"""Clear queue wredcounters"""
command = "wredstat -c"
run_command(command)

@queue.group(name='persistent-watermark')
def persistent_watermark():
"""Clear queue persistent WM. One does not simply clear WM, root is required"""
Expand Down
74 changes: 74 additions & 0 deletions counterpoll/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,74 @@ def disable(ctx):
fc_info['FLEX_COUNTER_STATUS'] = 'disable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_ROUTE", fc_info)

# WRED queue counter commands
@cli.group()
def wredqueue():
""" WRED queue counter commands """

@wredqueue.command()
@click.argument('poll_interval', type=click.IntRange(100, 30000))
def interval(poll_interval):
""" Set wred queue counter query interval """
configdb = ConfigDBConnector()
configdb.connect()
wred_queue_info = {}
if poll_interval is not None:
wred_queue_info['POLL_INTERVAL'] = poll_interval
configdb.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_QUEUE", wred_queue_info)

@wredqueue.command()
def enable():
""" Enable wred queue counter query """
configdb = ConfigDBConnector()
configdb.connect()
wred_queue_info = {}
wred_queue_info['FLEX_COUNTER_STATUS'] = 'enable'
configdb.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_QUEUE", wred_queue_info)

@wredqueue.command()
def disable():
""" Disable wred queue counter query """
configdb = ConfigDBConnector()
configdb.connect()
wred_queue_info = {}
wred_queue_info['FLEX_COUNTER_STATUS'] = 'disable'
configdb.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_QUEUE", wred_queue_info)

# WRED port counter commands
@cli.group()
def wredport():
""" WRED port counter commands """

@wredport.command()
@click.argument('poll_interval', type=click.IntRange(100, 30000))
def interval(poll_interval):
""" Set wred port counter query interval """
configdb = ConfigDBConnector()
configdb.connect()
wred_port_info = {}
if poll_interval is not None:
wred_port_info['POLL_INTERVAL'] = poll_interval
configdb.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_PORT", wred_port_info)

@wredport.command()
def enable():
""" Enable wred port counter query """
configdb = ConfigDBConnector()
configdb.connect()
wred_port_info = {}
wred_port_info['FLEX_COUNTER_STATUS'] = 'enable'
configdb.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_PORT", wred_port_info)

@wredport.command()
def disable():
""" Disable wred port counter query """
configdb = ConfigDBConnector()
configdb.connect()
wred_port_info = {}
wred_port_info['FLEX_COUNTER_STATUS'] = 'disable'
configdb.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_PORT", wred_port_info)

@cli.command()
def show():
""" Show the counter configuration """
Expand All @@ -399,6 +467,8 @@ def show():
tunnel_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'TUNNEL')
trap_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_TRAP')
route_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_ROUTE')
wred_queue_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'WRED_ECN_QUEUE')
wred_port_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'WRED_ECN_PORT')

header = ("Type", "Interval (in ms)", "Status")
data = []
Expand Down Expand Up @@ -427,6 +497,10 @@ def show():
if route_info:
data.append(["FLOW_CNT_ROUTE_STAT", route_info.get("POLL_INTERVAL", DEFLT_10_SEC),
route_info.get("FLEX_COUNTER_STATUS", DISABLE)])
if wred_queue_info:
data.append(["WRED_ECN_QUEUE_STAT", wred_queue_info.get("POLL_INTERVAL", DEFLT_10_SEC), wred_queue_info.get("FLEX_COUNTER_STATUS", DISABLE)])
if wred_port_info:
data.append(["WRED_ECN_PORT_STAT", wred_port_info.get("POLL_INTERVAL", DEFLT_1_SEC), wred_port_info.get("FLEX_COUNTER_STATUS", DISABLE)])

click.echo(tabulate(data, headers=header, tablefmt="simple", missingval=""))

Expand Down
78 changes: 78 additions & 0 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -7984,6 +7984,7 @@ This sub-section explains the following queue parameters that can be displayed u
2) queue watermark
3) priority-group watermark
4) queue persistent-watermark
5) queue wredcounters
**show queue counters**
Expand Down Expand Up @@ -8177,6 +8178,83 @@ This command displays the user persistet-watermark for the queues (Egress shared
admin@sonic:~$ sonic-clear priority-group drop counters
```
**show queue wredcounters**
This command displays wred-drop packet/byte and ecn-marked packet/byte counters for all queues of all ports or one specific-port given as arguement.
This command can be used to clear the counters for all queues of all ports. Note that port specific clear is not supported.
- Usage:
```
show queue wredcounters [<interface_name>]
```
- Example:
```
admin@sonic:~$ show queue wredcounters
Port TxQ WredDrp/pkts WredDrp/bytes EcnMarked/pkts EcnMarked/bytes
--------- ----- -------------- --------------- --------------- ----------------
Ethernet0 UC0 0 0 0 0
Ethernet0 UC1 0 0 0 0
Ethernet0 UC2 0 0 0 0
Ethernet0 UC3 0 0 0 0
Ethernet0 UC4 0 0 0 0
Ethernet0 UC5 0 0 0 0
Ethernet0 UC6 0 0 0 0
Ethernet0 UC7 0 0 0 0
Ethernet0 UC8 0 0 0 0
Ethernet0 UC9 0 0 0 0
Ethernet0 MC0 0 0 0 0
Ethernet0 MC1 0 0 0 0
Ethernet0 MC2 0 0 0 0
Ethernet0 MC3 0 0 0 0
Ethernet0 MC4 0 0 0 0
Ethernet0 MC5 0 0 0 0
Ethernet0 MC6 0 0 0 0
Ethernet0 MC7 0 0 0 0
Ethernet0 MC8 0 0 0 0
Ethernet0 MC9 0 0 0 0
Port TxQ WredDrp/pkts WredDrp/bytes EcnMarked/pkts EcnMarked/bytes
--------- ----- -------------- --------------- --------------- ----------------
Ethernet4 UC0 0 0 0 0
Ethernet4 UC1 0 0 0 0
Ethernet4 UC2 0 0 0 0
Ethernet4 UC3 0 0 0 0
Ethernet4 UC4 0 0 0 0
Ethernet4 UC5 0 0 0 0
Ethernet4 UC6 0 0 0 0
Ethernet4 UC7 0 0 0 0
Ethernet4 UC8 0 0 0 0
Ethernet4 UC9 0 0 0 0
Ethernet4 MC0 0 0 0 0
Ethernet4 MC1 0 0 0 0
Ethernet4 MC2 0 0 0 0
Ethernet4 MC3 0 0 0 0
Ethernet4 MC4 0 0 0 0
Ethernet4 MC5 0 0 0 0
Ethernet4 MC6 0 0 0 0
Ethernet4 MC7 0 0 0 0
Ethernet4 MC8 0 0 0 0
Ethernet4 MC9 0 0 0 0
...
```
Optionally, you can specify an interface name in order to display only that particular interface
- Example:
```
admin@sonic:~$ show queue wredcounters Ethernet72
```
- NOTE: Queue counters can be cleared by the user with the following command:
```
admin@sonic:~$ sonic-clear queue wredcounters
```
#### Buffer Pool
This sub-section explains the following buffer pool parameters that can be displayed using "show buffer_pool" command.
Expand Down
56 changes: 52 additions & 4 deletions scripts/portstat
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\
tx_64, tx_65_127, tx_128_255, tx_256_511, tx_512_1023, tx_1024_1518, tx_1519_2047, tx_2048_4095, tx_4096_9216, tx_9217_16383,\
tx_uca, tx_mca, tx_bca, tx_all,\
rx_jbr, rx_frag, rx_usize, rx_ovrrun,\
fec_corr, fec_uncorr, fec_symbol_err")
fec_corr, fec_uncorr, fec_symbol_err,\
wred_grn_drp_pkt, wred_ylw_drp_pkt, wred_red_drp_pkt, wred_tot_drp_pkt")
header_all = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_PPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR',
'TX_OK', 'TX_BPS', 'TX_PPS', 'TX_UTIL', 'TX_ERR', 'TX_DRP', 'TX_OVR']
header_std = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR',
Expand All @@ -70,7 +71,13 @@ RateStats = namedtuple("RateStats", ratestat_fields)
The order and count of statistics mentioned below needs to be in sync with the values in portstat script
So, any fields added/deleted in here should be reflected in portstat script also
"""
BUCKET_NUM = 45
BUCKET_NUM = 49

wred_green_pkt_stat_capable = False
wred_yellow_pkt_stat_capable = False
wred_red_pkt_stat_capable = False
wred_total_pkt_stat_capable = False

counter_bucket_dict = {
0:['SAI_PORT_STAT_IF_IN_UCAST_PKTS', 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS'],
1:['SAI_PORT_STAT_IF_IN_ERRORS'],
Expand Down Expand Up @@ -116,7 +123,11 @@ counter_bucket_dict = {
41:['SAI_PORT_STAT_IP_IN_RECEIVES'],
42:['SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES'],
43:['SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES'],
44:['SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS']
44:['SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS'],
45:['SAI_PORT_STAT_GREEN_WRED_DROPPED_PACKETS'],
46:['SAI_PORT_STAT_YELLOW_WRED_DROPPED_PACKETS'],
47:['SAI_PORT_STAT_RED_WRED_DROPPED_PACKETS'],
48:['SAI_PORT_STAT_WRED_DROPPED_PACKETS']
}

STATUS_NA = 'N/A'
Expand Down Expand Up @@ -170,6 +181,32 @@ class Portstat(object):
"""
Get the counters from specific table.
"""

global BUCKET_NUM

global wred_green_pkt_stat_capable
global wred_yellow_pkt_stat_capable
global wred_red_pkt_stat_capable
global wred_total_pkt_stat_capable
wred_green_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_GREEN_DROP_PKT_COUNTER","isSupported")
wred_yellow_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_YELLOW_DROP_PKT_COUNTER","isSupported")
wred_red_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_RED_DROP_PKT_COUNTER","isSupported")
wred_total_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_TOTAL_DROP_PKT_COUNTER","isSupported")

# Remove the unsupported stats from the counter dict
if wred_green_pkt_stat_capable != "true" and ('SAI_PORT_STAT_GREEN_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_GREEN_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)
if wred_yellow_pkt_stat_capable != "true" and ('SAI_PORT_STAT_YELLOW_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_YELLOW_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)
if wred_red_pkt_stat_capable != "true" and ('SAI_PORT_STAT_RED_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_RED_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)
if wred_total_pkt_stat_capable != "true" and ('SAI_PORT_STAT_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)

fields = ["0"]*BUCKET_NUM

_, fvs = counter_table.get(PortCounter(), port)
Expand Down Expand Up @@ -399,9 +436,20 @@ class Portstat(object):
print("Unicast Packets Transmitted.................... {}".format(ns_diff(cntr.tx_uca, old_cntr.tx_uca)))
print("Multicast Packets Transmitted.................. {}".format(ns_diff(cntr.tx_mca, old_cntr.tx_mca)))
print("Broadcast Packets Transmitted.................. {}".format(ns_diff(cntr.tx_bca, old_cntr.tx_bca)))

print("Time Since Counters Last Cleared............... " + str(cnstat_old_dict.get('time')))

if wred_green_pkt_stat_capable == "true" or wred_yellow_pkt_stat_capable == "true" or wred_red_pkt_stat_capable == "true" or wred_total_pkt_stat_capable == "true":
print("")
if wred_green_pkt_stat_capable == "true":
print("WRED Green Dropped Packets..................... {}".format(ns_diff(cntr.wred_grn_drp_pkt, old_cntr.wred_grn_drp_pkt)))
if wred_yellow_pkt_stat_capable == "true":
print("WRED Yellow Dropped Packets.................... {}".format(ns_diff(cntr.wred_ylw_drp_pkt, old_cntr.wred_ylw_drp_pkt)))
if wred_red_pkt_stat_capable == "true":
print("WRED Red Dropped Packets....................... {}".format(ns_diff(cntr.wred_red_drp_pkt, old_cntr.wred_red_drp_pkt)))
if wred_total_pkt_stat_capable == "true":
print("WRED Total Dropped Packets..................... {}".format(ns_diff(cntr.wred_tot_drp_pkt, old_cntr.wred_tot_drp_pkt)))



def cnstat_diff_print(self, cnstat_new_dict, cnstat_old_dict,
ratestat_dict, intf_list, use_json,
Expand Down
Loading

0 comments on commit a22be8b

Please sign in to comment.