[ofa-general] [PATCH] opensm: move remote guids counting to ucast_mgr

Sasha Khapyorsky sashak at voltaire.com
Mon Jun 9 19:56:21 PDT 2008


This is pretty mechanical change - move remote sys/node guids
preallocation and counting (used when for lmc > 0 balancing) to
ucast_mgr. It is needed for future "preserve base lid routing"  change.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 opensm/include/opensm/osm_port.h   |    1 +
 opensm/include/opensm/osm_switch.h |   45 ++++++----------
 opensm/opensm/osm_dump.c           |    3 +-
 opensm/opensm/osm_switch.c         |  101 ++++++++----------------------------
 opensm/opensm/osm_ucast_mgr.c      |   99 ++++++++++++++++++++++++++---------
 5 files changed, 114 insertions(+), 135 deletions(-)

diff --git a/opensm/include/opensm/osm_port.h b/opensm/include/opensm/osm_port.h
index 3d501d8..c1cbd39 100644
--- a/opensm/include/opensm/osm_port.h
+++ b/opensm/include/opensm/osm_port.h
@@ -1149,6 +1149,7 @@ typedef struct _osm_port {
 	unsigned is_new;
 	osm_physp_t *p_physp;
 	cl_qlist_t mcm_list;
+	void *priv;
 } osm_port_t;
 /*
 * FIELDS
diff --git a/opensm/include/opensm/osm_switch.h b/opensm/include/opensm/osm_switch.h
index f5455af..0e9c5fa 100644
--- a/opensm/include/opensm/osm_switch.h
+++ b/opensm/include/opensm/osm_switch.h
@@ -153,31 +153,33 @@ typedef struct _osm_switch {
 *	Switch object
 *********/
 
-/****s* OpenSM: Switch/osm_switch_guid_count_t
+/****s* OpenSM: Switch/struct osm_remote_guids_count
 * NAME
-*	osm_switch_guid_count_t
+*	struct osm_remote_guids_count
 *
 * DESCRIPTION
-*	Stores system and node guids and the number of
+*	Stores array of pointers to remote node and the numbers of
 *	times a switch has forwarded to it.
 *
 * SYNOPSIS
 */
-typedef struct _osm_switch_guid_count {
-	uint64_t sys_guid;
-	uint64_t node_guid;
-	unsigned int forwarded_to;
-} osm_switch_guid_count_t;
+struct osm_remote_guids_count {
+	unsigned count;
+	struct osm_remote_node {
+		osm_node_t *node;
+		unsigned forwarded_to;
+	} guids[0];
+};
 /*
 * FIELDS
-*	sys_guid
-*		A system guid.
+*	count
+*		A number of used entries in array.
 *
-*	node_guid
-*		A node guid.
+*	node
+*		A pointer to node.
 *
 *	forwarded_to
-*		A count of lids forwarded to the sys_guid/node_guid.
+*		A count of lids forwarded to this node.
 *********/
 
 /****f* OpenSM: Switch/osm_switch_delete
@@ -980,10 +982,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 			  IN osm_port_t * p_port,
 			  IN const uint16_t lid_ho,
 			  IN const boolean_t ignore_existing,
-			  IN const boolean_t dor,
-			  IN OUT osm_switch_guid_count_t * remote_guids,
-			  IN OUT uint16_t * p_num_remote_guids,
-			  IN OUT osm_switch_guid_count_t ** p_remote_guid_count_used);
+			  IN const boolean_t dor);
 /*
 * PARAMETERS
 *	p_sw
@@ -1005,18 +1004,6 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 *	dor
 *		[in] If TRUE, Dimension Order Routing will be done.
 *
-*	remote_guids
-*		[in out] The array of remote guids already used to route
-*		the other lids of the same target port (if LMC > 0)
-*
-*	p_num_remote_guids
-*		[in out] The number of remote guids used for routing to
-*		the port.
-*
-*	p_remote_guid_count_used
-*		[in out] The specific osm_switch_guid_count_t used
-*		in switch recommendations.
-*
 * RETURN VALUE
 *	Returns the recommended port on which to route this LID.
 *
diff --git a/opensm/opensm/osm_dump.c b/opensm/opensm/osm_dump.c
index 2bac75a..b96984b 100644
--- a/opensm/opensm/osm_dump.c
+++ b/opensm/opensm/osm_dump.c
@@ -218,8 +218,7 @@ static void dump_ucast_routes(cl_map_item_t *p_map_item, FILE *file, void *cxt)
 		else {
 			/* No LMC Optimization */
 			best_port = osm_switch_recommend_path(p_sw, p_port,
-							      lid_ho, TRUE, dor,
-							      NULL, NULL, NULL);
+							      lid_ho, TRUE, dor);
 			fprintf(file, "No %u hop path possible via port %u!",
 				best_hops, best_port);
 		}
diff --git a/opensm/opensm/osm_switch.c b/opensm/opensm/osm_switch.c
index fdcd109..58936e3 100644
--- a/opensm/opensm/osm_switch.c
+++ b/opensm/opensm/osm_switch.c
@@ -214,15 +214,14 @@ osm_switch_get_fwd_tbl_block(IN const osm_switch_t * const p_sw,
 
 /**********************************************************************
  **********************************************************************/
-static osm_switch_guid_count_t *
+static struct osm_remote_node *
 osm_switch_find_guid_common(IN const osm_switch_t * const p_sw,
-			    IN osm_switch_guid_count_t * remote_guids,
-			    IN uint16_t * p_num_remote_guids,
+			    IN struct osm_remote_guids_count *r,
 			    IN uint8_t port_num,
 			    IN int find_sys_guid,
 			    IN int find_node_guid)
 {
-	osm_switch_guid_count_t *p_remote_guid = NULL;
+	struct osm_remote_node *p_remote_guid = NULL;
 	osm_physp_t *p_physp;
 	osm_physp_t *p_rem_physp;
 	osm_node_t *p_rem_node;
@@ -240,12 +239,12 @@ osm_switch_find_guid_common(IN const osm_switch_t * const p_sw,
 	sys_guid = p_rem_node->node_info.sys_guid;
 	node_guid = p_rem_node->node_info.node_guid;
 
-	for (i = 0; i < *p_num_remote_guids; i++) {
+	for (i = 0; i < r->count; i++) {
 		if ((!find_sys_guid
-		     || remote_guids[i].sys_guid == sys_guid)
+		     || r->guids[i].node->node_info.sys_guid == sys_guid)
 		    && (!find_node_guid
-			|| remote_guids[i].node_guid == node_guid)) {
-			p_remote_guid = &remote_guids[i];
+			|| r->guids[i].node->node_info.node_guid == node_guid)) {
+			p_remote_guid = &r->guids[i];
 			break;
 		}
 	}
@@ -253,49 +252,22 @@ osm_switch_find_guid_common(IN const osm_switch_t * const p_sw,
 	return p_remote_guid;
 }
 
-static osm_switch_guid_count_t *
+static struct osm_remote_node *
 osm_switch_find_sys_guid_count(IN const osm_switch_t * const p_sw,
-			       IN osm_switch_guid_count_t * remote_guids,
-			       IN uint16_t * p_num_remote_guids,
+			       IN struct osm_remote_guids_count *r,
 			       IN uint8_t port_num)
 {
-	return osm_switch_find_guid_common(p_sw,
-					   remote_guids,
-					   p_num_remote_guids,
-					   port_num,
-					   1,
-					   0);
+	return osm_switch_find_guid_common(p_sw, r, port_num, 1, 0);
 }
 
-static osm_switch_guid_count_t *
+static struct osm_remote_node *
 osm_switch_find_node_guid_count(IN const osm_switch_t * const p_sw,
-				IN osm_switch_guid_count_t * remote_guids,
-				IN uint16_t * p_num_remote_guids,
+				IN struct osm_remote_guids_count *r,
 				IN uint8_t port_num)
 {
-	return osm_switch_find_guid_common(p_sw,
-					   remote_guids,
-					   p_num_remote_guids,
-					   port_num,
-					   0,
-					   1);
+	return osm_switch_find_guid_common(p_sw, r, port_num, 0, 1);
 }
 
-static osm_switch_guid_count_t *
-osm_switch_find_guid_count(IN const osm_switch_t * const p_sw,
-			   IN osm_switch_guid_count_t * remote_guids,
-			   IN uint16_t * p_num_remote_guids,
-			   IN uint8_t port_num)
-{
-	return osm_switch_find_guid_common(p_sw,
-					   remote_guids,
-					   p_num_remote_guids,
-					   port_num,
-					   1,
-					   1);
-}
-
-
 /**********************************************************************
  **********************************************************************/
 uint8_t
@@ -303,10 +275,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 			  IN osm_port_t * p_port,
 			  IN const uint16_t lid_ho,
 			  IN const boolean_t ignore_existing,
-			  IN const boolean_t dor,
-			  IN OUT osm_switch_guid_count_t * remote_guids,
-			  IN OUT uint16_t * p_num_remote_guids,
-			  IN OUT osm_switch_guid_count_t ** p_remote_guid_count_used)
+			  IN const boolean_t dor)
 {
 	/*
 	   We support an enhanced LMC aware routing mode:
@@ -318,8 +287,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 	   If this procedure is provided with the tracking array
 	   and counter we can conduct this algorithm.
 	 */
-	boolean_t routing_for_lmc = remote_guids && p_num_remote_guids
-		&& p_remote_guid_count_used;
+	boolean_t routing_for_lmc = (p_port->priv != NULL);
 	uint16_t base_lid;
 	uint8_t hops;
 	uint8_t least_hops;
@@ -346,7 +314,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 	osm_physp_t *p_rem_physp;
 	osm_node_t *p_rem_node;
 	osm_node_t *p_rem_node_first = NULL;
-	osm_switch_guid_count_t *p_remote_guid = NULL;
+	struct osm_remote_node *p_remote_guid = NULL;
 
 	CL_ASSERT(lid_ho > 0);
 
@@ -461,8 +429,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 		if (routing_for_lmc) {
 			/* Is the sys guid already used ? */
 			p_remote_guid = osm_switch_find_sys_guid_count(p_sw,
-								       remote_guids,
-								       p_num_remote_guids,
+								       p_port->priv,
 								       port_num);
 
 			/* If not update the least hops for this case */
@@ -475,8 +442,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 			} else {	/* same sys found - try node */
 				/* Else is the node guid already used ? */
 				p_remote_guid = osm_switch_find_node_guid_count(p_sw,
-										remote_guids,
-										p_num_remote_guids,
+										p_port->priv,
 										port_num);
 
 				/* If not update the least hops for this case */
@@ -517,11 +483,10 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 			    && p_remote_guid
 			    && p_remote_guid->forwarded_to < least_forwarded_to)
 				least_forwarded_to = p_remote_guid->forwarded_to;
-		}
-		else if (routing_for_lmc
-			 && p_remote_guid
-			 && check_count == least_paths
-			 && p_remote_guid->forwarded_to < least_forwarded_to) {
+		} else if (routing_for_lmc
+			   && p_remote_guid
+			   && check_count == least_paths
+			   && p_remote_guid->forwarded_to < least_forwarded_to) {
 			least_forwarded_to = p_remote_guid->forwarded_to;
 			best_port = port_num;
 		}
@@ -540,28 +505,6 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
 			best_port = best_port_other_sys;
 		else if (best_port_other_node)
 			best_port = best_port_other_node;
-
-		/* track the remote node and system of the port used. */
-		p_remote_guid = osm_switch_find_guid_count(p_sw,
-							   remote_guids,
-							   p_num_remote_guids,
-							   best_port);
-
-		if (!p_remote_guid) {
-			/* track the remote node and system of the port used. */
-			p_physp = osm_node_get_physp_ptr(p_sw->p_node, best_port);
-			p_rem_physp = osm_physp_get_remote(p_physp);
-			p_rem_node = osm_physp_get_node_ptr(p_rem_physp);
-			memcpy(&(remote_guids[*p_num_remote_guids].sys_guid),
-			       &(p_rem_node->node_info.sys_guid),
-			       sizeof(uint64_t));
-			memcpy(&(remote_guids[*p_num_remote_guids].node_guid),
-				       &(p_rem_node->node_info.node_guid),
-			       sizeof(uint64_t));
-			remote_guids[*p_num_remote_guids].forwarded_to = 0;
-			(*p_num_remote_guids)++;
-		}
-		*p_remote_guid_count_used = p_remote_guid;
 	}
 
 	return (best_port);
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index 5923638..c073037 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -187,6 +187,24 @@ __osm_ucast_mgr_process_neighbor(IN osm_ucast_mgr_t * const p_mgr,
 
 /**********************************************************************
  **********************************************************************/
+static struct osm_remote_node *
+find_and_add_remote_sys(osm_switch_t *sw, uint8_t port,
+			struct osm_remote_guids_count *r)
+{
+	unsigned i;
+	osm_physp_t *p = osm_node_get_physp_ptr(sw->p_node, port);
+	osm_node_t *node = p->p_remote_physp->p_node;
+
+	for (i = 0; i < r->count; i++)
+		if (r->guids[i].node == node)
+			return &r->guids[i];
+
+	r->guids[i].node = node;
+	r->guids[i].forwarded_to = 0;
+	r->count++;
+	return &r->guids[i];
+}
+
 static void
 __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 			     IN osm_switch_t * const p_sw,
@@ -204,23 +222,10 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 	   in providing better routing in LMC > 0 situations
 	 */
 	uint16_t lids_per_port = 1 << p_mgr->p_subn->opt.lmc;
-	osm_switch_guid_count_t *remote_guids = NULL;
-	uint16_t num_used_guids = 0;
-	osm_switch_guid_count_t *p_remote_guid_used = NULL;
+	struct osm_remote_node *p_remote_guid_used = NULL;
 
 	OSM_LOG_ENTER(p_mgr->p_log);
 
-	if (lids_per_port > 1) {
-		remote_guids = malloc(sizeof(osm_switch_guid_count_t) * lids_per_port);
-		if (remote_guids == NULL) {
-			osm_log(p_mgr->p_log, OSM_LOG_ERROR,
-				"__osm_ucast_mgr_process_port: ERR 3A09: "
-				"Cannot allocate array. Insufficient memory\n");
-			goto Exit;
-		}
-		memset(remote_guids, 0, sizeof(osm_switch_guid_count_t) * lids_per_port);
-	}
-
 	osm_port_get_lid_range_ho(p_port, &min_lid_ho, &max_lid_ho);
 
 	/* If the lids are zero - then there was some problem with the initialization.
@@ -258,21 +263,19 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 	for (lid_ho = min_lid_ho; lid_ho <= max_lid_ho; lid_ho++) {
 		/* Use the enhanced algorithm only for LMC > 0 */
 		if (lids_per_port > 1) {
-			p_remote_guid_used = NULL;
 			port = osm_switch_recommend_path(p_sw, p_port, lid_ho,
 							 p_mgr->p_subn->
 							 ignore_existing_lfts,
-							 p_mgr->is_dor,
-							 remote_guids,
-							 &num_used_guids,
-							 &p_remote_guid_used);
-		}
-		else
+							 p_mgr->is_dor);
+			if (port > 0 && port != OSM_NO_PATH && p_port->priv)
+				p_remote_guid_used =
+				    find_and_add_remote_sys(p_sw, port,
+							    p_port->priv);
+		} else
 			port = osm_switch_recommend_path(p_sw, p_port, lid_ho,
 							 p_mgr->p_subn->
 							 ignore_existing_lfts,
-							 p_mgr->is_dor,
-							 NULL, NULL, NULL);
+							 p_mgr->is_dor);
 
 		/*
 		   There might be no path to the target
@@ -334,8 +337,6 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 	}
 
 Exit:
-	if (remote_guids)
-		free(remote_guids);
 	OSM_LOG_EXIT(p_mgr->p_log);
 }
 
@@ -460,6 +461,48 @@ osm_ucast_mgr_set_fwd_table(IN osm_ucast_mgr_t * const p_mgr,
 
 /**********************************************************************
  **********************************************************************/
+static void alloc_ports_priv(osm_ucast_mgr_t *mgr)
+{
+	cl_qmap_t *port_tbl = &mgr->p_subn->port_guid_tbl;
+	struct osm_remote_guids_count *r;
+	osm_port_t *port;
+	cl_map_item_t *item;
+	unsigned lmc;
+
+	for (item = cl_qmap_head(port_tbl); item != cl_qmap_end(port_tbl);
+	     item = cl_qmap_next(item)) {
+		port = (osm_port_t *)item;
+		lmc = ib_port_info_get_lmc(&port->p_physp->port_info);
+		if (!lmc)
+			continue;
+		r = malloc(sizeof(*r) + sizeof(r->guids[0]) * (1 << lmc));
+		if (!r) {
+			OSM_LOG(mgr->p_log, OSM_LOG_ERROR, "ERR 3A09: "
+				"cannot allocate memory to track remote"
+				" systems for lmc > 0\n");
+			port->priv = NULL;
+			continue;
+		}
+		memset(r, 0, sizeof(*r) + sizeof(r->guids[0]) * (1 << lmc));
+		port->priv = r;
+	}
+}
+
+static void free_ports_priv(osm_ucast_mgr_t *mgr)
+{
+	cl_qmap_t *port_tbl = &mgr->p_subn->port_guid_tbl;
+	osm_port_t *port;
+	cl_map_item_t *item;
+	for (item = cl_qmap_head(port_tbl); item != cl_qmap_end(port_tbl);
+	     item = cl_qmap_next(item)) {
+		port = (osm_port_t *)item;
+		if (port->priv) {
+			free(port->priv);
+			port->priv = NULL;
+		}
+	}
+}
+
 static void
 __osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
 			    IN void *context)
@@ -488,6 +531,9 @@ __osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
 
 	p_port_tbl = &p_mgr->p_subn->port_guid_tbl;
 
+	if (p_mgr->p_subn->opt.lmc)
+		alloc_ports_priv(p_mgr);
+
 	/*
 	   Iterate through every port setting LID routes for each
 	   port based on base LID and LMC value.
@@ -501,6 +547,9 @@ __osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
 
 	osm_ucast_mgr_set_fwd_table(p_mgr, p_sw);
 
+	if (p_mgr->p_subn->opt.lmc)
+		free_ports_priv(p_mgr);
+
 	OSM_LOG_EXIT(p_mgr->p_log);
 }
 
-- 
1.5.5.1.178.g1f811




More information about the general mailing list