[ofa-general] [PATCH 2/3] Enhanced qsort compareason function so it looks at the next switch level.

Nicolas Morey Chaisemartin nicolas.morey-chaisemartin at ext.bull.net
Thu Mar 5 06:01:22 PST 2009


Signed-off-by: Nicolas Morey-Chaisemartin <nicolas.morey-chaisemartin at ext.bull.net>
---
 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





More information about the general mailing list