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 
<[email protected]>
---
 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

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to