[ofa-general] [PATCH] opensm/osm_port_profile: Handle all possible ports

Hal Rosenstock hrosenstock at xsigo.com
Fri Jun 27 10:48:58 PDT 2008


opensm/osm_port_profile: Handle all possible ports rather than
artificial 32 port limit

Also, improve error handling when dealing with "ignore guids" file

Signed-off-by: Hal Rosenstock <hal at xsigo.com>

diff --git a/opensm/include/opensm/osm_port_profile.h b/opensm/include/opensm/osm_port_profile.h
index 42a6561..c7c969c 100644
--- a/opensm/include/opensm/osm_port_profile.h
+++ b/opensm/include/opensm/osm_port_profile.h
@@ -2,6 +2,7 @@
  * Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -100,6 +101,26 @@ typedef struct osm_port_profile {
 * SEE ALSO
 *********/
 
+/****s* OpenSM: Switch/osm_port_mask_t
+* NAME
+*	osm_port_mask_t
+*
+* DESCRIPTION
+*       The Port Mask object contains a port numbered bit mask
+*	for whether the port should be ignored by the link load
+*	equalization algorithm.
+*
+* SYNOPSIS
+*/
+typedef long osm_port_mask_t[32 / sizeof(long)];
+/*
+* FIELDS
+*	osm_port_mask_t
+*		Bit mask by port number
+*
+* SEE ALSO
+*********/
+
 /****f* OpenSM: Port Profile/osm_port_prof_construct
 * NAME
 *	osm_port_prof_construct
@@ -198,13 +219,15 @@ 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;
-	const void *p_obj = cl_map_get(p_map, node_guid);
-	size_t res;
+	void *p_obj = cl_map_get(p_map, node_guid);
+	long mask, *addr;
 
-	// HACK: we currently support ignoring ports 0 - 31
 	if (p_obj != NULL) {
-		res = (size_t) p_obj & (size_t) (1 << port_num);
-		return (res != 0);
+		/* 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;
 }
@@ -217,7 +240,8 @@ osm_port_prof_is_ignored_port(IN const osm_subn_t * p_subn,
 *		[in] The node guid
 *
 * RETURN VALUE
-*	None.
+*	Returns TRUE if ignore port mask for requested port number is set.
+*	FALSE otherwise;
 *
 * NOTES
 *
@@ -233,24 +257,36 @@ osm_port_prof_is_ignored_port(IN const osm_subn_t * p_subn,
 *
 * SYNOPSIS
 */
-static inline void
+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;
-	const void *p_obj = cl_map_get(p_map, node_guid);
-	size_t value = 0;
-
-	// HACK: we currently support ignoring ports 0 - 31
-	CL_ASSERT(port_num < 32);
+	void *p_obj = cl_map_get(p_map, node_guid);
+	long mask, *addr;
+	int insert = 0;
 
-	if (p_obj != NULL) {
-		value = (size_t) p_obj;
-		cl_map_remove(p_map, node_guid);
+	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;
 	}
 
-	value = value | (1 << port_num);
-	cl_map_insert(p_map, node_guid, (void *)value);
+	/* 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
@@ -261,7 +297,8 @@ osm_port_prof_set_ignored_port(IN osm_subn_t * p_subn,
 *		[in] The node guid
 *
 * RETURN VALUE
-*	None.
+*	Returns TRUE if the ignore port mask was properly updated.
+*       FALSE otherwise.
 *
 * NOTES
 *
diff --git a/opensm/opensm/main.c b/opensm/opensm/main.c
index 7c7525b..0490227 100644
--- a/opensm/opensm/main.c
+++ b/opensm/opensm/main.c
@@ -504,13 +504,27 @@ parse_ignore_guids_file(IN char *guids_file_name, IN osm_opensm_t * p_osm)
 			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 */
-		osm_port_prof_set_ignored_port(&p_osm->subn,
-					       cl_hton64(node_guid), port_num);
-		OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
-			"Inserted Node: 0x%" PRIx64
-			" PortNum: 0x%X into ignored guids list\n", node_guid,
-			port_num);
+		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);
 
 	}
 
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index 73b476f..756495c 100644
--- a/opensm/opensm/osm_subnet.c
+++ b/opensm/opensm/osm_subnet.c
@@ -100,6 +100,8 @@ 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);
@@ -159,7 +161,15 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
 
 	cl_ptr_vector_destroy(&p_subn->port_lid_tbl);
 
-	cl_map_remove_all(&p_subn->port_prof_ignore_guids);
+	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);





More information about the general mailing list