[ofa-general] [PATCH 3/6] opensm/updn: update root nodes at each run
Sasha Khapyorsky
sashak at voltaire.com
Wed Mar 26 17:27:14 PDT 2008
Update root nodes at each run, so restarting OpenSM is not needed when
Up/Down powered fabric topology is altered and some new nodes are addded.
Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
opensm/opensm/osm_ucast_updn.c | 331 ++++++++++++----------------------------
1 files changed, 95 insertions(+), 236 deletions(-)
diff --git a/opensm/opensm/osm_ucast_updn.c b/opensm/opensm/osm_ucast_updn.c
index 8a72a15..3623a69 100644
--- a/opensm/opensm/osm_ucast_updn.c
+++ b/opensm/opensm/osm_ucast_updn.c
@@ -65,17 +65,9 @@ typedef enum _updn_switch_dir {
DOWN
} updn_switch_dir_t;
-/* guids list */
-typedef struct _updn_input {
- uint32_t num_guids;
- uint64_t *guid_list;
-} updn_input_t;
-
/* updn structure */
typedef struct _updn {
- boolean_t auto_detect_root_nodes;
- updn_input_t updn_ucast_reg_inputs;
- cl_qlist_t root_nodes_list;
+ unsigned num_roots;
osm_opensm_t *p_osm;
} updn_t;
@@ -228,139 +220,30 @@ __updn_bfs_by_node(IN osm_log_t * p_log,
/**********************************************************************
**********************************************************************/
-static void updn_destroy(IN updn_t * const p_updn)
-{
- /* free the array of guids */
- if (p_updn->updn_ucast_reg_inputs.guid_list)
- free(p_updn->updn_ucast_reg_inputs.guid_list);
-
- /* destroy the list of root nodes */
- while (!cl_is_qlist_empty(&p_updn->root_nodes_list))
- free(cl_qlist_remove_head(&p_updn->root_nodes_list));
-
- free(p_updn);
-}
-
-/**********************************************************************
- **********************************************************************/
-static updn_t *updn_construct(osm_log_t * p_log)
-{
- updn_t *p_updn;
-
- OSM_LOG_ENTER(p_log);
-
- p_updn = malloc(sizeof(updn_t));
- if (p_updn)
- memset(p_updn, 0, sizeof(updn_t));
-
- OSM_LOG_EXIT(p_log);
- return (p_updn);
-}
-
-/**********************************************************************
- **********************************************************************/
-struct guid_list_item {
- cl_list_item_t list;
- uint64_t guid;
-};
-
-static int add_guid_item_to_list(void *cxt, uint64_t guid, char *p)
-{
- updn_t *updn = cxt;
- struct guid_list_item *item;
-
- item = malloc(sizeof(*item));
- if (!item)
- return -1;
-
- item->guid = guid;
- cl_qlist_insert_tail(&updn->root_nodes_list, &item->list);
-
- OSM_LOG(&updn->p_osm->log, OSM_LOG_DEBUG,
- "Inserting GUID 0x%" PRIx64 " as root node\n", guid);
-
- return 0;
-}
-
-static cl_status_t updn_init(IN updn_t * const p_updn, IN osm_opensm_t * p_osm)
-{
- ib_api_status_t status = IB_SUCCESS;
-
- OSM_LOG_ENTER(&p_osm->log);
-
- p_updn->p_osm = p_osm;
-
- cl_qlist_init(&p_updn->root_nodes_list);
- p_updn->updn_ucast_reg_inputs.num_guids = 0;
- p_updn->updn_ucast_reg_inputs.guid_list = NULL;
- p_updn->auto_detect_root_nodes = FALSE;
-
- /*
- Check the source for root node list, if file parse it, otherwise
- wait for a callback to activate auto detection
- */
- if (p_osm->subn.opt.root_guid_file) {
- /* For Debug Purposes ... */
- OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
- "UPDN - Fetching root nodes from file %s\n",
- p_osm->subn.opt.root_guid_file);
-
- if (parse_node_map(p_osm->subn.opt.root_guid_file,
- add_guid_item_to_list, p_updn)) {
- OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR : "
- "cannot parse root guids file \'%s\'\n",
- p_osm->subn.opt.root_guid_file);
- goto Exit;
- }
- } else
- p_updn->auto_detect_root_nodes = TRUE;
- /* If auto mode detection required - will be executed in main b4 the assignment of UI Ucast */
-
-Exit:
- OSM_LOG_EXIT(&p_osm->log);
- return (status);
-}
-
-/**********************************************************************
- **********************************************************************/
/* NOTE : PLS check if we need to decide that the first */
/* rank is a SWITCH for BFS purpose */
-static int
-updn_subn_rank(IN unsigned num_guids,
- IN uint64_t * guid_list, IN updn_t * p_updn)
+static int updn_subn_rank(IN updn_t * p_updn)
{
osm_switch_t *p_sw;
osm_physp_t *p_physp, *p_remote_physp;
cl_qlist_t list;
+ cl_map_item_t *item;
struct updn_node *u, *remote_u;
uint8_t num_ports, port_num;
osm_log_t *p_log = &p_updn->p_osm->log;
- unsigned idx = 0;
unsigned max_rank = 0;
OSM_LOG_ENTER(p_log);
cl_qlist_init(&list);
- /* Rank all the roots and add them to list */
-
- for (idx = 0; idx < num_guids; idx++) {
- /* Apply the ranking for each guid given by user - bypass illegal ones */
- p_sw =
- osm_get_switch_by_guid(&p_updn->p_osm->subn,
- cl_hton64(guid_list[idx]));
- if (!p_sw) {
- OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AA05: "
- "Root switch GUID 0x%" PRIx64 " not found\n",
- guid_list[idx]);
- continue;
- }
-
+ /* add all roots to the list */
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl);
+ item = cl_qmap_next(item)) {
+ p_sw = (osm_switch_t *)item;
u = p_sw->priv;
- OSM_LOG(p_log, OSM_LOG_DEBUG,
- "Ranking root port GUID 0x%" PRIx64 "\n",
- guid_list[idx]);
- u->rank = 0;
- cl_qlist_insert_tail(&list, &u->list);
+ if (!u->rank)
+ cl_qlist_insert_tail(&list, &u->list);
}
/* BFS the list till it's empty */
@@ -440,7 +323,8 @@ static int __osm_subn_set_up_down_min_hop_table(IN updn_t * p_updn)
{
osm_subn_t *p_subn = &p_updn->p_osm->subn;
osm_log_t *p_log = &p_updn->p_osm->log;
- osm_switch_t *p_next_sw, *p_sw;
+ osm_switch_t *p_sw;
+ cl_map_item_t *item;
OSM_LOG_ENTER(p_log);
@@ -449,10 +333,10 @@ static int __osm_subn_set_up_down_min_hop_table(IN updn_t * p_updn)
OSM_LOG(p_log, OSM_LOG_VERBOSE,
"Init Min Hop Table of all switches [\n");
- p_next_sw = (osm_switch_t *) cl_qmap_head(&p_subn->sw_guid_tbl);
- while (p_next_sw != (osm_switch_t *) cl_qmap_end(&p_subn->sw_guid_tbl)) {
- p_sw = p_next_sw;
- p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item);
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl);
+ item = cl_qmap_next(item)) {
+ p_sw = (osm_switch_t *)item;
/* Clear Min Hop Table */
if (p_subn->opt.connect_roots)
updn_clear_root_hops(p_updn, p_sw);
@@ -467,10 +351,10 @@ static int __osm_subn_set_up_down_min_hop_table(IN updn_t * p_updn)
OSM_LOG(p_log, OSM_LOG_VERBOSE,
"BFS through all port guids in the subnet [\n");
- p_next_sw = (osm_switch_t *) cl_qmap_head(&p_subn->sw_guid_tbl);
- while (p_next_sw != (osm_switch_t *) cl_qmap_end(&p_subn->sw_guid_tbl)) {
- p_sw = p_next_sw;
- p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item);
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl);
+ item = cl_qmap_next(item)) {
+ p_sw = (osm_switch_t *)item;
__updn_bfs_by_node(p_log, p_subn, p_sw);
}
@@ -483,9 +367,7 @@ static int __osm_subn_set_up_down_min_hop_table(IN updn_t * p_updn)
/**********************************************************************
**********************************************************************/
-static int
-updn_build_lid_matrices(IN uint32_t num_guids,
- IN uint64_t * guid_list, IN updn_t * p_updn)
+static int updn_build_lid_matrices(IN updn_t * p_updn)
{
int status;
@@ -493,7 +375,7 @@ updn_build_lid_matrices(IN uint32_t num_guids,
OSM_LOG(&p_updn->p_osm->log, OSM_LOG_VERBOSE,
"Ranking all port guids in the list\n");
- if (num_guids == 0) {
+ if (!p_updn->num_roots) {
OSM_LOG(&p_updn->p_osm->log, OSM_LOG_ERROR, "ERR AA0A: "
"No guids were provided or number of guids is 0\n");
status = -1;
@@ -509,7 +391,7 @@ updn_build_lid_matrices(IN uint32_t num_guids,
}
/* Rank the subnet switches */
- updn_subn_rank(num_guids, guid_list, p_updn);
+ updn_subn_rank(p_updn);
/* After multiple ranking need to set Min Hop Table by UpDn algorithm */
OSM_LOG(&p_updn->p_osm->log, OSM_LOG_VERBOSE,
@@ -552,20 +434,41 @@ static void dump_roots(cl_map_item_t *item, FILE *file, void *cxt)
cl_ntoh64(osm_node_get_node_guid(sw->p_node)));
}
+static int rank_root_node(void *cxt, uint64_t guid, char *p)
+{
+ updn_t *updn = cxt;
+ osm_switch_t *sw;
+
+ sw = osm_get_switch_by_guid(&updn->p_osm->subn, cl_hton64(guid));
+ if (!sw) {
+ OSM_LOG(&updn->p_osm->log, OSM_LOG_VERBOSE,
+ "switch with guid 0x%" PRIx64 " is not found\n", guid);
+ return 0;
+ }
+
+ OSM_LOG(&updn->p_osm->log, OSM_LOG_DEBUG,
+ "Ranking root port GUID 0x%" PRIx64 "\n", guid);
+
+ ((struct updn_node *)sw->priv)->rank = 0;
+ updn->num_roots++;
+
+ return 0;
+}
+
/* UPDN callback function */
static int __osm_updn_call(void *ctx)
{
updn_t *p_updn = ctx;
- cl_map_item_t *p_item;
+ cl_map_item_t *item;
osm_switch_t *p_sw;
int ret = 0;
OSM_LOG_ENTER(&p_updn->p_osm->log);
- p_item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
- while (p_item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl)) {
- p_sw = (osm_switch_t *) p_item;
- p_item = cl_qmap_next(p_item);
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl);
+ item = cl_qmap_next(item)) {
+ p_sw = (osm_switch_t *)item;
p_sw->priv = create_updn_node(p_sw);
if (!p_sw->priv) {
OSM_LOG(&(p_updn->p_osm->log), OSM_LOG_ERROR, "ERR AA0C: "
@@ -575,23 +478,33 @@ static int __osm_updn_call(void *ctx)
}
}
- /* First auto detect root nodes - if required */
- if (p_updn->auto_detect_root_nodes) {
+ /* First setup root nodes */
+ p_updn->num_roots = 0;
+
+ if (p_updn->p_osm->subn.opt.root_guid_file) {
+ OSM_LOG(&p_updn->p_osm->log, OSM_LOG_DEBUG,
+ "UPDN - Fetching root nodes from file %s\n",
+ p_updn->p_osm->subn.opt.root_guid_file);
+
+ ret = parse_node_map(p_updn->p_osm->subn.opt.root_guid_file,
+ rank_root_node, p_updn);
+ if (ret)
+ OSM_LOG(&p_updn->p_osm->log, OSM_LOG_ERROR, "ERR : "
+ "cannot parse root guids file \'%s\'\n",
+ p_updn->p_osm->subn.opt.root_guid_file);
+ if (p_updn->p_osm->subn.opt.connect_roots &&
+ p_updn->num_roots > 1)
+ osm_ucast_mgr_build_lid_matrices(&p_updn->p_osm->sm.ucast_mgr);
+ } else {
osm_ucast_mgr_build_lid_matrices(&p_updn->p_osm->sm.ucast_mgr);
__osm_updn_find_root_nodes_by_min_hop(p_updn);
- } else if (p_updn->p_osm->subn.opt.connect_roots &&
- p_updn->updn_ucast_reg_inputs.num_guids > 1)
- osm_ucast_mgr_build_lid_matrices(&p_updn->p_osm->sm.ucast_mgr);
+ }
- /* printf ("-V- after osm_updn_find_root_nodes_by_min_hop\n"); */
/* Only if there are assigned root nodes do the algorithm, otherwise perform do nothing */
- if (p_updn->updn_ucast_reg_inputs.num_guids > 0) {
+ if (p_updn->num_roots) {
OSM_LOG(&p_updn->p_osm->log, OSM_LOG_DEBUG,
"activating UPDN algorithm\n");
- ret = updn_build_lid_matrices(p_updn->updn_ucast_reg_inputs.
- num_guids,
- p_updn->updn_ucast_reg_inputs.
- guid_list, p_updn);
+ ret = updn_build_lid_matrices(p_updn);
} else {
OSM_LOG(&p_updn->p_osm->log, OSM_LOG_INFO,
"disabling UPDN algorithm, no root nodes were found\n");
@@ -603,10 +516,10 @@ static int __osm_updn_call(void *ctx)
&p_updn->p_osm->subn.sw_guid_tbl,
dump_roots, NULL);
- p_item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
- while (p_item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl)) {
- p_sw = (osm_switch_t *) p_item;
- p_item = cl_qmap_next(p_item);
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl);
+ item = cl_qmap_next(item)) {
+ p_sw = (osm_switch_t *) item;
delete_updn_node(p_sw->priv);
}
@@ -616,46 +529,14 @@ static int __osm_updn_call(void *ctx)
/**********************************************************************
**********************************************************************/
-/* UPDN convert cl_list to guid array in updn struct */
-static void __osm_updn_convert_list2array(IN updn_t * p_updn)
-{
- unsigned i;
-
- OSM_LOG_ENTER(&p_updn->p_osm->log);
-
- p_updn->updn_ucast_reg_inputs.num_guids =
- cl_qlist_count(&p_updn->root_nodes_list);
- if (p_updn->updn_ucast_reg_inputs.guid_list)
- free(p_updn->updn_ucast_reg_inputs.guid_list);
- p_updn->updn_ucast_reg_inputs.guid_list =
- (uint64_t *) malloc(p_updn->updn_ucast_reg_inputs.num_guids *
- sizeof(uint64_t));
- if (p_updn->updn_ucast_reg_inputs.guid_list)
- memset(p_updn->updn_ucast_reg_inputs.guid_list, 0,
- p_updn->updn_ucast_reg_inputs.num_guids *
- sizeof(uint64_t));
- for (i = 0; !cl_is_qlist_empty(&p_updn->root_nodes_list); i++) {
- struct guid_list_item *item;
- item = (void *)cl_qlist_remove_head(&p_updn->root_nodes_list);
- p_updn->updn_ucast_reg_inputs.guid_list[i] = item->guid;
- OSM_LOG(&p_updn->p_osm->log, OSM_LOG_DEBUG,
- "Map GUID 0x%" PRIx64 " into UPDN array\n",
- p_updn->updn_ucast_reg_inputs.guid_list[i]);
- free(item);
- }
- /* Since we need the template list for other sweeps, we wont destroy & free it */
- OSM_LOG_EXIT(&p_updn->p_osm->log);
-}
-
-/**********************************************************************
- **********************************************************************/
/* Find Root nodes automatically by Min Hop Table info */
static void __osm_updn_find_root_nodes_by_min_hop(OUT updn_t * p_updn)
{
osm_opensm_t *p_osm = p_updn->p_osm;
- osm_switch_t *p_next_sw, *p_sw;
- osm_port_t *p_next_port, *p_port;
+ osm_switch_t *p_sw;
+ osm_port_t *p_port;
osm_physp_t *p_physp;
+ cl_map_item_t *item;
double thd1, thd2;
unsigned i, cas_num = 0;
unsigned *cas_per_sw;
@@ -678,12 +559,10 @@ static void __osm_updn_find_root_nodes_by_min_hop(OUT updn_t * p_updn)
/* Find the Maximum number of CAs (and routers) for histogram normalization */
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
"Finding the number of CAs and storing them in cl_map\n");
- p_next_port = (osm_port_t *) cl_qmap_head(&p_osm->subn.port_guid_tbl);
- while (p_next_port !=
- (osm_port_t *) cl_qmap_end(&p_osm->subn.port_guid_tbl)) {
- p_port = p_next_port;
- p_next_port =
- (osm_port_t *) cl_qmap_next(&p_next_port->map_item);
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.port_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.port_guid_tbl);
+ item = cl_qmap_next(item)) {
+ p_port = (osm_port_t *)item;
if (!p_port->p_node->sw) {
p_physp = p_port->p_physp->p_remote_physp;
if (!p_physp || !p_physp->p_node->sw)
@@ -706,20 +585,18 @@ static void __osm_updn_find_root_nodes_by_min_hop(OUT updn_t * p_updn)
"Thresholds are thd1 = %f && thd2 = %f\n",
cas_num, cl_qmap_count(&p_osm->subn.sw_guid_tbl), thd1, thd2);
- p_next_sw = (osm_switch_t *) cl_qmap_head(&p_osm->subn.sw_guid_tbl);
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
"Passing through all switches to collect Min Hop info\n");
- while (p_next_sw !=
- (osm_switch_t *) cl_qmap_end(&p_osm->subn.sw_guid_tbl)) {
+ for (item = cl_qmap_head(&p_updn->p_osm->subn.sw_guid_tbl);
+ item != cl_qmap_end(&p_updn->p_osm->subn.sw_guid_tbl);
+ item = cl_qmap_next(item)) {
unsigned hop_hist[IB_SUBNET_PATH_HOPS_MAX];
uint16_t max_lid_ho;
uint8_t hop_val;
uint16_t numHopBarsOverThd1 = 0;
uint16_t numHopBarsOverThd2 = 0;
- p_sw = p_next_sw;
- /* Roll to the next switch */
- p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item);
+ p_sw = (osm_switch_t *) item;
memset(hop_hist, 0, sizeof(hop_hist));
@@ -747,28 +624,17 @@ static void __osm_updn_find_root_nodes_by_min_hop(OUT updn_t * p_updn)
numHopBarsOverThd2++;
}
- /* If thd conditions are valid insert the root node to the list */
+ /* If thd conditions are valid - rank the root node */
if ((numHopBarsOverThd1 == 1) && (numHopBarsOverThd2 == 1)) {
- struct guid_list_item *item;
- item = malloc(sizeof(*item));
- if (item) {
- item->guid = cl_ntoh64(osm_node_get_node_guid
- (p_sw->p_node));
- OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
- "Inserting GUID 0x%" PRIx64
- " as root node\n", item->guid);
- cl_qlist_insert_tail(&p_updn->root_nodes_list,
- &item->list);
- } else
- OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR AA13: "
- "No memory for p_guid\n");
+ OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
+ "Ranking GUID 0x%" PRIx64 " as root node\n",
+ cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)));
+ ((struct updn_node *)p_sw->priv)->rank = 0;
+ p_updn->num_roots++;
}
}
free(cas_per_sw);
- /* Now convert the cl_list to array */
- __osm_updn_convert_list2array(p_updn);
-
_exit:
OSM_LOG_EXIT(&p_osm->log);
return;
@@ -778,30 +644,23 @@ _exit:
**********************************************************************/
static void __osm_updn_delete(void *context)
{
- updn_t *p_updn = context;
-
- updn_destroy(p_updn);
+ free(context);
}
int osm_ucast_updn_setup(osm_opensm_t * p_osm)
{
updn_t *p_updn;
- p_updn = updn_construct(&p_osm->log);
+ p_updn = malloc(sizeof(updn_t));
if (!p_updn)
return -1;
+ memset(p_updn, 0, sizeof(updn_t));
- if (updn_init(p_updn, p_osm) != IB_SUCCESS) {
- updn_destroy(p_updn);
- return -1;
- }
+ p_updn->p_osm = p_osm;
p_osm->routing_engine.context = p_updn;
p_osm->routing_engine.delete = __osm_updn_delete;
p_osm->routing_engine.build_lid_matrices = __osm_updn_call;
- if (!p_updn->auto_detect_root_nodes)
- __osm_updn_convert_list2array(p_updn);
-
return 0;
}
--
1.5.4.1.122.gaa8d
More information about the general
mailing list