Skip to content

Commit 8995b30

Browse files
authored
[countercheck]: move pfc counter alerting to countercheckorch (sonic-net#456)
* [countercheck]: move pfc counter alerting to countercheckorch Signed-off-by: Sihui Han <[email protected]> * remove no need header Signed-off-by: Sihui Han <[email protected]>
1 parent caa4f0b commit 8995b30

File tree

4 files changed

+152
-142
lines changed

4 files changed

+152
-142
lines changed

orchagent/countercheckorch.cpp

+141-35
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "redisclient.h"
66
#include "sai_serialize.h"
77

8-
#define MC_WD_LOSSY_POLL_TIMEOUT_SEC (5 * 60)
8+
#define COUNTER_CHECK_POLL_TIMEOUT_SEC (5 * 60)
99

1010
extern sai_port_api_t *sai_port_api;
1111

@@ -28,7 +28,7 @@ CounterCheckOrch::CounterCheckOrch(DBConnector *db, vector<string> &tableNames):
2828
{
2929
SWSS_LOG_ENTER();
3030

31-
auto interv = timespec { .tv_sec = MC_WD_LOSSY_POLL_TIMEOUT_SEC, .tv_nsec = 0 };
31+
auto interv = timespec { .tv_sec = COUNTER_CHECK_POLL_TIMEOUT_SEC, .tv_nsec = 0 };
3232
auto timer = new SelectableTimer(interv);
3333
auto executor = new ExecutableTimer(timer, this);
3434
Orch::addExecutor("MC_COUNTERS_POLL", executor);
@@ -40,54 +40,78 @@ CounterCheckOrch::~CounterCheckOrch(void)
4040
SWSS_LOG_ENTER();
4141
}
4242

43-
QueueMcCounters CounterCheckOrch::getQueueMcCounters(
44-
const Port& port)
43+
void CounterCheckOrch::doTask(SelectableTimer &timer)
4544
{
4645
SWSS_LOG_ENTER();
4746

48-
vector<FieldValueTuple> fieldValues;
49-
QueueMcCounters counters;
50-
RedisClient redisClient(m_countersDb.get());
47+
mcCounterCheck();
48+
pfcFrameCounterCheck();
49+
}
5150

52-
for (uint8_t prio = 0; prio < port.m_queue_ids.size(); prio++)
51+
void CounterCheckOrch::mcCounterCheck()
52+
{
53+
SWSS_LOG_ENTER();
54+
55+
sai_attribute_t attr;
56+
attr.id = SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL;
57+
58+
for (auto& i : m_mcCountersMap)
5359
{
54-
sai_object_id_t queueId = port.m_queue_ids[prio];
55-
auto queueIdStr = sai_serialize_object_id(queueId);
56-
auto queueType = redisClient.hget(COUNTERS_QUEUE_TYPE_MAP, queueIdStr);
60+
auto oid = i.first;
61+
auto mcCounters = i.second;
5762

58-
if (queueType.get() == nullptr || *queueType != "SAI_QUEUE_TYPE_MULTICAST" || !m_countersTable->get(queueIdStr, fieldValues))
63+
Port port;
64+
if (!gPortsOrch->getPort(oid, port))
5965
{
66+
SWSS_LOG_ERROR("Invalid port oid 0x%lx", oid);
6067
continue;
6168
}
6269

63-
uint64_t pkts = numeric_limits<uint64_t>::max();
64-
for (const auto& fv : fieldValues)
70+
auto newMcCounters = getQueueMcCounters(port);
71+
72+
sai_status_t status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr);
73+
if (status != SAI_STATUS_SUCCESS)
6574
{
66-
const auto field = fvField(fv);
67-
const auto value = fvValue(fv);
75+
SWSS_LOG_ERROR("Failed to get PFC mask on port %s: %d", port.m_alias.c_str(), status);
76+
continue;
77+
}
6878

69-
if (field == "SAI_QUEUE_STAT_PACKETS")
79+
uint8_t pfcMask = attr.value.u8;
80+
81+
for (size_t prio = 0; prio != mcCounters.size(); prio++)
82+
{
83+
bool isLossy = ((1 << prio) & pfcMask) == 0;
84+
if (newMcCounters[prio] == numeric_limits<uint64_t>::max())
7085
{
71-
pkts = stoul(value);
86+
SWSS_LOG_WARN("Could not retreive MC counters on queue %lu port %s",
87+
prio,
88+
port.m_alias.c_str());
89+
}
90+
else if (!isLossy && mcCounters[prio] < newMcCounters[prio])
91+
{
92+
SWSS_LOG_WARN("Got Multicast %lu frame(s) on lossless queue %lu port %s",
93+
newMcCounters[prio] - mcCounters[prio],
94+
prio,
95+
port.m_alias.c_str());
7296
}
7397
}
74-
counters.push_back(pkts);
75-
}
7698

77-
return move(counters);
99+
i.second= newMcCounters;
100+
}
78101
}
79102

80-
void CounterCheckOrch::doTask(SelectableTimer &timer)
103+
void CounterCheckOrch::pfcFrameCounterCheck()
81104
{
82105
SWSS_LOG_ENTER();
83106

84107
sai_attribute_t attr;
85108
attr.id = SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL;
86109

87-
for (auto& i : m_CountersMap)
110+
for (auto& i : m_pfcFrameCountersMap)
88111
{
89112
auto oid = i.first;
90-
auto mcCounters = i.second;
113+
auto counters = i.second;
114+
auto newCounters = getPfcFrameCounters(oid);
91115

92116
Port port;
93117
if (!gPortsOrch->getPort(oid, port))
@@ -96,8 +120,6 @@ void CounterCheckOrch::doTask(SelectableTimer &timer)
96120
continue;
97121
}
98122

99-
auto newMcCounters = getQueueMcCounters(port);
100-
101123
sai_status_t status = sai_port_api->get_port_attribute(port.m_port_id, 1, &attr);
102124
if (status != SAI_STATUS_SUCCESS)
103125
{
@@ -107,34 +129,118 @@ void CounterCheckOrch::doTask(SelectableTimer &timer)
107129

108130
uint8_t pfcMask = attr.value.u8;
109131

110-
for (size_t prio = 0; prio != mcCounters.size(); prio++)
132+
for (size_t prio = 0; prio != counters.size(); prio++)
111133
{
112134
bool isLossy = ((1 << prio) & pfcMask) == 0;
113-
if (newMcCounters[prio] == numeric_limits<uint64_t>::max())
135+
if (newCounters[prio] == numeric_limits<uint64_t>::max())
114136
{
115-
SWSS_LOG_WARN("Could not retreive MC counters on queue %lu port %s",
137+
SWSS_LOG_WARN("Could not retreive PFC frame count on queue %lu port %s",
116138
prio,
117139
port.m_alias.c_str());
118140
}
119-
else if (!isLossy && mcCounters[prio] < newMcCounters[prio])
141+
else if (isLossy && counters[prio] < newCounters[prio])
120142
{
121-
SWSS_LOG_WARN("Got Multicast %lu frame(s) on lossless queue %lu port %s",
122-
newMcCounters[prio] - mcCounters[prio],
143+
SWSS_LOG_WARN("Got PFC %lu frame(s) on lossy queue %lu port %s",
144+
newCounters[prio] - counters[prio],
123145
prio,
124146
port.m_alias.c_str());
125147
}
126148
}
127149

128-
i.second= newMcCounters;
150+
i.second = newCounters;
151+
}
152+
}
153+
154+
155+
PfcFrameCounters CounterCheckOrch::getPfcFrameCounters(sai_object_id_t portId)
156+
{
157+
SWSS_LOG_ENTER();
158+
159+
vector<FieldValueTuple> fieldValues;
160+
PfcFrameCounters counters;
161+
counters.fill(numeric_limits<uint64_t>::max());
162+
163+
static const array<string, PFC_WD_TC_MAX> counterNames =
164+
{
165+
"SAI_PORT_STAT_PFC_0_RX_PKTS",
166+
"SAI_PORT_STAT_PFC_1_RX_PKTS",
167+
"SAI_PORT_STAT_PFC_2_RX_PKTS",
168+
"SAI_PORT_STAT_PFC_3_RX_PKTS",
169+
"SAI_PORT_STAT_PFC_4_RX_PKTS",
170+
"SAI_PORT_STAT_PFC_5_RX_PKTS",
171+
"SAI_PORT_STAT_PFC_6_RX_PKTS",
172+
"SAI_PORT_STAT_PFC_7_RX_PKTS"
173+
};
174+
175+
if (!m_countersTable->get(sai_serialize_object_id(portId), fieldValues))
176+
{
177+
return move(counters);
178+
}
179+
180+
for (const auto& fv : fieldValues)
181+
{
182+
const auto field = fvField(fv);
183+
const auto value = fvValue(fv);
184+
185+
186+
for (size_t prio = 0; prio != counterNames.size(); prio++)
187+
{
188+
if (field == counterNames[prio])
189+
{
190+
counters[prio] = stoul(value);
191+
}
192+
}
193+
}
194+
195+
return move(counters);
196+
}
197+
198+
QueueMcCounters CounterCheckOrch::getQueueMcCounters(
199+
const Port& port)
200+
{
201+
SWSS_LOG_ENTER();
202+
203+
vector<FieldValueTuple> fieldValues;
204+
QueueMcCounters counters;
205+
RedisClient redisClient(m_countersDb.get());
206+
207+
for (uint8_t prio = 0; prio < port.m_queue_ids.size(); prio++)
208+
{
209+
sai_object_id_t queueId = port.m_queue_ids[prio];
210+
auto queueIdStr = sai_serialize_object_id(queueId);
211+
auto queueType = redisClient.hget(COUNTERS_QUEUE_TYPE_MAP, queueIdStr);
212+
213+
if (queueType.get() == nullptr || *queueType != "SAI_QUEUE_TYPE_MULTICAST" || !m_countersTable->get(queueIdStr, fieldValues))
214+
{
215+
continue;
216+
}
217+
218+
uint64_t pkts = numeric_limits<uint64_t>::max();
219+
for (const auto& fv : fieldValues)
220+
{
221+
const auto field = fvField(fv);
222+
const auto value = fvValue(fv);
223+
224+
if (field == "SAI_QUEUE_STAT_PACKETS")
225+
{
226+
pkts = stoul(value);
227+
}
228+
}
229+
counters.push_back(pkts);
129230
}
231+
232+
return move(counters);
130233
}
131234

235+
132236
void CounterCheckOrch::addPort(const Port& port)
133237
{
134-
m_CountersMap.emplace(port.m_port_id, getQueueMcCounters(port));
238+
m_mcCountersMap.emplace(port.m_port_id, getQueueMcCounters(port));
239+
m_pfcFrameCountersMap.emplace(port.m_port_id, getPfcFrameCounters(port.m_port_id));
135240
}
136241

137242
void CounterCheckOrch::removePort(const Port& port)
138243
{
139-
m_CountersMap.erase(port.m_port_id);
244+
m_mcCountersMap.erase(port.m_port_id);
245+
m_pfcFrameCountersMap.erase(port.m_port_id);
140246
}

orchagent/countercheckorch.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
#include "orch.h"
55
#include "port.h"
66
#include "timer.h"
7+
#include <array>
8+
9+
#define PFC_WD_TC_MAX 8
710

811
extern "C" {
912
#include "sai.h"
1013
}
1114

1215
typedef vector<uint64_t> QueueMcCounters;
16+
typedef array<uint64_t, PFC_WD_TC_MAX> PfcFrameCounters;
1317

1418
class CounterCheckOrch: public Orch
1519
{
@@ -24,7 +28,12 @@ class CounterCheckOrch: public Orch
2428
CounterCheckOrch(DBConnector *db, vector<string> &tableNames);
2529
virtual ~CounterCheckOrch(void);
2630
QueueMcCounters getQueueMcCounters(const Port& port);
27-
map<sai_object_id_t, QueueMcCounters> m_CountersMap;
31+
PfcFrameCounters getPfcFrameCounters(sai_object_id_t portId);
32+
void mcCounterCheck();
33+
void pfcFrameCounterCheck();
34+
35+
map<sai_object_id_t, QueueMcCounters> m_mcCountersMap;
36+
map<sai_object_id_t, PfcFrameCounters> m_pfcFrameCountersMap;
2837

2938
shared_ptr<DBConnector> m_countersDb = nullptr;
3039
shared_ptr<Table> m_countersTable = nullptr;

0 commit comments

Comments
 (0)