Skip to content

Commit

Permalink
[watermarkstat] Fix issue of fields overwritten before display (sonic…
Browse files Browse the repository at this point in the history
…-net#862)

Fix the bug where the unicast/multicast queue watermark display was incorrect

- How I did it
Calculate the header list dynamically for PG and queue display
Display the correct queue numbers in the output instead of always starting the index from 0
Calculate the display position relative to the starting index

Signed-off-by: Neetha John <nejo@microsoft.com>
  • Loading branch information
neethajohn authored and abdosi committed Aug 3, 2020
1 parent 9a0be97 commit a531039
Showing 1 changed file with 34 additions and 14 deletions.
48 changes: 34 additions & 14 deletions scripts/watermarkstat
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ from natsort import natsorted
from tabulate import tabulate


headerPg = ['Port', 'PG0', 'PG1', 'PG2', 'PG3', 'PG4', 'PG5', 'PG6', 'PG7']
headerUc = ['Port', 'UC0', 'UC1', 'UC2', 'UC3', 'UC4', 'UC5', 'UC6', 'UC7']
headerMc = ['Port', 'MC8', 'MC9', 'MC10', 'MC11', 'MC12', 'MC13', 'MC14', 'MC15']
headerBufferPool = ['Pool', 'Bytes']


Expand Down Expand Up @@ -140,22 +137,22 @@ class Watermarkstat(object):
"obj_map" : self.port_pg_map,
"idx_func": self.get_pg_index,
"wm_name" : "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES",
"header" : headerPg},
"header_prefix": "PG"},
"pg_shared" : {"message" : "Ingress shared pool occupancy per PG:",
"obj_map" : self.port_pg_map,
"idx_func": self.get_pg_index,
"wm_name" : "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES",
"header" : headerPg},
"header_prefix": "PG"},
"q_shared_uni" : {"message" : "Egress shared pool occupancy per unicast queue:",
"obj_map" : self.port_uc_queues_map,
"idx_func": self.get_queue_index,
"wm_name" : "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
"header" : headerUc},
"header_prefix": "UC"},
"q_shared_multi": {"message" : "Egress shared pool occupancy per multicast queue:",
"obj_map" : self.port_mc_queues_map,
"idx_func": self.get_queue_index,
"wm_name" : "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
"header" : headerMc},
"header_prefix": "MC"},
"buffer_pool" : {"message": "Shared pool maximum occupancy:",
"wm_name": "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES",
"header" : headerBufferPool}
Expand All @@ -177,28 +174,48 @@ class Watermarkstat(object):

return pg_index

def build_header(self, wm_type):
if wm_type is None:
print >> sys.stderr, "Header info is not available!"
sys.exit(1)

self.header_list = ['Port']
header_map = wm_type["obj_map"]
single_key = header_map.keys()[0]
header_len = len(header_map[single_key])
min_idx = float("inf")

for name, counter_oid in header_map[single_key].items():
curr_idx = int(wm_type["idx_func"](counter_oid))
min_idx = min(min_idx, curr_idx)

self.min_idx = int(min_idx)
self.header_list += ["{}{}".format(wm_type["header_prefix"], idx) for idx in range(self.min_idx, self.min_idx + header_len)]

def get_counters(self, table_prefix, port_obj, idx_func, watermark):
"""
Get the counters from specific table.
"""

fields = ["0"] * 8
# header list contains the port name followed by the queues/pgs. fields is used to populate the queue/pg values
fields = ["0"]* (len(self.header_list) - 1)

for name, obj_id in port_obj.items():
full_table_id = table_prefix + obj_id
pos = int(idx_func(obj_id)) % len(fields)
idx = int(idx_func(obj_id))
pos = idx - self.min_idx
counter_data = self.counters_db.get(self.counters_db.COUNTERS_DB, full_table_id, watermark)
if counter_data is None:
fields[pos] = STATUS_NA
elif fields[pos] != STATUS_NA:
fields[pos] = str(int(counter_data))
cntr = tuple(fields)
return cntr
return fields

def print_all_stat(self, table_prefix, key):
table = []
type = self.watermark_types[key]
if key == 'buffer_pool':
self.header_list = type['header']
# Get stats for each buffer pool
for buf_pool, bp_oid in natsorted(self.buffer_pool_name_to_oid_map.items()):
key = table_prefix + bp_oid
Expand All @@ -207,15 +224,18 @@ class Watermarkstat(object):
data = STATUS_NA
table.append((buf_pool, data))
else:
self.build_header(type)
# Get stat for each port
for port in natsorted(self.counter_port_name_map):
row_data = list()
data = self.get_counters(table_prefix,
type["obj_map"][port], type["idx_func"], type["wm_name"])
table.append((port, data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]))
row_data.append(port)
row_data.extend(data)
table.append(tuple(row_data))

print(type["message"])
print tabulate(table, type["header"], tablefmt='simple', stralign='right')
print tabulate(table, self.header_list, tablefmt='simple', stralign='right')

def send_clear_notification(self, data):
msg = json.dumps(data, separators=(',', ':'))
Expand Down

0 comments on commit a531039

Please sign in to comment.