[ofa-general] [PATCH] osm_ucast_ftree.c Allow horizontal links between switches of max rank

Line.Holen at Sun.COM Line.Holen at Sun.COM
Wed May 27 03:07:41 PDT 2009


This patch makes it legal to have cross links (horizontal links) between
switches at max rank. These switches do have same rank, so hop count cannot
be calculated based on rank anymore.
The horizontal links are treated as downlinks. Switch A has a downlink to B
while B has a downlink to A. Tests on lids and also number of hops makes sure
that we don't loop back and forth across the link.

Signed-off-by: Frank Olaf Sem-Jacobsen <frankose at simula.no>
Signed-off-by: Line Holen <Line.Holen at sun.com>

---

diff --git a/opensm/opensm/osm_ucast_ftree.c b/opensm/opensm/osm_ucast_ftree.c
index 8ed2f74..1f1d0ff 100644
--- a/opensm/opensm/osm_ucast_ftree.c
+++ b/opensm/opensm/osm_ucast_ftree.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2009 Simula Research Laboratory. All rights reserved.
  * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2002-2007 Mellanox Technologies LTD. All rights reserved.
@@ -1495,7 +1496,8 @@ static void fabric_make_indexing(IN ftree_fabric_t * p_ftree)
 				p_remote_sw =
 				    p_sw->down_port_groups[i]->remote_hca_or_sw.
 				    p_sw;
-				if (tuple_assigned(p_remote_sw->tuple)) {
+				if (tuple_assigned(p_remote_sw->tuple) ||
+				    (p_sw->rank == p_remote_sw->rank)) {
 					/* this switch has been already indexed */
 					continue;
 				}
@@ -1903,12 +1905,11 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 				   IN ftree_sw_t * p_sw,
 				   IN ftree_sw_t * p_prev_sw,
 				   IN uint16_t target_lid,
-				   IN uint8_t target_rank,
 				   IN boolean_t is_real_lid,
 				   IN boolean_t is_main_path,
 				   IN boolean_t is_target_a_sw,
-				   IN uint8_t highest_rank_in_route,
-				   IN uint16_t reverse_hops)
+				   IN uint16_t reverse_hops,
+				   IN uint8_t current_hops)
 {
 	ftree_sw_t *p_remote_sw;
 	uint16_t ports_num;
@@ -1919,6 +1920,7 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 	uint16_t j;
 	uint16_t k;
 	boolean_t created_route = FALSE;
+	uint8_t least_hops;
 
 	/* we shouldn't enter here if both real_lid and main_path are false */
 	CL_ASSERT(is_real_lid || is_main_path);
@@ -1968,14 +1970,15 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 		   Set on the remote switch how to get to the target_lid -
 		   set LFT(target_lid) on the remote switch to the remote port */
 		p_remote_sw = p_group->remote_hca_or_sw.p_sw;
+		least_hops = sw_get_least_hops(p_remote_sw, target_lid);
 
-		if (sw_get_least_hops(p_remote_sw, target_lid) != OSM_NO_PATH) {
+		if ((least_hops != OSM_NO_PATH) && (least_hops <= current_hops)) {
 			/* Loop in the fabric - we already routed the remote switch
 			   on our way UP, and now we see it again on our way DOWN */
 			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
 				"Loop of lenght %d in the fabric:\n                             "
 				"Switch %s (LID %u) closes loop through switch %s (LID %u)\n",
-				(p_remote_sw->rank - highest_rank_in_route) * 2,
+				current_hops,
 				tuple_to_str(p_remote_sw->tuple),
 				p_group->base_lid,
 				tuple_to_str(p_sw->tuple),
@@ -2022,20 +2025,17 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 			p_remote_sw->p_osm_sw->new_lft[target_lid] =
 			    p_min_port->remote_port_num;
 			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
-				"Switch %s: set path to CA LID %u through port %u\n",
+				"Switch %s: set path to CA LID %u through port %u, hops %u\n",
 				tuple_to_str(p_remote_sw->tuple),
 				target_lid,
-				p_min_port->remote_port_num);
+				p_min_port->remote_port_num,
+				current_hops + 1);
 
 			/* On the remote switch that is pointed by the p_group,
 			   set hops for ALL the ports in the remote group. */
 
 			set_hops_on_remote_sw(p_group, target_lid,
-					      ((target_rank -
-						highest_rank_in_route) +
-					       (p_remote_sw->rank -
-						highest_rank_in_route) +
-					       reverse_hops * 2),
+					      current_hops + 1 + reverse_hops * 2,
 					      is_target_a_sw);
 		}
 
@@ -2050,13 +2050,13 @@ fabric_route_upgoing_by_going_down(IN ftree_fabric_t * p_ftree,
 		/* Recursion step:
 		   Assign upgoing ports by stepping down, starting on REMOTE switch */
 		created_route |= fabric_route_upgoing_by_going_down(p_ftree, p_remote_sw,	/* remote switch - used as a route-upgoing alg. start point */
-								    NULL,	/* prev. position - NULL to mark that we went down and not up */
+								    p_sw,	/* prev. position */
 								    target_lid,	/* LID that we're routing to */
-								    target_rank,	/* rank of the LID that we're routing to */
 								    is_real_lid,	/* whether the target LID is real or dummy */
 								    is_main_path,	/* whether this is path to HCA that should by tracked by counters */
 								    is_target_a_sw,	/* Wheter target lid is a switch or not */
-								    highest_rank_in_route, reverse_hops);	/* highest visited point in the tree before going down */
+								    reverse_hops,
+								    current_hops + 1);
 	}
 	/* done scanning all the down-going port groups */
 
@@ -2087,12 +2087,12 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 					       IN ftree_sw_t * p_sw,
 					       IN ftree_sw_t * p_prev_sw,
 					       IN uint16_t target_lid,
-					       IN uint8_t target_rank,
 					       IN boolean_t is_real_lid,
 					       IN boolean_t is_main_path,
 					       IN boolean_t is_target_a_sw,
 					       IN uint16_t reverse_hop_credit,
-					       IN uint16_t reverse_hops)
+					       IN uint16_t reverse_hops,
+					       IN uint8_t current_hops)
 {
 	ftree_sw_t *p_remote_sw;
 	uint16_t ports_num;
@@ -2110,12 +2110,11 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 	fabric_route_upgoing_by_going_down(p_ftree, p_sw,	/* local switch - used as a route-upgoing alg. start point */
 					   p_prev_sw,	/* switch that we went up from (NULL means that we went down) */
 					   target_lid,	/* LID that we're routing to */
-					   target_rank,	/* rank of the LID that we're routing to */
 					   is_real_lid,	/* whether this target LID is real or dummy */
 					   is_main_path,	/* whether this path to HCA should by tracked by counters */
 					   is_target_a_sw,	/* Wheter target lid is a switch or not */
-					   p_sw->rank,	/* the highest visited point in the tree before going down */
-					   reverse_hops);	/* Number of reverse_hops done up to this point */
+					   reverse_hops,	/* Number of reverse_hops done up to this point */
+					   current_hops);
 
 	/* recursion stop condition - if it's a root switch, */
 	if (p_sw->rank == 0) {
@@ -2140,12 +2139,12 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 				fabric_route_downgoing_by_going_up(p_ftree, p_remote_sw,	/* remote switch - used as a route-downgoing alg. next step point */
 								   p_sw,	/* this switch - prev. position switch for the function */
 								   target_lid,	/* LID that we're routing to */
-								   target_rank,	/* rank of the LID that we're routing to */
 								   is_real_lid,	/* whether this target LID is real or dummy */
 								   is_main_path,	/* whether this is path to HCA that should by tracked by counters */
 								   is_target_a_sw,	/* Wheter target lid is a switch or not */
 								   reverse_hop_credit - 1,	/* Remaining reverse_hops allowed */
-								   reverse_hops + 1);	/* Number of reverse_hops done up to this point */
+								   reverse_hops + 1,	/* Number of reverse_hops done up to this point */
+								   current_hops + 1);
 			}
 
 		}
@@ -2244,17 +2243,17 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 				    new_lft[target_lid] =
 				    p_min_port->remote_port_num;
 				OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
-					"Switch %s: set path to CA LID %u through port %u\n",
+					"Switch %s: set path to CA LID %u through port %u, hops %u\n",
 					tuple_to_str(p_remote_sw->tuple),
 					target_lid,
-					p_min_port->remote_port_num);
+					p_min_port->remote_port_num, current_hops + 1);
 			}
 			/* On the remote switch that is pointed by the min_group,
 			   set hops for ALL the ports in the remote group. */
 
 			set_hops_on_remote_sw(p_min_group, target_lid,
-					      target_rank - p_remote_sw->rank +
-					      2 * reverse_hops, is_target_a_sw);
+					      current_hops + 1 + 2 * reverse_hops,
+					      is_target_a_sw);
 		}
 
 		/* Recursion step:
@@ -2262,12 +2261,12 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 		fabric_route_downgoing_by_going_up(p_ftree, p_remote_sw,	/* remote switch - used as a route-downgoing alg. next step point */
 						   p_sw,	/* this switch - prev. position switch for the function */
 						   target_lid,	/* LID that we're routing to */
-						   target_rank,	/* rank of the LID that we're routing to */
 						   is_real_lid,	/* whether this target LID is real or dummy */
 						   is_main_path,	/* whether this is path to HCA that should by tracked by counters */
 						   is_target_a_sw,	/* Wheter target lid is a switch or not */
 						   reverse_hop_credit,	/* Remaining reverse_hops allowed */
-						   reverse_hops);	/* Number of reverse_hops done up to this point */
+						   reverse_hops,	/* Number of reverse_hops done up to this point */
+						   current_hops + 1);
 	}
 
 	/* we're done for the third case */
@@ -2335,22 +2334,21 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 
 		/* On the remote switch that is pointed by the p_group,
 		   set hops for ALL the ports in the remote group. */
-
 		set_hops_on_remote_sw(p_group, target_lid,
-				      target_rank - p_remote_sw->rank +
-				      2 * reverse_hops, is_target_a_sw);
+				      current_hops + 1 + 2 * reverse_hops,
+				      is_target_a_sw);
 
 		/* Recursion step:
 		   Assign downgoing ports by stepping up, starting on REMOTE switch. */
 		fabric_route_downgoing_by_going_up(p_ftree, p_remote_sw,	/* remote switch - used as a route-downgoing alg. next step point */
 						   p_sw,	/* this switch - prev. position switch for the function */
 						   target_lid,	/* LID that we're routing to */
-						   target_rank,	/* rank of the LID that we're routing to */
 						   TRUE,	/* whether the target LID is real or dummy */
 						   FALSE,	/* whether this is path to HCA that should by tracked by counters */
 						   is_target_a_sw,	/* Wheter target lid is a switch or not */
 						   reverse_hop_credit,	/* Remaining reverse_hops allowed */
-						   reverse_hops);	/* Number of reverse_hops done up to this point */
+						   reverse_hops,	/* Number of reverse_hops done up to this point */
+						   current_hops + 1);
 	}
 
 	/* If we don't have any reverse hop credits, we are done */
@@ -2374,12 +2372,12 @@ static void fabric_route_downgoing_by_going_up(IN ftree_fabric_t * p_ftree,
 		fabric_route_downgoing_by_going_up(p_ftree, p_remote_sw,	/* remote switch - used as a route-downgoing alg. next step point */
 						   p_sw,	/* this switch - prev. position switch for the function */
 						   target_lid,	/* LID that we're routing to */
-						   target_rank,	/* rank of the LID that we're routing to */
 						   TRUE,	/* whether the target LID is real or dummy */
 						   TRUE,	/* whether this is path to HCA that should by tracked by counters */
 						   is_target_a_sw,	/* Wheter target lid is a switch or not */
 						   reverse_hop_credit - 1,	/* Remaining reverse_hops allowed */
-						   reverse_hops + 1);	/* Number of reverse_hops done up to this point */
+						   reverse_hops + 1,	/* Number of reverse_hops done up to this point */
+						   current_hops + 1);
 	}
 
 }				/* ftree_fabric_route_downgoing_by_going_up() */
@@ -2451,7 +2449,7 @@ static void fabric_route_to_cns(IN ftree_fabric_t * p_ftree)
 			    p_port->port_num;
 
 			OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
-				"Switch %s: set path to CN LID %u through port %u\n",
+				"Switch %s: set path to CN LID %u through port %u, hop 1\n",
 				tuple_to_str(p_sw->tuple),
 				hca_lid, p_port->port_num);
 
@@ -2464,12 +2462,12 @@ static void fabric_route_to_cns(IN ftree_fabric_t * p_ftree)
 			fabric_route_downgoing_by_going_up(p_ftree, p_sw,	/* local switch - used as a route-downgoing alg. start point */
 							   NULL,	/* prev. position switch */
 							   hca_lid,	/* LID that we're routing to */
-							   p_sw->rank + 1,	/* rank of the LID that we're routing to */
 							   TRUE,	/* whether this HCA LID is real or dummy */
 							   TRUE,	/* whether this path to HCA should by tracked by counters */
 							   FALSE,	/* wheter target lid is a switch or not */
 							   0,	/* Number of reverse hops allowed */
-							   0);	/* Number of reverse hops done yet */
+							   0,	/* Number of reverse hops done yet */
+							   1);
 
 			/* count how many real targets have been routed from this leaf switch */
 			routed_targets_on_leaf++;
@@ -2492,12 +2490,12 @@ static void fabric_route_to_cns(IN ftree_fabric_t * p_ftree)
 				fabric_route_downgoing_by_going_up(p_ftree, p_sw,	/* local switch - used as a route-downgoing alg. start point */
 								   NULL,	/* prev. position switch */
 								   0,	/* LID that we're routing to - ignored for dummy HCA */
-								   0,	/* rank of the LID that we're routing to - ignored for dummy HCA */
 								   FALSE,	/* whether this HCA LID is real or dummy */
 								   TRUE,	/* whether this path to HCA should by tracked by counters */
 								   FALSE,	/* Wheter the target LID is a switch or not */
 								   0,	/* Number of reverse hops allowed */
-								   0);	/* Number of reverse hops done yet */
+								   0,	/* Number of reverse hops done yet */
+								   1);
 			}
 		}
 	}
@@ -2579,12 +2577,12 @@ static void fabric_route_to_non_cns(IN ftree_fabric_t * p_ftree)
 			fabric_route_downgoing_by_going_up(p_ftree, p_sw,	/* local switch - used as a route-downgoing alg. start point */
 							   NULL,	/* prev. position switch */
 							   hca_lid,	/* LID that we're routing to */
-							   p_sw->rank + 1,	/* rank of the LID that we're routing to */
 							   TRUE,	/* whether this HCA LID is real or dummy */
 							   TRUE,	/* whether this path to HCA should by tracked by counters */
 							   FALSE,	/* Wheter the target LID is a switch or not */
 							   p_hca_port_group->is_io ? p_ftree->p_osm->subn.opt.max_reverse_hops : 0,	/* Number or reverse hops allowed */
-							   0);	/* Number or reverse hops done yet */
+							   0,	/* Number or reverse hops done yet */
+							   1);
 		}
 		/* done with all the port groups of this HCA - go to next HCA */
 	}
@@ -2632,12 +2630,12 @@ static void fabric_route_to_switches(IN ftree_fabric_t * p_ftree)
 		fabric_route_downgoing_by_going_up(p_ftree, p_sw,	/* local switch - used as a route-downgoing alg. start point */
 						   NULL,	/* prev. position switch */
 						   p_sw->base_lid,	/* LID that we're routing to */
-						   p_sw->rank,	/* rank of the LID that we're routing to */
 						   TRUE,	/* whether the target LID is a real or dummy */
 						   FALSE,	/* whether this path to HCA should by tracked by counters */
 						   TRUE,	/* Wheter the target LID is a switch or not */
 						   0,	/* Number of reverse hops allowed */
-						   0);	/* Number of reverse hops done yet */
+						   0,	/* Number of reverse hops done yet */
+						   0);
 	}
 
 	OSM_LOG_EXIT(&p_ftree->p_osm->log);
@@ -3058,7 +3056,8 @@ static int fabric_construct_sw_ports(IN ftree_fabric_t * p_ftree,
 
 			p_remote_hca_or_sw = (void *)p_remote_sw;
 
-			if (abs(p_sw->rank - p_remote_sw->rank) != 1) {
+			if ((abs(p_sw->rank - p_remote_sw->rank) != 1) &&
+			    (p_sw->rank != p_ftree->max_switch_rank)) {
 				OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_ERROR,
 					"ERR AB16: "
 					"Illegal link between switches with ranks %u and %u:\n"



More information about the general mailing list