[ofa-general] [PATCH] opensm: move remote guids counting to ucast_mgr
Sasha Khapyorsky
sashak at voltaire.com
Mon Jun 9 19:56:21 PDT 2008
This is pretty mechanical change - move remote sys/node guids
preallocation and counting (used when for lmc > 0 balancing) to
ucast_mgr. It is needed for future "preserve base lid routing" change.
Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
opensm/include/opensm/osm_port.h | 1 +
opensm/include/opensm/osm_switch.h | 45 ++++++----------
opensm/opensm/osm_dump.c | 3 +-
opensm/opensm/osm_switch.c | 101 ++++++++----------------------------
opensm/opensm/osm_ucast_mgr.c | 99 ++++++++++++++++++++++++++---------
5 files changed, 114 insertions(+), 135 deletions(-)
diff --git a/opensm/include/opensm/osm_port.h b/opensm/include/opensm/osm_port.h
index 3d501d8..c1cbd39 100644
--- a/opensm/include/opensm/osm_port.h
+++ b/opensm/include/opensm/osm_port.h
@@ -1149,6 +1149,7 @@ typedef struct _osm_port {
unsigned is_new;
osm_physp_t *p_physp;
cl_qlist_t mcm_list;
+ void *priv;
} osm_port_t;
/*
* FIELDS
diff --git a/opensm/include/opensm/osm_switch.h b/opensm/include/opensm/osm_switch.h
index f5455af..0e9c5fa 100644
--- a/opensm/include/opensm/osm_switch.h
+++ b/opensm/include/opensm/osm_switch.h
@@ -153,31 +153,33 @@ typedef struct _osm_switch {
* Switch object
*********/
-/****s* OpenSM: Switch/osm_switch_guid_count_t
+/****s* OpenSM: Switch/struct osm_remote_guids_count
* NAME
-* osm_switch_guid_count_t
+* struct osm_remote_guids_count
*
* DESCRIPTION
-* Stores system and node guids and the number of
+* Stores array of pointers to remote node and the numbers of
* times a switch has forwarded to it.
*
* SYNOPSIS
*/
-typedef struct _osm_switch_guid_count {
- uint64_t sys_guid;
- uint64_t node_guid;
- unsigned int forwarded_to;
-} osm_switch_guid_count_t;
+struct osm_remote_guids_count {
+ unsigned count;
+ struct osm_remote_node {
+ osm_node_t *node;
+ unsigned forwarded_to;
+ } guids[0];
+};
/*
* FIELDS
-* sys_guid
-* A system guid.
+* count
+* A number of used entries in array.
*
-* node_guid
-* A node guid.
+* node
+* A pointer to node.
*
* forwarded_to
-* A count of lids forwarded to the sys_guid/node_guid.
+* A count of lids forwarded to this node.
*********/
/****f* OpenSM: Switch/osm_switch_delete
@@ -980,10 +982,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
IN osm_port_t * p_port,
IN const uint16_t lid_ho,
IN const boolean_t ignore_existing,
- IN const boolean_t dor,
- IN OUT osm_switch_guid_count_t * remote_guids,
- IN OUT uint16_t * p_num_remote_guids,
- IN OUT osm_switch_guid_count_t ** p_remote_guid_count_used);
+ IN const boolean_t dor);
/*
* PARAMETERS
* p_sw
@@ -1005,18 +1004,6 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
* dor
* [in] If TRUE, Dimension Order Routing will be done.
*
-* remote_guids
-* [in out] The array of remote guids already used to route
-* the other lids of the same target port (if LMC > 0)
-*
-* p_num_remote_guids
-* [in out] The number of remote guids used for routing to
-* the port.
-*
-* p_remote_guid_count_used
-* [in out] The specific osm_switch_guid_count_t used
-* in switch recommendations.
-*
* RETURN VALUE
* Returns the recommended port on which to route this LID.
*
diff --git a/opensm/opensm/osm_dump.c b/opensm/opensm/osm_dump.c
index 2bac75a..b96984b 100644
--- a/opensm/opensm/osm_dump.c
+++ b/opensm/opensm/osm_dump.c
@@ -218,8 +218,7 @@ static void dump_ucast_routes(cl_map_item_t *p_map_item, FILE *file, void *cxt)
else {
/* No LMC Optimization */
best_port = osm_switch_recommend_path(p_sw, p_port,
- lid_ho, TRUE, dor,
- NULL, NULL, NULL);
+ lid_ho, TRUE, dor);
fprintf(file, "No %u hop path possible via port %u!",
best_hops, best_port);
}
diff --git a/opensm/opensm/osm_switch.c b/opensm/opensm/osm_switch.c
index fdcd109..58936e3 100644
--- a/opensm/opensm/osm_switch.c
+++ b/opensm/opensm/osm_switch.c
@@ -214,15 +214,14 @@ osm_switch_get_fwd_tbl_block(IN const osm_switch_t * const p_sw,
/**********************************************************************
**********************************************************************/
-static osm_switch_guid_count_t *
+static struct osm_remote_node *
osm_switch_find_guid_common(IN const osm_switch_t * const p_sw,
- IN osm_switch_guid_count_t * remote_guids,
- IN uint16_t * p_num_remote_guids,
+ IN struct osm_remote_guids_count *r,
IN uint8_t port_num,
IN int find_sys_guid,
IN int find_node_guid)
{
- osm_switch_guid_count_t *p_remote_guid = NULL;
+ struct osm_remote_node *p_remote_guid = NULL;
osm_physp_t *p_physp;
osm_physp_t *p_rem_physp;
osm_node_t *p_rem_node;
@@ -240,12 +239,12 @@ osm_switch_find_guid_common(IN const osm_switch_t * const p_sw,
sys_guid = p_rem_node->node_info.sys_guid;
node_guid = p_rem_node->node_info.node_guid;
- for (i = 0; i < *p_num_remote_guids; i++) {
+ for (i = 0; i < r->count; i++) {
if ((!find_sys_guid
- || remote_guids[i].sys_guid == sys_guid)
+ || r->guids[i].node->node_info.sys_guid == sys_guid)
&& (!find_node_guid
- || remote_guids[i].node_guid == node_guid)) {
- p_remote_guid = &remote_guids[i];
+ || r->guids[i].node->node_info.node_guid == node_guid)) {
+ p_remote_guid = &r->guids[i];
break;
}
}
@@ -253,49 +252,22 @@ osm_switch_find_guid_common(IN const osm_switch_t * const p_sw,
return p_remote_guid;
}
-static osm_switch_guid_count_t *
+static struct osm_remote_node *
osm_switch_find_sys_guid_count(IN const osm_switch_t * const p_sw,
- IN osm_switch_guid_count_t * remote_guids,
- IN uint16_t * p_num_remote_guids,
+ IN struct osm_remote_guids_count *r,
IN uint8_t port_num)
{
- return osm_switch_find_guid_common(p_sw,
- remote_guids,
- p_num_remote_guids,
- port_num,
- 1,
- 0);
+ return osm_switch_find_guid_common(p_sw, r, port_num, 1, 0);
}
-static osm_switch_guid_count_t *
+static struct osm_remote_node *
osm_switch_find_node_guid_count(IN const osm_switch_t * const p_sw,
- IN osm_switch_guid_count_t * remote_guids,
- IN uint16_t * p_num_remote_guids,
+ IN struct osm_remote_guids_count *r,
IN uint8_t port_num)
{
- return osm_switch_find_guid_common(p_sw,
- remote_guids,
- p_num_remote_guids,
- port_num,
- 0,
- 1);
+ return osm_switch_find_guid_common(p_sw, r, port_num, 0, 1);
}
-static osm_switch_guid_count_t *
-osm_switch_find_guid_count(IN const osm_switch_t * const p_sw,
- IN osm_switch_guid_count_t * remote_guids,
- IN uint16_t * p_num_remote_guids,
- IN uint8_t port_num)
-{
- return osm_switch_find_guid_common(p_sw,
- remote_guids,
- p_num_remote_guids,
- port_num,
- 1,
- 1);
-}
-
-
/**********************************************************************
**********************************************************************/
uint8_t
@@ -303,10 +275,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
IN osm_port_t * p_port,
IN const uint16_t lid_ho,
IN const boolean_t ignore_existing,
- IN const boolean_t dor,
- IN OUT osm_switch_guid_count_t * remote_guids,
- IN OUT uint16_t * p_num_remote_guids,
- IN OUT osm_switch_guid_count_t ** p_remote_guid_count_used)
+ IN const boolean_t dor)
{
/*
We support an enhanced LMC aware routing mode:
@@ -318,8 +287,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
If this procedure is provided with the tracking array
and counter we can conduct this algorithm.
*/
- boolean_t routing_for_lmc = remote_guids && p_num_remote_guids
- && p_remote_guid_count_used;
+ boolean_t routing_for_lmc = (p_port->priv != NULL);
uint16_t base_lid;
uint8_t hops;
uint8_t least_hops;
@@ -346,7 +314,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
osm_physp_t *p_rem_physp;
osm_node_t *p_rem_node;
osm_node_t *p_rem_node_first = NULL;
- osm_switch_guid_count_t *p_remote_guid = NULL;
+ struct osm_remote_node *p_remote_guid = NULL;
CL_ASSERT(lid_ho > 0);
@@ -461,8 +429,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
if (routing_for_lmc) {
/* Is the sys guid already used ? */
p_remote_guid = osm_switch_find_sys_guid_count(p_sw,
- remote_guids,
- p_num_remote_guids,
+ p_port->priv,
port_num);
/* If not update the least hops for this case */
@@ -475,8 +442,7 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
} else { /* same sys found - try node */
/* Else is the node guid already used ? */
p_remote_guid = osm_switch_find_node_guid_count(p_sw,
- remote_guids,
- p_num_remote_guids,
+ p_port->priv,
port_num);
/* If not update the least hops for this case */
@@ -517,11 +483,10 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
&& p_remote_guid
&& p_remote_guid->forwarded_to < least_forwarded_to)
least_forwarded_to = p_remote_guid->forwarded_to;
- }
- else if (routing_for_lmc
- && p_remote_guid
- && check_count == least_paths
- && p_remote_guid->forwarded_to < least_forwarded_to) {
+ } else if (routing_for_lmc
+ && p_remote_guid
+ && check_count == least_paths
+ && p_remote_guid->forwarded_to < least_forwarded_to) {
least_forwarded_to = p_remote_guid->forwarded_to;
best_port = port_num;
}
@@ -540,28 +505,6 @@ osm_switch_recommend_path(IN const osm_switch_t * const p_sw,
best_port = best_port_other_sys;
else if (best_port_other_node)
best_port = best_port_other_node;
-
- /* track the remote node and system of the port used. */
- p_remote_guid = osm_switch_find_guid_count(p_sw,
- remote_guids,
- p_num_remote_guids,
- best_port);
-
- if (!p_remote_guid) {
- /* track the remote node and system of the port used. */
- p_physp = osm_node_get_physp_ptr(p_sw->p_node, best_port);
- p_rem_physp = osm_physp_get_remote(p_physp);
- p_rem_node = osm_physp_get_node_ptr(p_rem_physp);
- memcpy(&(remote_guids[*p_num_remote_guids].sys_guid),
- &(p_rem_node->node_info.sys_guid),
- sizeof(uint64_t));
- memcpy(&(remote_guids[*p_num_remote_guids].node_guid),
- &(p_rem_node->node_info.node_guid),
- sizeof(uint64_t));
- remote_guids[*p_num_remote_guids].forwarded_to = 0;
- (*p_num_remote_guids)++;
- }
- *p_remote_guid_count_used = p_remote_guid;
}
return (best_port);
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index 5923638..c073037 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -187,6 +187,24 @@ __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,
+ 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;
+
+ for (i = 0; i < r->count; i++)
+ if (r->guids[i].node == node)
+ return &r->guids[i];
+
+ r->guids[i].node = node;
+ r->guids[i].forwarded_to = 0;
+ r->count++;
+ return &r->guids[i];
+}
+
static void
__osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
IN osm_switch_t * const p_sw,
@@ -204,23 +222,10 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
in providing better routing in LMC > 0 situations
*/
uint16_t lids_per_port = 1 << p_mgr->p_subn->opt.lmc;
- osm_switch_guid_count_t *remote_guids = NULL;
- uint16_t num_used_guids = 0;
- osm_switch_guid_count_t *p_remote_guid_used = NULL;
+ struct osm_remote_node *p_remote_guid_used = NULL;
OSM_LOG_ENTER(p_mgr->p_log);
- if (lids_per_port > 1) {
- remote_guids = malloc(sizeof(osm_switch_guid_count_t) * lids_per_port);
- if (remote_guids == NULL) {
- osm_log(p_mgr->p_log, OSM_LOG_ERROR,
- "__osm_ucast_mgr_process_port: ERR 3A09: "
- "Cannot allocate array. Insufficient memory\n");
- goto Exit;
- }
- memset(remote_guids, 0, sizeof(osm_switch_guid_count_t) * lids_per_port);
- }
-
osm_port_get_lid_range_ho(p_port, &min_lid_ho, &max_lid_ho);
/* If the lids are zero - then there was some problem with the initialization.
@@ -258,21 +263,19 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
for (lid_ho = min_lid_ho; lid_ho <= max_lid_ho; lid_ho++) {
/* Use the enhanced algorithm only for LMC > 0 */
if (lids_per_port > 1) {
- p_remote_guid_used = NULL;
port = osm_switch_recommend_path(p_sw, p_port, lid_ho,
p_mgr->p_subn->
ignore_existing_lfts,
- p_mgr->is_dor,
- remote_guids,
- &num_used_guids,
- &p_remote_guid_used);
- }
- else
+ p_mgr->is_dor);
+ if (port > 0 && port != OSM_NO_PATH && p_port->priv)
+ p_remote_guid_used =
+ find_and_add_remote_sys(p_sw, port,
+ p_port->priv);
+ } else
port = osm_switch_recommend_path(p_sw, p_port, lid_ho,
p_mgr->p_subn->
ignore_existing_lfts,
- p_mgr->is_dor,
- NULL, NULL, NULL);
+ p_mgr->is_dor);
/*
There might be no path to the target
@@ -334,8 +337,6 @@ __osm_ucast_mgr_process_port(IN osm_ucast_mgr_t * const p_mgr,
}
Exit:
- if (remote_guids)
- free(remote_guids);
OSM_LOG_EXIT(p_mgr->p_log);
}
@@ -460,6 +461,48 @@ osm_ucast_mgr_set_fwd_table(IN osm_ucast_mgr_t * const p_mgr,
/**********************************************************************
**********************************************************************/
+static void alloc_ports_priv(osm_ucast_mgr_t *mgr)
+{
+ cl_qmap_t *port_tbl = &mgr->p_subn->port_guid_tbl;
+ struct osm_remote_guids_count *r;
+ osm_port_t *port;
+ cl_map_item_t *item;
+ unsigned lmc;
+
+ for (item = cl_qmap_head(port_tbl); item != cl_qmap_end(port_tbl);
+ item = cl_qmap_next(item)) {
+ port = (osm_port_t *)item;
+ lmc = ib_port_info_get_lmc(&port->p_physp->port_info);
+ if (!lmc)
+ continue;
+ r = malloc(sizeof(*r) + sizeof(r->guids[0]) * (1 << lmc));
+ if (!r) {
+ OSM_LOG(mgr->p_log, OSM_LOG_ERROR, "ERR 3A09: "
+ "cannot allocate memory to track remote"
+ " systems for lmc > 0\n");
+ port->priv = NULL;
+ continue;
+ }
+ memset(r, 0, sizeof(*r) + sizeof(r->guids[0]) * (1 << lmc));
+ port->priv = r;
+ }
+}
+
+static void free_ports_priv(osm_ucast_mgr_t *mgr)
+{
+ cl_qmap_t *port_tbl = &mgr->p_subn->port_guid_tbl;
+ osm_port_t *port;
+ cl_map_item_t *item;
+ for (item = cl_qmap_head(port_tbl); item != cl_qmap_end(port_tbl);
+ item = cl_qmap_next(item)) {
+ port = (osm_port_t *)item;
+ if (port->priv) {
+ free(port->priv);
+ port->priv = NULL;
+ }
+ }
+}
+
static void
__osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
IN void *context)
@@ -488,6 +531,9 @@ __osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
p_port_tbl = &p_mgr->p_subn->port_guid_tbl;
+ if (p_mgr->p_subn->opt.lmc)
+ alloc_ports_priv(p_mgr);
+
/*
Iterate through every port setting LID routes for each
port based on base LID and LMC value.
@@ -501,6 +547,9 @@ __osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item,
osm_ucast_mgr_set_fwd_table(p_mgr, p_sw);
+ if (p_mgr->p_subn->opt.lmc)
+ free_ports_priv(p_mgr);
+
OSM_LOG_EXIT(p_mgr->p_log);
}
--
1.5.5.1.178.g1f811
More information about the general
mailing list