[ofa-general] [PATCH] opensm: improve port_prof_ignore handling

Sasha Khapyorsky sashak at voltaire.com
Wed Jul 9 15:23:15 PDT 2008


Instead of keeping special map for switch ports which should be ignored
by the link equalization and searching over there at every routing
iteration it will keep 'is_prof_ignored' flag as member of osm_physp
structure for switch external ports.

The parser now uses already common parse_node_map() framework and read
the file on each heavy sweep to keep ignore ports list up to date.

Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
 opensm/include/opensm/osm_port.h         |    5 ++
 opensm/include/opensm/osm_port_profile.h |  101 ------------------------------
 opensm/include/opensm/osm_subnet.h       |    4 -
 opensm/opensm/main.c                     |   94 ---------------------------
 opensm/opensm/osm_subnet.c               |   17 -----
 opensm/opensm/osm_ucast_mgr.c            |   63 +++++++++++++++++--
 6 files changed, 63 insertions(+), 221 deletions(-)

diff --git a/opensm/include/opensm/osm_port.h b/opensm/include/opensm/osm_port.h
index 3521adc..8fbb28d 100644
--- a/opensm/include/opensm/osm_port.h
+++ b/opensm/include/opensm/osm_port.h
@@ -110,6 +110,7 @@ typedef struct osm_physp {
 	boolean_t healthy;
 	uint8_t vl_high_limit;
 	unsigned need_update;
+	unsigned is_prof_ignored;
 	osm_dr_path_t dr_path;
 	osm_pkey_tbl_t pkeys;
 	ib_vl_arb_table_t vl_arb[4];
@@ -152,6 +153,10 @@ typedef struct osm_physp {
 *		When set indicates that port was probably reset and port
 *		related tables (PKey, SL2VL, VLArb) require refreshing.
 *
+*	is_prof_ignored
+*		When set indicates that switch port will be ignored by
+*		the link load equalization algorithm.
+*
 *	dr_path
 *		The directed route path to this port.
 *
diff --git a/opensm/include/opensm/osm_port_profile.h b/opensm/include/opensm/osm_port_profile.h
index cb95269..9b33e3a 100644
--- a/opensm/include/opensm/osm_port_profile.h
+++ b/opensm/include/opensm/osm_port_profile.h
@@ -204,106 +204,5 @@ osm_port_prof_path_count_get(IN const osm_port_profile_t * const p_prof)
 * SEE ALSO
 *********/
 
-/****f* OpenSM: Port Profile Opt/osm_port_prof_is_ignored_port
-* NAME
-*	osm_port_prof_is_ignored_port
-*
-* DESCRIPTION
-*	Check to see if this port is to be ignored in path counting.
-*  This is done by examining the optional list of port_prof_ignore_guids.
-*
-* SYNOPSIS
-*/
-static inline boolean_t
-osm_port_prof_is_ignored_port(IN const osm_subn_t * p_subn,
-			      IN ib_net64_t node_guid, IN uint8_t port_num)
-{
-	const cl_map_t *p_map = &p_subn->port_prof_ignore_guids;
-	void *p_obj = cl_map_get(p_map, node_guid);
-	long mask, *addr;
-
-	if (p_obj != NULL) {
-		/* Test bit corresponding to port_num */
-		addr = p_obj;
-		addr += port_num / (8 * sizeof(long));
-		mask = 1L << (port_num % (8 * sizeof(long)));
-		return ((mask & *addr) != 0);
-	}
-	return FALSE;
-}
-/*
-* PARAMETERS
-*	p_subn
-*		[in] Pointer to the OSM Subnet object.
-*
-*	node_guid
-*		[in] The node guid
-*
-* RETURN VALUE
-*	Returns TRUE if ignore port mask for requested port number is set.
-*	FALSE otherwise;
-*
-* NOTES
-*
-* SEE ALSO
-*********/
-
-/****f* OpenSM: Port Profile Opt/osm_port_prof_set_ignored_port
-* NAME
-*	osm_port_prof_set_ignored_port
-*
-* DESCRIPTION
-*	Set the ignored property of a port.
-*
-* SYNOPSIS
-*/
-static inline boolean_t
-osm_port_prof_set_ignored_port(IN osm_subn_t * p_subn,
-			       IN ib_net64_t node_guid, IN uint8_t port_num)
-{
-	cl_map_t *p_map = &p_subn->port_prof_ignore_guids;
-	void *p_obj = cl_map_get(p_map, node_guid);
-	long mask, *addr;
-	int insert = 0;
-
-	if (!p_obj) {
-		p_obj = malloc(sizeof(osm_port_mask_t));
-		if (!p_obj)
-			return FALSE;
-		memset(p_obj, 0, sizeof(osm_port_mask_t));
-		insert = 1;
-	}
-
-	/* Set bit corresponding to port_num */
-	addr = p_obj;
-	addr += port_num / (8 * sizeof(long));
-	mask = 1L << (port_num % (8 * sizeof(long)));
-	*addr |= mask;
-
-	if (insert) {
-		if (!cl_map_insert(p_map, node_guid, p_obj)) {
-			free(p_obj);
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-/*
-* PARAMETERS
-*	p_subn
-*		[in] Pointer to the OSM Subnet object.
-*
-*	node_guid
-*		[in] The node guid
-*
-* RETURN VALUE
-*	Returns TRUE if the ignore port mask was properly updated.
-*       FALSE otherwise.
-*
-* NOTES
-*
-* SEE ALSO
-*********/
-
 END_C_DECLS
 #endif				/* _OSM_PORT_PROFILE_H_ */
diff --git a/opensm/include/opensm/osm_subnet.h b/opensm/include/opensm/osm_subnet.h
index 44f5d55..289684b 100644
--- a/opensm/include/opensm/osm_subnet.h
+++ b/opensm/include/opensm/osm_subnet.h
@@ -477,7 +477,6 @@ typedef struct osm_subn {
 	cl_qlist_t sa_sr_list;
 	cl_qlist_t sa_infr_list;
 	cl_ptr_vector_t port_lid_tbl;
-	cl_map_t port_prof_ignore_guids;
 	ib_net16_t master_sm_base_lid;
 	ib_net16_t sm_base_lid;
 	ib_net64_t sm_port_guid;
@@ -532,9 +531,6 @@ typedef struct osm_subn {
 *		Container of pointers to all Port objects in the subent.
 *		Indexed by port LID.
 *
-*	port_prof_ignore_guids
-*		A map of guids to be ignored by port profiling.
-*
 *	master_sm_base_lid
 *		The base LID owned by the subnet's master SM.
 *
diff --git a/opensm/opensm/main.c b/opensm/opensm/main.c
index 0490227..8edce33 100644
--- a/opensm/opensm/main.c
+++ b/opensm/opensm/main.c
@@ -455,88 +455,6 @@ static ib_net64_t get_port_guid(IN osm_opensm_t * p_osm, uint64_t port_guid)
 
 /**********************************************************************
  **********************************************************************/
-#define OSM_MAX_IGNORE_GUID_LINES_LEN 128
-
-static int
-parse_ignore_guids_file(IN char *guids_file_name, IN osm_opensm_t * p_osm)
-{
-	FILE *fh;
-	char line[OSM_MAX_IGNORE_GUID_LINES_LEN];
-	char *p_c, *p_ec;
-	uint32_t line_num = 0;
-	uint64_t node_guid;
-	ib_api_status_t status = IB_SUCCESS;
-	unsigned int port_num;
-
-	OSM_LOG_ENTER(&p_osm->log);
-
-	fh = fopen(guids_file_name, "r");
-	if (fh == NULL) {
-		OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 0601: "
-			"Unable to open ignore guids file (%s)\n",
-			guids_file_name);
-		status = IB_ERROR;
-		goto Exit;
-	}
-
-	/*
-	 * Parse the file and add to the ignore guids map.
-	 */
-	while (fgets(line, OSM_MAX_IGNORE_GUID_LINES_LEN, fh) != NULL) {
-		line_num++;
-		p_c = line;
-		while ((*p_c == ' ') && (*p_c != '\0'))
-			p_c++;
-		node_guid = strtoull(p_c, &p_ec, 16);
-		if (p_ec == p_c) {
-			OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 0602: "
-				"Error in line (%u): %s\n", line_num, line);
-			status = IB_ERROR;
-			goto Exit;
-		}
-
-		while ((*p_ec == ' ') && (*p_ec != '\0'))
-			p_ec++;
-		if (!sscanf(p_ec, "%d", &port_num)) {
-			OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 0603: "
-				"Error in line (%u): %s\n", line_num, p_ec);
-			status = IB_ERROR;
-			goto Exit;
-		}
-
-		if (port_num > IB_NODE_NUM_PORTS_MAX) {
-			OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 0604: "
-				"Invalid PortNum: 0x%X for Node: 0x%"
-				PRIx64 "\n", port_num, node_guid);
-			status = IB_ERROR;
-			goto Exit;
-		}
-
-		/* ok insert it */
-		if (!osm_port_prof_set_ignored_port(&p_osm->subn,
-						    cl_hton64(node_guid),
-						    port_num))
-			OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 0605: "
-				"osm_port_prof_set_ignored_port failed for "
-				"Node: 0x%" PRIx64 " PortNum: 0x%X\n",
-				node_guid, port_num);
-		else
-			OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
-				"Inserted Node: 0x%" PRIx64
-				" PortNum: 0x%X into ignored guids list\n",
-				node_guid, port_num);
-
-	}
-
-	fclose(fh);
-
-Exit:
-	OSM_LOG_EXIT(&p_osm->log);
-	return (status);
-}
-
-/**********************************************************************
- **********************************************************************/
 
 static int daemonize(osm_opensm_t * osm)
 {
@@ -1075,18 +993,6 @@ int main(int argc, char *argv[])
 		goto Exit;
 	}
 
-	/*
-	 * Define some port guids to ignore during path equalization
-	 */
-	if (opt.port_prof_ignore_file != NULL) {
-		status = parse_ignore_guids_file(opt.port_prof_ignore_file, &osm);
-		if (status != IB_SUCCESS) {
-			printf("\nError from parse_ignore_guids_file (0x%X)\n",
-			       status);
-			goto Exit;
-		}
-	}
-
 	setup_signals();
 
 	osm_opensm_sweep(&osm);
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index 6a818d4..19351d1 100644
--- a/opensm/opensm/osm_subnet.c
+++ b/opensm/opensm/osm_subnet.c
@@ -100,8 +100,6 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
 	osm_prtn_t *p_prtn, *p_next_prtn;
 	osm_mgrp_t *p_mgrp;
 	osm_infr_t *p_infr, *p_next_infr;
-	cl_map_iterator_t pmask_iter, next_pmask_iter;
-	osm_port_mask_t *p_port_mask;
 
 	/* it might be a good idea to de-allocate all known objects */
 	p_next_node = (osm_node_t *) cl_qmap_head(&p_subn->node_guid_tbl);
@@ -161,17 +159,6 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
 
 	cl_ptr_vector_destroy(&p_subn->port_lid_tbl);
 
-	next_pmask_iter = cl_map_head(&p_subn->port_prof_ignore_guids);
-	while (next_pmask_iter != cl_map_end(&p_subn->port_prof_ignore_guids)) {
-		pmask_iter = next_pmask_iter;
-		next_pmask_iter = cl_map_next(next_pmask_iter);
-		p_port_mask = cl_map_obj(pmask_iter);
-		cl_map_remove_item(&p_subn->port_prof_ignore_guids, pmask_iter);
-		free(p_port_mask);
-	}
-
-	cl_map_destroy(&p_subn->port_prof_ignore_guids);
-
 	osm_qos_policy_destroy(p_subn->p_qos_policy);
 
 	while (!cl_is_qlist_empty(&p_subn->prefix_routes_list)) {
@@ -213,10 +200,6 @@ osm_subn_init(IN osm_subn_t * const p_subn,
 	p_subn->max_mcast_lid_ho = IB_LID_MCAST_END_HO;
 	p_subn->min_ca_mtu = IB_MAX_MTU;
 	p_subn->min_ca_rate = IB_MAX_RATE;
-
-	/* note that insert and remove are part of the port_profile thing */
-	cl_map_init(&p_subn->port_prof_ignore_guids, 10);
-
 	p_subn->ignore_existing_lfts = TRUE;
 
 	/* we assume master by default - so we only need to set it true if STANDBY */
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index 9f54486..82d1f4b 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -285,6 +285,8 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 				"No path to get to LID %u from switch 0x%"
 				PRIx64 "\n", lid_ho, cl_ntoh64(node_guid));
 	} else {
+		osm_physp_t *p = osm_node_get_physp_ptr(p_sw->p_node, port);
+
 		OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
 			"Routing LID %u to port 0x%X"
 			" for switch 0x%" PRIx64 "\n",
@@ -294,9 +296,7 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
 		   we would like to optionally ignore this port in equalization
 		   as in the case of the Mellanox Anafa Internal PCI TCA port
 		 */
-		is_ignored_by_port_prof =
-		    osm_port_prof_is_ignored_port(p_mgr->p_subn,
-						  node_guid, port);
+		is_ignored_by_port_prof = p->is_prof_ignored;
 
 		/*
 		   We also would ignore this route if the target lid is of
@@ -722,22 +722,75 @@ static void add_port_to_order_list(cl_map_item_t * const p_map_item, void *ctx)
 		port->flag = 0;
 }
 
+static int mark_ignored_port(void *ctx, uint64_t guid, char *p)
+{
+	osm_ucast_mgr_t *m = ctx;
+	osm_node_t *node = osm_get_node_by_guid(m->p_subn, cl_hton64(guid));
+	osm_physp_t *physp;
+	unsigned port;
+
+	if (!node || !node->sw) {
+		OSM_LOG(m->p_log, OSM_LOG_DEBUG,
+			"switch with guid 0x%016" PRIx64 " is not found\n",
+			guid);
+		return 0;
+	}
+
+	if (!p || !*p || !(port = strtoul(p, NULL, 0)) ||
+	    port >= node->sw->num_ports) {
+		OSM_LOG(m->p_log, OSM_LOG_DEBUG,
+			"bad port specified for guid 0x%016" PRIx64 "\n", guid);
+		return 0;
+	}
+
+	physp = osm_node_get_physp_ptr(node, port);
+	if (!physp)
+		return 0;
+
+	physp->is_prof_ignored = 1;
+
+	return 0;
+}
+
+static void clear_prof_ignore_flag(cl_map_item_t * const p_map_item, void *ctx)
+{
+	osm_switch_t *sw = (osm_switch_t *)p_map_item;
+	int i;
+
+	for (i = 1; i < sw->num_ports; i++) {
+		osm_physp_t *p = osm_node_get_physp_ptr(sw->p_node, i);
+		if (p)
+			p->is_prof_ignored = 0;
+	}
+}
+
 static void ucast_mgr_build_lfts(osm_ucast_mgr_t *p_mgr)
 {
 	cl_qlist_init(&p_mgr->port_order_list);
 
 	if (p_mgr->p_subn->opt.guid_routing_order_file) {
 		OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
-			"Fetching guid routing order file %s\n",
+			"Fetching guid routing order file \'%s\'\n",
 			p_mgr->p_subn->opt.guid_routing_order_file);
 
 		if (parse_node_map(p_mgr->p_subn->opt.guid_routing_order_file,
 				   add_guid_to_order_list, p_mgr))
 			OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR : "
-				"cannot parse guid routing order file %s\n",
+				"cannot parse guid routing order file \'%s\'\n",
 				p_mgr->p_subn->opt.guid_routing_order_file);
 	}
 
+	if (p_mgr->p_subn->opt.port_prof_ignore_file) {
+		cl_qmap_apply_func(&p_mgr->p_subn->sw_guid_tbl,
+				   clear_prof_ignore_flag, NULL);
+		if (parse_node_map(p_mgr->p_subn->opt.port_prof_ignore_file,
+				   mark_ignored_port, p_mgr)) {
+			OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR : "
+				"cannot parse port prof ignore file \'%s\'\n",
+				p_mgr->p_subn->opt.port_prof_ignore_file);
+		}
+	}
+
 	cl_qmap_apply_func(&p_mgr->p_subn->port_guid_tbl,
 			   add_port_to_order_list, p_mgr);
 
-- 
1.5.5.1.178.g1f811




More information about the general mailing list