@@ -18,6 +18,13 @@ PfcWatchdog::QueueCounterIds::QueueCounterIds(
1818{
1919}
2020
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+
2128void PfcWatchdog::setPortCounterList (
2229 _In_ sai_object_id_t portVid,
2330 _In_ sai_object_id_t portId,
@@ -64,6 +71,30 @@ void PfcWatchdog::setQueueCounterList(
6471 wd.startWatchdogThread ();
6572}
6673
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+
6798void PfcWatchdog::removePort (
6899 _In_ sai_object_id_t portVid)
69100{
@@ -81,7 +112,7 @@ void PfcWatchdog::removePort(
81112 wd.m_portCounterIdsMap .erase (it);
82113
83114 // 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 () )
85116 {
86117 wd.endWatchdogThread ();
87118 }
@@ -94,17 +125,26 @@ void PfcWatchdog::removeQueue(
94125
95126 PfcWatchdog &wd = getInstance ();
96127
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 ())
99130 {
100131 SWSS_LOG_ERROR (" Trying to remove nonexisting queue counter Ids 0x%lx" , queueVid);
101132 return ;
102133 }
103134
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);
105145
106146 // 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 () )
108148 {
109149 wd.endWatchdogThread ();
110150 }
@@ -176,8 +216,6 @@ void PfcWatchdog::collectCounters(
176216{
177217 SWSS_LOG_ENTER ();
178218
179- std::lock_guard<std::mutex> lock (g_mutex);
180-
181219 // Collect stats for every registered port
182220 for (const auto &kv: m_portCounterIdsMap)
183221 {
@@ -249,15 +287,56 @@ void PfcWatchdog::collectCounters(
249287
250288 countersTable.set (queueVidStr, values, " " );
251289 }
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+
252333}
253334
254335void PfcWatchdog::runPlugins (
255336 _In_ swss::DBConnector& db)
256337{
257338 SWSS_LOG_ENTER ();
258339
259- std::lock_guard<std::mutex> lock (g_mutex);
260-
261340 const std::vector<std::string> argv =
262341 {
263342 std::to_string (COUNTERS_DB),
@@ -299,6 +378,8 @@ void PfcWatchdog::pfcWatchdogThread(void)
299378
300379 while (m_runPfcWatchdogThread)
301380 {
381+
382+ std::lock_guard<std::mutex> lock (g_mutex);
302383 collectCounters (countersTable);
303384 runPlugins (db);
304385
0 commit comments