Skip to content

Commit

Permalink
Add support for voq counters in portsorch. (sonic-net#2467)
Browse files Browse the repository at this point in the history
* swss: Add 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.
  • Loading branch information
skbarista authored Oct 12, 2022
1 parent c8d4905 commit 15beee4
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 12 deletions.
2 changes: 1 addition & 1 deletion orchagent/p4orch/tests/fake_portorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ bool PortsOrch::getQueueTypeAndIndex(sai_object_id_t queue_id, string &type, uin
return true;
}

void PortsOrch::generateQueueMapPerPort(const Port &port)
void PortsOrch::generateQueueMapPerPort(const Port &port, bool voq)
{
}

Expand Down
121 changes: 111 additions & 10 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
/* Initialize counter table */
m_counter_db = shared_ptr<DBConnector>(new DBConnector("COUNTERS_DB", 0));
m_counterTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_PORT_NAME_MAP));
m_counterSysPortTable = unique_ptr<Table>(
new Table(m_counter_db.get(), COUNTERS_SYSTEM_PORT_NAME_MAP));
m_counterLagTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_LAG_NAME_MAP));
FieldValueTuple tuple("", "");
vector<FieldValueTuple> defaultLagFv;
Expand All @@ -383,6 +385,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi

/* Initialize queue tables */
m_queueTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_NAME_MAP));
m_voqTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_VOQ_NAME_MAP));
m_queuePortTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_PORT_MAP));
m_queueIndexTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_INDEX_MAP));
m_queueTypeTable = unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_QUEUE_TYPE_MAP));
Expand Down Expand Up @@ -2465,6 +2468,9 @@ bool PortsOrch::getQueueTypeAndIndex(sai_object_id_t queue_id, string &type, uin
case SAI_QUEUE_TYPE_MULTICAST:
type = "SAI_QUEUE_TYPE_MULTICAST";
break;
case SAI_QUEUE_TYPE_UNICAST_VOQ:
type = "SAI_QUEUE_TYPE_UNICAST_VOQ";
break;
default:
SWSS_LOG_ERROR("Got unsupported queue type %d for %" PRIu64 " queue", attr[0].value.s32, queue_id);
throw runtime_error("Got unsupported queue type");
Expand Down Expand Up @@ -2797,7 +2803,7 @@ bool PortsOrch::initPort(const string &alias, const string &role, const int inde
/* when a port is added and queue map counter is enabled --> we need to add queue map counter for it */
if (m_isQueueMapGenerated)
{
generateQueueMapPerPort(p);
generateQueueMapPerPort(p, false);
}

PortUpdate update = { p, true };
Expand Down Expand Up @@ -4512,6 +4518,51 @@ void PortsOrch::doTask(Consumer &consumer)
}
}

void PortsOrch::initializeVoqs(Port &port)
{
SWSS_LOG_ENTER();

sai_attribute_t attr;
attr.id = SAI_SYSTEM_PORT_ATTR_QOS_NUMBER_OF_VOQS;
sai_status_t status = sai_system_port_api->get_system_port_attribute(
port.m_system_port_oid, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to get number of voqs for port %s rv:%d", port.m_alias.c_str(), status);
task_process_status handle_status = handleSaiGetStatus(SAI_API_PORT, status);
if (handle_status != task_process_status::task_success)
{
throw runtime_error("PortsOrch initialization failure.");
}
}
SWSS_LOG_INFO("Get %d voq for port %s", attr.value.u32, port.m_alias.c_str());

m_port_voq_ids[port.m_alias] = std::vector<sai_object_id_t>( attr.value.u32 );

if (attr.value.u32 == 0)
{
return;
}

attr.id = SAI_SYSTEM_PORT_ATTR_QOS_VOQ_LIST;
attr.value.objlist.count = (uint32_t) m_port_voq_ids[port.m_alias].size();
attr.value.objlist.list = m_port_voq_ids[port.m_alias].data();

status = sai_system_port_api->get_system_port_attribute(
port.m_system_port_oid, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to get voq list for port %s rv:%d", port.m_alias.c_str(), status);
task_process_status handle_status = handleSaiGetStatus(SAI_API_PORT, status);
if (handle_status != task_process_status::task_success)
{
throw runtime_error("PortsOrch initialization failure.");
}
}

SWSS_LOG_INFO("Get voqs for port %s", port.m_alias.c_str());
}

void PortsOrch::initializeQueues(Port &port)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -5981,7 +6032,16 @@ void PortsOrch::generateQueueMap()
{
if (it.second.m_type == Port::PHY)
{
generateQueueMapPerPort(it.second);
generateQueueMapPerPort(it.second, false);
if (gMySwitchType == "voq")
{
generateQueueMapPerPort(it.second, true);
}
}

if (it.second.m_type == Port::SYSTEM)
{
generateQueueMapPerPort(it.second, true);
}
}

Expand Down Expand Up @@ -6026,28 +6086,51 @@ void PortsOrch::removeQueueMapPerPort(const Port& port)
CounterCheckOrch::getInstance().removePort(port);
}

void PortsOrch::generateQueueMapPerPort(const Port& port)
void PortsOrch::generateQueueMapPerPort(const Port& port, bool voq)
{
/* Create the Queue map in the Counter DB */
/* Add stat counters to flex_counter */
vector<FieldValueTuple> queueVector;
vector<FieldValueTuple> queuePortVector;
vector<FieldValueTuple> queueIndexVector;
vector<FieldValueTuple> queueTypeVector;
std::vector<sai_object_id_t> queue_ids;
if (voq)
{
queue_ids = m_port_voq_ids[port.m_alias];
}
else
{
queue_ids = port.m_queue_ids;
}

for (size_t queueIndex = 0; queueIndex < port.m_queue_ids.size(); ++queueIndex)
for (size_t queueIndex = 0; queueIndex < queue_ids.size(); ++queueIndex)
{
std::ostringstream name;
name << port.m_alias << ":" << queueIndex;
if (voq)
{
name << port.m_system_port_info.alias << ":" << queueIndex;
}
else
{
name << port.m_alias << ":" << queueIndex;
}

const auto id = sai_serialize_object_id(port.m_queue_ids[queueIndex]);
const auto id = sai_serialize_object_id(queue_ids[queueIndex]);

queueVector.emplace_back(name.str(), id);
queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id));
if (voq)
{
queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_system_port_oid));
}
else
{
queuePortVector.emplace_back(id, sai_serialize_object_id(port.m_port_id));
}

string queueType;
uint8_t queueRealIndex = 0;
if (getQueueTypeAndIndex(port.m_queue_ids[queueIndex], queueType, queueRealIndex))
if (getQueueTypeAndIndex(queue_ids[queueIndex], queueType, queueRealIndex))
{
queueTypeVector.emplace_back(id, queueType);
queueIndexVector.emplace_back(id, to_string(queueRealIndex));
Expand All @@ -6059,7 +6142,11 @@ void PortsOrch::generateQueueMapPerPort(const Port& port)
{
counter_stats.emplace(sai_serialize_queue_stat(it));
}
queue_stat_manager.setCounterIdList(port.m_queue_ids[queueIndex], CounterType::QUEUE, counter_stats);
queue_stat_manager.setCounterIdList(queue_ids[queueIndex], CounterType::QUEUE, counter_stats);

if (voq) {
continue;
}

/* add watermark queue counters */
string key = getQueueWatermarkFlexCounterTableKey(id);
Expand All @@ -6078,7 +6165,14 @@ void PortsOrch::generateQueueMapPerPort(const Port& port)
m_flexCounterTable->set(key, fieldValues);
}

m_queueTable->set("", queueVector);
if (voq)
{
m_voqTable->set("", queueVector);
}
else
{
m_queueTable->set("", queueVector);
}
m_queuePortTable->set("", queuePortVector);
m_queueIndexTable->set("", queueIndexVector);
m_queueTypeTable->set("", queueTypeVector);
Expand Down Expand Up @@ -7361,7 +7455,14 @@ bool PortsOrch::addSystemPorts()
port.m_system_port_info.speed = attrs[1].value.sysportconfig.speed;
port.m_system_port_info.num_voq = attrs[1].value.sysportconfig.num_voq;

initializeVoqs( port );
setPort(port.m_alias, port);
/* Add system port name map to counter table */
FieldValueTuple tuple(port.m_system_port_info.alias,
sai_serialize_object_id(system_port_oid));
vector<FieldValueTuple> fields;
fields.push_back(tuple);
m_counterSysPortTable->set("", fields);
if(m_port_ref_count.find(port.m_alias) == m_port_ref_count.end())
{
m_port_ref_count[port.m_alias] = 0;
Expand Down
7 changes: 6 additions & 1 deletion orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,12 @@ class PortsOrch : public Orch, public Subject

private:
unique_ptr<Table> m_counterTable;
unique_ptr<Table> m_counterSysPortTable;
unique_ptr<Table> m_counterLagTable;
unique_ptr<Table> m_portTable;
unique_ptr<Table> m_gearboxTable;
unique_ptr<Table> m_queueTable;
unique_ptr<Table> m_voqTable;
unique_ptr<Table> m_queuePortTable;
unique_ptr<Table> m_queueIndexTable;
unique_ptr<Table> m_queueTypeTable;
Expand Down Expand Up @@ -251,6 +253,7 @@ class PortsOrch : public Orch, public Subject
map<set<int>, tuple<string, uint32_t, int, string, int, string>> m_lanesAliasSpeedMap;
map<string, Port> m_portList;
map<string, vlan_members_t> m_portVlanMember;
map<string, std::vector<sai_object_id_t>> m_port_voq_ids;
/* mapping from SAI object ID to Name for faster
* retrieval of Port/VLAN from object ID for events
* coming from SAI
Expand Down Expand Up @@ -288,6 +291,8 @@ class PortsOrch : public Orch, public Subject
void initializePriorityGroups(Port &port);
void initializePortBufferMaximumParameters(Port &port);
void initializeQueues(Port &port);
void initializeVoqs(Port &port);


bool addHostIntfs(Port &port, string alias, sai_object_id_t &host_intfs_id);
bool setHostIntfsStripTag(Port &port, sai_hostif_vlan_tag_t strip);
Expand Down Expand Up @@ -344,7 +349,7 @@ class PortsOrch : public Orch, public Subject
bool getQueueTypeAndIndex(sai_object_id_t queue_id, string &type, uint8_t &index);

bool m_isQueueMapGenerated = false;
void generateQueueMapPerPort(const Port& port);
void generateQueueMapPerPort(const Port& port, bool voq);
void removeQueueMapPerPort(const Port& port);

bool m_isPriorityGroupMapGenerated = false;
Expand Down
2 changes: 2 additions & 0 deletions tests/test_vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ def arp_accept_disabled():
wait_for_result(arp_accept_disabled, PollingConfig(), "IPv4 arp_accept not disabled")

self.dvs_vlan.remove_vlan(vlan)
self.dvs_vlan.get_and_verify_vlan_ids(0)

def test_VlanProxyArp(self, dvs):

Expand Down Expand Up @@ -487,6 +488,7 @@ def proxy_arp_disabled():
wait_for_result(proxy_arp_disabled, PollingConfig(), 'IPv4 proxy_arp or proxy_arp_pvlan not disabled')

self.dvs_vlan.remove_vlan(vlan)
self.dvs_vlan.get_and_verify_vlan_ids(0)

def test_VlanMemberLinkDown(self, dvs):

Expand Down

0 comments on commit 15beee4

Please sign in to comment.