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 <[EMAIL PROTECTED]>

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);


_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to