]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[OpenSM] - OpenSM/osm_lid_mgr.c: handle different MTU
authoreitan <eitan@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Sun, 12 Mar 2006 13:22:56 +0000 (13:22 +0000)
committereitan <eitan@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Sun, 12 Mar 2006 13:22:56 +0000 (13:22 +0000)
Fix a bug that in case of a difference between the MTU of two ports, only the
port with the higher MTU was set to down. It's remote port was written in the
DB in the ACTIVE state although its real status was INIT. Because of this,
the SM didn't try to lift the remote port to ACTIVE.

git-svn-id: svn://openib.tc.cornell.edu/gen1@239 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

trunk/ulp/opensm/user/opensm/osm_lid_mgr.c

index a4c469ed463aae42f8a2abde21ae3e0314e870e1..3473041c93eafe20d2d8e437489f9d15332bf0da 100644 (file)
  *    __osm_lid_mgr_get_port_lid( p_mgr, port, &min_lid ):
  *    0.1 if the port info lid matches the guid2lid return 0
  *    0.2 if the port info has a lid and that range is empty in
- *        port_lid_tbl - return 0 and update the port_lid_tbl and
+ *        port_lid_tbl, return 0 and update the port_lid_tbl and
  *        guid2lid
  *    0.3 else find an empty space in port_lid_tbl,  update the
- *    port_lid_tbl and guid2lid, return 1 to flag a change required.
+ *    port_lid_tbl and guid2lid, return 1 to flag a change required.
  *
  * 1. During initialization:
  *   1.1 initialize the guid2lid database domain.
@@ -60,7 +60,7 @@
  *   1.2.2 validate no duplicate use of lids and lids are 2^(lmc-1)
  *
  * 2. During SM port lid assignment:
- *   2.1 if reassign_lids is set - make it 2^lmc
+ *   2.1 if reassign_lids is set, make it 2^lmc
  *   2.2 cleanup all port_lid_tbl and re-fill it according to guid2lid
  *   2.3 call __osm_lid_mgr_get_port_lid the SM port
  *   2.4 set the port info
@@ -202,12 +202,12 @@ __osm_lid_mgr_validate_db(
       }
       else if ((min_lid != max_lid) && ((min_lid & lmc_mask) != min_lid))
       {
-        /* check that if the lids define a range - that range is valid
+        /* check that if the lids define a range that is valid
            for the current LMC mask */
         osm_log( p_mgr->p_log, OSM_LOG_ERROR,
                  "__osm_lid_mgr_validate_db: ERR 0313: "
                  "LID range [0x%x:0x%x] for guid:0x%016" PRIx64
-                 " is not aligned acording to mask:0x%04x\n",
+                 " is not aligned according to mask:0x%04x\n",
                  min_lid, max_lid, p_item->guid, lmc_mask
                  );
         lids_ok = FALSE;
@@ -384,7 +384,7 @@ __osm_lid_mgr_init_sweep(
   {
     osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
              "__osm_lid_mgr_init_sweep: "
-             "Skipping all lids as we are reassigning them\n");
+             "Skipping all lids as we are reassigning them\n");
     p_range =
       (osm_lid_mgr_range_t *)cl_malloc(sizeof(osm_lid_mgr_range_t));
     p_range->min_lid = 1;
@@ -401,7 +401,7 @@ __osm_lid_mgr_init_sweep(
     osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);
     for (lid = disc_min_lid; lid <= disc_max_lid; lid++)
       cl_ptr_vector_set(p_discovered_vec, lid, p_port );
-    /* make sure the guid2lid entry is valid. If not - clean it. */
+    /* make sure the guid2lid entry is valid. If not, clean it. */
     if (!osm_db_guid2lid_get( p_mgr->p_g2l,
                               cl_ntoh64(osm_port_get_guid(p_port)),
                               &db_min_lid, &db_max_lid))
@@ -416,7 +416,7 @@ __osm_lid_mgr_init_sweep(
           (((db_min_lid & lmc_mask) != db_min_lid) ||
            (db_max_lid - db_min_lid + 1 < num_lids)) )
       {
-        /* Not aligned, or not wide enough - remove the entry */
+        /* Not aligned, or not wide enough, then remove the entry */
         osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
                  "__osm_lid_mgr_init_sweep: "
                  "Cleaning persistent entry for guid:0x%016" PRIx64
@@ -479,7 +479,7 @@ __osm_lid_mgr_init_sweep(
       if (lid <= max_discovered_lid && (p_port = (osm_port_t *)cl_ptr_vector_get(p_discovered_vec, lid)))
       {
         /* we have a port. Now lets see if we can preserve its lid range. */
-        /* For that - we need to make sure:
+        /* For that, we need to make sure:
            1. The port has a (legal) persistency entry. Then the local lid
               is free (we will use the persistency value).
            2. Can the port keep its local assignment?
@@ -546,7 +546,7 @@ __osm_lid_mgr_init_sweep(
       {
               /* This port will use its local lid, and consume the entire required lid range.
                  Thus we can skip that range. */
-              /* If the disc_max_lid is greater then lid - we can skip right to it, 
+              /* If the disc_max_lid is greater then lid, we can skip right to it, 
                  since we've done all neccessary checks on the lids in between. */
               if (disc_max_lid > lid)
                 lid = disc_max_lid;
@@ -723,7 +723,7 @@ __osm_lid_mgr_find_free_lid_range(
     Couldn't find a free range of lids.
   */
   *p_min_lid = *p_max_lid = 0;
-  /* if we run out of lids - give an error and abort! */
+  /* if we run out of lids, give an error and abort! */
   osm_log( p_mgr->p_log, OSM_LOG_ERROR,
            "__osm_lid_mgr_find_free_lid_range: ERR 0307: "
            "OPENSM RAN OUT OF LIDS!!!\n");
@@ -753,10 +753,10 @@ void
 /**********************************************************************
  0.1 if the port info lid matches the guid2lid return 0
  0.2 if the port info has a lid and that range is empty in
-     port_lid_tbl - return 0 and update the port_lid_tbl and
+     port_lid_tbl, return 0 and update the port_lid_tbl and
      guid2lid
  0.3 else find an empty space in port_lid_tbl,  update the
- port_lid_tbl and guid2lid, return 1 to flag a change required.
+ port_lid_tbl and guid2lid, return 1 to flag a change required.
 **********************************************************************/
 int
 __osm_lid_mgr_get_port_lid(
@@ -889,6 +889,22 @@ __osm_lid_mgr_get_port_lid(
   return lid_changed;
 }
 
+/**********************************************************************
+ Set to INIT the remote port of the given physical port
+ **********************************************************************/
+static void
+__osm_lid_mgr_set_remote_pi_state_to_init(
+  IN osm_lid_mgr_t *       const p_mgr,
+  IN osm_physp_t*          const p_physp)
+{
+  ib_port_info_t *p_pi;
+  osm_physp_t *p_rem_port = osm_physp_get_remote(p_physp);
+  CL_ASSERT(p_rem_port);
+
+  p_pi = osm_physp_get_port_info_ptr( p_rem_port );
+  ib_port_info_set_port_state( p_pi, IB_LINK_INIT );
+}
+
 /**********************************************************************
  **********************************************************************/
 static boolean_t
@@ -929,7 +945,7 @@ __osm_lid_mgr_set_physp_pi(
       (port_num != 0) )
   {
     /*
-      Switch ports that are not numbered 0 should not be set with the
+      Switch ports that are not numbered 0 should not be set with the
       following attributes set later (during NO_CHANGE state in link mgr).
     */
     if( osm_log_is_active( p_mgr->p_log, OSM_LOG_DEBUG ) )
@@ -969,22 +985,22 @@ __osm_lid_mgr_set_physp_pi(
     FUJITSU line:
 
     Should never write back a value that is bigger then 3 in
-    the PortPhysicalState field - so can not simply copy!
+    the PortPhysicalState field, so cannot simply copy!
 
     Actually we want to write there:
-    port physical state - no change,
+    port physical state - no change
     link down default state = polling
     port state - no change
   */
   /* these values can be set only for hca ports, so if we are
-     on a switch node - set these values to zero */
+     on a switch node, set these values to zero */
   if ( osm_node_get_type( p_node ) == IB_NODE_TYPE_SWITCH )
     p_pi->state_info2 = 0x0;
   else
   {
     p_pi->state_info2 = 0x02;
     /* Check to see if the value we are setting is different than
-       the value in the port_info. If it is - turn on send_set flag */
+       the value in the port_info. If it is, turn on send_set flag */
     if ( ib_port_info_get_link_down_def_state(p_pi) !=
          ib_port_info_get_link_down_def_state(p_old_pi) )
       send_set = TRUE;
@@ -994,20 +1010,20 @@ __osm_lid_mgr_set_physp_pi(
 
   p_pi->m_key = p_mgr->p_subn->opt.m_key;
   /* Check to see if the value we are setting is different than
-     the value in the port_info. If it is - turn on send_set flag */
+     the value in the port_info. If it is, turn on send_set flag */
   if (cl_memcmp( &p_pi->m_key, &p_old_pi->m_key, sizeof(p_pi->m_key) ))
     send_set = TRUE;
 
   p_pi->subnet_prefix = p_mgr->p_subn->opt.subnet_prefix;
   /* Check to see if the value we are setting is different than
-     the value in the port_info. If it is - turn on send_set flag */
+     the value in the port_info. If it is, turn on send_set flag */
   if (cl_memcmp( &p_pi->subnet_prefix, &p_old_pi->subnet_prefix,
                  sizeof(p_pi->subnet_prefix) ))
     send_set = TRUE;
 
   p_pi->base_lid = lid;
   /* Check to see if the value we are setting is different than
-     the value in the port_info. If it is - turn on send_set flag */
+     the value in the port_info. If it is, turn on send_set flag */
   if (cl_memcmp( &p_pi->base_lid, &p_old_pi->base_lid,
                  sizeof(p_pi->base_lid) ))
     send_set = TRUE;
@@ -1015,14 +1031,14 @@ __osm_lid_mgr_set_physp_pi(
   /* we are updating the ports with our local sm_base_lid */
   p_pi->master_sm_base_lid = p_mgr->p_subn->sm_base_lid;
   /* Check to see if the value we are setting is different than
-     the value in the port_info. If it is - turn on send_set flag */
+     the value in the port_info. If it is, turn on send_set flag */
   if (cl_memcmp( &p_pi->master_sm_base_lid, &p_old_pi->master_sm_base_lid,
                  sizeof(p_pi->master_sm_base_lid) ))
     send_set = TRUE;
 
   p_pi->m_key_lease_period = p_mgr->p_subn->opt.m_key_lease_period;
   /* Check to see if the value we are setting is different than
-     the value in the port_info. If it is - turn on send_set flag */
+     the value in the port_info. If it is, turn on send_set flag */
   if (cl_memcmp( &p_pi->m_key_lease_period, &p_old_pi->m_key_lease_period,
                  sizeof(p_pi->m_key_lease_period) ))
     send_set = TRUE;
@@ -1033,7 +1049,7 @@ __osm_lid_mgr_set_physp_pi(
   */
   ib_port_info_set_timeout( p_pi, p_mgr->p_subn->opt.subnet_timeout );
   /* Check to see if the value we are setting is different than
-     the value in the port_info. If it is - turn on send_set flag */
+     the value in the port_info. If it is, turn on send_set flag */
   if (ib_port_info_get_timeout( p_pi ) != ib_port_info_get_timeout( p_old_pi ))
     send_set = TRUE;
 
@@ -1046,7 +1062,7 @@ __osm_lid_mgr_set_physp_pi(
     */
     p_pi->link_width_enabled = p_old_pi->link_width_supported;
     /* Check to see if the value we are setting is different than
-       the value in the port_info. If it is - turn on send_set flag */
+       the value in the port_info. If it is, turn on send_set flag */
     if (cl_memcmp( &p_pi->link_width_enabled, &p_old_pi->link_width_enabled,
                    sizeof(p_pi->link_width_enabled) ))
       send_set = TRUE;
@@ -1054,7 +1070,7 @@ __osm_lid_mgr_set_physp_pi(
     /* M_KeyProtectBits are always zero */
     p_pi->mkey_lmc = p_mgr->p_subn->opt.lmc;
     /* Check to see if the value we are setting is different than
-       the value in the port_info. If it is - turn on send_set flag */
+       the value in the port_info. If it is, turn on send_set flag */
     if (cl_memcmp( &p_pi->mkey_lmc, &p_old_pi->mkey_lmc, sizeof(p_pi->mkey_lmc) ))
       send_set = TRUE;
 
@@ -1087,10 +1103,6 @@ __osm_lid_mgr_set_physp_pi(
       send_set = TRUE;
 
     /*
-      TO DO -
-      If the subnet is being reconfigured, should we force the link
-      to the INIT state?
-
       To reset the port state machine we can send PortInfo.State = DOWN.
       (see: 7.2.7 p161 lines:10-19.)
     */
@@ -1106,6 +1118,13 @@ __osm_lid_mgr_set_physp_pi(
                  op_vls, ib_port_info_get_op_vls(p_old_pi)
                  );
       }
+
+      /* 
+         we need to make sure the internal DB will follow the fact the remote
+         port is also going through "down" state into "init"...
+      */
+      __osm_lid_mgr_set_remote_pi_state_to_init(p_mgr, p_physp);
+
       ib_port_info_set_port_state( p_pi, IB_LINK_DOWN );
       if ( ib_port_info_get_port_state(p_pi) !=
            ib_port_info_get_port_state(p_old_pi) )
@@ -1115,7 +1134,7 @@ __osm_lid_mgr_set_physp_pi(
   else
   {
     /*
-      For Port 0 - NeighborMTU is relevant only for Enh. SP0.
+      For Port 0, NeighborMTU is relevant only for Enh. SP0.
       In this case we'll set the MTU according to the mtu_cap
     */
     ib_port_info_set_neighbor_mtu( p_pi, ib_port_info_get_mtu_cap( p_old_pi ) );
@@ -1163,7 +1182,7 @@ __osm_lid_mgr_set_physp_pi(
      SM just became master, and it then needs to send a PortInfo Set to
      every port.
      3. got_set_resp on the physical port is FALSE. This means we haven't seen
-     this port before - need to send Set of PortInfo to it.
+     this port before and we need to send Set of PortInfo to it.
   */
   if (send_set || p_mgr->p_subn->first_time_master_sweep == TRUE ||
       p_physp->got_set_resp == FALSE)