[ofa-general] [PATCH] ibutils: Enhanced credit loop analysis
Yevgeny Kliteynik
kliteyn at dev.mellanox.co.il
Tue Oct 7 02:31:17 PDT 2008
[On behalf of Vladimir Zdornov]
Enhanced credit loop analysis.
Multiple VL/SL support added.
Loops are detected using DFS.
Signed-off-by: Vladimir Zdornov <zdv at mellanox.co.il>
---
ibdm/datamodel/CredLoops.cpp | 643 ++++++++++++------------------------------
ibdm/datamodel/Fabric.cpp | 214 ++++++++++++++
ibdm/datamodel/Fabric.h | 104 +++++++-
ibdm/src/osm_check.cpp | 214 +++++++++------
4 files changed, 619 insertions(+), 556 deletions(-)
diff --git a/ibdm/datamodel/CredLoops.cpp b/ibdm/datamodel/CredLoops.cpp
index 30cff4b..70e5879 100644
--- a/ibdm/datamodel/CredLoops.cpp
+++ b/ibdm/datamodel/CredLoops.cpp
@@ -46,55 +46,67 @@
*
*/
-#define RT_NOT_USED 0
-#define RT_USED 1
-#define RT_VISITED 2
-#define RT_LOOP_TRACED 4
-
//////////////////////////////////////////////////////////////////////////////
-// Allocate the tables on the switches
-int
-CrdLoopInitRtTbls(IBFabric *p_fabric) {
- IBNode *p_node;
-
- // Go over all SW nodes in the fabric and build a table
- // of input to output ports links. Each element should track
- // effect and traversal flags.
- for( map_str_pnode::iterator nI = p_fabric->NodeByName.begin();
- nI != p_fabric->NodeByName.end();
- nI++) {
+// Apply DFS on a dependency graph
- p_node = (*nI).second;
- if (p_node->type != IB_SW_NODE) continue;
+int CrdLoopDFS(VChannel* ch) {
+ // Already been there
+ if (ch->getFlag() == Closed)
+ return 0;
+ // Credit loop
+ if (ch->getFlag() == Open) {
+ return 1;
+ }
+ // Mark as open
+ ch->setFlag(Open);
+ // Make recursive steps
+ for (int i=0; i<ch->getDependSize();i++) {
+ VChannel* next = ch->getDependency(i);
+ if (next) {
+ if (CrdLoopDFS(next))
+ return 1;
+ }
+ }
+ // Mark as closed
+ ch->setFlag(Closed);
+ return 0;
+}
- uint8_t *p_tbl =
- new uint8_t[p_node->numPorts*p_node->numPorts];
+//////////////////////////////////////////////////////////////////////////////
- memset(p_tbl, RT_NOT_USED,
- sizeof(uint8_t)*p_node->numPorts*p_node->numPorts);
+// Go over CA's apply DFS on the dependency graphs starting from CA's port
- if (! p_tbl) {
- cout << "-F- Fail to allocate memory for port routing table" << endl;
- exit(2);
- }
+int CrdLoopFindLoops(IBFabric* p_fabric) {
+ unsigned int lidStep = 1 << p_fabric->lmc;
- // We use the appData1 of the node to store the routing links
- // info
- if (p_node->appData1.ptr) {
- cout << "-W- Application Data Pointer already set for node:"
- << p_node->name << endl;
- delete [] p_tbl;
- } else {
- p_node->appData1.ptr = (void *)p_tbl;
+ // go over all CA ports in the fabric
+ for (int i = p_fabric->minLid; i <= p_fabric->maxLid; i += lidStep) {
+ IBPort *p_Port = p_fabric->PortByLid[i];
+ if (!p_Port || (p_Port->p_node->type == IB_SW_NODE)) continue;
+ // Go over all CA's channels and find untouched one
+ for (int j=0;j < p_fabric->getNumSLs(); j++) {
+ dfs_t state = p_Port->channels[j]->getFlag();
+ if (state == Open) {
+ cout << "-E- open channel outside of DFS" << endl;
+ return 1;
+ }
+ // Already processed, continue
+ if (state == Closed)
+ continue;
+ // Found starting point
+ if (CrdLoopDFS(p_Port->channels[j]))
+ return 1;
}
}
return 0;
}
+
//////////////////////////////////////////////////////////////////////////////
// Trace a route from slid to dlid by LFT
+// Add dependency edges
int CrdLoopMarkRouteByLFT (
IBFabric *p_fabric,
unsigned int sLid , unsigned int dLid
@@ -102,99 +114,97 @@ int CrdLoopMarkRouteByLFT (
IBPort *p_port = p_fabric->getPortByLid(sLid);
IBNode *p_node;
- IBPort *p_remotePort;
+ IBPort *p_portNext;
unsigned int lidStep = 1 << p_fabric->lmc;
- int inPortNum = 0, outPortNum = 0;
- uint8_t *p_tbl;
- int hopCnt = 0;
+ int outPortNum = 0, inputPortNum = 0, hopCnt = 0;
+ bool done;
// make sure:
- if (! p_port) {
+ if (!p_port) {
cout << "-E- Provided source:" << sLid
<< " lid is not mapped to a port!" << endl;
return(1);
}
- // if the port is not a switch - go to the next switch:
- if (p_port->p_node->type != IB_SW_NODE) {
- // try the next one:
- if (!p_port->p_remotePort) {
- cout << "-E- Provided starting point is not connected !"
- << "lid:" << sLid << endl;
- return 1;
- }
- inPortNum = p_port->p_remotePort->num;
- p_node = p_port->p_remotePort->p_node;
- } else {
- // it is a switch :
- p_node = p_port->p_node;
- }
+ // Retrieve the relevant SL
+ uint8_t SL, VL;
+ SL = VL = p_port->p_node->getPSLForLid(dLid);
+ if (!p_port->p_remotePort) {
+ cout << "-E- Provided starting point is not connected !"
+ << "lid:" << sLid << endl;
+ return 1;
+ }
- // verify we are finally of a switch:
- if (p_node->type != IB_SW_NODE) {
- cout << "-E- Provided starting point is not connected to a switch !"
- << "lid:" << sLid << endl;
- return 1;
+ if (SL == IB_SLT_UNASSIGNED) {
+ cout << "-E- SL to destination is unassigned !"
+ << "slid: " << sLid << "dlid:" << dLid << endl;
+ return 1;
}
- // traverse:
- int done = 0;
+ // check if we are done:
+ done = ((p_port->p_remotePort->base_lid <= dLid) &&
+ (p_port->p_remotePort->base_lid+lidStep - 1 >= dLid));
while (!done) {
- // calc next node:
- outPortNum = p_node->getLFTPortForLid(dLid);
- if (outPortNum == IB_LFT_UNASSIGNED) {
- cout << "-E- Unassigned LFT for lid:" << dLid << " Dead end at:" << p_node->name << endl;
- return 1;
- }
-
- // get the port on the other side
- p_port = p_node->getPort(outPortNum);
-
- if (! (p_port &&
- p_port->p_remotePort &&
- p_port->p_remotePort->p_node)) {
- cout << "-E- Dead end at:" << p_node->name << endl;
- return 1;
- }
-
- // Track it please:
- p_tbl = (uint8_t *)p_node->appData1.ptr;
- if (! p_tbl) {
- cout << "-F- Got a non initialized routing table pointer!" << endl;
- exit(2);
- }
-
- // cout << "-V- Add usage Node:" << p_node->name
- // << " In:" << inPortNum << " to:" << outPortNum << endl;
-
- p_tbl[(inPortNum - 1)*p_node->numPorts + outPortNum - 1] = RT_USED;
+ // Get the node on the remote side
+ p_node = p_port->p_remotePort->p_node;
+ // Get remote port's number
+ inputPortNum = p_port->p_remotePort->num;
+ // Get number of ports on the remote side
+ int numPorts = p_node->numPorts;
+ // Init vchannel's number of possible dependencies
+ p_port->channels[VL]->setDependSize((numPorts+1)*p_fabric->getNumVLs());
+
+ // Get port num of the next hop
+ outPortNum = p_node->getLFTPortForLid(dLid);
+ // Get VL of the next hop
+ int nextVL = p_node->getSLVL(inputPortNum,outPortNum,SL);
+
+ if (outPortNum == IB_LFT_UNASSIGNED) {
+ cout << "-E- Unassigned LFT for lid:" << dLid << " Dead end at:" << p_node->name << endl;
+ return 1;
+ }
- p_remotePort = p_port->p_remotePort;
- inPortNum = p_remotePort->num;
+ if (nextVL == IB_SLT_UNASSIGNED) {
+ cout << "-E- Unassigned SL2VL entry, iport: "<< inputPortNum<<", oport:"<<outPortNum<<", SL:"<<(int)SL<< endl;
+ return 1;
+ }
- // check if we are done:
- done = ((p_remotePort->base_lid <= dLid) &&
- (p_remotePort->base_lid+lidStep - 1 >= dLid));
+ // get the next port on the other side
+ p_portNext = p_node->getPort(outPortNum);
- p_node = p_remotePort->p_node;
- if (hopCnt++ > 256) {
- cout << "-E- Aborting after 256 hops - loop in LFT?" << endl;
- return 1;
- }
+ if (! (p_portNext &&
+ p_portNext->p_remotePort &&
+ p_portNext->p_remotePort->p_node)) {
+ cout << "-E- Dead end at:" << p_node->name << endl;
+ return 1;
+ }
+ // Now add an edge
+ p_port->channels[VL]->setDependency(outPortNum*p_fabric->getNumVLs()+nextVL,p_portNext->channels[nextVL]);
+ // Advance
+ p_port = p_portNext;
+ VL = nextVL;
+ if (hopCnt++ > 256) {
+ cout << "-E- Aborting after 256 hops - loop in LFT?" << endl;
+ return 1;
+ }
+ //Check if done
+ done = ((p_port->p_remotePort->base_lid <= dLid) &&
+ (p_port->p_remotePort->base_lid+lidStep - 1 >= dLid));
}
return 0;
}
-//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+// Go over all CA to CA paths and connect dependant vchannel by an edge
-// Go over all CA to CA paths and mark the output links
-// input links connections on these paths in the routing tables.
int
-CrdLoopPopulateRtTbls(IBFabric *p_fabric) {
+CrdLoopConnectDepend(IBFabric* p_fabric)
+{
unsigned int lidStep = 1 << p_fabric->lmc;
- int anyError = 0, paths = 0;
+ int anyError = 0;
unsigned int i,j;
// go over all ports in the fabric
@@ -215,22 +225,20 @@ CrdLoopPopulateRtTbls(IBFabric *p_fabric) {
if (! p_dstPort) continue;
if (p_dstPort->p_node->type == IB_SW_NODE) continue;
-
unsigned int dLid = p_dstPort->base_lid;
-
// go over all LMC combinations:
- for (unsigned int l = 0; l < lidStep; l++) {
- paths++;
-
- // Trace the path but record the input to output ports used.
- if (CrdLoopMarkRouteByLFT(p_fabric, sLid + l, dLid + l)) {
- cout << "-E- Fail to find a path from:"
- << p_srcPort->p_node->name << "/" << p_srcPort->num
- << " to:" << p_dstPort->p_node->name << "/" << p_dstPort->num
- << endl;
- anyError++;
- }
- } // all LMC lids
+ for (unsigned int l1 = 0; l1 < lidStep; l1++) {
+ for (unsigned int l2 = 0; l2 < lidStep; l2++) {
+ // Trace the path but record the input to output ports used.
+ if (CrdLoopMarkRouteByLFT(p_fabric, sLid + l1, dLid + l2)) {
+ cout << "-E- Fail to find a path from:"
+ << p_srcPort->p_node->name << "/" << p_srcPort->num
+ << " to:" << p_dstPort->p_node->name << "/" << p_dstPort->num
+ << endl;
+ anyError++;
+ }
+ }// all LMC lids 2 */
+ } // all LMC lids 1 */
} // all targets
} // all sources
@@ -239,316 +247,34 @@ CrdLoopPopulateRtTbls(IBFabric *p_fabric) {
return 1;
}
- cout << "-I- Marked " << paths << " CA to CA Paths" << endl;
return 0;
}
//////////////////////////////////////////////////////////////////////////////
-// BFS from all CA's and require all inputs for an
-// output node to be marked visited to go through it.
-int
-CrdLoopBfsFromCAs(IBFabric *p_fabric) {
- int loops = 0;
- list< IBPort *> thisStepPorts, nextStepPorts;
-
- // go over all CA nodes and track the input ports for next step
- IBNode *p_node;
- IBPort *p_port;
-
- for( map_str_pnode::iterator nI = p_fabric->NodeByName.begin();
- nI != p_fabric->NodeByName.end();
- nI++) {
-
- p_node = (*nI).second;
- if (p_node->type != IB_CA_NODE) continue;
-
- // get the remote input port
- for (unsigned int pn = 1; pn <= p_node->numPorts; pn++) {
- p_port = p_node->getPort(pn);
-
- if (p_port && p_port->p_remotePort) {
- // add to the list
- thisStepPorts.push_back(p_port->p_remotePort);
- }
- }
- }
-
- // while you have next step ports
- while ( ! thisStepPorts.empty()) {
- loops++;
-
- nextStepPorts.clear();
-
- // go over all this step ports
- while (! thisStepPorts.empty()) {
- p_port = thisStepPorts.front();
- thisStepPorts.pop_front();
-
- p_node = p_port->p_node ;
-
- if (p_node->type != IB_SW_NODE) continue;
-
- uint8_t *p_tbl = (uint8_t *)p_node->appData1.ptr;
- int inPortNum = p_port->num;
-
- // go over all the out ports marked by this input port:
- for (unsigned int outPortNum = 1;
- outPortNum <= p_node->numPorts; outPortNum++) {
- int idx = (inPortNum - 1)*p_node->numPorts + outPortNum - 1;
- // check if port was marked as used:
- if (p_tbl[idx] == RT_USED) {
- // zero the port USED:
- p_tbl[idx] = (RT_USED | RT_VISITED);
-
- // now check if all the effecting ports are cleard:
- int foundUnVisited = 0;
- for (unsigned int pn = 0; !foundUnVisited && (pn < p_node->numPorts);
- pn++) {
- idx = pn*p_node->numPorts + outPortNum - 1;
- if (p_tbl[idx] == RT_USED) foundUnVisited = 1;
- }
-
- // only when we do not have a marked but not visited we
- // can progress to next port:
- if (!foundUnVisited) {
- // we only add ports if the are now unvisited:
- IBPort *p_oPort = p_node->getPort(outPortNum);
- if (p_oPort && p_oPort->p_remotePort) {
- nextStepPorts.push_back(p_oPort->p_remotePort);
- }
- }
- }
- }
- } // all this step ports
-
- // Copy next step ports to cur ports:
- thisStepPorts = nextStepPorts;
- }
-
- cout << "-I- Propagted ranking through Fabric in:"
- << loops << " BFS steps" << endl;
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Dump Routing Tables:
-int
-CrdLoopDumpRtTbls(IBFabric *p_fabric) {
- // go over all switches in the fabric
- IBNode *p_node;
-
- // Go over all SW nodes in the fabric and build a table
- // of input to output ports links. Each element should track
- // effect and traversal flags.
- for( map_str_pnode::iterator nI = p_fabric->NodeByName.begin();
- nI != p_fabric->NodeByName.end();
- nI++) {
-
- p_node = (*nI).second;
- if (p_node->type != IB_SW_NODE) continue;
-
- cout << "---- RT TBL DUMP -----" << endl;
- cout << "SW:" << p_node->name << endl;
-
- uint8_t *p_tbl = (uint8_t*)p_node->appData1.ptr;
-
- // header
- cout << "I\\O ";
- for (unsigned int outPortNum = 1; outPortNum <= p_node->numPorts;
- outPortNum++)
- cout << setw(3) << outPortNum << " ";
- cout << endl;
-
- // Now go over all out ports and check all input port.
- for (unsigned int inPortNum = 1; inPortNum <= p_node->numPorts;
- inPortNum++) {
- cout << setw(3) << inPortNum << " ";
- // go over all the out ports marked by this input port:
- for (unsigned int outPortNum = 1; outPortNum <= p_node->numPorts;
- outPortNum++) {
- int idx = (inPortNum - 1)*p_node->numPorts + outPortNum - 1;
- if (p_tbl[idx] == RT_USED)
- cout << setw(3) << "USE ";
- else if (p_tbl[idx] == (RT_USED | RT_VISITED))
- cout << setw(3) << "VIS ";
- else {
- cout << setw(3) << " ";
- }
- }
- cout << endl;
- }
- }
- return(0);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Trace a loop through a given node ports pair
-// We DFS fowrard and report all nodes of all the loops found.
-int
-CrdLoopTraceLoop(IBFabric *p_fabric,
- IBNode *p_endNode,
- int inPortNum,
- IBNode *p_startNode,
- int outPortNum,
- string path = string(""),
- int hops = 0,
- int doNotPrintPath = 0
- ) {
-
- // find the other end of the link if any
- IBPort *p_port = p_startNode->getPort(outPortNum);
-
- // we need to have a port and remote port
- if (! p_port || !p_port->p_remotePort) return 0;
-
- IBNode *p_remNode = p_port->p_remotePort->p_node;
-
- // we never go through CAs
- if (p_remNode->type != IB_SW_NODE) return 0;
-
- uint8_t *p_tbl = (uint8_t*)p_remNode->appData1.ptr;
-
- // if it is the target end node and port
- if (p_remNode == p_endNode && p_port->p_remotePort->num == inPortNum) {
- // print the path
- cout << "--------------------------------------------" << endl;
- cout << "-E- Found a credit loop on:" << p_endNode->name
- << " from port:" << inPortNum << " to port:"
- << outPortNum << endl;
- if (! doNotPrintPath) {
- cout << path << endl;
- cout << p_endNode->name << " " << inPortNum << endl;
- }
- return(1);
- } else {
- // track the number of downwards paths found.
- int numPaths = 0;
- static char buf[128];
-
- // we will track where we come from
- sprintf(buf, "%s %u -> ",
- p_remNode->name.c_str(),p_port->p_remotePort->num);
-
- // it is possible we already visited this node since we trace a
- // loop that is different then our own.
- if (path.find(buf) != string::npos) {
- if (! doNotPrintPath)
- cout << "-W- Marking a 'scroll' side loop at:"
- << p_remNode->name << "/" << p_port->p_remotePort->num << endl;
-
- // to avoid going into this scroll again
- // we encode a return code that should mark the
- // path as a scroll:
- return -1;
- }
-
- // abort if hops count is bigger then 1000
- if (hops > 1000) {
- if (! doNotPrintPath)
- cout << "-W- Aborting path:" << path << endl;
- return 0;
- }
-
- // add yourself to the path
- string fwdPath = path + string("\n") + string(buf);
-
- // go over all out ports not aleady marked routed from this in port
- for (unsigned int pn = 1; pn <= p_remNode->numPorts; pn++) {
- int idx = (p_port->p_remotePort->num - 1)*p_remNode->numPorts + pn - 1;
-
- // do we have a used but not visited connection:
- if (p_tbl[idx] == RT_USED) {
- // traverse forward
- sprintf(buf, "%u", pn);
- int foundPaths =
- CrdLoopTraceLoop(p_fabric, p_endNode, inPortNum,
- p_remNode, pn, fwdPath + string(buf), hops++,
- doNotPrintPath);
-
- // we might have encountered a scroll (return value < 0)
- // so we sould ignore it in the global count.
- if (foundPaths > 0) numPaths += foundPaths;
-
- // if found a loop or a scroll downwards mark the local port pair.
- if (foundPaths) {
- p_tbl[idx] = RT_LOOP_TRACED & RT_USED;
- }
- }
- }
- return(numPaths);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Report all Switch ports that are still marked as not
-// fully visited.
-int
-CrdLoopReportLoops(IBFabric *p_fabric, int doNotPrintPath) {
- int anyError = 0;
-
- // go over all switches in the fabric looking for used link to link
- // that was not marked as visited.
- IBNode *p_node;
-
- // Go over all SW nodes in the fabric and build a table
- // of input to output ports links. Each element should track
- // effect and traversal flags.
- for( map_str_pnode::iterator nI = p_fabric->NodeByName.begin();
- nI != p_fabric->NodeByName.end();
- nI++) {
-
- p_node = (*nI).second;
- if (p_node->type != IB_SW_NODE) continue;
-
- uint8_t *p_tbl = (uint8_t*)p_node->appData1.ptr;
-
- // Now go over all out ports and check all input port.
- for (unsigned int inPortNum = 1; inPortNum <= p_node->numPorts;
- inPortNum++) {
- // go over all the out ports marked by this input port:
- for (unsigned int outPortNum = 1; outPortNum <= p_node->numPorts;
- outPortNum++) {
- int idx = (inPortNum - 1)*p_node->numPorts + outPortNum - 1;
-
- if (p_tbl[idx] == RT_USED) {
- char buf[16];
- sprintf(buf, " %u", outPortNum);
- int loops = CrdLoopTraceLoop(p_fabric, p_node, inPortNum,
- p_node, outPortNum,
- p_node->name + string(buf),
- 0, doNotPrintPath
- );
- anyError += loops;
- }
- }
- }
- }
- if (anyError) cout << "--------------------------------------" << endl;
- return anyError;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
// Prepare the data model
int
CrdLoopPrepare(IBFabric *p_fabric) {
- IBNode *p_node;
-
- // Go over all SW nodes in the fabric and cleanup
- for( map_str_pnode::iterator nI = p_fabric->NodeByName.begin();
- nI != p_fabric->NodeByName.end();
- nI++) {
-
- p_node = (*nI).second;
- if (p_node->type != IB_SW_NODE) continue;
+ unsigned int lidStep = 1 << p_fabric->lmc;
- if (p_node->appData1.ptr) {
- p_node->appData1.ptr = NULL;
- }
+ // go over all ports in the fabric
+ for (int i = p_fabric->minLid; i <= p_fabric->maxLid; i += lidStep) {
+ IBPort *p_Port = p_fabric->PortByLid[i];
+ if (!p_Port) continue;
+ IBNode *p_node = p_Port->p_node;
+ int nL;
+ if (p_node->type == IB_CA_NODE)
+ nL = p_fabric->getNumSLs();
+ else
+ nL = p_fabric->getNumVLs();
+ // Go over all node's ports
+ for (int k=0;k<p_node->Ports.size();k++) {
+ IBPort* p_Port = p_node->Ports[k];
+ // Init virtual channel array
+ p_Port->channels.resize(nL);
+ for (int j=0;j<nL;j++)
+ p_Port->channels[j] = new VChannel;
+ }
}
return 0;
}
@@ -556,23 +282,25 @@ CrdLoopPrepare(IBFabric *p_fabric) {
// Cleanup the data model
int
CrdLoopCleanup(IBFabric *p_fabric) {
- IBNode *p_node;
-
- // Go over all SW nodes in the fabric and cleanup
- for( map_str_pnode::iterator nI = p_fabric->NodeByName.begin();
- nI != p_fabric->NodeByName.end();
- nI++) {
-
- p_node = (*nI).second;
- if (p_node->type != IB_SW_NODE) continue;
+ unsigned int lidStep = 1 << p_fabric->lmc;
- if (p_node->appData1.ptr) {
- uint8_t *p_tbl = (uint8_t *)p_node->appData1.ptr;
- delete [] p_tbl;
- p_node->appData1.ptr = NULL;
- }
+ // go over all ports in the fabric
+ for (int i = p_fabric->minLid; i <= p_fabric->maxLid; i += lidStep) {
+ IBPort *p_Port = p_fabric->PortByLid[i];
+ if (!p_Port) continue;
+ IBNode *p_node = p_Port->p_node;
+ int nL;
+ if (p_node->type == IB_CA_NODE)
+ nL = p_fabric->getNumSLs();
+ else
+ nL = p_fabric->getNumVLs();
+ // Go over all node's ports
+ for (int k=0;k<p_node->Ports.size();k++) {
+ IBPort* p_Port = p_node->Ports[k];
+ for (int j=0;j<nL;j++)
+ delete p_Port->channels[j];
+ }
}
- return 0;
}
//////////////////////////////////////////////////////////////////////////////
@@ -580,45 +308,30 @@ CrdLoopCleanup(IBFabric *p_fabric) {
// Top Level Subroutine:
int
CrdLoopAnalyze(IBFabric *p_fabric) {
+ int res=0;
- cout << "-I- Analyzing Fabric for Credit Loops (one VL used)." << endl;
-
- CrdLoopPrepare(p_fabric);
-
- // Allocate routing tables on all switches (appData1.ptr)
- CrdLoopInitRtTbls(p_fabric);
-
- // Go over all CA to CA paths and mark the output links
- // input links connections on these paths
- if (CrdLoopPopulateRtTbls(p_fabric)) {
- cout << "-E- Fail to populate the Routing Tables." << endl;
- return(1);
+ cout << "-I- Analyzing Fabric for Credit Loops "<<(int)p_fabric->getNumSLs()<<" SLs, "<<(int)p_fabric->getNumVLs()<< " VLs used...";
+ // Init data structures
+ if (CrdLoopPrepare(p_fabric)) {
+ cout << "-E- Fail to prepare data structures." << endl;
+ return(1);
}
-
- // CrdLoopDumpRtTbls(p_fabric);
-
- // Start BFS from all CA's and require all inputs for an
- // output node to be marked visited to go through it.
- if (CrdLoopBfsFromCAs(p_fabric)) {
- cout << "-E- Fail to BFS from all CA nodes through the Routing Tables." << endl;
- return(1);
- }
-
- // Report all Switch ports that are still marked as not
- // fully visited.
- int numLoopPorts;
- int doNotPrintPath = 1;
- if ((numLoopPorts = CrdLoopReportLoops(p_fabric, doNotPrintPath))) {
- cout << "-E- Found:" << numLoopPorts
- << " Credit Loops" << endl;
- } else {
- cout << "-I- No credit loops found." << endl;
+ // Create the dependencies
+ if (CrdLoopConnectDepend(p_fabric)) {
+ cout << "-E- Fail to build dependency graphs." << endl;
+ return(1);
}
+ // Find the loops if exist
+ res = CrdLoopFindLoops(p_fabric);
+ if (!res)
+ cout << " no credit loops found" << endl;
+ else
+ cout << endl << "-E- credit loops in routing"<<endl;
// cleanup:
CrdLoopCleanup(p_fabric);
- return 0;
+ return res;
}
diff --git a/ibdm/datamodel/Fabric.cpp b/ibdm/datamodel/Fabric.cpp
index 272d808..6ef2f9d 100644
--- a/ibdm/datamodel/Fabric.cpp
+++ b/ibdm/datamodel/Fabric.cpp
@@ -454,6 +454,67 @@ IBNode::getLFTPortForLid (unsigned int lid) {
}
//////////////////////////////////////////////////////////////////////////////
+
+// Set the PSL Table:
+void
+IBNode::setPSLForLid (unsigned int lid, unsigned int maxLid, uint8_t sl) {
+ if (PSL.empty())
+ {
+ PSL.resize(maxLid + 1);
+ for(unsigned int i = 0; i<PSL.size(); i++)
+ PSL[i] = IB_SLT_UNASSIGNED;
+ }
+ PSL[lid] = sl;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Get the PSL Table:
+uint8_t
+IBNode::getPSLForLid (unsigned int lid) {
+ if (PSL.empty())
+ return 0;
+
+ if (PSL.size() < lid+1)
+ return IB_SLT_UNASSIGNED;
+
+ return PSL[lid];
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Set the SL2VL Table:
+void
+IBNode::setSLVL (unsigned int iport,unsigned int oport,uint8_t sl, uint8_t vl) {
+ // Create an empty table
+ if (SLVL.empty())
+ {
+ SLVL.resize(numPorts+1);
+ for (int i=0;i<SLVL.size();i++) {
+ SLVL[i].resize(numPorts+1);
+ for (int j=0;j<SLVL[i].size();j++) {
+ SLVL[i][j].resize(IB_NUM_SL);
+ for (int k=0;k<SLVL[i][j].size();k++)
+ SLVL[i][j][k] = IB_SLT_UNASSIGNED;
+ }
+ }
+ }
+ SLVL[iport][oport][sl] = vl;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Get the SLVL Table:
+uint8_t
+IBNode::getSLVL (unsigned int iport,unsigned int oport,uint8_t sl) {
+ // Identity mapping
+ if (SLVL.empty())
+ return sl;
+
+ return SLVL[iport][oport][sl];
+}
+
+//////////////////////////////////////////////////////////////////////////////
// Set the Multicast FDB table
void
IBNode::setMFTPortForMLid(
@@ -2017,6 +2078,159 @@ IBFabric::parseFdbFile(string fn) {
return anyErr;
}
+//////////////////////////////////////////////////////////////////////////////
+
+// Parse PSL file and set the SLT tables accordingly
+int
+IBFabric::parsePSLFile(string fn) {
+ ifstream f(fn.c_str());
+ int maxLid = 0;
+
+ char sLine[1024];
+ // 0x0002c90000000099 154 0
+ // srcguid dlid sl
+ regExp slLine("0x([0-9a-z]+) ([0-9]+) ([0-9]+)");
+ rexMatch *p_rexRes;
+
+ if (f.fail())
+ {
+ cout << "-E- Fail to open file:" << fn.c_str() << endl;
+ return 1;
+ }
+
+ cout << "-I- Parsing SL file:" << fn.c_str() << endl;
+
+ int anyErr = 0;
+
+ // Find max HCA LID
+ while (f.good()) {
+ f.getline(sLine,1024);
+ p_rexRes = slLine.apply(sLine);
+ if (p_rexRes)
+ {
+ unsigned int lid = strtoull(p_rexRes->field(2).c_str(), NULL, 10);
+ maxLid = lid > maxLid ? lid:maxLid;
+ }
+ /*else
+ {
+ cout << "-E- Wrong file format:" << fn.c_str() << endl;
+ anyErr++;
+ }*/
+ }
+ f.close();
+
+ // Make second pass and build the tables
+ f.open(fn.c_str(),ifstream::in);
+ if (f.fail())
+ {
+ cout << "-E- Fail to open file:" << fn.c_str() << endl;
+ return 1;
+ }
+
+ while (f.good()) {
+ f.getline(sLine,1024);
+
+ p_rexRes = slLine.apply(sLine);
+ if (p_rexRes)
+ {
+ uint64_t guid = strtoull(p_rexRes->field(1).c_str(), NULL, 16);
+ unsigned int lid = strtoull(p_rexRes->field(2).c_str(), NULL, 10);
+ uint8_t sl = strtoull(p_rexRes->field(3).c_str(), NULL, 10);
+
+ IBNode* p_node = getNodeByGuid(guid);
+ if (!p_node)
+ {
+ cout << "-E- Fail to find node with guid:"
+ << guid << endl;
+ anyErr++;
+ }
+ else
+ {
+ // Update number of used SLs
+ numSLs = sl+1 > numSLs ? sl+1:numSLs;
+ // Insert table entry
+ p_node->setPSLForLid(lid,maxLid,sl);
+ }
+ delete p_rexRes;
+ }
+ /*else
+ {
+ cout << "-E- Wrong file format:" << fn.c_str() << endl;
+ anyErr++;
+ }*/
+ }
+ cout << "-I- Defined "<< (int)numSLs << " SLs in use" <<endl;
+ f.close();
+
+ return anyErr;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Parse SLVL file and set the SL2VL tables accordingly
+int
+IBFabric::parseSLVLFile(string fn) {
+ numVLs = 1;
+ ifstream f(fn.c_str());
+
+ char sLine[1024];
+ // 0x0002c90000000201 5 1 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xe7
+ // guid iport oport 0x(sl0)(sl1) 0x(sl2)(sl3)...
+ regExp slLine("0x([0-9a-z]+) ([0-9]+) ([0-9]+) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z]) 0x([0-9a-z])([0-9a-z])");
+ rexMatch *p_rexRes;
+
+ if (f.fail()) {
+ cout << "-E- Fail to open file:" << fn.c_str() << endl;
+ return 1;
+ }
+
+ cout << "-I- Parsing SLVL file:" << fn.c_str() << endl;
+
+ int anyErr = 0;
+
+ // Parse the file
+ while (f.good()) {
+ f.getline(sLine,1024);
+
+ p_rexRes = slLine.apply(sLine);
+ if (p_rexRes)
+ {
+ uint64_t guid = strtoull(p_rexRes->field(1).c_str(), NULL, 16);
+ unsigned int iport = strtoull(p_rexRes->field(2).c_str(), NULL, 10);
+ unsigned int oport = strtoull(p_rexRes->field(3).c_str(), NULL, 10);
+
+ IBNode* p_node = getNodeByGuid(guid);
+ if (!p_node)
+ {
+ cout << "-E- Fail to find node with guid:"
+ << guid << endl;
+ anyErr++;
+ }
+ else
+ {
+ for (int i=0;i<IB_NUM_SL;i++) {
+ // Extract the VL value
+ uint8_t vl = strtoull(p_rexRes->field(4+i).c_str(), NULL, 16);
+ numVLs = numVLs > vl+1 ? numVLs : vl+1;
+ // Set the table entry
+ p_node->setSLVL(iport,oport,i,vl);
+ }
+ }
+ delete p_rexRes;
+ }
+ /*else
+ {
+ cout << "-E- Wrong file format:" << fn.c_str() << endl;
+ anyErr++;
+ }*/
+ }
+ cout << "-I- Defined "<< (int)numVLs << " VLs in use" <<endl;
+
+ f.close();
+
+ return anyErr;
+}
+
///////////////////////////////////////////////////////////////////////////
// Parse an OpenSM MCFDBs file and set the MFT table accordingly
diff --git a/ibdm/datamodel/Fabric.h b/ibdm/datamodel/Fabric.h
index 9e5a741..44fd8e4 100644
--- a/ibdm/datamodel/Fabric.h
+++ b/ibdm/datamodel/Fabric.h
@@ -64,8 +64,11 @@
#define IB_LID_UNASSIGNED 0
#define IB_LFT_UNASSIGNED 255
+#define IB_SLT_UNASSIGNED 255
#define IB_HOP_UNASSIGNED 255
+#define IB_NUM_SL 16
+
#if __WORDSIZE == 64
#define PRIx64 "lx"
#else
@@ -91,15 +94,18 @@ typedef vector<vec_int > vec_vec_int;
typedef vector<uint8_t > vec_byte;
typedef vector<uint32_t > vec_word;
typedef vector<vec_byte > vec_vec_byte;
+typedef vector<vec_vec_byte > vec3_byte;
typedef vector<class IBPort * > vec_pport;
typedef vector<class IBNode * > vec_pnode;
+typedef vector<class VChannel * > vec_pvch;
typedef map< string, class IBSysPort *, strless > map_str_psysport;
typedef map< string, class IBNode *, strless > map_str_pnode;
typedef map< string, class IBSystem *, strless > map_str_psys;
typedef map< uint64_t, class IBPort *, less<uint64_t> > map_guid_pport;
typedef map< uint64_t, class IBNode *, less<uint64_t> > map_guid_pnode;
typedef map< uint64_t, class IBSystem *, less<uint64_t> > map_guid_psys;
+typedef map< string, int, strless > map_str_int;
typedef list<class IBNode * > list_pnode;
typedef list<class IBSystem * > list_psystem;
typedef list<int > list_int;
@@ -121,6 +127,9 @@ typedef set< uint16_t, less< uint16_t > > set_uint16;
#define FABU_LOG_VERBOSE 0x4
#define IBNODE_UNASSIGNED_RANK 0xFF
+// DFS constants type
+typedef enum {Untouched,Open,Closed} dfs_t;
+
//
// GLOBALS
//
@@ -198,6 +207,48 @@ static inline string guid2str(uint64_t guid) {
};
//
+// Virtual Channel class
+// Used for credit loops verification
+//
+
+class VChannel {
+ vec_pvch depend; // Vector of dependencies
+ dfs_t flag; // DFS state
+ public:
+ // Constructor
+ VChannel() {
+ flag = Untouched;
+ };
+ //Getters/Setters
+ inline void setDependSize(int numDepend) {
+ if (depend.size() != (unsigned)numDepend) {
+ depend.resize(numDepend);
+ for (int i=0;i<numDepend;i++) {
+ depend[i] = NULL;
+ }
+ }
+ };
+ inline int getDependSize() {
+ return depend.size();
+ };
+ inline dfs_t getFlag() {
+ return flag;
+ };
+
+ inline void setFlag(dfs_t f) {
+ flag = f;
+ };
+
+ inline void setDependency(int i,VChannel* p) {
+ depend[i]=p;
+ };
+
+ inline VChannel* getDependency(int i) {
+ return depend[i];
+ };
+};
+
+//
// IB Port class.
// This is not the "End Node" but the physical port of
// a node.
@@ -208,8 +259,9 @@ class IBPort {
class IBPort * p_remotePort; // Port connected on the other side of link
class IBSysPort * p_sysPort; // The system port (if any) connected to
class IBNode * p_node; // The node the port is part of.
- int num; // Physical ports are identified by number.
- unsigned int base_lid; // The base lid assigned to the port.
+ vec_pvch channels; // Virtual channels associated with the port
+ int num; // Physical ports are identified by number.
+ unsigned int base_lid; // The base lid assigned to the port.
IBLinkWidth width; // The link width of the port
IBLinkSpeed speed; // The link speed of the port
unsigned int counter1; // a generic value to be used by various algorithms
@@ -250,8 +302,8 @@ typedef union _PrivateAppData {
class IBNode {
uint64_t guid;
public:
- string name; // Name of the node (instance name of the chip)
- IBNodeType type; // Either a CA or SW
+ string name; // Name of the node (instance name of the chip)
+ IBNodeType type; // Either a CA or SW
uint32_t devId; // The device ID of the node
uint32_t revId; // The device revision Id.
uint32_t vendId; // The device Vendor ID.
@@ -260,10 +312,12 @@ class IBNode {
class IBFabric *p_fabric; // What fabric we belong to.
unsigned int numPorts; // Number of physical ports
string attributes;// Comma-sep string of arbitrary attributes k=v
- vec_pport Ports; // Vector of all the ports
- vec_vec_byte MinHopsTable; // Table describing minimal hop count through
+ vec_pport Ports; // Vector of all the ports
+ vec_vec_byte MinHopsTable; // Table describing minimal hop count through
// each port to each target lid
vec_byte LFT; // The LFT of this node (for switches only)
+ vec_byte PSL; // PSL table (CAxCA->SL mapping) of this node (for CAs only)
+ vec3_byte SLVL; // SL2VL table of this node (for switches only)
vec_word MFT; // The Multicast forwarding table
PrivateAppData appData1; // Application Private Data #1
PrivateAppData appData2; // Application Private Data #2
@@ -316,6 +370,18 @@ class IBNode {
// Get the LFT for a given lid
int getLFTPortForLid (unsigned int lid);
+ // Set the PSL table
+ void setPSLForLid (unsigned int lid, unsigned int maxLid, uint8_t sl);
+
+ // Add entry to SL2VL table
+ void setSLVL(unsigned int iport,unsigned int oport,uint8_t sl, uint8_t vl);
+
+ // Get the PSL table for a given lid
+ uint8_t getPSLForLid(unsigned int lid);
+
+ // Get the SL2VL table entry
+ uint8_t getSLVL(unsigned int iport, unsigned int oport, uint8_t sl);
+
// Set the Multicast FDB table
void setMFTPortForMLid(unsigned int lid, unsigned int portNum);
@@ -423,6 +489,8 @@ class IBFabric {
unsigned int lmc; // LMC value used
uint8_t defAllPorts; // If not zero all ports (unconn) are declared
uint8_t subnCANames; // The Subnet.lst has host names for CA's
+ uint8_t numSLs; // Number of used SLs
+ uint8_t numVLs; // Number of used VLs
set_uint16 mcGroups; // A set of all active multicast groups
// Constructor
@@ -430,6 +498,8 @@ class IBFabric {
maxLid = 0;
defAllPorts = 1;
subnCANames = 1;
+ numSLs = 1;
+ numVLs = 1;
lmc = 0;
minLid = 0;
PortByLid.push_back(NULL); // make sure we always have one for LID=0
@@ -493,6 +563,12 @@ class IBFabric {
// Parse OpenSM FDB dump file
int parseFdbFile(string fn);
+ // Parse PSL mapping
+ int parsePSLFile(string fn);
+
+ // Parse SLVL mapping
+ int parseSLVLFile(string fn);
+
// Parse an OpenSM MCFDBs file and set the MFT table accordingly
int parseMCFdbFile(string fn);
@@ -513,6 +589,22 @@ class IBFabric {
return (PortByLid[lid]);
};
+ inline void setNumSLs(uint8_t nSL) {
+ numSLs=nSL;
+ };
+
+ inline uint8_t getNumSLs() {
+ return numSLs;
+ };
+
+ inline void setNumVLs(uint8_t nVL) {
+ numVLs=nVL;
+ };
+
+ inline uint8_t getNumVLs() {
+ return numVLs;
+ };
+
// dump out the contents of the entire fabric
void dump(ostream &sout);
diff --git a/ibdm/src/osm_check.cpp b/ibdm/src/osm_check.cpp
index e1e03e3..f1d2895 100644
--- a/ibdm/src/osm_check.cpp
+++ b/ibdm/src/osm_check.cpp
@@ -45,7 +45,7 @@ void
show_usage() {
cout << "Usage: there are two modes: Design/Verify" << endl;
cout << " Design: ibdmchk [-v][-h][-e][-u][-l <lmc>][-r <roots file>] -t <topology file> -n <SM Node> -p <SM Port>" << endl;
- cout << " Verify: ibdmchk [-v][-h][-l <lmc>][-r <roots file>] [-s <subnet file>] [-f <fdb file>] [-m <mcfdb file>]" << endl;
+ cout << " Verify: ibdmchk [-v][-h][-l <lmc>][-r <roots file>] [-s <subnet file>] [-f <fdb file>] [-m <mcfdb file>] [-c <path-sl file>] [-d <sl2vl file>]\n\n" << endl;
}
void
@@ -72,7 +72,7 @@ show_help() {
<< " -p|--port <SM Port> = the port number by which the SM nodes is attached to the fabric.\n"
<< "\n"
<< " Options:\n"
- << " -v|--verbose = verbsoe mode\n"
+ << " -v|--verbose = verbose mode\n"
<< " -h|--help = provide this help message\n"
<< " -l|--lmc <lmc> = LMC value > 0 means assigning 2^lmc lids to each port.\n"
<< " -e|--enh = use enhanced routing algorithm when LMC > 0 and report the resulting paths\n"
@@ -82,11 +82,15 @@ show_help() {
<< "\n"
<< " CLUSTER VERIFICATION:\n"
<< " Usage:\n"
- << " ibdmchk [-v][-h][-r <roots file>] [-s <subnet file>] [-f <fdb file>] [-l <lmc>]\n\n"
+ << " ibdmchk [-v][-h][-r <roots file>] [-s <subnet file>] [-f <fdb file>] [-m <mcfdb file>] [-l <lmc>] [-c <path-sl file>] [-d <sl2vl file>]\n\n"
<< " Description:\n"
<< " After the cluster is built and OpenSM is run (using flag -D 0x43) it reports the\n"
<< " subnet and FDB tables into the files osm-subnet.lst, osm.fdbs and osm.fdbs in\n"
- << " /var/log/ (or subnet.lst, osm.fdbs and osm.mcfdbs into /tmp in older versions).\n"
+ << " /var/log/ (or subnet.lst, osm.fdbs and osm.mcfdbs into /tmp in older versions).\n"
+ << " If more than one SL is known to be used additional file holding CAxCA->SL mapping \n"
+ << " is generated (format: 0xsrc_guid dlid sl) . In this case the SL2VL mapping is \n"
+ << " optionally supplied in an additional file (format: 0xsw_guid inport outport 0x(sl0)(sl1),\n"
+ << " 0x(sl2)(sl3),...). Without SL2VL mapping file an identity mapping is used.\n"
<< " Based on these files the utility checks all CA to CA connectivity. Further analysis\n"
<< " for credit deadlock potential is performed and reported. \n"
<< " In case of an LMC > 0 it reports histograms for how many systems and nodes\n"
@@ -96,13 +100,15 @@ show_help() {
<< " -l|--lmc <lmc> = The LMC value used while running OpenSM. Mandatory if not the default 0.\n"
<< "\n"
<< " Options:\n"
- << " -v|--verbose = verbsoe mode\n"
+ << " -v|--verbose = verbose mode\n"
<< " -h|--help = provide this help message\n"
<< " -s|--subnet <file> = OpenSM subnet.lst file (/var/log/osm-subnet.lst or /tmp/subnet.lst)\n"
<< " -f|--fdb <file> = OpenSM dump of Ucast LFDB. Use -D 0x41 to generate it.\n"
<< " (default is /var/log/osm.fdbs or /tmp/osm.fdbs).\n"
<< " -m|--mcfdb <file> = OpenSM dump of Multicast LFDB. Use -D 0x41 to generate it.\n"
<< " (default is /var/log/osm.mcfdbs or /tmp/osm.mcfdbs).\n"
+ << " -c|--psl <file> = CAxCA->SL mapping. \n"
+ << " -d|--slvl <file> = SL2VL mapping. \n"
<< " -r|--roots <roots file> = a file holding all root nodes guids (one per line).\n"
<< "\n"
<< "Author: Eitan Zahavi, Mellanox Technologies LTD.\n"
@@ -189,6 +195,8 @@ int main (int argc, char **argv) {
string mcFdbFile = string("");
string TopoFile = string("");
string SmNodeName = string("");
+ string PSLFile = string("");
+ string SLVLFile = string("");
string RootsFileName = string("");
int EnhancedRouting = 0;
int lmc = 0;
@@ -197,11 +205,11 @@ int main (int argc, char **argv) {
int AllPaths = 0;
/*
- * Parseing of Command Line
+ * Parsing of Command Line
*/
char next_option;
- const char * const short_option = "vhl:s:f:m:el:t:p:n:uar:";
+ const char * const short_option = "vhl:s:f:m:el:t:p:n:uar:c:d:";
/*
In the array below, the 2nd parameter specified the number
of arguments as follows:
@@ -217,13 +225,15 @@ int main (int argc, char **argv) {
{ "subnet", 1, NULL, 's'},
{ "fdb", 1, NULL, 'f'},
{ "mcfdb", 1, NULL, 'm'},
+ { "psl", 1, NULL, 'c'},
+ { "slvl", 1, NULL, 'd'},
{ "topology", 1, NULL, 't'},
- { "node", 1, NULL, 'n'},
+ { "node", 1, NULL, 'n'},
{ "port", 1, NULL, 'p'},
- { "enh", 0, NULL, 'e'},
- { "updn", 0, NULL, 'u'},
- { "roots", 1, NULL, 'r'},
- { "all", 0, NULL, 'a'},
+ { "enh", 0, NULL, 'e'},
+ { "updn", 0, NULL, 'u'},
+ { "roots", 1, NULL, 'r'},
+ { "all", 0, NULL, 'a'},
{ NULL, 0, NULL, 0 } /* Required at the end of the array */
};
@@ -274,6 +284,20 @@ int main (int argc, char **argv) {
subnetFile = string(optarg);
break;
+ case 'c':
+ /*
+ Specifies CAxCA->SL
+ */
+ PSLFile = string(optarg);
+ break;
+
+ case 'd':
+ /*
+ Specifies SL->VL
+ */
+ SLVLFile = string(optarg);
+ break;
+
case 't':
/*
Specifies Topology
@@ -342,6 +366,7 @@ int main (int argc, char **argv) {
printf(" SM Node ........ %s\n", SmNodeName.c_str());
printf(" SM Port ........ %u\n", SmPortNum);
printf(" LMC ............ %u\n", lmc);
+
if (EnhancedRouting && lmc > 0)
printf(" Using Enhanced Routing\n");
if (RootsFileName.size())
@@ -352,75 +377,74 @@ int main (int argc, char **argv) {
exit(1);
}
- // get the SM Port
- IBNode *p_smNode = fabric.getNode(SmNodeName);
- if (! p_smNode ) {
- cout << "-E- Fail to find SM node:" << SmNodeName << endl;
- exit(1);
- }
+ // get the SM Port
+ IBNode *p_smNode = fabric.getNode(SmNodeName);
+ if (! p_smNode ) {
+ cout << "-E- Fail to find SM node:" << SmNodeName << endl;
+ exit(1);
+ }
- IBPort *p_smPort = p_smNode->getPort(SmPortNum);
- if (! p_smPort) {
- cout << "-E- Fail to find SM Port: " << SmNodeName
- << "/" << SmPortNum << endl;
- exit(1);
+ IBPort *p_smPort = p_smNode->getPort(SmPortNum);
+ if (! p_smPort) {
+ cout << "-E- Fail to find SM Port: " << SmNodeName
+ << "/" << SmPortNum << endl;
+ exit(1);
+ }
+
+ // assign lids
+ if (SubnMgtAssignLids(p_smPort,lmc)) {
+ cout << "-E- Fail to assign LIDs." << endl;
+ exit(1);
+ }
+
+ // we need to run min hop calculation anyway
+ if (SubnMgtCalcMinHopTables(&fabric)) {
+ cout << "-E- Fail to update Min Hops Tables." << endl;
+ exit(1);
+ }
+
+ if (UseUpDown) {
+ list <IBNode *> rootNodes;
+ if (RootsFileName.size()) {
+ rootNodes = ParseRootNodeNamesFile(&fabric, RootsFileName);
+ }
+ else {
+ rootNodes = SubnMgtFindRootNodesByMinHop(&fabric);
+ }
+
+ if (!rootNodes.empty()) {
+ cout << "-I- Recognized " << rootNodes.size() << " root nodes:" << endl;
+ for (list <IBNode *>::iterator nI = rootNodes.begin();
+ nI != rootNodes.end(); nI++) {
+ cout << " " << (*nI)->name << endl;
}
+ cout << "---------------------------------------------------------------------------\n" << endl;
- // assign lids
- if (SubnMgtAssignLids(p_smPort,lmc)) {
- cout << "-E- Fail to assign LIDs." << endl;
+ map_pnode_int nodesRank;
+ SubnRankFabricNodesByRootNodes(&fabric, rootNodes, nodesRank);
+
+ if (SubnMgtCalcUpDnMinHopTbls(&fabric, nodesRank)) {
+ cout << "-E- Fail to update Min Hops Tables." << endl;
exit(1);
}
+ } else {
+ cout << "-E- Fail to recognize any root nodes. Up/Down is not active!" << endl;
+ }
+ }
+
+ if (!EnhancedRouting) {
+
+ if (SubnMgtOsmRoute(&fabric)) {
+ cout << "-E- Fail to update LFT Tables." << endl;
+ exit(1);
+ }
+ } else {
+ if (SubnMgtOsmEnhancedRoute(&fabric)) {
+ cout << "-E- Fail to update LFT Tables." << endl;
+ exit(1);
+ }
+ }
- // we need to run min hop calculation anyway
- if (SubnMgtCalcMinHopTables(&fabric)) {
- cout << "-E- Fail to update Min Hops Tables." << endl;
- exit(1);
- }
-
- if (UseUpDown) {
- list <IBNode *> rootNodes;
- if (RootsFileName.size())
- {
- rootNodes = ParseRootNodeNamesFile(&fabric, RootsFileName);
- }
- else
- {
- rootNodes = SubnMgtFindRootNodesByMinHop(&fabric);
- }
-
- if (!rootNodes.empty()) {
- cout << "-I- Recognized " << rootNodes.size() << " root nodes:" << endl;
- for (list <IBNode *>::iterator nI = rootNodes.begin();
- nI != rootNodes.end(); nI++) {
- cout << " " << (*nI)->name << endl;
- }
- cout << "---------------------------------------------------------------------------\n" << endl;
-
- map_pnode_int nodesRank;
- SubnRankFabricNodesByRootNodes(&fabric, rootNodes, nodesRank);
-
- if (SubnMgtCalcUpDnMinHopTbls(&fabric, nodesRank)) {
- cout << "-E- Fail to update Min Hops Tables." << endl;
- exit(1);
- }
- } else {
- cout << "-E- Fail to recognize any root nodes. Up/Down is not active!" << endl;
- }
- }
-
- if (!EnhancedRouting) {
-
- if (SubnMgtOsmRoute(&fabric)) {
- cout << "-E- Fail to update LFT Tables." << endl;
- exit(1);
- }
- } else {
- if (SubnMgtOsmEnhancedRoute(&fabric)) {
- cout << "-E- Fail to update LFT Tables." << endl;
- exit(1);
- }
- }
} else {
int anyMissingFile = 0;
@@ -463,6 +487,14 @@ int main (int argc, char **argv) {
printf(" FDB File = %s\n", fdbFile.c_str());
printf(" MCFDB File = %s\n", mcFdbFile.c_str());
printf(" Subnet File = %s\n", subnetFile.c_str());
+ if (PSLFile.size() >0)
+ printf(" SL File = %s\n", PSLFile.c_str());
+ else
+ printf(" SL File = NONE, using single SL\n");
+ if (SLVLFile.size() >0)
+ printf(" SLVL File = %s\n", SLVLFile.c_str());
+ else
+ printf(" SLVL File = NONE, using identity mapping\n");
printf(" LMC = %u\n", lmc);
printf("-------------------------------------------------\n");
@@ -478,6 +510,18 @@ int main (int argc, char **argv) {
exit(1);
}
+ if (PSLFile.size() && fabric.parsePSLFile(PSLFile)) {
+ cout << "-E- Fail to parse SL file:" << PSLFile << endl;
+ exit(1);
+ }
+
+ fabric.setNumVLs(fabric.getNumSLs());
+
+ if (SLVLFile.size() && fabric.parseSLVLFile(SLVLFile)) {
+ cout << "-E- Fail to parse SL file:" << SLVLFile << endl;
+ exit(1);
+ }
+
if (fabric.parseMCFdbFile(mcFdbFile)) {
cout << "-E- Fail to parse multicast fdb file:" << mcFdbFile << endl;
exit(1);
@@ -509,20 +553,20 @@ int main (int argc, char **argv) {
int anyErr = 0;
if (RootsFileName.size())
- {
- if (TopoFile.size())
{
- rootNodes = ParseRootNodeNamesFile(&fabric, RootsFileName);
+ if (TopoFile.size())
+ {
+ rootNodes = ParseRootNodeNamesFile(&fabric, RootsFileName);
+ }
+ else
+ {
+ rootNodes = ParseRootNodeGuidsFile(&fabric, RootsFileName);
+ }
}
- else
+ else
{
- rootNodes = ParseRootNodeGuidsFile(&fabric, RootsFileName);
+ rootNodes = SubnMgtFindRootNodesByMinHop(&fabric); //(Causes segmentation fault with DOR)
}
- }
- else
- {
- rootNodes = SubnMgtFindRootNodesByMinHop(&fabric);
- }
if (!rootNodes.empty()) {
cout << "-I- Recognized " << rootNodes.size() << " root nodes:" << endl;
--
1.5.1.4
More information about the general
mailing list