[ofa-general] [PATCH] opensm: yet another up/down speedup

Sasha Khapyorsky sashak at voltaire.com
Sat Mar 3 05:59:46 PST 2007


The idea of this optimization is to perform all time consuming up/down
min hops calculation cycles only for switches, and when this is ready
just to populate (in one pass) calculated min hops values for CAs and
routers as its neighbour switch's min hops + 1. Tests show yet another
6-7 times speedup.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 osm/opensm/osm_ucast_updn.c |  160 ++++++++++++++++++++-----------------------
 1 files changed, 73 insertions(+), 87 deletions(-)

diff --git a/osm/opensm/osm_ucast_updn.c b/osm/opensm/osm_ucast_updn.c
index 72d943b..39f3bef 100644
--- a/osm/opensm/osm_ucast_updn.c
+++ b/osm/opensm/osm_ucast_updn.c
@@ -161,86 +161,26 @@ static int
 __updn_bfs_by_node(
   IN osm_log_t *p_log,
   IN osm_subn_t *p_subn,
-  IN osm_port_t *p_port )
+  IN osm_switch_t *p_sw )
 {
-  osm_switch_t *p_self_node = NULL;
   uint8_t pn, pn_rem;
-  osm_physp_t *p_physp, *p_remote_physp;
   cl_qlist_t list;
-  uint16_t root_lid;
+  uint16_t lid;
   struct updn_node *u;
   updn_switch_dir_t next_dir, current_dir;
 
   OSM_LOG_ENTER( p_log, __updn_bfs_by_node );
 
-  p_physp = osm_port_get_default_phys_ptr(p_port);
-  /* Check valid pointer */
-  if (!p_physp || !osm_physp_is_valid( p_physp ))
-  {
-    OSM_LOG_EXIT( p_log );
-    return 1;
-  }
+  lid = osm_node_get_base_lid(p_sw->p_node, 0);
+  lid = cl_ntoh16(lid);
+  osm_switch_set_hops(p_sw, lid, 0, 0);
 
-  /* The Root BFS - lid  */
-  root_lid = cl_ntoh16(osm_physp_get_base_lid( p_physp ));
-  /* printf ("-V- BFS through lid : 0x%x\n", root_lid); */
   osm_log( p_log, OSM_LOG_DEBUG,
            "__updn_bfs_by_node: "
-           "Starting lid : 0x%x \n", root_lid );
+           "Starting from switch - port GUID 0x%" PRIx64 " lid %u\n",
+           cl_ntoh64(p_sw->p_node->node_info.port_guid), lid );
 
-  if (p_port->p_node->sw)
-  {
-    p_self_node = p_port->p_node->sw;
-    /* Update its Min Hop Table */
-    osm_log( p_log, OSM_LOG_DEBUG,
-             "__updn_bfs_by_node: "
-             "Update Min Hop Table of GUID 0x%" PRIx64 "\n",
-             cl_ntoh64(p_port->guid) );
-    osm_switch_set_hops(p_self_node, root_lid, 0, 0);
-  }
-  else
-  {
-    /* This is a CA or router - need to take its remote port */
-    p_remote_physp = p_physp->p_remote_physp;
-    /*
-      make sure that the following occur:
-      1. The port isn't NULL
-      2. The port is a valid port
-    */
-    if ( p_remote_physp && osm_physp_is_valid( p_remote_physp ))
-    {
-      /* Check if the remote port is a switch, and if it is,
-         update root_lid and Min Hop Table */
-      if (!p_remote_physp->p_node->sw)
-      {
-        osm_log( p_log, OSM_LOG_ERROR,
-                 "__updn_bfs_by_node: ERR AA07: "
-                 "This is not a switched subnet OR valid connection, cannot perform UPDN algorithm\n" );
-        OSM_LOG_EXIT( p_log );
-        return 1;
-      }
-      else
-      {
-        p_self_node = p_remote_physp->p_node->sw;
-        /* Update its Min Hop Table */
-        /* NOTE : Check if there is a function which prints the Min Hop Table */
-        osm_log( p_log, OSM_LOG_DEBUG,
-                 "__updn_bfs_by_node: "
-                 "Update Min Hop Table of GUID 0x%" PRIx64 "\n",
-                 cl_ntoh64(p_remote_physp->port_guid) );
-        osm_switch_set_hops(p_self_node, root_lid, p_remote_physp->port_num, 1);
-      }
-    }
-  }
-
-  CL_ASSERT(p_self_node);
-
-  osm_log( p_log, OSM_LOG_DEBUG,
-           "__updn_bfs_by_node: "
-           "Starting from switch - port GUID 0x%" PRIx64 "\n",
-           cl_ntoh64(p_self_node->p_node->node_info.port_guid) );
-
-  u = p_self_node->priv;
+  u = p_sw->priv;
   u->dir = UP;
 
   /* Update list with the new element */
@@ -290,13 +230,13 @@ __updn_bfs_by_node(
         continue;
       }
       /* Set MinHop value for the current lid */
-      current_min_hop = osm_switch_get_least_hops(u->sw, root_lid);
+      current_min_hop = osm_switch_get_least_hops(u->sw, lid);
       /* Check hop count if better insert into list && update
          the remote node Min Hop Table */
-      remote_min_hop = osm_switch_get_hop_count(p_remote_sw, root_lid, pn_rem);
+      remote_min_hop = osm_switch_get_hop_count(p_remote_sw, lid, pn_rem);
       if (current_min_hop + 1 < remote_min_hop)
       {
-        set_hop_return_value = osm_switch_set_hops(p_remote_sw, root_lid, pn_rem, current_min_hop + 1);
+        set_hop_return_value = osm_switch_set_hops(p_remote_sw, lid, pn_rem, current_min_hop + 1);
         if (set_hop_return_value)
         {
           osm_log( p_log, OSM_LOG_ERROR,
@@ -569,14 +509,60 @@ updn_subn_rank(
 /**********************************************************************
  **********************************************************************/
 static int
+populate_min_hops_for_cas(
+  osm_subn_t *p_subn,
+  osm_switch_t *p_sw )
+{
+  osm_port_t *p_next_port,*p_port;
+  osm_physp_t *p_physp;
+  uint16_t lid, sw_lid;
+  uint8_t i, hops;
+
+  p_next_port = (osm_port_t*)cl_qmap_head( &p_subn->port_guid_tbl );
+  while( p_next_port != (osm_port_t*)cl_qmap_end( &p_subn->port_guid_tbl ) )
+  {
+    p_port = p_next_port;
+    p_next_port = (osm_port_t*)cl_qmap_next( &p_port->map_item );
+
+    if (p_port->p_node->sw)
+      continue;
+    p_physp = osm_port_get_default_phys_ptr(p_port);
+    if (!p_physp || !p_physp->p_remote_physp ||
+        !p_physp->p_remote_physp->p_node->sw)
+      continue;
+
+    lid = osm_physp_get_base_lid(p_physp);
+    lid = cl_ntoh16(lid);
+
+    if (p_physp->p_remote_physp->p_node->sw == p_sw)
+    {
+      osm_switch_set_hops(p_sw, lid, p_physp->p_remote_physp->port_num, 1);
+      continue;
+    }
+
+    sw_lid = osm_node_get_base_lid(p_physp->p_remote_physp->p_node, 0);
+    sw_lid = cl_ntoh16(sw_lid);
+
+    for (i = 1 ; i < p_sw->num_ports ; i++)
+    {
+      hops = osm_switch_get_hop_count(p_sw, sw_lid, i);
+      if (hops == OSM_NO_PATH)
+        continue;
+      osm_switch_set_hops(p_sw, lid, i, hops + 1);
+    }
+  }
+  return 0;
+}
+
+/**********************************************************************
+ **********************************************************************/
+static int
 __osm_subn_set_up_down_min_hop_table(
   IN updn_t* p_updn )
 {
   osm_subn_t *p_subn = &p_updn->p_osm->subn;
   osm_log_t *p_log = &p_updn->p_osm->log;
   osm_switch_t *p_next_sw,*p_sw;
-  osm_port_t *p_next_port,*p_port;
-  ib_net64_t port_guid;
 
   OSM_LOG_ENTER( p_log, __osm_subn_set_up_down_min_hop_table );
 
@@ -603,21 +589,21 @@ __osm_subn_set_up_down_min_hop_table(
   osm_log( p_log, OSM_LOG_VERBOSE,
            "__osm_subn_set_up_down_min_hop_table: "
            "BFS through all port guids in the subnet [\n" );
-  p_next_port = (osm_port_t*)cl_qmap_head( &p_subn->port_guid_tbl );
-  while( p_next_port != (osm_port_t*)cl_qmap_end( &p_subn->port_guid_tbl ) )
+
+  p_next_sw = (osm_switch_t*)cl_qmap_head( &p_subn->sw_guid_tbl );
+  while( p_next_sw != (osm_switch_t*)cl_qmap_end( &p_subn->sw_guid_tbl ) )
   {
-    p_port = p_next_port;
-    p_next_port = (osm_port_t*)cl_qmap_next( &p_port->map_item );
-    port_guid = cl_qmap_key(&(p_port->map_item));
-    osm_log( p_log, OSM_LOG_DEBUG,
-             "__osm_subn_set_up_down_min_hop_table: "
-             "BFS through port GUID 0x%" PRIx64 "\n",
-             cl_ntoh64(port_guid) );
-    if(__updn_bfs_by_node(p_log, p_subn, p_port))
-    {
-      OSM_LOG_EXIT( p_log );
-      return 1;
-    }
+    p_sw = p_next_sw;
+    p_next_sw = (osm_switch_t*)cl_qmap_next( &p_sw->map_item );
+    __updn_bfs_by_node(p_log, p_subn, p_sw);
+  }
+
+  p_next_sw = (osm_switch_t*)cl_qmap_head( &p_subn->sw_guid_tbl );
+  while( p_next_sw != (osm_switch_t*)cl_qmap_end( &p_subn->sw_guid_tbl ) )
+  {
+    p_sw = p_next_sw;
+    p_next_sw = (osm_switch_t*)cl_qmap_next( &p_sw->map_item );
+    populate_min_hops_for_cas(p_subn, p_sw);
   }
 
   osm_log( p_log, OSM_LOG_VERBOSE,
-- 
1.5.0.1.40.gb40d




More information about the general mailing list