Signed-off-by: Nicolas Morey-Chaisemartin 
<[email protected]>
---
 opensm/opensm/osm_ucast_ftree.c |   56 ++++++++++++++++++++++++++++++++++++---
 1 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/opensm/opensm/osm_ucast_ftree.c b/opensm/opensm/osm_ucast_ftree.c
index da72ade..b00cf4a 100644
--- a/opensm/opensm/osm_ucast_ftree.c
+++ b/opensm/opensm/osm_ucast_ftree.c
@@ -173,6 +173,7 @@ typedef struct ftree_sw_t_ {
        uint8_t up_port_groups_num;
        boolean_t is_leaf;
        unsigned down_port_groups_idx;
+       uint32_t min_counter_down;
 } ftree_sw_t;
 
 /***************************************************
@@ -1904,8 +1905,33 @@ static void __osm_ftree_set_sw_fwd_table(IN 
cl_map_item_t * const p_map_item,
                                    p_sw->p_osm_sw);
 }
 
+static void
+__osm_ftree_recalculate_min_counter_down(ftree_sw_t *p_sw){
+       uint32_t min= (1<<30);
+       uint32_t i;
+       for(i=0;i < p_sw->down_port_groups_num; i++) {
+               if(p_sw->down_port_groups[i]->counter_down < min){
+                       min = p_sw->down_port_groups[i]->counter_down;
+               }
+       }
+       p_sw->min_counter_down = min;
+       return;
+}
 
+static uint32_t
+__osm_ftree_find_lowest_loaded_group_on_sw(ftree_sw_t *p_sw){
+       /*uint32_t min= (1<<30);
+               uint32_t i;
+       for(i=0;i < p_sw->down_port_groups_num; i++) {
+               if(p_sw->down_port_groups[i]->counter_down < min){
+                       min = p_sw->down_port_groups[i]->counter_down;
+               }
+               }*/
+       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 */
 static int
 __osm_ftree_port_group_compare_load_down(const void* p1,const void* p2){
        int temp = (*((ftree_port_group_t**)p1))->counter_down 
-(*((ftree_port_group_t**)p2))->counter_down ;
@@ -1913,9 +1939,26 @@ __osm_ftree_port_group_compare_load_down(const void* 
p1,const void* p2){
                return 1;
        if(temp < 0)
                return -1;
-       return 0;
+
+       /* Find the less loaded remote sw and choose this one */
+       do{
+               uint32_t 
load1=__osm_ftree_find_lowest_loaded_group_on_sw((*((ftree_port_group_t**)p1))->remote_hca_or_sw.p_sw);
+               uint32_t 
load2=__osm_ftree_find_lowest_loaded_group_on_sw((*((ftree_port_group_t**)p2))->remote_hca_or_sw.p_sw);
+               temp = load1-load2;
+               if(temp > 0)
+                       return 1;
+               if(temp < 0)
+                       return -1;
+       }while(0);
+
+       /* If they are both equal, choose the biggest GUID */
+       if(((*((ftree_port_group_t**)p1)))->remote_port_guid > 
((*((ftree_port_group_t**)p2)))->remote_port_guid)
+               return 1;
+
+       return -1;
 }
 
+/* This is for upgoing_by_going_down. There is not much equilibration to do so 
don't bother looking at the next rank */
 static int
 __osm_ftree_port_group_compare_load_up(const void* p1,const void* p2){
        int temp = (*((ftree_port_group_t**)p1))->counter_up 
-(*((ftree_port_group_t**)p2))->counter_up ;
@@ -2216,8 +2259,8 @@ __osm_ftree_fabric_route_downgoing_by_going_up(IN 
ftree_fabric_t * p_ftree,
         * going port and explore the other pots on secondary routes more 
easily (and quickly) */
        
qsort(p_sw->up_port_groups,p_sw->up_port_groups_num,sizeof(*(p_sw->up_port_groups)),
 __osm_ftree_port_group_compare_load_down);
 
-
        p_min_group = p_sw->up_port_groups[0];
+
        /* Find the least loaded upgoing port in the selected group */
        p_min_port = NULL;
        ports_num = (uint16_t) cl_ptr_vector_get_size(&p_min_group->ports);
@@ -2281,12 +2324,17 @@ __osm_ftree_fabric_route_downgoing_by_going_up(IN 
ftree_fabric_t * p_ftree,
                                __osm_ftree_tuple_to_str(p_sw->tuple),
                                __osm_ftree_tuple_to_str(p_remote_sw->tuple));
                }
+
                /* The number of downgoing routes is tracked in the
                   p_group->counter_down p_port->counter_down counters of the
                   group and port that belong to the lower side of the link
                   (on switch with higher rank) */
                p_min_group->counter_down++;
                p_min_port->counter_down++;
+               if(p_min_group->counter_down == 
(p_min_group->remote_hca_or_sw.p_sw->min_counter_down+1)){
+                       
__osm_ftree_recalculate_min_counter_down(p_min_group->remote_hca_or_sw.p_sw);
+               }
+
                if (is_real_lid) {
                        /* This LID may already be in the LFT in the 
reverse_hop feature is used */
                        /* We update the LFT only if this LID isn't already 
present. */
@@ -2375,7 +2423,7 @@ __osm_ftree_fabric_route_downgoing_by_going_up(IN 
ftree_fabric_t * p_ftree,
                /* skip if target lid has been already set on remote switch fwd 
tbl (with a bigger hop count)*/
                if (p_remote_sw->p_osm_sw->new_lft[cl_ntoh16(target_lid)] != 
OSM_NO_PATH)
                        if((target_rank -p_remote_sw->rank + 2*reverse_hops) >=
-                          osm_switch_get_least_hops(p_remote_sw->p_osm_sw, 
cl_ntoh16(target_lid)))
+                            osm_switch_get_least_hops(p_remote_sw->p_osm_sw, 
cl_ntoh16(target_lid)))
                                continue;
 
                if (p_sw->is_leaf) {
@@ -2391,7 +2439,7 @@ __osm_ftree_fabric_route_downgoing_by_going_up(IN 
ftree_fabric_t * p_ftree,
                   We can safely assume that switch will initiate very
                   few traffic, so there's no point waisting runtime on
                   trying to balance these routes - always pick port 0. */
-               /* GET MIN PORT HERE */
+
                p_min_port = NULL;
                ports_num = (uint16_t) cl_ptr_vector_get_size(&p_group->ports);
                for (j = 0; j < ports_num; j++) {
-- 
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