DOR routing equilizes traffic across redundant links representing
dimensions.  This change makes DOR compatible with LMC and tries to
equilize traffic across redundant links between LMC aliased LIDs.

Signed-off-by: Dale Purdy <[email protected]>
---
 opensm/include/opensm/osm_switch.h |    4 +++
 opensm/opensm/osm_switch.c         |   42 +++++++++++++++++++++++------------
 opensm/opensm/osm_ucast_mgr.c      |    8 +++++-
 3 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/opensm/include/opensm/osm_switch.h 
b/opensm/include/opensm/osm_switch.h
index 0b15e63..7ce28c5 100644
--- a/opensm/include/opensm/osm_switch.h
+++ b/opensm/include/opensm/osm_switch.h
@@ -167,6 +167,7 @@ struct osm_remote_guids_count {
        struct osm_remote_node {
                osm_node_t *node;
                unsigned forwarded_to;
+               uint8_t port;
        } guids[0];
 };
 /*
@@ -179,6 +180,9 @@ struct osm_remote_guids_count {
 *
 *      forwarded_to
 *              A count of lids forwarded to this node.
+*
+*      port
+*              Port number on the node.
 *********/
 
 /****f* OpenSM: Switch/osm_switch_delete
diff --git a/opensm/opensm/osm_switch.c b/opensm/opensm/osm_switch.c
index 6dde47c..d236329 100644
--- a/opensm/opensm/osm_switch.c
+++ b/opensm/opensm/osm_switch.c
@@ -303,6 +303,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const 
p_sw,
        osm_node_t *p_rem_node;
        osm_node_t *p_rem_node_first = NULL;
        struct osm_remote_node *p_remote_guid = NULL;
+       struct osm_remote_node null_remote_node = {NULL, 0, 0};
 
        CL_ASSERT(lid_ho > 0);
 
@@ -413,12 +414,37 @@ osm_switch_recommend_path(IN const osm_switch_t * const 
p_sw,
                check_count =
                    osm_port_prof_path_count_get(&p_sw->p_prof[port_num]);
 
+               if (dor) {
+                       /* Get the Remote Node */
+                       p_rem_physp = osm_physp_get_remote(p_physp);
+                       p_rem_node = osm_physp_get_node_ptr(p_rem_physp);
+                       /* use the first dimension, but spread traffic
+                        * out among the group of ports representing
+                        * that dimension */
+                       if (!p_rem_node_first)
+                               p_rem_node_first = p_rem_node;
+                       else if (p_rem_node != p_rem_node_first)
+                               continue;
+                       if (routing_for_lmc) {
+                               struct osm_remote_guids_count *r = p_port->priv;
+                               uint8_t rem_port = 
osm_physp_get_port_num(p_rem_physp);
+                               int j;
+
+                               for (j = 0; j < r->count; j++) {
+                                       p_remote_guid = &r->guids[j];
+                                       if ((p_remote_guid->node == p_rem_node)
+                                           && (p_remote_guid->port == 
rem_port))
+                                               break;
+                               }
+                               if (j == r->count)
+                                       p_remote_guid = &null_remote_node;
+                       }
                /*
                   Advanced LMC routing requires tracking of the
                   best port by the node connected to the other side of
                   it.
                 */
-               if (routing_for_lmc) {
+               } else if (routing_for_lmc) {
                        /* Is the sys guid already used ? */
                        p_remote_guid = osm_switch_find_sys_guid_count(p_sw,
                                                                       
p_port->priv,
@@ -454,20 +480,6 @@ osm_switch_recommend_path(IN const osm_switch_t * const 
p_sw,
                   the count is min but also lower then the max subscribed
                 */
                if (check_count < least_paths) {
-                       if (dor) {
-                               /* Get the Remote Node */
-                               p_rem_physp = osm_physp_get_remote(p_physp);
-                               p_rem_node =
-                                   osm_physp_get_node_ptr(p_rem_physp);
-                               /* use the first dimension, but spread
-                                * traffic out among the group of ports
-                                * representing that dimension */
-                               if (port_found) {
-                                       if (p_rem_node != p_rem_node_first)
-                                               continue;
-                               } else
-                                       p_rem_node_first = p_rem_node;
-                       }
                        port_found = TRUE;
                        best_port = port_num;
                        least_paths = check_count;
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index fe0a446..90d9732 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -186,19 +186,22 @@ __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,
+find_and_add_remote_sys(osm_switch_t *sw, uint8_t port, const boolean_t dor,
                        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;
+       uint8_t rem_port = osm_physp_get_port_num(p->p_remote_physp);
 
        for (i = 0; i < r->count; i++)
                if (r->guids[i].node == node)
+                 if (!dor || (r->guids[i].port == rem_port))
                        return &r->guids[i];
 
        r->guids[i].node = node;
        r->guids[i].forwarded_to = 0;
+       r->guids[i].port = rem_port;
        r->count++;
        return &r->guids[i];
 }
@@ -236,7 +239,7 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const 
p_mgr,
        if (lid_ho > max_lid_ho)
                goto Exit;
 
-       if (lid_offset)
+       if (lid_offset && !p_mgr->is_dor)
                /* ignore potential overflow - it is handled in osm_switch.c */
                start_from = osm_switch_get_port_by_lid(p_sw, lid_ho - 1) + 1;
 
@@ -302,6 +305,7 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const 
p_mgr,
                osm_switch_count_path(p_sw, port);
                if (port > 0 && p_port->priv &&
                    (rem_node_used = find_and_add_remote_sys(p_sw, port,
+                                                            p_mgr->is_dor,
                                                             p_port->priv)))
                        rem_node_used->forwarded_to++;
        }
-- 
1.6.2

_______________________________________________
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