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
