@@ -18,6 +18,7 @@ from tabulate import tabulate
18
18
headerPg = ['Port' , 'PG0' , 'PG1' , 'PG2' , 'PG3' , 'PG4' , 'PG5' , 'PG6' , 'PG7' ]
19
19
headerUc = ['Port' , 'UC0' , 'UC1' , 'UC2' , 'UC3' , 'UC4' , 'UC5' , 'UC6' , 'UC7' ]
20
20
headerMc = ['Port' , 'MC8' , 'MC9' , 'MC10' , 'MC11' , 'MC12' , 'MC13' , 'MC14' , 'MC15' ]
21
+ headerBufferPool = ['Pool' , 'Bytes' ]
21
22
22
23
23
24
STATUS_NA = 'N/A'
@@ -43,6 +44,7 @@ COUNTERS_QUEUE_PORT_MAP = "COUNTERS_QUEUE_PORT_MAP"
43
44
COUNTERS_PG_NAME_MAP = "COUNTERS_PG_NAME_MAP"
44
45
COUNTERS_PG_PORT_MAP = "COUNTERS_PG_PORT_MAP"
45
46
COUNTERS_PG_INDEX_MAP = "COUNTERS_PG_INDEX_MAP"
47
+ COUNTERS_BUFFER_POOL_NAME_MAP = "COUNTERS_BUFFER_POOL_NAME_MAP"
46
48
47
49
48
50
class Watermarkstat (object ):
@@ -58,7 +60,7 @@ class Watermarkstat(object):
58
60
def get_queue_type (table_id ):
59
61
queue_type = self .counters_db .get (self .counters_db .COUNTERS_DB , COUNTERS_QUEUE_TYPE_MAP , table_id )
60
62
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
62
64
sys .exit (1 )
63
65
elif queue_type == SAI_QUEUE_TYPE_MULTICAST :
64
66
return QUEUE_TYPE_MC
@@ -67,29 +69,29 @@ class Watermarkstat(object):
67
69
elif queue_type == SAI_QUEUE_TYPE_ALL :
68
70
return QUEUE_TYPE_ALL
69
71
else :
70
- print "Queue Type is invalid:" , table_id , queue_type
72
+ print >> sys . stderr , "Queue Type is invalid:" , table_id , queue_type
71
73
sys .exit (1 )
72
74
73
75
def get_queue_port (table_id ):
74
76
port_table_id = self .counters_db .get (self .counters_db .COUNTERS_DB , COUNTERS_QUEUE_PORT_MAP , table_id )
75
77
if port_table_id is None :
76
- print "Port is not available!" , table_id
78
+ print >> sys . stderr , "Port is not available!" , table_id
77
79
sys .exit (1 )
78
80
79
81
return port_table_id
80
82
81
83
def get_pg_port (table_id ):
82
84
port_table_id = self .counters_db .get (self .counters_db .COUNTERS_DB , COUNTERS_PG_PORT_MAP , table_id )
83
85
if port_table_id is None :
84
- print "Port is not available!" , table_id
86
+ print >> sys . stderr , "Port is not available!" , table_id
85
87
sys .exit (1 )
86
88
87
89
return port_table_id
88
90
89
91
# Get all ports
90
92
self .counter_port_name_map = self .counters_db .get_all (self .counters_db .COUNTERS_DB , COUNTERS_PORT_NAME_MAP )
91
93
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!"
93
95
sys .exit (1 )
94
96
95
97
self .port_uc_queues_map = {}
@@ -106,7 +108,7 @@ class Watermarkstat(object):
106
108
# Get Queues for each port
107
109
counter_queue_name_map = self .counters_db .get_all (self .counters_db .COUNTERS_DB , COUNTERS_QUEUE_NAME_MAP )
108
110
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!"
110
112
sys .exit (1 )
111
113
112
114
for queue in counter_queue_name_map :
@@ -120,48 +122,57 @@ class Watermarkstat(object):
120
122
# Get PGs for each port
121
123
counter_pg_name_map = self .counters_db .get_all (self .counters_db .COUNTERS_DB , COUNTERS_PG_NAME_MAP )
122
124
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!"
124
126
sys .exit (1 )
125
127
126
128
for pg in counter_pg_name_map :
127
129
port = self .port_name_map [get_pg_port (counter_pg_name_map [pg ])]
128
130
self .port_pg_map [port ][pg ] = counter_pg_name_map [pg ]
129
131
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
+
130
138
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 }
151
162
}
152
163
153
164
def get_queue_index (self , table_id ):
154
165
queue_index = self .counters_db .get (self .counters_db .COUNTERS_DB , COUNTERS_QUEUE_INDEX_MAP , table_id )
155
166
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
157
168
sys .exit (1 )
158
169
159
170
return queue_index
160
171
161
172
def get_pg_index (self , table_id ):
162
173
pg_index = self .counters_db .get (self .counters_db .COUNTERS_DB , COUNTERS_PG_INDEX_MAP , table_id )
163
174
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
165
176
sys .exit (1 )
166
177
167
178
return pg_index
@@ -171,7 +182,7 @@ class Watermarkstat(object):
171
182
Get the counters from specific table.
172
183
"""
173
184
174
- fields = ["0" ]* 8
185
+ fields = ["0" ] * 8
175
186
176
187
for name , obj_id in port_obj .items ():
177
188
full_table_id = table_prefix + obj_id
@@ -184,14 +195,25 @@ class Watermarkstat(object):
184
195
cntr = tuple (fields )
185
196
return cntr
186
197
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 ):
189
199
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
+
195
217
print (type ["message" ])
196
218
print tabulate (table , type ["header" ], tablefmt = 'simple' , stralign = 'right' )
197
219
@@ -214,12 +236,15 @@ Examples:
214
236
watermarkstat -t q_shared_multi -c
215
237
watermarkstat -p -t pg_shared
216
238
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
217
242
""" )
218
243
219
244
parser .add_argument ('-c' , '--clear' , action = 'store_true' , help = 'Clear watermarks request' )
220
245
parser .add_argument ('-p' , '--persistent' , action = 'store_true' , help = 'Do the operations on the persistent watermark' )
221
246
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' ],
223
248
help = 'The type of watermark' )
224
249
args = parser .parse_args ()
225
250
watermarkstat = Watermarkstat ()
@@ -229,7 +254,7 @@ Examples:
229
254
sys .exit (0 )
230
255
231
256
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 )
233
258
sys .exit (0 )
234
259
235
260
0 commit comments