Skip to content

Commit b7fcb1f

Browse files
authored
Add buffer pool watermark support in watermarkstat and counterpoll (#521)
* Add buffer pool watermark support to watermarkstat Signed-off-by: Wenda Ni <wenni@microsoft.com> * Add buffer pool watermark to counterpoll Signed-off-by: Wenda Ni <wenni@microsoft.com> * Print N/A if the buffer pool watermark value is not present Signed-off-by: Wenda Ni <wenni@microsoft.com> * Fix syntax error; Change signature of function get_print_all_stat Signed-off-by: Wenda Ni <wenni@microsoft.com> * Address review comments Signed-off-by: Wenda Ni <wenni@microsoft.com>
1 parent 635dc88 commit b7fcb1f

File tree

3 files changed

+105
-47
lines changed

3 files changed

+105
-47
lines changed

counterpoll/main.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
import swsssdk
55
from tabulate import tabulate
66

7+
BUFFER_POOL_WATERMARK = "BUFFER_POOL_WATERMARK"
8+
DISABLE = "disable"
9+
DEFLT_10_SEC= "default (10000)"
10+
DEFLT_1_SEC = "default (1000)"
11+
712
@click.group()
813
def cli():
914
""" SONiC Static Counter Poll configurations """
@@ -123,11 +128,14 @@ def interval(poll_interval):
123128
configdb.connect()
124129
queue_wm_info = {}
125130
pg_wm_info = {}
131+
buffer_pool_wm_info = {}
126132
if poll_interval is not None:
127133
queue_wm_info['POLL_INTERVAL'] = poll_interval
128134
pg_wm_info['POLL_INTERVAL'] = poll_interval
135+
buffer_pool_wm_info['POLL_INTERVAL'] = poll_interval
129136
configdb.mod_entry("FLEX_COUNTER_TABLE", "QUEUE_WATERMARK", queue_wm_info)
130137
configdb.mod_entry("FLEX_COUNTER_TABLE", "PG_WATERMARK", pg_wm_info)
138+
configdb.mod_entry("FLEX_COUNTER_TABLE", BUFFER_POOL_WATERMARK, buffer_pool_wm_info)
131139

132140
@watermark.command()
133141
def enable():
@@ -138,6 +146,7 @@ def enable():
138146
fc_info['FLEX_COUNTER_STATUS'] = 'enable'
139147
configdb.mod_entry("FLEX_COUNTER_TABLE", "QUEUE_WATERMARK", fc_info)
140148
configdb.mod_entry("FLEX_COUNTER_TABLE", "PG_WATERMARK", fc_info)
149+
configdb.mod_entry("FLEX_COUNTER_TABLE", BUFFER_POOL_WATERMARK, fc_info)
141150

142151
@watermark.command()
143152
def disable():
@@ -148,6 +157,7 @@ def disable():
148157
fc_info['FLEX_COUNTER_STATUS'] = 'disable'
149158
configdb.mod_entry("FLEX_COUNTER_TABLE", "QUEUE_WATERMARK", fc_info)
150159
configdb.mod_entry("FLEX_COUNTER_TABLE", "PG_WATERMARK", fc_info)
160+
configdb.mod_entry("FLEX_COUNTER_TABLE", BUFFER_POOL_WATERMARK, fc_info)
151161

152162
@cli.command()
153163
def show():
@@ -159,19 +169,22 @@ def show():
159169
rif_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'RIF')
160170
queue_wm_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'QUEUE_WATERMARK')
161171
pg_wm_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'PG_WATERMARK')
172+
buffer_pool_wm_info = configdb.get_entry('FLEX_COUNTER_TABLE', BUFFER_POOL_WATERMARK)
162173

163174
header = ("Type", "Interval (in ms)", "Status")
164175
data = []
165176
if queue_info:
166-
data.append(["QUEUE_STAT", queue_info["POLL_INTERVAL"] if 'POLL_INTERVAL' in queue_info else 'default (10000)', queue_info["FLEX_COUNTER_STATUS"] if 'FLEX_COUNTER_STATUS' in queue_info else 'disable' ])
177+
data.append(["QUEUE_STAT", queue_info.get("POLL_INTERVAL", DEFLT_10_SEC), queue_info.get("FLEX_COUNTER_STATUS", DISABLE)])
167178
if port_info:
168-
data.append(["PORT_STAT", port_info["POLL_INTERVAL"] if 'POLL_INTERVAL' in port_info else 'default (1000)', port_info["FLEX_COUNTER_STATUS"] if 'FLEX_COUNTER_STATUS' in port_info else 'disable'])
179+
data.append(["PORT_STAT", port_info.get("POLL_INTERVAL", DEFLT_1_SEC), port_info.get("FLEX_COUNTER_STATUS", DISABLE)])
169180
if rif_info:
170-
data.append(["RIF_STAT", rif_info["POLL_INTERVAL"] if 'POLL_INTERVAL' in rif_info else 'default (1000)', rif_info["FLEX_COUNTER_STATUS"] if 'FLEX_COUNTER_STATUS' in rif_info else 'disable'])
181+
data.append(["RIF_STAT", rif_info.get("POLL_INTERVAL", DEFLT_1_SEC), rif_info.get("FLEX_COUNTER_STATUS", DISABLE)])
171182
if queue_wm_info:
172-
data.append(["QUEUE_WATERMARK_STAT", queue_wm_info["POLL_INTERVAL"] if 'POLL_INTERVAL' in queue_wm_info else 'default (10000)', queue_wm_info["FLEX_COUNTER_STATUS"] if 'FLEX_COUNTER_STATUS' in queue_wm_info else 'disable' ])
183+
data.append(["QUEUE_WATERMARK_STAT", queue_wm_info.get("POLL_INTERVAL", DEFLT_10_SEC), queue_wm_info.get("FLEX_COUNTER_STATUS", DISABLE)])
173184
if pg_wm_info:
174-
data.append(["PG_WATERMARK_STAT", pg_wm_info["POLL_INTERVAL"] if 'POLL_INTERVAL' in pg_wm_info else 'default (10000)', pg_wm_info["FLEX_COUNTER_STATUS"] if 'FLEX_COUNTER_STATUS' in pg_wm_info else 'disable'])
185+
data.append(["PG_WATERMARK_STAT", pg_wm_info.get("POLL_INTERVAL", DEFLT_10_SEC), pg_wm_info.get("FLEX_COUNTER_STATUS", DISABLE)])
186+
if buffer_pool_wm_info:
187+
data.append(["BUFFER_POOL_WATERMARK_STAT", buffer_pool_wm_info.get("POLL_INTERVAL", DEFLT_10_SEC), buffer_pool_wm_info.get("FLEX_COUNTER_STATUS", DISABLE)])
175188

176189
print tabulate(data, headers=header, tablefmt="simple", missingval="")
177190

scripts/watermarkstat

+64-39
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ from tabulate import tabulate
1818
headerPg = ['Port', 'PG0', 'PG1', 'PG2', 'PG3', 'PG4', 'PG5', 'PG6', 'PG7']
1919
headerUc = ['Port', 'UC0', 'UC1', 'UC2', 'UC3', 'UC4', 'UC5', 'UC6', 'UC7']
2020
headerMc = ['Port', 'MC8', 'MC9', 'MC10', 'MC11', 'MC12', 'MC13', 'MC14', 'MC15']
21+
headerBufferPool = ['Pool', 'Bytes']
2122

2223

2324
STATUS_NA = 'N/A'
@@ -43,6 +44,7 @@ COUNTERS_QUEUE_PORT_MAP = "COUNTERS_QUEUE_PORT_MAP"
4344
COUNTERS_PG_NAME_MAP = "COUNTERS_PG_NAME_MAP"
4445
COUNTERS_PG_PORT_MAP = "COUNTERS_PG_PORT_MAP"
4546
COUNTERS_PG_INDEX_MAP = "COUNTERS_PG_INDEX_MAP"
47+
COUNTERS_BUFFER_POOL_NAME_MAP = "COUNTERS_BUFFER_POOL_NAME_MAP"
4648

4749

4850
class Watermarkstat(object):
@@ -58,7 +60,7 @@ class Watermarkstat(object):
5860
def get_queue_type(table_id):
5961
queue_type = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_QUEUE_TYPE_MAP, table_id)
6062
if queue_type is None:
61-
print "Queue Type is not available!", table_id
63+
print >> sys.stderr, "Queue Type is not available!", table_id
6264
sys.exit(1)
6365
elif queue_type == SAI_QUEUE_TYPE_MULTICAST:
6466
return QUEUE_TYPE_MC
@@ -67,29 +69,29 @@ class Watermarkstat(object):
6769
elif queue_type == SAI_QUEUE_TYPE_ALL:
6870
return QUEUE_TYPE_ALL
6971
else:
70-
print "Queue Type is invalid:", table_id, queue_type
72+
print >> sys.stderr, "Queue Type is invalid:", table_id, queue_type
7173
sys.exit(1)
7274

7375
def get_queue_port(table_id):
7476
port_table_id = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_QUEUE_PORT_MAP, table_id)
7577
if port_table_id is None:
76-
print "Port is not available!", table_id
78+
print >> sys.stderr, "Port is not available!", table_id
7779
sys.exit(1)
7880

7981
return port_table_id
8082

8183
def get_pg_port(table_id):
8284
port_table_id = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_PG_PORT_MAP, table_id)
8385
if port_table_id is None:
84-
print "Port is not available!", table_id
86+
print >> sys.stderr, "Port is not available!", table_id
8587
sys.exit(1)
8688

8789
return port_table_id
8890

8991
# Get all ports
9092
self.counter_port_name_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP)
9193
if self.counter_port_name_map is None:
92-
print "COUNTERS_PORT_NAME_MAP is empty!"
94+
print >> sys.stderr, "COUNTERS_PORT_NAME_MAP is empty!"
9395
sys.exit(1)
9496

9597
self.port_uc_queues_map = {}
@@ -106,7 +108,7 @@ class Watermarkstat(object):
106108
# Get Queues for each port
107109
counter_queue_name_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, COUNTERS_QUEUE_NAME_MAP)
108110
if counter_queue_name_map is None:
109-
print "COUNTERS_QUEUE_NAME_MAP is empty!"
111+
print >> sys.stderr, "COUNTERS_QUEUE_NAME_MAP is empty!"
110112
sys.exit(1)
111113

112114
for queue in counter_queue_name_map:
@@ -120,48 +122,57 @@ class Watermarkstat(object):
120122
# Get PGs for each port
121123
counter_pg_name_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, COUNTERS_PG_NAME_MAP)
122124
if counter_pg_name_map is None:
123-
print "COUNTERS_PG_NAME_MAP is empty!"
125+
print >> sys.stderr, "COUNTERS_PG_NAME_MAP is empty!"
124126
sys.exit(1)
125127

126128
for pg in counter_pg_name_map:
127129
port = self.port_name_map[get_pg_port(counter_pg_name_map[pg])]
128130
self.port_pg_map[port][pg] = counter_pg_name_map[pg]
129131

132+
# Get all buffer pools
133+
self.buffer_pool_name_to_oid_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, COUNTERS_BUFFER_POOL_NAME_MAP)
134+
if self.buffer_pool_name_to_oid_map is None:
135+
print >> sys.stderr, "COUNTERS_BUFFER_POOL_NAME_MAP is empty!"
136+
sys.exit(1)
137+
130138
self.watermark_types = {
131-
"pg_headroom": {"message": "Ingress headroom per PG:",
132-
"obj_map": self.port_pg_map,
133-
"idx_func": self.get_pg_index,
134-
"wm_name": "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES",
135-
"header": headerPg},
136-
"pg_shared": {"message": "Ingress shared pool occupancy per PG:",
137-
"obj_map": self.port_pg_map,
138-
"idx_func": self.get_pg_index,
139-
"wm_name": "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES",
140-
"header": headerPg},
141-
"q_shared_uni": {"message": "Egress shared pool occupancy per unicast queue:",
142-
"obj_map": self.port_uc_queues_map,
143-
"idx_func": self.get_queue_index,
144-
"wm_name": "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
145-
"header": headerUc},
146-
"q_shared_multi": {"message": "Egress shared pool occupancy per multicast queue:",
147-
"obj_map": self.port_mc_queues_map,
148-
"idx_func": self.get_queue_index,
149-
"wm_name": "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
150-
"header": headerMc}
139+
"pg_headroom" : {"message" : "Ingress headroom per PG:",
140+
"obj_map" : self.port_pg_map,
141+
"idx_func": self.get_pg_index,
142+
"wm_name" : "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES",
143+
"header" : headerPg},
144+
"pg_shared" : {"message" : "Ingress shared pool occupancy per PG:",
145+
"obj_map" : self.port_pg_map,
146+
"idx_func": self.get_pg_index,
147+
"wm_name" : "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES",
148+
"header" : headerPg},
149+
"q_shared_uni" : {"message" : "Egress shared pool occupancy per unicast queue:",
150+
"obj_map" : self.port_uc_queues_map,
151+
"idx_func": self.get_queue_index,
152+
"wm_name" : "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
153+
"header" : headerUc},
154+
"q_shared_multi": {"message" : "Egress shared pool occupancy per multicast queue:",
155+
"obj_map" : self.port_mc_queues_map,
156+
"idx_func": self.get_queue_index,
157+
"wm_name" : "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
158+
"header" : headerMc},
159+
"buffer_pool" : {"message": "Shared pool maximum occupancy:",
160+
"wm_name": "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES",
161+
"header" : headerBufferPool}
151162
}
152163

153164
def get_queue_index(self, table_id):
154165
queue_index = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_QUEUE_INDEX_MAP, table_id)
155166
if queue_index is None:
156-
print "Queue index is not available!", table_id
167+
print >> sys.stderr, "Queue index is not available!", table_id
157168
sys.exit(1)
158169

159170
return queue_index
160171

161172
def get_pg_index(self, table_id):
162173
pg_index = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_PG_INDEX_MAP, table_id)
163174
if pg_index is None:
164-
print "Priority group index is not available!", table_id
175+
print >> sys.stderr, "Priority group index is not available!", table_id
165176
sys.exit(1)
166177

167178
return pg_index
@@ -171,7 +182,7 @@ class Watermarkstat(object):
171182
Get the counters from specific table.
172183
"""
173184

174-
fields = ["0"]*8
185+
fields = ["0"] * 8
175186

176187
for name, obj_id in port_obj.items():
177188
full_table_id = table_prefix + obj_id
@@ -184,14 +195,25 @@ class Watermarkstat(object):
184195
cntr = tuple(fields)
185196
return cntr
186197

187-
def get_print_all_stat(self, table_prefix, type):
188-
# Get stat for each port
198+
def print_all_stat(self, table_prefix, key):
189199
table = []
190-
for port in natsorted(self.counter_port_name_map):
191-
data = self.get_counters(table_prefix,
192-
type["obj_map"][port], type["idx_func"], type["wm_name"])
193-
table.append((port, data[0], data[1], data[2], data[3],
194-
data[4], data[5], data[6], data[7]))
200+
type = self.watermark_types[key]
201+
if key == 'buffer_pool':
202+
# Get stats for each buffer pool
203+
for buf_pool, bp_oid in natsorted(self.buffer_pool_name_to_oid_map.items()):
204+
key = table_prefix + bp_oid
205+
data = self.counters_db.get(self.counters_db.COUNTERS_DB, key, type["wm_name"])
206+
if data is None:
207+
data = STATUS_NA
208+
table.append((buf_pool, data))
209+
else:
210+
# Get stat for each port
211+
for port in natsorted(self.counter_port_name_map):
212+
data = self.get_counters(table_prefix,
213+
type["obj_map"][port], type["idx_func"], type["wm_name"])
214+
table.append((port, data[0], data[1], data[2], data[3],
215+
data[4], data[5], data[6], data[7]))
216+
195217
print(type["message"])
196218
print tabulate(table, type["header"], tablefmt='simple', stralign='right')
197219

@@ -214,12 +236,15 @@ Examples:
214236
watermarkstat -t q_shared_multi -c
215237
watermarkstat -p -t pg_shared
216238
watermarkstat -p -t q_shared_multi -c
239+
watermarkstat -t buffer_pool
240+
watermarkstat -t buffer_pool -c
241+
watermarkstat -p -t buffer_pool -c
217242
""")
218243

219244
parser.add_argument('-c', '--clear', action='store_true', help='Clear watermarks request')
220245
parser.add_argument('-p', '--persistent', action='store_true', help='Do the operations on the persistent watermark')
221246
parser.add_argument('-t', '--type', required=True, action='store',
222-
choices=['pg_headroom', 'pg_shared', 'q_shared_uni', 'q_shared_multi'],
247+
choices=['pg_headroom', 'pg_shared', 'q_shared_uni', 'q_shared_multi', 'buffer_pool'],
223248
help='The type of watermark')
224249
args = parser.parse_args()
225250
watermarkstat = Watermarkstat()
@@ -229,7 +254,7 @@ Examples:
229254
sys.exit(0)
230255

231256
table_prefix = PERSISTENT_TABLE_PREFIX if args.persistent else USER_TABLE_PREFIX
232-
watermarkstat.get_print_all_stat(table_prefix, watermarkstat.watermark_types[args.type])
257+
watermarkstat.print_all_stat(table_prefix, args.type)
233258
sys.exit(0)
234259

235260

show/main.py

+23-3
Original file line numberDiff line numberDiff line change
@@ -747,10 +747,9 @@ def pwm_q_multi():
747747
def priority_group():
748748
"""Show details of the PGs """
749749

750-
751750
@priority_group.group()
752751
def watermark():
753-
"""Show priority_group user WM"""
752+
"""Show priority-group user WM"""
754753
pass
755754

756755
@watermark.command('headroom')
@@ -767,7 +766,7 @@ def wm_pg_shared():
767766

768767
@priority_group.group(name='persistent-watermark')
769768
def persistent_watermark():
770-
"""Show queue persistent WM"""
769+
"""Show priority-group persistent WM"""
771770
pass
772771

773772
@persistent_watermark.command('headroom')
@@ -783,6 +782,27 @@ def pwm_pg_shared():
783782
run_command(command)
784783

785784

785+
#
786+
# 'buffer_pool' group ("show buffer_pool ...")
787+
#
788+
789+
@cli.group(name='buffer_pool', cls=AliasedGroup, default_if_no_args=False)
790+
def buffer_pool():
791+
"""Show details of the buffer pools"""
792+
793+
@buffer_pool.command('watermark')
794+
def wm_buffer_pool():
795+
"""Show user WM for buffer pools"""
796+
command = 'watermarkstat -t buffer_pool'
797+
run_command(command)
798+
799+
@buffer_pool.command('persistent-watermark')
800+
def pwm_buffer_pool():
801+
"""Show persistent WM for buffer pools"""
802+
command = 'watermarkstat -p -t buffer_pool'
803+
run_command(command)
804+
805+
786806
#
787807
# 'mac' command ("show mac ...")
788808
#

0 commit comments

Comments
 (0)