This implements the real stuff in this patch series. Loads and parses
the guid_routing_order_file. Finds ports that aren't specified in the
file and puts them at the end of the list for sorting. I do add a flag
variable into osm_port_t for convenience.
Al
--
Albert Chu
[EMAIL PROTECTED]
925-422-5311
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
>From 93c7585b42a9a51658636cc209ccde5272f2905c Mon Sep 17 00:00:00 2001
From: Albert L. Chu <[EMAIL PROTECTED]>
Date: Thu, 22 May 2008 10:15:43 -0700
Subject: [PATCH] support guid_routing_order_file
Signed-off-by: Albert L. Chu <[EMAIL PROTECTED]>
---
opensm/include/opensm/osm_port.h | 4 +
opensm/opensm/osm_ucast_updn.c | 230 +++++++++++++++++++++++++++++++++++++-
2 files changed, 233 insertions(+), 1 deletions(-)
diff --git a/opensm/include/opensm/osm_port.h b/opensm/include/opensm/osm_port.h
index a9bf78f..5977410 100644
--- a/opensm/include/opensm/osm_port.h
+++ b/opensm/include/opensm/osm_port.h
@@ -1154,6 +1154,7 @@ typedef struct _osm_port {
unsigned is_new;
osm_physp_t *p_physp;
cl_qlist_t mcm_list;
+ int flag;
} osm_port_t;
/*
* FIELDS
@@ -1178,6 +1179,9 @@ typedef struct _osm_port {
* mcm_list
* Multicast member list
*
+* flag
+* Utility flag for port management.
+*
* SEE ALSO
* Port, Physical Port, Physical Port Table
*********/
diff --git a/opensm/opensm/osm_ucast_updn.c b/opensm/opensm/osm_ucast_updn.c
index e8428e8..85940e9 100644
--- a/opensm/opensm/osm_ucast_updn.c
+++ b/opensm/opensm/osm_ucast_updn.c
@@ -52,6 +52,7 @@
#include <ctype.h>
#include <complib/cl_debug.h>
#include <complib/cl_qmap.h>
+#include <complib/cl_qlist.h>
#include <opensm/osm_switch.h>
#include <opensm/osm_opensm.h>
#include <opensm/osm_ucast_mgr.h>
@@ -81,6 +82,22 @@ struct updn_node {
unsigned visited;
};
+struct updn_list_ctx {
+ osm_ucast_mgr_t *p_mgr;
+ cl_qlist_t *p_list;
+};
+
+struct updn_guid_list_item {
+ cl_list_item_t list;
+ uint64_t ho_guid;
+ uint64_t no_guid;
+};
+
+struct updn_port_list_item {
+ cl_list_item_t list;
+ osm_port_t *p_port;
+};
+
/* ///////////////////////////////// */
/* Statics */
/* ///////////////////////////////// */
@@ -681,6 +698,168 @@ _exit:
}
/**********************************************************************
**********************************************************************/
+static int
+__guid_qlist_insert(void *ctx, uint64_t guid, char *p)
+{
+ struct updn_list_ctx *list_ctx = ctx;
+ struct updn_guid_list_item *item = NULL;
+
+ item = malloc(sizeof(struct updn_guid_list_item));
+ if (!item) {
+ OSM_LOG(list_ctx->p_mgr->p_log, OSM_LOG_DEBUG,
+ "__guid_qlist_insert: insufficient memory\n");
+ return -1;
+ }
+
+ item->ho_guid = guid;
+ item->no_guid = cl_ntoh64(guid);
+ cl_qlist_insert_tail(list_ctx->p_list, &item->list);
+
+ return 0;
+}
+
+static void
+__clear_port_flag(IN cl_map_item_t * const p_map_item, void *context)
+{
+ osm_port_t *p_port = (osm_port_t *)p_map_item;
+
+ p_port->flag = 0;
+}
+
+static void
+__find_non_specified_ports(IN cl_map_item_t * const p_map_item, void *context)
+{
+ osm_port_t *p_port = (osm_port_t *)p_map_item;
+ struct updn_list_ctx *list_ctx = context;
+ osm_ucast_mgr_t *p_mgr = list_ctx->p_mgr;
+ cl_qlist_t *port_routing_order_list = list_ctx->p_list;
+
+ if (!p_port->flag) {
+ struct updn_port_list_item *p_item = NULL;
+
+ p_item = malloc(sizeof(struct updn_port_list_item));
+ if (!p_item) {
+ OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
+ "__find_non_specified_ports: insufficient memory\n");
+ return;
+ }
+
+ p_item->p_port = p_port;
+ cl_qlist_insert_tail(port_routing_order_list, &p_item->list);
+ }
+}
+
+static int
+__port_qlist_create(osm_ucast_mgr_t *p_mgr,
+ cl_qlist_t *guid_routing_order_list,
+ cl_qlist_t *port_routing_order_list)
+{
+ cl_qmap_t *p_port_tbl = &p_mgr->p_subn->port_guid_tbl;
+ struct updn_guid_list_item *g_item;
+ struct updn_list_ctx list_ctx;
+ osm_port_t *p_port;
+
+ /* Set each osm_port_t flag to 0 */
+ cl_qmap_apply_func(p_port_tbl, __clear_port_flag, NULL);
+
+ /* Find the port of the guid input */
+ for (g_item = (void *)cl_qlist_head(guid_routing_order_list);
+ g_item != (void *)cl_qlist_end(guid_routing_order_list);
+ g_item = (void *)cl_qlist_next(&g_item->list)) {
+ struct updn_port_list_item *p_item = NULL;
+
+ p_port = (void *)cl_qmap_get(p_port_tbl, g_item->no_guid);
+ if (p_port == (void *)cl_qmap_end(p_port_tbl)) {
+ OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
+ "UPDN - port guid not found: 0x%016" PRIx64 "\n",
+ g_item->ho_guid);
+ continue;
+ }
+
+ if (p_port->flag) {
+ OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
+ "UPDN - port guid specified multiple times"
+ "0x%016" PRIx64 "\n",
+ g_item->ho_guid);
+ continue;
+ }
+
+ p_item = malloc(sizeof(struct updn_port_list_item));
+ if (!p_item) {
+ OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
+ "__port_qlist_create: insufficient memory\n");
+ return -1;
+ }
+
+ p_item->p_port = p_port;
+ cl_qlist_insert_tail(port_routing_order_list, &p_item->list);
+ p_port->flag++;
+ }
+
+ /* Any ports not specified, add them to the end of the list */
+
+ list_ctx.p_mgr = p_mgr;
+ list_ctx.p_list = port_routing_order_list;
+
+ cl_qmap_apply_func(p_port_tbl, __find_non_specified_ports,
+ &list_ctx);
+
+ return 0;
+}
+
+static void
+__osm_updn_build_fwd_tables_ordered_cb(IN cl_map_item_t * const p_map_item,
+ IN void *context)
+{
+ osm_switch_t *const p_sw = (osm_switch_t *) p_map_item;
+ struct updn_list_ctx *list_ctx = (struct updn_list_ctx *)context;
+ osm_ucast_mgr_t *p_mgr = list_ctx->p_mgr;
+ cl_qlist_t *port_routing_order_list = list_ctx->p_list;
+ struct updn_port_list_item *p_item;
+ osm_node_t *p_node;
+
+ OSM_LOG_ENTER(p_mgr->p_log);
+
+ p_node = p_sw->p_node;
+
+ CL_ASSERT(p_node);
+ CL_ASSERT(osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH);
+
+ if (osm_log_is_active(p_mgr->p_log, OSM_LOG_DEBUG)) {
+ OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
+ "UPDN - Processing switch 0x%" PRIx64 "\n",
+ cl_ntoh64(osm_node_get_node_guid(p_node)));
+ }
+
+ /* Initialize LIDs in buffer to invalid port number. */
+ memset(p_mgr->lft_buf, OSM_NO_PATH, IB_LID_UCAST_END_HO + 1);
+
+ for (p_item = (void *)cl_qlist_head(port_routing_order_list);
+ p_item != (void *)cl_qlist_end(port_routing_order_list);
+ p_item = (void *)cl_qlist_next(&p_item->list)) {
+ osm_ucast_mgr_process_port(p_mgr, p_sw, p_item->p_port);
+ }
+
+ osm_ucast_mgr_set_fwd_table(p_mgr, p_sw);
+ OSM_LOG_EXIT(p_mgr->p_log);
+}
+
+static void
+__osm_updn_build_fwd_tables_ordered(IN osm_ucast_mgr_t * const p_mgr,
+ IN cl_qlist_t *port_routing_order_list)
+{
+ cl_qmap_t *p_sw_guid_tbl;
+ struct updn_list_ctx list_ctx;
+
+ p_sw_guid_tbl = &p_mgr->p_subn->sw_guid_tbl;
+
+ list_ctx.p_mgr = p_mgr;
+ list_ctx.p_list = port_routing_order_list;
+
+ cl_qmap_apply_func(p_sw_guid_tbl, __osm_updn_build_fwd_tables_ordered_cb,
+ &list_ctx);
+}
+
static void
__osm_updn_build_fwd_tables_default_cb(IN cl_map_item_t * const p_map_item,
IN void *context)
@@ -708,16 +887,65 @@ __osm_updn_fwd(void *ctx)
updn_t *p_updn;
osm_opensm_t *p_osm;
osm_ucast_mgr_t *p_mgr;
+ cl_qmap_t *p_sw_guid_tbl;
+ cl_qlist_t guid_routing_order_list;
+ cl_qlist_t port_routing_order_list;
+ unsigned int lists_created = 0;
+ unsigned int use_routing_order = 0;
+ int ret = 0;
CL_ASSERT(ctx);
p_updn = ctx;
p_osm = p_updn->p_osm;
p_mgr = &(p_osm->sm.ucast_mgr);
+ p_sw_guid_tbl = &(p_mgr->p_subn->sw_guid_tbl);
OSM_LOG_ENTER(p_mgr->p_log);
- __osm_updn_build_fwd_tables_default(p_mgr);
+ if (p_osm->subn.opt.guid_routing_order_file) {
+ struct updn_list_ctx list_ctx;
+
+ OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
+ "UPDN - Fetching guid routing order file %s\n",
+ p_osm->subn.opt.guid_routing_order_file);
+
+ cl_qlist_init(&guid_routing_order_list);
+ cl_qlist_init(&port_routing_order_list);
+
+ lists_created++;
+
+ list_ctx.p_mgr = p_mgr;
+ list_ctx.p_list = &guid_routing_order_list;
+
+ ret = parse_node_map(p_osm->subn.opt.guid_routing_order_file,
+ __guid_qlist_insert,
+ &list_ctx);
+ if (!ret && cl_qlist_count(&guid_routing_order_list)) {
+ if (__port_qlist_create(p_mgr,
+ &guid_routing_order_list,
+ &port_routing_order_list) < 0)
+ goto cleanup;
+ use_routing_order++;
+ }
+ else
+ OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR : "
+ "cannot parse guid routing order file %s\n",
+ p_updn->p_osm->subn.opt.guid_routing_order_file);
+ }
+
+ if (use_routing_order)
+ __osm_updn_build_fwd_tables_ordered(p_mgr, &port_routing_order_list);
+ else
+ __osm_updn_build_fwd_tables_default(p_mgr);
+cleanup:
+ if (lists_created) {
+ while (!cl_is_qlist_empty(&guid_routing_order_list))
+ free(cl_qlist_remove_head(&guid_routing_order_list));
+
+ while (!cl_is_qlist_empty(&port_routing_order_list))
+ free(cl_qlist_remove_head(&port_routing_order_list));
+ }
OSM_LOG_EXIT(p_mgr->p_log);
--
1.5.1
_______________________________________________
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