[ofa-general] [PATCH 4/4] Many fixes on balanced minhop enhancements

Nicolas Morey Chaisemartin nicolas.morey-chaisemartin at ext.bull.net
Tue Mar 10 07:00:14 PDT 2009


	Fixed stupid order on 2nd lvl sort
 	Fixed bad init value for downgoing calls
 	Fixed bug in port counters
 	Fixed comments of bubble sort functions

Signed-off-by: Nicolas Morey-Chaisemartin <nicolas.morey-chaisemartin at ext.bull.net>
---
 opensm/opensm/osm_ucast_ftree.c |  106 +++++++++++++++++++++++++++++----------
 1 files changed, 80 insertions(+), 26 deletions(-)

diff --git a/opensm/opensm/osm_ucast_ftree.c b/opensm/opensm/osm_ucast_ftree.c
index bfefa0f..638504c 100644
--- a/opensm/opensm/osm_ucast_ftree.c
+++ b/opensm/opensm/osm_ucast_ftree.c
@@ -1901,6 +1901,13 @@ static void __osm_ftree_set_sw_fwd_table(IN cl_map_item_t * const p_map_item,
 				    p_sw->p_osm_sw);
 }
 
+/***************************************************
+ ***************************************************/
+
+/*
+ * Function: Finds the least loaded port group and stores its counter
+ * Given   : A switch
+ */
 static inline void
 __osm_ftree_recalculate_min_counter_down(ftree_sw_t *p_sw){
 	uint32_t min= (1<<30);
@@ -1914,13 +1921,23 @@ __osm_ftree_recalculate_min_counter_down(ftree_sw_t *p_sw){
 	return;
 }
 
+/*
+ * Function: Return the counter value of the least loaded down port group
+ * Given   : A switch
+ */
 static inline uint32_t
 __osm_ftree_find_lowest_loaded_group_on_sw(ftree_sw_t *p_sw){
 	return p_sw->min_counter_down;
 }
 
-/* This is for downgoing_by_going_up.
- * If load are equals, let's have a look at the remote switches and find the less loaded one */
+/*
+ * Function: Compare the load of two port groups and return which is the least loaded
+ * Given   : Two port groups with remote switch
+ * When both port groups are equally loaded, it picks the one whom
+ * remote switch down ports are least loaded.
+ * This way, it prefers the switch from where it will be easier to go down (creating upward routes).
+ * If both are equal, it picks the bigger GUID to be deterministic.
+ */
 static inline int
 __osm_ftree_port_group_compare_load_down(const ftree_port_group_t *p1,const ftree_port_group_t *p2){
 	int temp = p1->counter_down -p2->counter_down ;
@@ -1936,63 +1953,100 @@ __osm_ftree_port_group_compare_load_down(const ftree_port_group_t *p1,const ftre
 		temp = load1-load2;
 		if(temp > 0)
 			return 1;
-		return 0;
 	}while(0);
+       /* If they are both equal, choose the biggest GUID */
+       if(p1->remote_port_guid > p2->remote_port_guid)
+               return 1;
+
+       return -1;
 
 }
 
+/*
+ * Function: Sorts an array of port group by up load order
+ * Given   : A port group array and its length
+ * As the list is mostly sorted, we used a bubble sort instead of qsort
+ * as it is much faster.
+ *
+ * Important note:
+ * This function and __osm_ftree_bubble_sort_down must NOT be factorized.
+ * Although most of the code is the same and a function pointer could be used
+ * for the compareason function, it would prevent the compareason function to be inlined
+ * and cost a great deal to performances.
+ */
 static inline void
 __osm_ftree_bubble_sort_up(ftree_port_group_t **p_group_array, uint32_t nmemb)
 {
-        uint32_t i   = 0; /* Indice de répétition du tri */
-        uint32_t j   = 0; /* Variable de boucle */
-        ftree_port_group_t *tmp = p_group_array[0]; /* Variable de stockage temporaire et de fin de tri*/
+        uint32_t i   = 0;
+        uint32_t j   = 0;
+        ftree_port_group_t *tmp = p_group_array[0];
+
+	/* As this function is a great number of times, we only go into the loop
+	 * if one of the port counters has changed, thus saving some tests */
 	if(tmp->hca_or_sw.p_sw->counter_up_changed == FALSE){
 		return;
 	}
-        /* Boucle de répétition du tri et le test qui
-           arrête le tri dès que le tableau est ordonné */
+	/* While we did modifications on the array order*/
+	/* i may grew above array length but next loop will fail and tmp will be null for the next time
+	 * this way we save a test i < nmemb for each pass through the loop */
         for(i = 0 ; tmp ; i++)
         {
-                /* Supposons le tableau ordonné */
+		/* Assume the array is orderd */
                 tmp = NULL;
-                /* Vérification des éléments des places j et j-1 */
+                /* Comparing elements j and j-1 */
                 for(j = 1 ; j < (nmemb - i) ; j++)
                 {
-                        /* Si les 2 éléments sont mal triés */
+			/* If they are the wrong way around */
                         if( p_group_array[j]->counter_up < p_group_array[j-1]->counter_up)
                         {
-                                /* Inversion des 2 éléments */
+				/* We invert them */
                                 tmp = p_group_array[j-1];
                                 p_group_array[j-1] = p_group_array[j];
 				p_group_array[j] = tmp;
-
+				/* This sets tmp != NULL so the main loop will make another pass */
                         }
                 }
         }
+
+	/* We have reordered the array so as long noone changes the counter
+	 * it's not necessary to do it again */
 	 p_group_array[0]->hca_or_sw.p_sw->counter_up_changed = FALSE;
 }
 
+/*
+ * Function: Sorts an array of port group. Order is decide through
+ * __osm_ftree_port_group_compare_load_down ( up counters, least load remote switch, biggest GUID)
+ * Given   : A port group array and its length. Each port group points to a remote switch (not a HCA)
+ * As the list is mostly sorted, we used a bubble sort instead of qsort
+ * as it is much faster.
+ *
+ * Important note:
+ * This function and __osm_ftree_bubble_sort_up must NOT be factorized.
+ * Although most of the code is the same and a function pointer could be used
+ * for the compareason function, it would prevent the compareason function to be inlined
+ * and cost a great deal to performances.
+ */
 static inline void
 __osm_ftree_bubble_sort_down(ftree_port_group_t **p_group_array, uint32_t nmemb)
 {
-        uint32_t i   = 0; /* Indice de répétition du tri */
-        uint32_t j   = 0; /* Variable de boucle */
-        ftree_port_group_t *tmp = p_group_array[0]; ; /* Variable de stockage temporaire et de fin de tri*/
+        uint32_t i   = 0;
+        uint32_t j   = 0;
+        ftree_port_group_t *tmp = p_group_array[0];
 
-        /* Boucle de répétition du tri et le test qui
-           arrête le tri dès que le tableau est ordonné */
+        /* While we did modifications on the array order*/
+        /* i may grew above array length but next loop will fail and tmp will be null for the next time
+         * this way we save a test i < nmemb for each pass through the loop */
         for(i = 0 ; tmp ; i++)
         {
-                /* Supposons le tableau ordonné */
-                tmp = NULL;
-                /* Vérification des éléments des places j et j-1 */
+		/* Assume the array is orderd */
+		tmp = NULL;
+		/* Comparing elements j and j-1 */
                 for(j = 1 ; j < (nmemb - i) ; j++)
                 {
-                        /* Si les 2 éléments sont mal triés */
+			/* If they are the wrong way around */
                         if( __osm_ftree_port_group_compare_load_down(p_group_array[j],p_group_array[j-1]) < 0 )
 			{
-                                /* Inversion des 2 éléments */
+				/* We invert them */
                                 tmp = p_group_array[j-1];
                                 p_group_array[j-1] = p_group_array[j];
                                 p_group_array[j] = tmp;
@@ -2187,12 +2241,12 @@ __osm_ftree_fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 								   is_main_path,	/* whether this is path to HCA that should by tracked by counters */
 								   highest_rank_in_route, reverse_hops);	/* highest visited point in the tree before going down */
 		created_route|=routed;
-		if(routed)
+		if(routed){
 			p_min_port->counter_up++;
 			p_group->counter_up++;
 			p_group->hca_or_sw.p_sw->counter_up_changed = TRUE;
 		}
-
+	}
 	/* done scanning all the down-going port groups */
 
 	/* if the route was created, promote the index that
@@ -2449,7 +2503,7 @@ __osm_ftree_fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 	 *         - go UP(TRUE,FALSE) to the remote switch
 	 */
 
-	for (i = 1; i < p_sw->up_port_groups_num; i++) {
+	for (i = 0; i < p_sw->up_port_groups_num; i++) {
 		p_group = p_sw->up_port_groups[i];
 		p_remote_sw = p_group->remote_hca_or_sw.p_sw;
 
-- 
1.6.2-rc2.GIT




More information about the general mailing list