14
14
#define PFC_WD_ACTION " action"
15
15
#define PFC_WD_DETECTION_TIME " detection_time"
16
16
#define PFC_WD_RESTORATION_TIME " restoration_time"
17
+ #define BIG_RED_SWITCH_FIELD " BIG_RED_SWITCH"
17
18
18
19
#define PFC_WD_DETECTION_TIME_MAX (5 * 1000 )
19
20
#define PFC_WD_DETECTION_TIME_MIN 100
@@ -261,6 +262,8 @@ template <typename DropHandler, typename ForwardHandler>
261
262
void PfcWdSwOrch<DropHandler, ForwardHandler>::createEntry(const string& key,
262
263
const vector<FieldValueTuple>& data)
263
264
{
265
+ SWSS_LOG_ENTER ();
266
+
264
267
if (key == PFC_WD_GLOBAL)
265
268
{
266
269
for (auto valuePair: data)
@@ -274,6 +277,11 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::createEntry(const string& key,
274
277
fieldValues.emplace_back (POLL_INTERVAL_FIELD, value);
275
278
m_flexCounterGroupTable->set (PFC_WD_FLEX_COUNTER_GROUP, fieldValues);
276
279
}
280
+ else if (field == BIG_RED_SWITCH_FIELD)
281
+ {
282
+ SWSS_LOG_NOTICE (" Recieve brs mode set, %s" , value.c_str ());
283
+ setBigRedSwitchMode (value);
284
+ }
277
285
}
278
286
}
279
287
else
@@ -282,6 +290,166 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::createEntry(const string& key,
282
290
}
283
291
}
284
292
293
+ template <typename DropHandler, typename ForwardHandler>
294
+ void PfcWdSwOrch<DropHandler, ForwardHandler>::setBigRedSwitchMode(const string value)
295
+ {
296
+ SWSS_LOG_ENTER ();
297
+
298
+ if (value == " enable" )
299
+ {
300
+ // When BIG_RED_SWITCH mode is enabled, pfcwd is automatically disabled
301
+ enableBigRedSwitchMode ();
302
+ }
303
+ else if (value == " disable" )
304
+ {
305
+ disableBigRedSwitchMode ();
306
+ }
307
+ else
308
+ {
309
+ SWSS_LOG_NOTICE (" Unsupported BIG_RED_SWITCH mode set input, please use enable or disable" );
310
+ }
311
+
312
+ }
313
+
314
+ template <typename DropHandler, typename ForwardHandler>
315
+ void PfcWdSwOrch<DropHandler, ForwardHandler>::disableBigRedSwitchMode()
316
+ {
317
+ SWSS_LOG_ENTER ();
318
+
319
+ m_bigRedSwitchFlag = false ;
320
+ // Disable pfcwdaction hanlder on each queue if exists.
321
+ for (auto &entry : m_brsEntryMap)
322
+ {
323
+
324
+ if (entry.second .handler != nullptr )
325
+ {
326
+ SWSS_LOG_NOTICE (
327
+ " PFC Watchdog BIG_RED_SWITCH mode disabled on port %s, queue index %d, queue id 0x%lx and port id 0x%lx." ,
328
+ entry.second .portAlias .c_str (),
329
+ entry.second .index ,
330
+ entry.first ,
331
+ entry.second .portId );
332
+
333
+ entry.second .handler ->commitCounters ();
334
+ entry.second .handler = nullptr ;
335
+ }
336
+
337
+ auto queueId = entry.first ;
338
+ RedisClient redisClient (PfcWdOrch<DropHandler, ForwardHandler>::getCountersDb ().get ());
339
+ string countersKey = COUNTERS_TABLE " :" + sai_serialize_object_id (queueId);
340
+ redisClient.hdel (countersKey, " BIG_RED_SWITCH_MODE" );
341
+ }
342
+
343
+ m_brsEntryMap.clear ();
344
+ }
345
+
346
+ template <typename DropHandler, typename ForwardHandler>
347
+ void PfcWdSwOrch<DropHandler, ForwardHandler>::enableBigRedSwitchMode()
348
+ {
349
+ SWSS_LOG_ENTER ();
350
+
351
+ m_bigRedSwitchFlag = true ;
352
+ // Write to database that each queue enables BIG_RED_SWITCH
353
+ auto allPorts = gPortsOrch ->getAllPorts ();
354
+ sai_attribute_t attr;
355
+ attr.id = SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL;
356
+
357
+ for (auto &it: allPorts)
358
+ {
359
+ Port port = it.second ;
360
+
361
+ if (port.m_type != Port::PHY)
362
+ {
363
+ SWSS_LOG_INFO (" Skip non-phy port %s" , port.m_alias .c_str ());
364
+ continue ;
365
+ }
366
+
367
+ // use portorch api to get lossless tc in future.
368
+ sai_status_t status = sai_port_api->get_port_attribute (port.m_port_id , 1 , &attr);
369
+ if (status != SAI_STATUS_SUCCESS)
370
+ {
371
+ SWSS_LOG_ERROR (" Failed to get PFC mask on port %s: %d" , port.m_alias .c_str (), status);
372
+ return ;
373
+ }
374
+
375
+ uint8_t pfcMask = attr.value .u8 ;
376
+ for (uint8_t i = 0 ; i < PFC_WD_TC_MAX; i++)
377
+ {
378
+ sai_object_id_t queueId = port.m_queue_ids [i];
379
+ if ((pfcMask & (1 << i)) == 0 && m_entryMap.find (queueId) == m_entryMap.end ())
380
+ {
381
+ continue ;
382
+ }
383
+
384
+ string queueIdStr = sai_serialize_object_id (queueId);
385
+
386
+ vector<FieldValueTuple> countersFieldValues;
387
+ countersFieldValues.emplace_back (" BIG_RED_SWITCH_MODE" , " enable" );
388
+ PfcWdOrch<DropHandler, ForwardHandler>::getCountersTable ()->set (queueIdStr, countersFieldValues);
389
+ }
390
+ }
391
+
392
+ // Disable pfcwdaction handler on each queue if exists.
393
+ for (auto & entry: m_entryMap)
394
+ {
395
+ if (entry.second .handler != nullptr )
396
+ {
397
+ entry.second .handler ->commitCounters ();
398
+ entry.second .handler = nullptr ;
399
+ }
400
+ }
401
+
402
+ // Create pfcwdaction hanlder on all the ports.
403
+ for (auto & it: allPorts)
404
+ {
405
+ Port port = it.second ;
406
+ if (port.m_type != Port::PHY)
407
+ {
408
+ SWSS_LOG_INFO (" Skip non-phy port %s" , port.m_alias .c_str ());
409
+ continue ;
410
+ }
411
+
412
+ // use portorch api to get lossless tc in future after asym PFC is available.
413
+ sai_status_t status = sai_port_api->get_port_attribute (port.m_port_id , 1 , &attr);
414
+ if (status != SAI_STATUS_SUCCESS)
415
+ {
416
+ SWSS_LOG_ERROR (" Failed to get PFC mask on port %s: %d" , port.m_alias .c_str (), status);
417
+ return ;
418
+ }
419
+
420
+ uint8_t pfcMask = attr.value .u8 ;
421
+ for (uint8_t i = 0 ; i < PFC_WD_TC_MAX; i++)
422
+ {
423
+ if ((pfcMask & (1 << i)) == 0 )
424
+ {
425
+ continue ;
426
+ }
427
+
428
+ sai_object_id_t queueId = port.m_queue_ids [i];
429
+ string queueIdStr = sai_serialize_object_id (queueId);
430
+
431
+ auto entry = m_brsEntryMap.emplace (queueId, PfcWdQueueEntry (PfcWdAction::PFC_WD_ACTION_DROP, port.m_port_id , i, port.m_alias )).first ;
432
+
433
+ if (entry->second .handler == nullptr )
434
+ {
435
+ SWSS_LOG_NOTICE (
436
+ " PFC Watchdog BIG_RED_SWITCH mode enabled on port %s, queue index %d, queue id 0x%lx and port id 0x%lx." ,
437
+ entry->second .portAlias .c_str (),
438
+ entry->second .index ,
439
+ entry->first ,
440
+ entry->second .portId );
441
+
442
+ entry->second .handler = make_shared<DropHandler>(
443
+ entry->second .portId ,
444
+ entry->first ,
445
+ entry->second .index ,
446
+ PfcWdOrch<DropHandler, ForwardHandler>::getCountersTable ());
447
+ entry->second .handler ->initCounters ();
448
+ }
449
+ }
450
+ }
451
+ }
452
+
285
453
template <typename DropHandler, typename ForwardHandler>
286
454
void PfcWdSwOrch<DropHandler, ForwardHandler>::registerInWdDb(const Port& port,
287
455
uint32_t detectionTime, uint32_t restorationTime, PfcWdAction action)
@@ -355,7 +523,7 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::registerInWdDb(const Port& port,
355
523
}
356
524
357
525
// Create internal entry
358
- m_entryMap.emplace (queueId, PfcWdQueueEntry (action, port.m_port_id , i));
526
+ m_entryMap.emplace (queueId, PfcWdQueueEntry (action, port.m_port_id , i, port. m_alias ));
359
527
360
528
string key = getFlexCounterTableKey (queueIdStr);
361
529
m_flexCounterTable->set (key, queueFieldValues);
@@ -513,10 +681,11 @@ PfcWdSwOrch<DropHandler, ForwardHandler>::~PfcWdSwOrch(void)
513
681
514
682
template <typename DropHandler, typename ForwardHandler>
515
683
PfcWdSwOrch<DropHandler, ForwardHandler>::PfcWdQueueEntry::PfcWdQueueEntry(
516
- PfcWdAction action, sai_object_id_t port, uint8_t idx):
684
+ PfcWdAction action, sai_object_id_t port, uint8_t idx, string alias ):
517
685
action (action),
518
686
portId(port),
519
- index(idx)
687
+ index(idx),
688
+ portAlias(alias)
520
689
{
521
690
SWSS_LOG_ENTER ();
522
691
}
@@ -564,12 +733,24 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::doTask(swss::NotificationConsumer
564
733
}
565
734
566
735
SWSS_LOG_NOTICE (" Receive notification, %s" , event.c_str ());
567
- if (event == " storm" )
736
+
737
+ if (m_bigRedSwitchFlag)
738
+ {
739
+ SWSS_LOG_NOTICE (" Big_RED_SWITCH mode is on, ingore syncd pfc watchdog notification" );
740
+ }
741
+ else if (event == " storm" )
568
742
{
569
743
if (entry->second .action == PfcWdAction::PFC_WD_ACTION_ALERT)
570
744
{
571
745
if (entry->second .handler == nullptr )
572
746
{
747
+ SWSS_LOG_NOTICE (
748
+ " PFC Watchdog detected PFC storm on port %s, queue index %d, queue id 0x%lx and port id 0x%lx." ,
749
+ entry->second .portAlias .c_str (),
750
+ entry->second .index ,
751
+ entry->first ,
752
+ entry->second .portId );
753
+
573
754
entry->second .handler = make_shared<PfcWdActionHandler>(
574
755
entry->second .portId ,
575
756
entry->first ,
@@ -582,6 +763,13 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::doTask(swss::NotificationConsumer
582
763
{
583
764
if (entry->second .handler == nullptr )
584
765
{
766
+ SWSS_LOG_NOTICE (
767
+ " PFC Watchdog detected PFC storm on port %s, queue index %d, queue id 0x%lx and port id 0x%lx." ,
768
+ entry->second .portAlias .c_str (),
769
+ entry->second .index ,
770
+ entry->first ,
771
+ entry->second .portId );
772
+
585
773
entry->second .handler = make_shared<DropHandler>(
586
774
entry->second .portId ,
587
775
entry->first ,
@@ -594,6 +782,13 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::doTask(swss::NotificationConsumer
594
782
{
595
783
if (entry->second .handler == nullptr )
596
784
{
785
+ SWSS_LOG_NOTICE (
786
+ " PFC Watchdog detected PFC storm on port %s, queue index %d, queue id 0x%lx and port id 0x%lx." ,
787
+ entry->second .portAlias .c_str (),
788
+ entry->second .index ,
789
+ entry->first ,
790
+ entry->second .portId );
791
+
597
792
entry->second .handler = make_shared<ForwardHandler>(
598
793
entry->second .portId ,
599
794
entry->first ,
@@ -604,13 +799,20 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::doTask(swss::NotificationConsumer
604
799
}
605
800
else
606
801
{
607
- throw runtime_error (" Unknown PFC WD action" );
802
+ SWSS_LOG_ERROR (" Unknown PFC WD action" );
608
803
}
609
804
}
610
805
else if (event == " restore" )
611
806
{
612
807
if (entry->second .handler != nullptr )
613
808
{
809
+ SWSS_LOG_NOTICE (
810
+ " PFC Watchdog storm restored on port %s, queue index %d, queue id 0x%lx and port id 0x%lx." ,
811
+ entry->second .portAlias .c_str (),
812
+ entry->second .index ,
813
+ entry->first ,
814
+ entry->second .portId );
815
+
614
816
entry->second .handler ->commitCounters ();
615
817
entry->second .handler = nullptr ;
616
818
}
0 commit comments