@@ -18,6 +18,13 @@ PfcWatchdog::QueueCounterIds::QueueCounterIds(
18
18
{
19
19
}
20
20
21
+ PfcWatchdog::QueueAttrIds::QueueAttrIds (
22
+ _In_ sai_object_id_t queue,
23
+ _In_ const std::vector<sai_queue_attr_t > &queueIds):
24
+ queueId(queue), queueAttrIds(queueIds)
25
+ {
26
+ }
27
+
21
28
void PfcWatchdog::setPortCounterList (
22
29
_In_ sai_object_id_t portVid,
23
30
_In_ sai_object_id_t portId,
@@ -64,6 +71,30 @@ void PfcWatchdog::setQueueCounterList(
64
71
wd.startWatchdogThread ();
65
72
}
66
73
74
+ void PfcWatchdog::setQueueAttrList (
75
+ _In_ sai_object_id_t queueVid,
76
+ _In_ sai_object_id_t queueId,
77
+ _In_ const std::vector<sai_queue_attr_t > &attrIds)
78
+ {
79
+ SWSS_LOG_ENTER ();
80
+
81
+ PfcWatchdog &wd = getInstance ();
82
+
83
+ auto it = wd.m_queueAttrIdsMap .find (queueVid);
84
+ if (it != wd.m_queueAttrIdsMap .end ())
85
+ {
86
+ (*it).second ->queueAttrIds = attrIds;
87
+ return ;
88
+ }
89
+
90
+ auto queueAttrIds = std::make_shared<QueueAttrIds>(queueId, attrIds);
91
+ wd.m_queueAttrIdsMap .emplace (queueVid, queueAttrIds);
92
+
93
+ // Start watchdog thread in case it was not running due to empty counter IDs map
94
+ wd.startWatchdogThread ();
95
+ }
96
+
97
+
67
98
void PfcWatchdog::removePort (
68
99
_In_ sai_object_id_t portVid)
69
100
{
@@ -81,7 +112,7 @@ void PfcWatchdog::removePort(
81
112
wd.m_portCounterIdsMap .erase (it);
82
113
83
114
// Stop watchdog thread if counter IDs map is empty
84
- if (wd.m_queueCounterIdsMap .empty () && wd.m_portCounterIdsMap .empty ())
115
+ if (wd.m_queueCounterIdsMap .empty () && wd.m_portCounterIdsMap .empty () && wd. m_queueAttrIdsMap . empty () )
85
116
{
86
117
wd.endWatchdogThread ();
87
118
}
@@ -94,17 +125,26 @@ void PfcWatchdog::removeQueue(
94
125
95
126
PfcWatchdog &wd = getInstance ();
96
127
97
- auto it = wd.m_queueCounterIdsMap .find (queueVid);
98
- if (it == wd.m_queueCounterIdsMap .end ())
128
+ auto counterIter = wd.m_queueCounterIdsMap .find (queueVid);
129
+ if (counterIter == wd.m_queueCounterIdsMap .end ())
99
130
{
100
131
SWSS_LOG_ERROR (" Trying to remove nonexisting queue counter Ids 0x%lx" , queueVid);
101
132
return ;
102
133
}
103
134
104
- wd.m_queueCounterIdsMap .erase (it);
135
+ wd.m_queueCounterIdsMap .erase (counterIter);
136
+
137
+ auto attrIter = wd.m_queueAttrIdsMap .find (queueVid);
138
+ if (attrIter == wd.m_queueAttrIdsMap .end ())
139
+ {
140
+ SWSS_LOG_ERROR (" Trying to remove nonexisting queue attr Ids 0x%lx" , queueVid);
141
+ return ;
142
+ }
143
+
144
+ wd.m_queueAttrIdsMap .erase (attrIter);
105
145
106
146
// Stop watchdog thread if counter IDs map is empty
107
- if (wd.m_queueCounterIdsMap .empty () && wd.m_portCounterIdsMap .empty ())
147
+ if (wd.m_queueCounterIdsMap .empty () && wd.m_portCounterIdsMap .empty () && wd. m_queueAttrIdsMap . empty () )
108
148
{
109
149
wd.endWatchdogThread ();
110
150
}
@@ -176,8 +216,6 @@ void PfcWatchdog::collectCounters(
176
216
{
177
217
SWSS_LOG_ENTER ();
178
218
179
- std::lock_guard<std::mutex> lock (g_mutex);
180
-
181
219
// Collect stats for every registered port
182
220
for (const auto &kv: m_portCounterIdsMap)
183
221
{
@@ -249,15 +287,56 @@ void PfcWatchdog::collectCounters(
249
287
250
288
countersTable.set (queueVidStr, values, " " );
251
289
}
290
+
291
+ // Collect stats for every registered queue
292
+ for (const auto &kv: m_queueAttrIdsMap)
293
+ {
294
+ const auto &queueVid = kv.first ;
295
+ const auto &queueId = kv.second ->queueId ;
296
+ const auto &queueAttrIds = kv.second ->queueAttrIds ;
297
+
298
+ std::vector<sai_attribute_t > queueAttr (queueAttrIds.size ());
299
+
300
+ for (uint64_t i =0 ; i< queueAttrIds.size (); i++)
301
+ {
302
+ queueAttr[i].id = queueAttrIds[i];
303
+ }
304
+
305
+ // Get queue attr
306
+ sai_status_t status = sai_metadata_sai_queue_api->get_queue_attribute (
307
+ queueId,
308
+ static_cast <uint32_t >(queueAttrIds.size ()),
309
+ queueAttr.data ());
310
+
311
+ if (status != SAI_STATUS_SUCCESS)
312
+ {
313
+ SWSS_LOG_ERROR (" Failed to get attr of queue 0x%lx: %d" , queueVid, status);
314
+ continue ;
315
+ }
316
+
317
+ // Push all counter values to a single vector
318
+ std::vector<swss::FieldValueTuple> values;
319
+
320
+ for (size_t i = 0 ; i != queueAttrIds.size (); i++)
321
+ {
322
+ const std::string &counterName = sai_serialize_queue_attr (queueAttrIds[i]);
323
+ auto meta = sai_metadata_get_attr_metadata (SAI_OBJECT_TYPE_QUEUE, queueAttr[i].id );
324
+
325
+ values.emplace_back (counterName, sai_serialize_attr_value (*meta, queueAttr[i]));
326
+ }
327
+ // Write counters to DB
328
+ std::string queueVidStr = sai_serialize_object_id (queueVid);
329
+
330
+ countersTable.set (queueVidStr, values, " " );
331
+ }
332
+
252
333
}
253
334
254
335
void PfcWatchdog::runPlugins (
255
336
_In_ swss::DBConnector& db)
256
337
{
257
338
SWSS_LOG_ENTER ();
258
339
259
- std::lock_guard<std::mutex> lock (g_mutex);
260
-
261
340
const std::vector<std::string> argv =
262
341
{
263
342
std::to_string (COUNTERS_DB),
@@ -299,6 +378,8 @@ void PfcWatchdog::pfcWatchdogThread(void)
299
378
300
379
while (m_runPfcWatchdogThread)
301
380
{
381
+
382
+ std::lock_guard<std::mutex> lock (g_mutex);
302
383
collectCounters (countersTable);
303
384
runPlugins (db);
304
385
0 commit comments