<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2654.45">
<TITLE>Patches for Opensm</TITLE>
</HEAD>
<BODY>
<P><FONT SIZE=2>Hi Hal,</FONT>
</P>
<P><FONT SIZE=2>I noticed that you've checked in a change to the osm trunk few days ago without</FONT>
<BR><FONT SIZE=2>sending a patch regarding it.</FONT>
<BR><FONT SIZE=2>Since I am the owner of the opensm tree under Windows, and I am trying to keep</FONT>
<BR><FONT SIZE=2>the Windows tree as similar as possible to the Linux tree - I want to know </FONT>
<BR><FONT SIZE=2>about checkins to the osm tree, so I can add the patches to the Windows tree as well.</FONT>
<BR><FONT SIZE=2>Please send an e-mail with a patch when you commit changes to the osm tree.</FONT>
</P>
<P><FONT SIZE=2>Thanks,</FONT>
<BR><FONT SIZE=2>Yael</FONT>
</P>
<BR>
<P><FONT SIZE=2>-----Original Message-----</FONT>
<BR><FONT SIZE=2>From: Yael Kalka [<A HREF="mailto:yael@mellanox.co.il">mailto:yael@mellanox.co.il</A>]</FONT>
<BR><FONT SIZE=2>Sent: Thursday, October 27, 2005 3:04 PM</FONT>
<BR><FONT SIZE=2>To: halr@voltaire.com</FONT>
<BR><FONT SIZE=2>Cc: openib-general@openib.org; eitan@mellanox.co.il; yael@mellanox.co.il</FONT>
<BR><FONT SIZE=2>Subject: [PATCH] Opensm - fix lmc algorithm</FONT>
</P>
<BR>
<P><FONT SIZE=2>Hi Hal,</FONT>
</P>
<P><FONT SIZE=2>We noticed a problem in the lmc assignment algorithm.</FONT>
<BR><FONT SIZE=2>In the current code - when trying to run opensm with lmc > 0, the</FONT>
<BR><FONT SIZE=2>opensm goes into infinite loop.</FONT>
<BR><FONT SIZE=2>Debugging the problem we noticed that there is a problem with the</FONT>
<BR><FONT SIZE=2>lid assignment, and we changed the algorithm. The change is in the</FONT>
<BR><FONT SIZE=2>osm_lid_mgr_init_sweep function.</FONT>
<BR><FONT SIZE=2>We have done some testing to the new code, and it seems that the lmc</FONT>
<BR><FONT SIZE=2>assignment is ok with the fix.</FONT>
</P>
<P><FONT SIZE=2>Thanks,</FONT>
<BR><FONT SIZE=2>Yael</FONT>
</P>
<P><FONT SIZE=2>Signed-off-by: Yael Kalka <yael@mellanox.co.il></FONT>
</P>
<P><FONT SIZE=2>Index: opensm/osm_lid_mgr.c</FONT>
<BR><FONT SIZE=2>===================================================================</FONT>
<BR><FONT SIZE=2>--- opensm/osm_lid_mgr.c (revision 3848)</FONT>
<BR><FONT SIZE=2>+++ opensm/osm_lid_mgr.c (working copy)</FONT>
<BR><FONT SIZE=2>@@ -337,7 +337,7 @@ __osm_lid_mgr_init_sweep(</FONT>
<BR><FONT SIZE=2> uint16_t max_defined_lid;</FONT>
<BR><FONT SIZE=2> uint16_t max_persistent_lid;</FONT>
<BR><FONT SIZE=2> uint16_t max_discovered_lid;</FONT>
<BR><FONT SIZE=2>- uint16_t lid, l;</FONT>
<BR><FONT SIZE=2>+ uint16_t lid;</FONT>
<BR><FONT SIZE=2> uint16_t disc_min_lid;</FONT>
<BR><FONT SIZE=2> uint16_t disc_max_lid;</FONT>
<BR><FONT SIZE=2> uint16_t db_min_lid;</FONT>
<BR><FONT SIZE=2>@@ -349,16 +349,23 @@ __osm_lid_mgr_init_sweep(</FONT>
<BR><FONT SIZE=2> osm_port_t *p_port;</FONT>
<BR><FONT SIZE=2> cl_qmap_t *p_port_guid_tbl;</FONT>
<BR><FONT SIZE=2> uint8_t lmc_num_lids = (uint8_t)(1 << p_mgr->p_subn->opt.lmc);</FONT>
<BR><FONT SIZE=2>+ uint16_t lmc_mask;</FONT>
<BR><FONT SIZE=2>+ uint16_t req_lid, num_lids;</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> OSM_LOG_ENTER( p_mgr->p_log, __osm_lid_mgr_init_sweep );</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2>+ if (p_mgr->p_subn->opt.lmc)</FONT>
<BR><FONT SIZE=2>+ lmc_mask = ~((1 << p_mgr->p_subn->opt.lmc) - 1);</FONT>
<BR><FONT SIZE=2>+ else</FONT>
<BR><FONT SIZE=2>+ lmc_mask = 0xffff;</FONT>
<BR><FONT SIZE=2>+</FONT>
<BR><FONT SIZE=2> /* if we came out of standby we need to discard any previous guid 2 lid</FONT>
<BR><FONT SIZE=2> info we might had */</FONT>
<BR><FONT SIZE=2> if ( p_mgr->p_subn->coming_out_of_standby == TRUE )</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2> osm_db_clear( p_mgr->p_g2l );</FONT>
<BR><FONT SIZE=2> for (lid = 0; lid < cl_ptr_vector_get_size(&p_mgr->used_lids); lid++)</FONT>
<BR><FONT SIZE=2>- cl_ptr_vector_set(&p_mgr->used_lids, lid, NULL);</FONT>
<BR><FONT SIZE=2>+ cl_ptr_vector_set(p_persistent_vec, lid, NULL);</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> /* we need to cleanup the empty ranges list */</FONT>
<BR><FONT SIZE=2>@@ -375,7 +382,7 @@ __osm_lid_mgr_init_sweep(</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> /* we if are on the first sweep and in re-assign lids mode </FONT>
<BR><FONT SIZE=2> we should ignore all the available info and simply define one </FONT>
<BR><FONT SIZE=2>- hufe empty range */</FONT>
<BR><FONT SIZE=2>+ huge empty range */</FONT>
<BR><FONT SIZE=2> if ((p_mgr->p_subn->first_time_master_sweep == TRUE) &&</FONT>
<BR><FONT SIZE=2> (p_mgr->p_subn->opt.reassign_lids == TRUE ))</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>@@ -398,6 +405,34 @@ __osm_lid_mgr_init_sweep(</FONT>
<BR><FONT SIZE=2> osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);</FONT>
<BR><FONT SIZE=2> for (lid = disc_min_lid; lid <= disc_max_lid; lid++)</FONT>
<BR><FONT SIZE=2> cl_ptr_vector_set(p_discovered_vec, lid, p_port );</FONT>
<BR><FONT SIZE=2>+ /* make sure the guid2lid entry is valid. If not - clean it. */</FONT>
<BR><FONT SIZE=2>+ if (!osm_db_guid2lid_get( p_mgr->p_g2l,</FONT>
<BR><FONT SIZE=2>+ cl_ntoh64(osm_port_get_guid(p_port)),</FONT>
<BR><FONT SIZE=2>+ &db_min_lid, &db_max_lid))</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ if ( osm_node_get_type( osm_port_get_parent_node( p_port ) ) !=</FONT>
<BR><FONT SIZE=2>+ IB_NODE_TYPE_SWITCH)</FONT>
<BR><FONT SIZE=2>+ num_lids = lmc_num_lids;</FONT>
<BR><FONT SIZE=2>+ else</FONT>
<BR><FONT SIZE=2>+ num_lids = 1;</FONT>
<BR><FONT SIZE=2>+</FONT>
<BR><FONT SIZE=2>+ if ((num_lids != 1) &&</FONT>
<BR><FONT SIZE=2>+ (((db_min_lid & lmc_mask) != db_min_lid) ||</FONT>
<BR><FONT SIZE=2>+ (db_max_lid - db_min_lid + 1 < num_lids)) )</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ /* Not alligned, or not wide enough - remove the entry */</FONT>
<BR><FONT SIZE=2>+ osm_log( p_mgr->p_log, OSM_LOG_DEBUG,</FONT>
<BR><FONT SIZE=2>+ "__osm_lid_mgr_init_sweep: "</FONT>
<BR><FONT SIZE=2>+ "Cleaning persistent entry for guid:0x%016" PRIx64</FONT>
<BR><FONT SIZE=2>+ " illegal range:[0x%x:0x%x] \n",</FONT>
<BR><FONT SIZE=2>+ cl_ntoh64(osm_port_get_guid(p_port)), db_min_lid,</FONT>
<BR><FONT SIZE=2>+ db_max_lid );</FONT>
<BR><FONT SIZE=2>+ osm_db_guid2lid_delete( p_mgr->p_g2l,</FONT>
<BR><FONT SIZE=2>+ cl_ntoh64(osm_port_get_guid(p_port)));</FONT>
<BR><FONT SIZE=2>+ for ( lid = db_min_lid ; lid <= db_max_lid ; lid++ )</FONT>
<BR><FONT SIZE=2>+ cl_ptr_vector_set(p_persistent_vec, lid, NULL);</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> /* </FONT>
<BR><FONT SIZE=2>@@ -434,7 +469,7 @@ __osm_lid_mgr_init_sweep(</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2> is_free = TRUE;</FONT>
<BR><FONT SIZE=2> /* first check to see if the lid is used by a persistent assignment */</FONT>
<BR><FONT SIZE=2>- if ((lid < max_persistent_lid) && cl_ptr_vector_get(p_persistent_vec, lid))</FONT>
<BR><FONT SIZE=2>+ if ((lid <= max_persistent_lid) && cl_ptr_vector_get(p_persistent_vec, lid))</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2> osm_log( p_mgr->p_log, OSM_LOG_DEBUG,</FONT>
<BR><FONT SIZE=2> "__osm_lid_mgr_init_sweep: "</FONT>
<BR><FONT SIZE=2>@@ -442,62 +477,86 @@ __osm_lid_mgr_init_sweep(</FONT>
<BR><FONT SIZE=2> lid);</FONT>
<BR><FONT SIZE=2> is_free = FALSE;</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2>-</FONT>
<BR><FONT SIZE=2>- /* check the discovered port if there is one */</FONT>
<BR><FONT SIZE=2>- if ((lid < max_discovered_lid) &&</FONT>
<BR><FONT SIZE=2>- (p_port = (osm_port_t *)cl_ptr_vector_get(p_discovered_vec, lid)))</FONT>
<BR><FONT SIZE=2>+ else</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>- /* get the lid range of that port - but we know how many lids we </FONT>
<BR><FONT SIZE=2>- are about to assign to it */</FONT>
<BR><FONT SIZE=2>- osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);</FONT>
<BR><FONT SIZE=2>- if ( osm_node_get_type( osm_port_get_parent_node( p_port ) ) !=</FONT>
<BR><FONT SIZE=2>- IB_NODE_TYPE_SWITCH)</FONT>
<BR><FONT SIZE=2>- disc_max_lid = disc_min_lid + lmc_num_lids - 1;</FONT>
<BR><FONT SIZE=2>-</FONT>
<BR><FONT SIZE=2>+ /* check this is a discovered port */</FONT>
<BR><FONT SIZE=2>+ CL_ASSERT(lid <= max_discovered_lid);</FONT>
<BR><FONT SIZE=2>+ if ((p_port = (osm_port_t *)cl_ptr_vector_get(p_discovered_vec, lid)))</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ /* we have a port. Now lets see if we can preserve its lid range. */</FONT>
<BR><FONT SIZE=2>+ /* For that - we need to make sure:</FONT>
<BR><FONT SIZE=2>+ 1. The port has a (legal) persistancy entry. Then the local lid</FONT>
<BR><FONT SIZE=2>+ is free (we will use the persistancy value).</FONT>
<BR><FONT SIZE=2>+ 2. Can the port keep its local assignment?</FONT>
<BR><FONT SIZE=2>+ a. Make sure the lid a alligned.</FONT>
<BR><FONT SIZE=2>+ b. Make sure all needed lids (for the lmc) are free according</FONT>
<BR><FONT SIZE=2>+ to persistancy table.</FONT>
<BR><FONT SIZE=2>+ */</FONT>
<BR><FONT SIZE=2> /* qualify the guid of the port is not persistently mapped to </FONT>
<BR><FONT SIZE=2> another range */</FONT>
<BR><FONT SIZE=2> if (!osm_db_guid2lid_get( p_mgr->p_g2l,</FONT>
<BR><FONT SIZE=2> cl_ntoh64(osm_port_get_guid(p_port)),</FONT>
<BR><FONT SIZE=2> &db_min_lid, &db_max_lid))</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>- /* ok there is an asignment - is it the same ? */</FONT>
<BR><FONT SIZE=2>- if ((disc_min_lid == db_min_lid) && (disc_max_lid == db_max_lid))</FONT>
<BR><FONT SIZE=2>- {</FONT>
<BR><FONT SIZE=2> osm_log( p_mgr->p_log, OSM_LOG_DEBUG,</FONT>
<BR><FONT SIZE=2> "__osm_lid_mgr_init_sweep: "</FONT>
<BR><FONT SIZE=2>- "[0x%04x,0x%04x] is not free as it was discovered "</FONT>
<BR><FONT SIZE=2>- " and mapped by the persistent db.\n",</FONT>
<BR><FONT SIZE=2>- disc_min_lid, disc_max_lid);</FONT>
<BR><FONT SIZE=2>- is_free = FALSE;</FONT>
<BR><FONT SIZE=2>+ "0x%04x is free as it was discovered "</FONT>
<BR><FONT SIZE=2>+ "but mapped by the persistent db to [0x%04x:0x%04x].\n",</FONT>
<BR><FONT SIZE=2>+ lid, db_min_lid, db_max_lid);</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2>+ else</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ /* can the port keep its assignment ? */</FONT>
<BR><FONT SIZE=2>+ /* get the lid range of that port, and the required number</FONT>
<BR><FONT SIZE=2>+ of lids we are about to assign to it */</FONT>
<BR><FONT SIZE=2>+ osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);</FONT>
<BR><FONT SIZE=2>+ if ( osm_node_get_type( osm_port_get_parent_node( p_port ) ) !=</FONT>
<BR><FONT SIZE=2>+ IB_NODE_TYPE_SWITCH)</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ disc_max_lid = disc_min_lid + lmc_num_lids - 1;</FONT>
<BR><FONT SIZE=2>+ num_lids = lmc_num_lids;</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> else</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>+ num_lids = 1;</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2>+ /* Make sure the lid is alligned */</FONT>
<BR><FONT SIZE=2>+ if ((num_lids != 1) && ((disc_min_lid & lmc_mask) != disc_min_lid))</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ /* The lid cannot be used */</FONT>
<BR><FONT SIZE=2> osm_log( p_mgr->p_log, OSM_LOG_DEBUG,</FONT>
<BR><FONT SIZE=2> "__osm_lid_mgr_init_sweep: "</FONT>
<BR><FONT SIZE=2>- "[0x%04x,0x%04x] is free as it was discovered"</FONT>
<BR><FONT SIZE=2>- " but mapped to range: [0x%x:0x%x] by the persistent db.\n",</FONT>
<BR><FONT SIZE=2>- disc_min_lid, disc_max_lid, db_min_lid, db_max_lid);</FONT>
<BR><FONT SIZE=2>- for (l = disc_min_lid; l <= disc_max_lid; l++)</FONT>
<BR><FONT SIZE=2>- cl_ptr_vector_set(p_discovered_vec, l, NULL);</FONT>
<BR><FONT SIZE=2>- }</FONT>
<BR><FONT SIZE=2>+ "0x%04x is free as it was discovered "</FONT>
<BR><FONT SIZE=2>+ "but not alligned. \n",</FONT>
<BR><FONT SIZE=2>+ lid );</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> else</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>+ /* check that all needed lids are not persistantly mapped */</FONT>
<BR><FONT SIZE=2>+ is_free = FALSE;</FONT>
<BR><FONT SIZE=2>+ for ( req_lid = disc_min_lid + 1 ; req_lid <= disc_max_lid ; req_lid++ )</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2>+ if ((req_lid <= max_persistent_lid) && cl_ptr_vector_get(p_persistent_vec, req_lid))</FONT>
<BR><FONT SIZE=2>+ {</FONT>
<BR><FONT SIZE=2> osm_log( p_mgr->p_log, OSM_LOG_DEBUG,</FONT>
<BR><FONT SIZE=2> "__osm_lid_mgr_init_sweep: "</FONT>
<BR><FONT SIZE=2>- "0x%04x is not free as it was discovered"</FONT>
<BR><FONT SIZE=2>- " and there is no persistent db entry for it.\n",</FONT>
<BR><FONT SIZE=2>+ "0x%04x is free as it was discovered "</FONT>
<BR><FONT SIZE=2>+ "but mapped. \n",</FONT>
<BR><FONT SIZE=2> lid);</FONT>
<BR><FONT SIZE=2>- is_free = FALSE;</FONT>
<BR><FONT SIZE=2>+ is_free = TRUE;</FONT>
<BR><FONT SIZE=2>+ break;</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2>-</FONT>
<BR><FONT SIZE=2>- /* if there is more then one lid on that port - and the discovered port</FONT>
<BR><FONT SIZE=2>- is going to retain its lids advance to the max lid */</FONT>
<BR><FONT SIZE=2> if (is_free == FALSE)</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>+ /* This port will use its local lid, and consume the entire required lid range.</FONT>
<BR><FONT SIZE=2>+ Thus we can skip that range. */</FONT>
<BR><FONT SIZE=2> lid = disc_max_lid;</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2>+ }</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> if (is_free)</FONT>
<BR><FONT SIZE=2> {</FONT>
<BR><FONT SIZE=2>@@ -1300,7 +1359,6 @@ osm_lid_mgr_process_subnet(</FONT>
<BR><FONT SIZE=2> /* the proc returns the fact it sent a set port info */</FONT>
<BR><FONT SIZE=2> if (__osm_lid_mgr_set_physp_pi( p_mgr, p_physp, cl_hton16( min_lid_ho )))</FONT>
<BR><FONT SIZE=2> p_mgr->send_set_reqs = TRUE;</FONT>
<BR><FONT SIZE=2>- </FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> } /* all ports */</FONT>
<BR><FONT SIZE=2> </FONT>
</P>
</BODY>
</HTML>