[ofa-general] Re: [PATCH v2] opensm: support routing engine update

Eli Dorfman (Voltaire) dorfman.eli at gmail.com
Mon Mar 16 01:24:36 PDT 2009


support routing engine update

perform setup of routing engine only before configuration.
save last routing engine before routing engine selection
and cleanup of last if not used any more.

Signed-off-by: Eli Dorfman <elid at voltaire.com>
---
 opensm/include/opensm/osm_opensm.h |    5 +++
 opensm/opensm/osm_opensm.c         |   58 +++++++++++++++++++++++++++++++-----
 opensm/opensm/osm_subnet.c         |    7 ++++-
 opensm/opensm/osm_ucast_mgr.c      |   29 ++++++++++++++++++
 4 files changed, 90 insertions(+), 9 deletions(-)

diff --git a/opensm/include/opensm/osm_opensm.h b/opensm/include/opensm/osm_opensm.h
index c121be4..d297dd8 100644
--- a/opensm/include/opensm/osm_opensm.h
+++ b/opensm/include/opensm/osm_opensm.h
@@ -122,6 +122,8 @@ typedef enum _osm_routing_engine_type {
 struct osm_routing_engine {
 	const char *name;
 	void *context;
+	int initialized;
+	int (*setup) (void *re, void *p_osm);
 	int (*build_lid_matrices) (void *context);
 	int (*ucast_build_fwd_tables) (void *context);
 	void (*ucast_dump_tables) (void *context);
@@ -183,6 +185,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;
@@ -523,5 +526,7 @@ extern volatile unsigned int osm_exit_flag;
 *  Set to one to cause all threads to leave
 *********/
 
+void osm_update_routing_engines(osm_opensm_t *osm, const char *engine_names);
+
 END_C_DECLS
 #endif				/* _OSM_OPENSM_H_ */
diff --git a/opensm/opensm/osm_opensm.c b/opensm/opensm/osm_opensm.c
index cfe6474..7126658 100644
--- a/opensm/opensm/osm_opensm.c
+++ b/opensm/opensm/osm_opensm.c
@@ -169,14 +169,7 @@ static void setup_routing_engine(osm_opensm_t *osm, const char *name)
 			memset(re, 0, sizeof(struct osm_routing_engine));
 
 			re->name = m->name;
-			if (m->setup(re, osm)) {
-				OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
-					"setup of routing"
-					" engine \'%s\' failed\n", name);
-				return;
-			}
-			OSM_LOG(&osm->log, OSM_LOG_DEBUG,
-				"\'%s\' routing engine set up\n", re->name);
+			re->setup = (int (*)(void *, void *))m->setup;
 			append_routing_engine(osm, re);
 			return;
 		}
@@ -236,6 +229,55 @@ static void destroy_routing_engines(osm_opensm_t *osm)
 			r->delete(r->context);
 		free(r);
 	}
+	osm->routing_engine_list = NULL;
+}
+
+static void update_routing_engine(
+	struct osm_routing_engine *cur,
+	struct osm_routing_engine *last)
+{
+	cur->context = last->context;
+	cur->initialized = last->initialized;
+	cur->setup = last->setup;
+	cur->build_lid_matrices = last->build_lid_matrices;
+	cur->ucast_build_fwd_tables = last->ucast_build_fwd_tables;
+	cur->ucast_dump_tables = last->ucast_dump_tables;
+	cur->delete = last->delete;
+}
+
+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;
+	}
 }
 
 /**********************************************************************
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index 4ab440b..62b7bc7 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 *))
@@ -325,7 +330,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 fe0a446..abae978 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -970,8 +970,25 @@ int osm_ucast_mgr_process(IN osm_ucast_mgr_t * const p_mgr)
 
 	p_osm->routing_engine_used = OSM_ROUTING_ENGINE_TYPE_NONE;
 	while (p_routing_eng) {
+		if (!p_routing_eng->initialized && 
+			p_routing_eng->setup(p_routing_eng, p_osm)) {
+			OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
+					"ERR 3A0F: setup of routing engine \'%s\' failed\n", 
+					p_routing_eng->name);
+			p_routing_eng = p_routing_eng->next;
+			continue;
+		}
+		OSM_LOG(p_mgr->p_log, OSM_LOG_INFO,
+			"\'%s\' routing engine set up\n", p_routing_eng->name);
+		p_routing_eng->initialized = 1;
+
 		if (!ucast_mgr_route(p_routing_eng, p_osm))
 			break;
+
+		/* delete unused routing engine */
+		if (p_routing_eng->delete)
+			p_routing_eng->delete(p_routing_eng->context);
+
 		p_routing_eng = p_routing_eng->next;
 	}
 
@@ -982,6 +999,18 @@ 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->initialized &&
+			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);
+	}
+
 	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