Skip to content

Commit 9339d9c

Browse files
marian-pritsaklguohan
authored andcommitted
[pfcwdactionhandler]: Add PG setting (sonic-net#326)
PFC storm drop handler that applies zero size buffer profile to a queue, also has to apply zero size profile to ingress PG to drop RX traffic too. Code that creates profiles and pools was refactored to always create only one mode of pools/profiles (because it actually doesn't matter which mode is configured - traffic is dropped anyway). Signed-off-by: marian-pritsak <[email protected]>
1 parent 455fd5e commit 9339d9c

File tree

2 files changed

+96
-146
lines changed

2 files changed

+96
-146
lines changed

orchagent/pfcactionhandler.cpp

+76-134
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "pfcactionhandler.h"
22
#include "logger.h"
33
#include "saiserialize.h"
4+
#include "portsorch.h"
45

56
#include <vector>
67

@@ -15,6 +16,7 @@
1516
#define SAI_QUEUE_STAT_DROPPED_PACKETS_STR "SAI_QUEUE_STAT_DROPPED_PACKETS"
1617

1718
extern sai_object_id_t gSwitchId;
19+
extern PortsOrch *gPortsOrch;
1820
extern sai_port_api_t *sai_port_api;
1921
extern sai_queue_api_t *sai_queue_api;
2022
extern sai_buffer_api_t *sai_buffer_api;
@@ -200,53 +202,57 @@ PfcWdZeroBufferHandler::PfcWdZeroBufferHandler(sai_object_id_t port,
200202
return;
201203
}
202204

203-
sai_object_id_t oldProfileId = attr.value.oid;
204-
#if 0
205-
attr.id = SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE;
206-
attr.value.u32 = 0;
205+
sai_object_id_t oldQueueProfileId = attr.value.oid;
206+
207+
attr.id = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID;
208+
attr.value.oid = ZeroBufferProfile::getZeroBufferProfile(false);
207209

208-
// Get threshold mode of buffer profile
209-
status = sai_buffer_api->get_buffer_profile_attribute(oldProfileId, 1, &attr);
210+
// Set our zero buffer profile
211+
status = sai_queue_api->set_queue_attribute(queue, &attr);
210212
if (status != SAI_STATUS_SUCCESS)
211213
{
212-
SWSS_LOG_ERROR("Failed to get buffer profile threshold mode for 0x%lx: %d", queue, status);
214+
SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", queue, status);
213215
return;
214216
}
215217

216-
sai_buffer_profile_threshold_mode_t threshold_mode = static_cast<sai_buffer_profile_threshold_mode_t>(attr.value.u32);
217-
#endif
218-
219-
// XXX: Remove when above is fixed
220-
sai_buffer_profile_threshold_mode_t threshold_mode = SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC;
218+
// Save original buffer profile
219+
m_originalQueueBufferProfile = oldQueueProfileId;
221220

222-
sai_object_id_t zeroBufferProfileId = SAI_NULL_OBJECT_ID;
223-
if (threshold_mode == SAI_BUFFER_PROFILE_THRESHOLD_MODE_STATIC)
224-
{
225-
zeroBufferProfileId = ZeroBufferProfile::getStaticProfile();
226-
}
227-
else if (threshold_mode == SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC)
221+
// Get PG
222+
Port portInstance;
223+
if (!gPortsOrch->getPort(port, portInstance))
228224
{
229-
zeroBufferProfileId = ZeroBufferProfile::getDynamicProfile();
225+
SWSS_LOG_ERROR("Cannot get port by ID 0x%lx", port);
226+
return;
230227
}
231-
else
228+
229+
sai_object_id_t pg = portInstance.m_priority_group_ids[queueId];
230+
231+
attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE;
232+
233+
// Get PG's buffer profile
234+
status = sai_buffer_api->get_ingress_priority_group_attribute(pg, 1, &attr);
235+
if (status != SAI_STATUS_SUCCESS)
232236
{
233-
SWSS_LOG_ERROR("Buffer mode in buffer 0x%lx is not supported", queue);
237+
SWSS_LOG_ERROR("Failed to get buffer profile ID on PG 0x%lx: %d", pg, status);
234238
return;
235239
}
236240

237-
attr.id = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID;
238-
attr.value.oid = zeroBufferProfileId;
241+
// Set zero profile to PG
242+
sai_object_id_t oldPgProfileId = attr.value.oid;
239243

240-
// Set our zero buffer profile
241-
status = sai_queue_api->set_queue_attribute(queue, &attr);
244+
attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE;
245+
attr.value.oid = ZeroBufferProfile::getZeroBufferProfile(true);
246+
247+
status = sai_buffer_api->set_ingress_priority_group_attribute(pg, &attr);
242248
if (status != SAI_STATUS_SUCCESS)
243249
{
244-
SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", queue, status);
250+
SWSS_LOG_ERROR("Failed to set buffer profile ID on pg 0x%lx: %d", pg, status);
245251
return;
246252
}
247253

248254
// Save original buffer profile
249-
m_originalBufferProfile = oldProfileId;
255+
m_originalPgBufferProfile = oldPgProfileId;
250256
}
251257

252258
PfcWdZeroBufferHandler::~PfcWdZeroBufferHandler(void)
@@ -255,15 +261,35 @@ PfcWdZeroBufferHandler::~PfcWdZeroBufferHandler(void)
255261

256262
sai_attribute_t attr;
257263
attr.id = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID;
258-
attr.value.oid = m_originalBufferProfile;
264+
attr.value.oid = m_originalQueueBufferProfile;
259265

260-
// Set our zero buffer profile
266+
// Set our zero buffer profile on a queue
261267
sai_status_t status = sai_queue_api->set_queue_attribute(getQueue(), &attr);
262268
if (status != SAI_STATUS_SUCCESS)
263269
{
264270
SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", getQueue(), status);
265271
return;
266272
}
273+
274+
Port portInstance;
275+
if (!gPortsOrch->getPort(getPort(), portInstance))
276+
{
277+
SWSS_LOG_ERROR("Cannot get port by ID 0x%lx", getPort());
278+
return;
279+
}
280+
281+
sai_object_id_t pg = portInstance.m_priority_group_ids[getQueueId()];
282+
283+
attr.id = SAI_INGRESS_PRIORITY_GROUP_ATTR_BUFFER_PROFILE;
284+
attr.value.oid = m_originalPgBufferProfile;
285+
286+
// Set our zero buffer profile
287+
status = sai_buffer_api->set_ingress_priority_group_attribute(pg, &attr);
288+
if (status != SAI_STATUS_SUCCESS)
289+
{
290+
SWSS_LOG_ERROR("Failed to set buffer profile ID on queue 0x%lx: %d", getQueue(), status);
291+
return;
292+
}
267293
}
268294

269295
PfcWdZeroBufferHandler::ZeroBufferProfile::ZeroBufferProfile(void)
@@ -275,8 +301,9 @@ PfcWdZeroBufferHandler::ZeroBufferProfile::~ZeroBufferProfile(void)
275301
{
276302
SWSS_LOG_ENTER();
277303

278-
destroyStaticProfile();
279-
destroyDynamicProfile();
304+
// Destory ingress and egress prifiles and pools
305+
destroyZeroBufferProfile(true);
306+
destroyZeroBufferProfile(false);
280307
}
281308

282309
PfcWdZeroBufferHandler::ZeroBufferProfile &PfcWdZeroBufferHandler::ZeroBufferProfile::getInstance(void)
@@ -288,111 +315,40 @@ PfcWdZeroBufferHandler::ZeroBufferProfile &PfcWdZeroBufferHandler::ZeroBufferPro
288315
return instance;
289316
}
290317

291-
sai_object_id_t PfcWdZeroBufferHandler::ZeroBufferProfile::getStaticProfile(void)
318+
sai_object_id_t PfcWdZeroBufferHandler::ZeroBufferProfile::getZeroBufferProfile(bool ingress)
292319
{
293320
SWSS_LOG_ENTER();
294321

295-
if (getInstance().m_zeroStaticBufferProfile == SAI_NULL_OBJECT_ID)
322+
if (getInstance().getProfile(ingress) == SAI_NULL_OBJECT_ID)
296323
{
297-
getInstance().createStaticProfile();
324+
getInstance().createZeroBufferProfile(ingress);
298325
}
299326

300-
return getInstance().m_zeroStaticBufferProfile;
327+
return getInstance().getProfile(ingress);
301328
}
302329

303-
sai_object_id_t PfcWdZeroBufferHandler::ZeroBufferProfile::getDynamicProfile(void)
304-
{
305-
SWSS_LOG_ENTER();
306-
307-
if (getInstance().m_zeroDynamicBufferProfile == SAI_NULL_OBJECT_ID)
308-
{
309-
getInstance().createDynamicProfile();
310-
}
311-
312-
return getInstance().m_zeroDynamicBufferProfile;
313-
}
314-
315-
void PfcWdZeroBufferHandler::ZeroBufferProfile::createStaticProfile(void)
330+
void PfcWdZeroBufferHandler::ZeroBufferProfile::createZeroBufferProfile(bool ingress)
316331
{
317332
SWSS_LOG_ENTER();
318333

319334
sai_attribute_t attr;
320335
vector<sai_attribute_t> attribs;
321336

322-
// Create static zero pool
337+
// Create zero pool
323338
attr.id = SAI_BUFFER_POOL_ATTR_SIZE;
324339
attr.value.u32 = 0;
325340
attribs.push_back(attr);
326341

327342
attr.id = SAI_BUFFER_POOL_ATTR_TYPE;
328-
attr.value.u32 = SAI_BUFFER_POOL_TYPE_EGRESS;
329-
attribs.push_back(attr);
330-
331-
attr.id = SAI_BUFFER_POOL_ATTR_THRESHOLD_MODE;
332-
attr.value.u32 = SAI_BUFFER_POOL_THRESHOLD_MODE_STATIC;
333-
attribs.push_back(attr);
334-
335-
sai_status_t status = sai_buffer_api->create_buffer_pool(
336-
&m_zeroStaticBufferPool,
337-
gSwitchId,
338-
static_cast<uint32_t>(attribs.size()),
339-
attribs.data());
340-
if (status != SAI_STATUS_SUCCESS)
341-
{
342-
SWSS_LOG_ERROR("Failed to create static zero buffer pool for PFC WD: %d", status);
343-
return;
344-
}
345-
346-
// Create static zero profile
347-
attribs.clear();
348-
349-
attr.id = SAI_BUFFER_PROFILE_ATTR_POOL_ID;
350-
attr.value.oid = m_zeroStaticBufferPool;
351-
attribs.push_back(attr);
352-
353-
attr.id = SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE;
354-
attr.value.u32 = 0;
355-
attribs.push_back(attr);
356-
357-
attr.id = SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH;
358-
attr.value.u32 = 0;
359-
attribs.push_back(attr);
360-
361-
status = sai_buffer_api->create_buffer_profile(
362-
&m_zeroStaticBufferProfile,
363-
gSwitchId,
364-
static_cast<uint32_t>(attribs.size()),
365-
attribs.data());
366-
if (status != SAI_STATUS_SUCCESS)
367-
{
368-
SWSS_LOG_ERROR("Failed to create static zero buffer profile for PFC WD: %d", status);
369-
return;
370-
}
371-
}
372-
373-
374-
void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void)
375-
{
376-
SWSS_LOG_ENTER();
377-
378-
sai_attribute_t attr;
379-
vector<sai_attribute_t> attribs;
380-
381-
// Create dynamic zero pool
382-
attr.id = SAI_BUFFER_POOL_ATTR_SIZE;
383-
attr.value.u32 = 0;
384-
attribs.push_back(attr);
385-
386-
attr.id = SAI_BUFFER_POOL_ATTR_TYPE;
387-
attr.value.u32 = SAI_BUFFER_POOL_TYPE_EGRESS;
343+
attr.value.u32 = ingress ? SAI_BUFFER_POOL_TYPE_INGRESS : SAI_BUFFER_POOL_TYPE_EGRESS;
388344
attribs.push_back(attr);
389345

390346
attr.id = SAI_BUFFER_POOL_ATTR_THRESHOLD_MODE;
391347
attr.value.u32 = SAI_BUFFER_POOL_THRESHOLD_MODE_DYNAMIC;
392348
attribs.push_back(attr);
393349

394350
sai_status_t status = sai_buffer_api->create_buffer_pool(
395-
&m_zeroDynamicBufferPool,
351+
&getPool(ingress),
396352
gSwitchId,
397353
static_cast<uint32_t>(attribs.size()),
398354
attribs.data());
@@ -402,11 +358,15 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void)
402358
return;
403359
}
404360

405-
// Create dynamic zero profile
361+
// Create zero profile
406362
attribs.clear();
407363

408364
attr.id = SAI_BUFFER_PROFILE_ATTR_POOL_ID;
409-
attr.value.oid = m_zeroDynamicBufferPool;
365+
attr.value.oid = getPool(ingress);
366+
attribs.push_back(attr);
367+
368+
attr.id = SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE;
369+
attr.value.u32 = SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC;
410370
attribs.push_back(attr);
411371

412372
attr.id = SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE;
@@ -418,7 +378,7 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void)
418378
attribs.push_back(attr);
419379

420380
status = sai_buffer_api->create_buffer_profile(
421-
&m_zeroDynamicBufferProfile,
381+
&getProfile(ingress),
422382
gSwitchId,
423383
static_cast<uint32_t>(attribs.size()),
424384
attribs.data());
@@ -429,38 +389,20 @@ void PfcWdZeroBufferHandler::ZeroBufferProfile::createDynamicProfile(void)
429389
}
430390
}
431391

432-
void PfcWdZeroBufferHandler::ZeroBufferProfile::destroyStaticProfile(void)
392+
void PfcWdZeroBufferHandler::ZeroBufferProfile::destroyZeroBufferProfile(bool ingress)
433393
{
434394
SWSS_LOG_ENTER();
435395

436-
sai_status_t status = sai_buffer_api->remove_buffer_profile(m_zeroStaticBufferProfile);
396+
sai_status_t status = sai_buffer_api->remove_buffer_profile(getProfile(ingress));
437397
if (status != SAI_STATUS_SUCCESS)
438398
{
439399
SWSS_LOG_ERROR("Failed to remove static zero buffer profile for PFC WD: %d", status);
440400
return;
441401
}
442402

443-
status = sai_buffer_api->remove_buffer_pool(m_zeroStaticBufferPool);
403+
status = sai_buffer_api->remove_buffer_pool(getPool(ingress));
444404
if (status != SAI_STATUS_SUCCESS)
445405
{
446406
SWSS_LOG_ERROR("Failed to remove static zero buffer pool for PFC WD: %d", status);
447407
}
448408
}
449-
450-
void PfcWdZeroBufferHandler::ZeroBufferProfile::destroyDynamicProfile(void)
451-
{
452-
SWSS_LOG_ENTER();
453-
454-
sai_status_t status = sai_buffer_api->remove_buffer_profile(m_zeroDynamicBufferProfile);
455-
if (status != SAI_STATUS_SUCCESS)
456-
{
457-
SWSS_LOG_ERROR("Failed to remove dynamic zero buffer profile for PFC WD: %d", status);
458-
return;
459-
}
460-
461-
status = sai_buffer_api->remove_buffer_pool(m_zeroDynamicBufferPool);
462-
if (status != SAI_STATUS_SUCCESS)
463-
{
464-
SWSS_LOG_ERROR("Failed to remove dynamic zero buffer pool for PFC WD: %d", status);
465-
}
466-
}

orchagent/pfcactionhandler.h

+20-12
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,32 @@ class PfcWdZeroBufferHandler: public PfcWdLossyHandler
8383
{
8484
public:
8585
~ZeroBufferProfile(void);
86-
static sai_object_id_t getStaticProfile(void);
87-
static sai_object_id_t getDynamicProfile(void);
86+
static sai_object_id_t getZeroBufferProfile(bool ingress);
8887

8988
private:
9089
ZeroBufferProfile(void);
9190
static ZeroBufferProfile &getInstance(void);
92-
void createStaticProfile(void);
93-
void createDynamicProfile(void);
94-
void destroyStaticProfile(void);
95-
void destroyDynamicProfile(void);
96-
97-
sai_object_id_t m_zeroStaticBufferPool = SAI_NULL_OBJECT_ID;
98-
sai_object_id_t m_zeroDynamicBufferPool = SAI_NULL_OBJECT_ID;
99-
sai_object_id_t m_zeroStaticBufferProfile = SAI_NULL_OBJECT_ID;
100-
sai_object_id_t m_zeroDynamicBufferProfile = SAI_NULL_OBJECT_ID;
91+
void createZeroBufferProfile(bool ingress);
92+
void destroyZeroBufferProfile(bool ingress);
93+
94+
sai_object_id_t& getProfile(bool ingress)
95+
{
96+
return ingress ? m_zeroIngressBufferProfile : m_zeroEgressBufferProfile;
97+
}
98+
99+
sai_object_id_t& getPool(bool ingress)
100+
{
101+
return ingress ? m_zeroIngressBufferPool : m_zeroEgressBufferPool;
102+
}
103+
104+
sai_object_id_t m_zeroIngressBufferPool = SAI_NULL_OBJECT_ID;
105+
sai_object_id_t m_zeroEgressBufferPool = SAI_NULL_OBJECT_ID;
106+
sai_object_id_t m_zeroIngressBufferProfile = SAI_NULL_OBJECT_ID;
107+
sai_object_id_t m_zeroEgressBufferProfile = SAI_NULL_OBJECT_ID;
101108
};
102109

103-
sai_object_id_t m_originalBufferProfile;
110+
sai_object_id_t m_originalQueueBufferProfile = SAI_NULL_OBJECT_ID;
111+
sai_object_id_t m_originalPgBufferProfile = SAI_NULL_OBJECT_ID;
104112
};
105113

106114
#endif

0 commit comments

Comments
 (0)