Skip to content

Commit b7fd660

Browse files
committed
swss: Voq counter support
* Add m_voq_ids to SystemPortInfo to maintain the list of queue ids. * Add two new tables COUNTERS_SYSTEM_PORT_NAME_MAP and COUNTERS_VOQ_NAME_MAP to enable queuestat to differentiate between Port Tx queues and Voqs. * Add a new function initializeVoqs that retrieves the number of voqs for a system port and stores the voq object ids in m_voq_ids * Add code to handle queue type SAI_QUEUE_TYPE_UNICAST_VOQ. * Initialize voqs and populate COUNTERS_SYSTEM_PORT_NAME_MAP in addSystemPorts function. * Update generateQueueMap to generate queue maps for both Txqs and Voq. For PHY ports in a voq system both Txqs and Voqs are instantiated. For Voqs of remote system port, only Voq counters are initialized.
1 parent b8ee07d commit b7fd660

15 files changed

+289
-34
lines changed

cfgmgr/intfmgr.cpp

+18-2
Original file line numberDiff line numberDiff line change
@@ -535,11 +535,12 @@ void IntfMgr::removeSubIntfState(const string &alias)
535535
bool IntfMgr::setIntfGratArp(const string &alias, const string &grat_arp)
536536
{
537537
/*
538-
* Enable gratuitous ARP by accepting unsolicited ARP replies
538+
* Enable gratuitous ARP by accepting unsolicited ARP replies and untracked neighbor advertisements
539539
*/
540540
stringstream cmd;
541541
string res;
542542
string garp_enabled;
543+
int rc;
543544

544545
if (grat_arp == "enabled")
545546
{
@@ -557,8 +558,23 @@ bool IntfMgr::setIntfGratArp(const string &alias, const string &grat_arp)
557558

558559
cmd << ECHO_CMD << " " << garp_enabled << " > /proc/sys/net/ipv4/conf/" << alias << "/arp_accept";
559560
EXEC_WITH_ERROR_THROW(cmd.str(), res);
560-
561561
SWSS_LOG_INFO("ARP accept set to \"%s\" on interface \"%s\"", grat_arp.c_str(), alias.c_str());
562+
563+
cmd.clear();
564+
cmd.str(std::string());
565+
566+
// `accept_untracked_na` is not available in all kernels, so check for it before trying to set it
567+
cmd << "test -f /proc/sys/net/ipv6/conf/" << alias << "/accept_untracked_na";
568+
rc = swss::exec(cmd.str(), res);
569+
570+
if (rc == 0) {
571+
cmd.clear();
572+
cmd.str(std::string());
573+
cmd << ECHO_CMD << " " << garp_enabled << " > /proc/sys/net/ipv6/conf/" << alias << "/accept_untracked_na";
574+
EXEC_WITH_ERROR_THROW(cmd.str(), res);
575+
SWSS_LOG_INFO("`accept_untracked_na` set to \"%s\" on interface \"%s\"", grat_arp.c_str(), alias.c_str());
576+
}
577+
562578
return true;
563579
}
564580

orchagent/intfsorch.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ void IntfsOrch::increaseRouterIntfsRefCount(const string &alias)
183183
SWSS_LOG_ENTER();
184184

185185
m_syncdIntfses[alias].ref_count++;
186-
SWSS_LOG_DEBUG("Router interface %s ref count is increased to %d",
186+
SWSS_LOG_INFO("Router interface %s ref count is increased to %d",
187187
alias.c_str(), m_syncdIntfses[alias].ref_count);
188188
}
189189

@@ -192,7 +192,7 @@ void IntfsOrch::decreaseRouterIntfsRefCount(const string &alias)
192192
SWSS_LOG_ENTER();
193193

194194
m_syncdIntfses[alias].ref_count--;
195-
SWSS_LOG_DEBUG("Router interface %s ref count is decreased to %d",
195+
SWSS_LOG_INFO("Router interface %s ref count is decreased to %d",
196196
alias.c_str(), m_syncdIntfses[alias].ref_count);
197197
}
198198

@@ -1271,7 +1271,7 @@ bool IntfsOrch::removeRouterIntfs(Port &port)
12711271

12721272
if (m_syncdIntfses[port.m_alias].ref_count > 0)
12731273
{
1274-
SWSS_LOG_NOTICE("Router interface is still referenced");
1274+
SWSS_LOG_NOTICE("Router interface %s is still referenced with ref count %d", port.m_alias.c_str(), m_syncdIntfses[port.m_alias].ref_count);
12751275
return false;
12761276
}
12771277

orchagent/main.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ bool gSairedisRecord = true;
5858
bool gSwssRecord = true;
5959
bool gResponsePublisherRecord = false;
6060
bool gLogRotate = false;
61-
bool gSaiRedisLogRotate = false;
6261
bool gResponsePublisherLogRotate = false;
6362
bool gSyncMode = false;
6463
sai_redis_communication_mode_t gRedisCommunicationMode = SAI_REDIS_COMMUNICATION_MODE_REDIS_ASYNC;

orchagent/orchdaemon.cpp

+24-10
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ FlowCounterRouteOrch *gFlowCounterRouteOrch;
5757
DebugCounterOrch *gDebugCounterOrch;
5858

5959
bool gIsNatSupported = false;
60+
bool gSaiRedisLogRotate = false;
6061
event_handle_t g_events_handle;
6162

6263
#define DEFAULT_MAX_BULK_SIZE 1000
@@ -676,24 +677,26 @@ void OrchDaemon::flush()
676677
SWSS_LOG_ERROR("Failed to flush redis pipeline %d", status);
677678
abort();
678679
}
680+
}
679681

680-
// check if logroate is requested
681-
if (gSaiRedisLogRotate)
682+
/* Release the file handle so the log can be rotated */
683+
void OrchDaemon::logRotate() {
684+
SWSS_LOG_ENTER();
685+
sai_attribute_t attr;
686+
attr.id = SAI_REDIS_SWITCH_ATTR_PERFORM_LOG_ROTATE;
687+
attr.value.booldata = true;
688+
sai_status_t status = sai_switch_api->set_switch_attribute(gSwitchId, &attr);
689+
if (status != SAI_STATUS_SUCCESS)
682690
{
683-
SWSS_LOG_NOTICE("performing log rotate");
684-
685-
gSaiRedisLogRotate = false;
686-
687-
attr.id = SAI_REDIS_SWITCH_ATTR_PERFORM_LOG_ROTATE;
688-
attr.value.booldata = true;
689-
690-
sai_switch_api->set_switch_attribute(gSwitchId, &attr);
691+
SWSS_LOG_ERROR("Failed to release the file handle on sairedis log %d", status);
691692
}
692693
}
693694

695+
694696
void OrchDaemon::start()
695697
{
696698
SWSS_LOG_ENTER();
699+
gSaiRedisLogRotate = false;
697700

698701
for (Orch *o : m_orchList)
699702
{
@@ -737,6 +740,17 @@ void OrchDaemon::start()
737740
continue;
738741
}
739742

743+
// check if logroate is requested
744+
if (gSaiRedisLogRotate)
745+
{
746+
SWSS_LOG_NOTICE("performing log rotate");
747+
748+
gSaiRedisLogRotate = false;
749+
750+
logRotate();
751+
continue;
752+
}
753+
740754
auto *c = (Executor *)s;
741755
c->execute();
742756

orchagent/orchdaemon.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@
4545
#include "bfdorch.h"
4646
#include "srv6orch.h"
4747
#include "nvgreorch.h"
48+
#include <sairedis.h>
4849

4950
using namespace swss;
51+
extern bool gSaiRedisLogRotate;
5052

5153
class OrchDaemon
5254
{
@@ -67,6 +69,7 @@ class OrchDaemon
6769
{
6870
m_fabricEnabled = enabled;
6971
}
72+
void logRotate();
7073
private:
7174
DBConnector *m_applDb;
7275
DBConnector *m_configDb;

orchagent/p4orch/tests/fake_portorch.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ bool PortsOrch::getQueueTypeAndIndex(sai_object_id_t queue_id, string &type, uin
582582
return true;
583583
}
584584

585-
void PortsOrch::generateQueueMapPerPort(const Port &port)
585+
void PortsOrch::generateQueueMapPerPort(const Port &port, bool voq)
586586
{
587587
}
588588

orchagent/p4orch/tests/test_main.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ size_t gMaxBulkSize = DEFAULT_MAX_BULK_SIZE;
4343
bool gSairedisRecord = true;
4444
bool gSwssRecord = true;
4545
bool gLogRotate = false;
46-
bool gSaiRedisLogRotate = false;
4746
bool gResponsePublisherRecord = false;
4847
bool gResponsePublisherLogRotate = false;
4948
bool gSyncMode = false;

orchagent/portsorch.cpp

+113-9
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
369369
/* Initialize counter table */
370370
m_counter_db = shared_ptr<DBConnector>(new DBConnector("COUNTERS_DB", 0));
371371
m_counterTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_PORT_NAME_MAP));
372+
m_counterSysPortTable = unique_ptr<Table>(
373+
new Table(m_counter_db.get(), COUNTERS_SYSTEM_PORT_NAME_MAP));
372374
m_counterLagTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_LAG_NAME_MAP));
373375
FieldValueTuple tuple("", "");
374376
vector<FieldValueTuple> defaultLagFv;
@@ -383,6 +385,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
383385

384386
/* Initialize queue tables */
385387
m_queueTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_NAME_MAP));
388+
m_voqTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_VOQ_NAME_MAP));
386389
m_queuePortTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_PORT_MAP));
387390
m_queueIndexTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_INDEX_MAP));
388391
m_queueTypeTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_TYPE_MAP));
@@ -2465,6 +2468,9 @@ bool PortsOrch::getQueueTypeAndIndex(sai_object_id_t queue_id, string &type, uin
24652468
case SAI_QUEUE_TYPE_MULTICAST:
24662469
type = "SAI_QUEUE_TYPE_MULTICAST";
24672470
break;
2471+
case SAI_QUEUE_TYPE_UNICAST_VOQ:
2472+
type = "SAI_QUEUE_TYPE_UNICAST_VOQ";
2473+
break;
24682474
default:
24692475
SWSS_LOG_ERROR("Got unsupported queue type %d for %" PRIu64 " queue", attr[0].value.s32, queue_id);
24702476
throw runtime_error("Got unsupported queue type");
@@ -2797,7 +2803,7 @@ bool PortsOrch::initPort(const string &alias, const string &role, const int inde
27972803
/* when a port is added and queue map counter is enabled --> we need to add queue map counter for it */
27982804
if (m_isQueueMapGenerated)
27992805
{
2800-
generateQueueMapPerPort(p);
2806+
generateQueueMapPerPort(p, false);
28012807
}
28022808

28032809
PortUpdate update = { p, true };
@@ -4512,6 +4518,51 @@ void PortsOrch::doTask(Consumer &consumer)
45124518
}
45134519
}
45144520

4521+
void PortsOrch::initializeVoqs(Port &port)
4522+
{
4523+
SWSS_LOG_ENTER();
4524+
4525+
sai_attribute_t attr;
4526+
attr.id = SAI_SYSTEM_PORT_ATTR_QOS_NUMBER_OF_VOQS;
4527+
sai_status_t status = sai_system_port_api->get_system_port_attribute(
4528+
port.m_system_port_oid, 1, &attr);
4529+
if (status != SAI_STATUS_SUCCESS)
4530+
{
4531+
SWSS_LOG_ERROR("Failed to get number of voqs for port %s rv:%d", port.m_alias.c_str(), status);
4532+
task_process_status handle_status = handleSaiGetStatus(SAI_API_PORT, status);
4533+
if (handle_status != task_process_status::task_success)
4534+
{
4535+
throw runtime_error("PortsOrch initialization failure.");
4536+
}
4537+
}
4538+
SWSS_LOG_INFO("Get %d voq for port %s", attr.value.u32, port.m_alias.c_str());
4539+
4540+
m_port_voq_ids[port.m_alias] = std::vector<sai_object_id_t>( attr.value.u32 );
4541+
4542+
if (attr.value.u32 == 0)
4543+
{
4544+
return;
4545+
}
4546+
4547+
attr.id = SAI_SYSTEM_PORT_ATTR_QOS_VOQ_LIST;
4548+
attr.value.objlist.count = (uint32_t)m_port_voq_ids[port.m_alias].size();
4549+
attr.value.objlist.list = m_port_voq_ids[port.m_alias].data();
4550+
4551+
status = sai_system_port_api->get_system_port_attribute(
4552+
port.m_system_port_oid, 1, &attr);
4553+
if (status != SAI_STATUS_SUCCESS)
4554+
{
4555+
SWSS_LOG_ERROR("Failed to get voq list for port %s rv:%d", port.m_alias.c_str(), status);
4556+
task_process_status handle_status = handleSaiGetStatus(SAI_API_PORT, status);
4557+
if (handle_status != task_process_status::task_success)
4558+
{
4559+
throw runtime_error("PortsOrch initialization failure.");
4560+
}
4561+
}
4562+
4563+
SWSS_LOG_INFO("Get voqs for port %s", port.m_alias.c_str());
4564+
}
4565+
45154566
void PortsOrch::initializeQueues(Port &port)
45164567
{
45174568
SWSS_LOG_ENTER();
@@ -5981,8 +6032,17 @@ void PortsOrch::generateQueueMap()
59816032
{
59826033
if (it.second.m_type == Port::PHY)
59836034
{
5984-
generateQueueMapPerPort(it.second);
6035+
generateQueueMapPerPort(it.second, false);
6036+
if (gMySwitchType == "voq")
6037+
{
6038+
generateQueueMapPerPort(it.second, true);
6039+
}
59856040
}
6041+
6042+
if (it.second.m_type == Port::SYSTEM)
6043+
{
6044+
generateQueueMapPerPort(it.second, true);
6045+
}
59866046
}
59876047

59886048
m_isQueueMapGenerated = true;
@@ -6026,40 +6086,69 @@ void PortsOrch::removeQueueMapPerPort(const Port& port)
60266086
CounterCheckOrch::getInstance().removePort(port);
60276087
}
60286088

6029-
void PortsOrch::generateQueueMapPerPort(const Port& port)
6089+
void PortsOrch::generateQueueMapPerPort(const Port& port, bool voq)
60306090
{
60316091
/* Create the Queue map in the Counter DB */
60326092
/* Add stat counters to flex_counter */
60336093
vector<FieldValueTuple> queueVector;
60346094
vector<FieldValueTuple> queuePortVector;
60356095
vector<FieldValueTuple> queueIndexVector;
60366096
vector<FieldValueTuple> queueTypeVector;
6097+
std::vector<sai_object_id_t> queue_ids;
6098+
if (voq)
6099+
{
6100+
queue_ids = m_port_voq_ids[port.m_alias];
6101+
}
6102+
else
6103+
{
6104+
queue_ids = port.m_queue_ids;
6105+
}
60376106

6038-
for (size_t queueIndex = 0; queueIndex < port.m_queue_ids.size(); ++queueIndex)
6107+
for (size_t queueIndex = 0; queueIndex < queue_ids.size(); ++queueIndex)
60396108
{
60406109
std::ostringstream name;
6041-
name << port.m_alias << ":" << queueIndex;
6110+
if (voq)
6111+
{
6112+
name << port.m_system_port_info.alias << ":" << queueIndex;
6113+
}
6114+
else
6115+
{
6116+
name << port.m_alias << ":" << queueIndex;
6117+
}
60426118

6043-
const auto id = sai_serialize_object_id(port.m_queue_ids[queueIndex]);
6119+
const auto id = sai_serialize_object_id(queue_ids[queueIndex]);
60446120

60456121
queueVector.emplace_back(name.str(), id);
60466122
queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id));
60476123

60486124
string queueType;
60496125
uint8_t queueRealIndex = 0;
6050-
if (getQueueTypeAndIndex(port.m_queue_ids[queueIndex], queueType, queueRealIndex))
6126+
if (getQueueTypeAndIndex(queue_ids[queueIndex], queueType, queueRealIndex))
60516127
{
60526128
queueTypeVector.emplace_back(id, queueType);
60536129
queueIndexVector.emplace_back(id, to_string(queueRealIndex));
60546130
}
60556131

6132+
if (voq)
6133+
{
6134+
queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_system_port_oid));
6135+
}
6136+
else
6137+
{
6138+
queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id));
6139+
}
6140+
60566141
// Install a flex counter for this queue to track stats
60576142
std::unordered_set<string> counter_stats;
60586143
for (const auto& it: queue_stat_ids)
60596144
{
60606145
counter_stats.emplace(sai_serialize_queue_stat(it));
60616146
}
6062-
queue_stat_manager.setCounterIdList(port.m_queue_ids[queueIndex], CounterType::QUEUE, counter_stats);
6147+
queue_stat_manager.setCounterIdList(queue_ids[queueIndex], CounterType::QUEUE, counter_stats);
6148+
6149+
if (voq) {
6150+
continue;
6151+
}
60636152

60646153
/* add watermark queue counters */
60656154
string key = getQueueWatermarkFlexCounterTableKey(id);
@@ -6078,7 +6167,15 @@ void PortsOrch::generateQueueMapPerPort(const Port& port)
60786167
m_flexCounterTable->set(key, fieldValues);
60796168
}
60806169

6081-
m_queueTable->set("", queueVector);
6170+
if (voq)
6171+
{
6172+
m_voqTable->set("", queueVector);
6173+
}
6174+
else
6175+
{
6176+
m_queueTable->set("", queueVector);
6177+
}
6178+
60826179
m_queuePortTable->set("", queuePortVector);
60836180
m_queueIndexTable->set("", queueIndexVector);
60846181
m_queueTypeTable->set("", queueTypeVector);
@@ -7361,7 +7458,14 @@ bool PortsOrch::addSystemPorts()
73617458
port.m_system_port_info.speed = attrs[1].value.sysportconfig.speed;
73627459
port.m_system_port_info.num_voq = attrs[1].value.sysportconfig.num_voq;
73637460

7461+
initializeVoqs( port );
73647462
setPort(port.m_alias, port);
7463+
/* Add system port name map to counter table */
7464+
FieldValueTuple tuple(port.m_system_port_info.alias,
7465+
sai_serialize_object_id(system_port_oid));
7466+
vector<FieldValueTuple> fields;
7467+
fields.push_back(tuple);
7468+
m_counterSysPortTable->set("", fields);
73657469
if(m_port_ref_count.find(port.m_alias) == m_port_ref_count.end())
73667470
{
73677471
m_port_ref_count[port.m_alias] = 0;

0 commit comments

Comments
 (0)