[ofa-general] Re: [PATCH v3 2/2] opensm: support routing engine update

Eli Dorfman (Voltaire) dorfman.eli at gmail.com
Thu Mar 19 06:41:56 PDT 2009


 support routing engine update.

 save used routing engine as last routing engine.
 destroy old routing engine list and allocate new routing list.
 cleanup used routing engine allocation if needed
 and only after new routing engine was configured.

Signed-off-by: Eli Dorfman <elid at voltaire.com>
---
 opensm/include/opensm/osm_opensm.h |    1 +
 opensm/opensm/osm_opensm.c         |   49 ++++++++++++++++++++++++++++++++++++
 opensm/opensm/osm_subnet.c         |    7 ++++-
 opensm/opensm/osm_ucast_mgr.c      |   13 +++++++++
 4 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/opensm/include/opensm/osm_opensm.h b/opensm/include/opensm/osm_opensm.h
index 8d1b276..658c717 100644
--- a/opensm/include/opensm/osm_opensm.h
+++ b/opensm/include/opensm/osm_opensm.h
@@ -187,6 +187,7 @@ typedef struct osm_opensm {
 	cl_dispatcher_t disp;
 	cl_plock_t lock;
 	struct osm_routing_engine *routing_engine_list;
+	struct osm_routing_engine *last_routing_engine;
 	osm_routing_engine_type_t routing_engine_used;
 	osm_stats_t stats;
 	osm_console_t console;
diff --git a/opensm/opensm/osm_opensm.c b/opensm/opensm/osm_opensm.c
index 9739122..4e95fcf 100644
--- a/opensm/opensm/osm_opensm.c
+++ b/opensm/opensm/osm_opensm.c
@@ -232,6 +232,55 @@ static void destroy_routing_engines(osm_opensm_t *osm)
 	osm->routing_engine_list = NULL;
 }
 
+static void update_routing_engine(
+	struct osm_routing_engine *cur,
+	struct osm_routing_engine *last)
+{
+	struct osm_routing_engine *next = cur->next;
+
+	if (!last)
+		return; /* no last routing engine */
+	
+	memcpy(cur, last, sizeof(*cur));
+	/* restore next */
+	cur->next = next;
+}
+
+void osm_update_routing_engines(osm_opensm_t *osm, const char *engine_names)
+{
+	struct osm_routing_engine *r, *l;
+
+	/* find used routing engine and save as last */
+	l = r = osm->routing_engine_list;
+	if (r && osm->routing_engine_used == osm_routing_engine_type(r->name)) {
+		osm->last_routing_engine = r;
+		osm->routing_engine_list = r->next;
+	}
+	else while ((r = r->next)) {
+		if (osm->routing_engine_used == 
+			osm_routing_engine_type(r->name)) {
+			osm->last_routing_engine = r;
+			l->next = r->next;
+			break;
+		}
+		l = r;
+	}
+	/* cleanup prev routing engine list and replace with current list */
+	destroy_routing_engines(osm);
+	setup_routing_engines(osm, engine_names);
+
+	/* check if last routing engine exist in new list and update callbacks */
+	r = osm->routing_engine_list;
+	while (r) {
+		if (osm->routing_engine_used == 
+			osm_routing_engine_type(r->name)) {
+			update_routing_engine(r, osm->last_routing_engine);
+			break;
+		}
+		r = r->next;
+	}
+}
+
 /**********************************************************************
  **********************************************************************/
 static void destroy_plugins(osm_opensm_t *osm)
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index ec15f8a..e308515 100644
--- a/opensm/opensm/osm_subnet.c
+++ b/opensm/opensm/osm_subnet.c
@@ -151,6 +151,11 @@ static void opts_setup_sm_priority(osm_subn_t *p_subn, void *p_val)
 	osm_set_sm_priority(p_sm, sm_priority);
 }
 
+static void opts_setup_routing_engine(osm_subn_t *p_subn, void *p_val)
+{
+	osm_update_routing_engines(p_subn->p_osm, p_val);
+}
+
 static void opts_parse_net64(IN osm_subn_t *p_subn, IN char *p_key,
 			     IN char *p_val_str, void *p_v1, void *p_v2,
 			     void (*pfn)(osm_subn_t *, void *))
@@ -323,7 +328,7 @@ static const opt_rec_t opt_tbl[] = {
 	{ "hop_weights_file", OPT_OFFSET(hop_weights_file), opts_parse_charp, NULL, 0 },
 	{ "port_profile_switch_nodes", OPT_OFFSET(port_profile_switch_nodes), opts_parse_boolean, NULL, 1 },
 	{ "sweep_on_trap", OPT_OFFSET(sweep_on_trap), opts_parse_boolean, NULL, 1 },
-	{ "routing_engine", OPT_OFFSET(routing_engine_names), opts_parse_charp, NULL, 0 },
+	{ "routing_engine", OPT_OFFSET(routing_engine_names), opts_parse_charp, opts_setup_routing_engine, 1 },
 	{ "connect_roots", OPT_OFFSET(connect_roots), opts_parse_boolean, NULL, 1 },
 	{ "use_ucast_cache", OPT_OFFSET(use_ucast_cache), opts_parse_boolean, NULL, 1 },
 	{ "log_file", OPT_OFFSET(log_file), opts_parse_charp, NULL, 0 },
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index 102ffc6..349c4bb 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -999,6 +999,19 @@ int osm_ucast_mgr_process(IN osm_ucast_mgr_t * const p_mgr)
 		p_osm->routing_engine_used = OSM_ROUTING_ENGINE_TYPE_MINHOP;
 	}
 
+	/* if for some reason different routing engine is used */
+	/* cleanup last unused routing engine */
+	p_routing_eng = p_osm->last_routing_engine;
+	if (p_routing_eng) {
+		if (p_routing_eng->context &&
+			p_routing_eng->delete &&
+			p_osm->routing_engine_used != 
+				osm_routing_engine_type(p_routing_eng->name))
+			p_routing_eng->delete(p_routing_eng->context);
+		free(p_routing_eng);
+		p_osm->last_routing_engine = NULL;
+	}
+
 	OSM_LOG(p_mgr->p_log, OSM_LOG_INFO,
 		"%s tables configured on all switches\n",
 		osm_routing_engine_type_str(p_osm->routing_engine_used));
-- 
1.5.5




More information about the general mailing list