[ofa-general] [PATCH 3/6] Improve the switch_map by storing the map file in memory for faster lookups
Ira Weiny
weiny2 at llnl.gov
Thu Oct 25 11:43:32 PDT 2007
>From e11fd56785ed646018735f990346023e733b5358 Mon Sep 17 00:00:00 2001
From: Ira K. Weiny <weiny2 at llnl.gov>
Date: Fri, 19 Oct 2007 16:25:26 -0700
Subject: [PATCH] Improve the switch_map by storing the map file in memory for faster lookups
This also makes lookups thread safe as long as "free_switch_map" is not
called.
Signed-off-by: Ira K. Weiny <weiny2 at llnl.gov>
---
infiniband-diags/src/ibnetdiscover.c | 28 ++----
infiniband-diags/src/ibtracert.c | 28 ++----
infiniband-diags/src/saquery.c | 12 +-
infiniband-diags/src/smpquery.c | 12 +-
libibcommon/Makefile.am | 2 +-
libibcommon/include/infiniband/common.h | 41 +++++---
libibcommon/src/libibcommon.map | 4 +-
libibcommon/src/switch_map.c | 155 +++++++++++++++++++++++++++++++
libibcommon/src/util.c | 83 ----------------
9 files changed, 214 insertions(+), 151 deletions(-)
create mode 100644 libibcommon/src/switch_map.c
diff --git a/infiniband-diags/src/ibnetdiscover.c b/infiniband-diags/src/ibnetdiscover.c
index e627e84..2857117 100644
--- a/infiniband-diags/src/ibnetdiscover.c
+++ b/infiniband-diags/src/ibnetdiscover.c
@@ -91,8 +91,8 @@ static FILE *f;
char *argv0 = "ibnetdiscover";
-static char *switch_map = NULL;
-static FILE *switch_map_fp = NULL;
+static char *switch_map_name = NULL;
+static sw_map_t *switch_map = NULL;
Node *nodesdist[MAXHOPS+1]; /* last is Ca list */
Node *mynode;
@@ -462,7 +462,7 @@ list_node(Node *node)
char *nodename = NULL;
if (node->type == SWITCH_NODE)
- nodename = lookup_switch_name(switch_map_fp, node->nodeguid,
+ nodename = lookup_switch_name(switch_map, node->nodeguid,
node->nodedesc);
else
nodename = clean_nodedesc(node->nodedesc);
@@ -484,9 +484,6 @@ list_node(Node *node)
node_type,
node->nodeguid, node->numports, node->devid, node->vendid,
nodename);
-
- if (nodename && (node->type == SWITCH_NODE))
- free(nodename);
}
void
@@ -542,7 +539,7 @@ out_switch(Node *node, int group, char *chname)
}
if (node->type == SWITCH_NODE)
- nodename = lookup_switch_name(switch_map_fp, node->nodeguid,
+ nodename = lookup_switch_name(switch_map, node->nodeguid,
node->nodedesc);
else
nodename = clean_nodedesc(node->nodedesc);
@@ -551,8 +548,6 @@ out_switch(Node *node, int group, char *chname)
nodename,
node->smaenhsp0 ? "enhanced" : "base",
node->smalid, node->smalmc);
- if (nodename && (node->type == SWITCH_NODE))
- free(nodename);
}
void
@@ -613,7 +608,7 @@ out_switch_port(Port *port, int group)
fprintf(f, "%s", ext_port_str);
if (port->remoteport->node->type == SWITCH_NODE)
- rem_nodename = lookup_switch_name(switch_map_fp,
+ rem_nodename = lookup_switch_name(switch_map,
port->remoteport->node->nodeguid,
port->remoteport->node->nodedesc);
else
@@ -637,9 +632,6 @@ out_switch_port(Port *port, int group)
else if (is_xsigo_hca(port->remoteport->portguid))
fprintf(f, " (scp)");
fprintf(f, "\n");
-
- if (rem_nodename && (port->remoteport->node->type == SWITCH_NODE))
- free(rem_nodename);
}
void
@@ -661,7 +653,7 @@ out_ca_port(Port *port, int group)
fprintf(f, " (%" PRIx64 ") ", port->remoteport->portguid);
if (port->remoteport->node->type == SWITCH_NODE)
- rem_nodename = lookup_switch_name(switch_map_fp,
+ rem_nodename = lookup_switch_name(switch_map,
port->remoteport->node->nodeguid,
port->remoteport->node->nodedesc);
else
@@ -671,8 +663,6 @@ out_ca_port(Port *port, int group)
port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,
get_linkwidth_str(port->linkwidth),
get_linkspeed_str(port->linkspeed));
- if (rem_nodename && (port->remoteport->node->type == SWITCH_NODE))
- free(rem_nodename);
}
int
@@ -902,7 +892,7 @@ main(int argc, char **argv)
break;
switch(ch) {
case 1:
- switch_map = strdup(optarg);
+ switch_map_name = strdup(optarg);
break;
case 'C':
ca = optarg;
@@ -959,7 +949,7 @@ main(int argc, char **argv)
IBERROR("can't open file %s for writing", argv[0]);
madrpc_init(ca, ca_port, mgmt_classes, 2);
- switch_map_fp = open_switch_map(switch_map);
+ switch_map = create_switch_map(switch_map_name);
if (discover(&my_portid) < 0)
IBERROR("discover");
@@ -969,6 +959,6 @@ main(int argc, char **argv)
dump_topology(list, group);
- close_switch_map(switch_map_fp);
+ free_switch_map(switch_map);
exit(0);
}
diff --git a/infiniband-diags/src/ibtracert.c b/infiniband-diags/src/ibtracert.c
index e553f4f..aee0b1c 100644
--- a/infiniband-diags/src/ibtracert.c
+++ b/infiniband-diags/src/ibtracert.c
@@ -70,8 +70,8 @@ static FILE *f;
char *argv0 = "ibtracert";
-static char *switch_map = NULL;
-static FILE *switch_map_fp = NULL;
+static char *switch_map_name = NULL;
+static sw_map_t *switch_map = NULL;
typedef struct Port Port;
typedef struct Switch Switch;
@@ -205,7 +205,7 @@ dump_endnode(int dump, char *prompt, Node *node, Port *port)
}
if (node->type == IB_NODE_SWITCH)
- nodename = lookup_switch_name(switch_map_fp, node->nodeguid, node->nodedesc);
+ nodename = lookup_switch_name(switch_map, node->nodeguid, node->nodedesc);
else
nodename = clean_nodedesc(node->nodedesc);
@@ -215,9 +215,6 @@ dump_endnode(int dump, char *prompt, Node *node, Port *port)
node->nodeguid, node->type == IB_NODE_SWITCH ? 0 : port->portnum,
port->lid, port->lid + (1 << port->lmc) - 1,
nodename);
-
- if (nodename && (node->type == IB_NODE_SWITCH))
- free(nodename);
}
static void
@@ -229,7 +226,7 @@ dump_route(int dump, Node *node, int outport, Port *port)
return;
if (node->type == IB_NODE_SWITCH)
- nodename = lookup_switch_name(switch_map_fp, node->nodeguid, node->nodedesc);
+ nodename = lookup_switch_name(switch_map, node->nodeguid, node->nodedesc);
else
nodename = clean_nodedesc(node->nodedesc);
@@ -243,9 +240,6 @@ dump_route(int dump, Node *node, int outport, Port *port)
port->portguid, port->portnum,
port->lid, port->lid + (1 << port->lmc) - 1,
nodename);
-
- if (nodename && (node->type == IB_NODE_SWITCH))
- free(nodename);
}
static int
@@ -645,7 +639,7 @@ dump_mcpath(Node *node, int dumplevel)
dump_mcpath(node->upnode, dumplevel);
if (node->type == IB_NODE_SWITCH)
- nodename = lookup_switch_name(switch_map_fp, node->nodeguid, node->nodedesc);
+ nodename = lookup_switch_name(switch_map, node->nodeguid, node->nodedesc);
else
nodename = clean_nodedesc(node->nodedesc);
@@ -655,7 +649,7 @@ dump_mcpath(Node *node, int dumplevel)
node->nodeguid, node->ports->portnum, node->ports->lid,
node->ports->lid + (1 << node->ports->lmc) - 1,
nodename);
- goto free_name;
+ return;
}
if (node->dist) {
@@ -679,10 +673,6 @@ dump_mcpath(Node *node, int dumplevel)
node->nodeguid, node->ports->portnum, node->ports->lid,
node->ports->lid + (1 << node->ports->lmc) - 1,
nodename);
-
-free_name:
- if (nodename && (node->type == IB_NODE_SWITCH))
- free(nodename);
}
static void
@@ -752,7 +742,7 @@ main(int argc, char **argv)
break;
switch(ch) {
case 1:
- switch_map = strdup(optarg);
+ switch_map_name = strdup(optarg);
break;
case 'C':
ca = optarg;
@@ -810,7 +800,7 @@ main(int argc, char **argv)
usage();
madrpc_init(ca, ca_port, mgmt_classes, 3);
- switch_map_fp = open_switch_map(switch_map);
+ switch_map = create_switch_map(switch_map_name);
if (ib_resolve_portid_str(&src_portid, argv[0], dest_type, sm_id) < 0)
IBERROR("can't resolve source port %s", argv[0]);
@@ -849,6 +839,6 @@ main(int argc, char **argv)
/* dump multicast path */
dump_mcpath(endnode, dumplevel);
- close_switch_map(switch_map_fp);
+ free_switch_map(switch_map);
exit(0);
}
diff --git a/infiniband-diags/src/saquery.c b/infiniband-diags/src/saquery.c
index e17ec5a..f76fa41 100644
--- a/infiniband-diags/src/saquery.c
+++ b/infiniband-diags/src/saquery.c
@@ -59,8 +59,8 @@
char *argv0 = "saquery";
-static char *switch_map = NULL;
-static FILE *switch_map_fp = NULL;
+static char *switch_map_name = NULL;
+static sw_map_t *switch_map = NULL;
/**
* Declare some globals because I don't want this to be too complex.
@@ -137,7 +137,7 @@ print_node_record(ib_node_record_t *node_record)
case NAME_OF_LID:
case NAME_OF_GUID:
if (p_ni->node_type == IB_NODE_TYPE_SWITCH)
- name = lookup_switch_name(switch_map_fp,
+ name = lookup_switch_name(switch_map,
cl_ntoh64(p_ni->node_guid),
(char *)p_nd->description);
else
@@ -1144,7 +1144,7 @@ main(int argc, char **argv)
break;
}
case 2:
- switch_map = strdup(optarg);
+ switch_map_name = strdup(optarg);
break;
case 'p':
query_type = IB_MAD_ATTR_PATH_RECORD;
@@ -1249,7 +1249,7 @@ main(int argc, char **argv)
}
bind_handle = get_bind_handle();
- switch_map_fp = open_switch_map(switch_map);
+ switch_map = create_switch_map(switch_map_name);
switch (query_type) {
case IB_MAD_ATTR_NODE_RECORD:
@@ -1295,6 +1295,6 @@ main(int argc, char **argv)
if (dst)
free(dst);
clean_up();
- close_switch_map(switch_map_fp);
+ free_switch_map(switch_map);
return (status);
}
diff --git a/infiniband-diags/src/smpquery.c b/infiniband-diags/src/smpquery.c
index 73e880b..29ba9c2 100644
--- a/infiniband-diags/src/smpquery.c
+++ b/infiniband-diags/src/smpquery.c
@@ -84,8 +84,8 @@ static const match_rec_t match_tbl[] = {
};
char *argv0 = "smpquery";
-static char *switch_map = NULL;
-static FILE *switch_map_fp = NULL;
+static char *switch_map_name = NULL;
+static sw_map_t *switch_map = NULL;
/*******************************************/
static char *
@@ -108,7 +108,7 @@ node_desc(ib_portid_t *dest, char **argv, int argc)
return "node desc query failed";
if (node_type == IB_NODE_SWITCH)
- nodename = lookup_switch_name(switch_map_fp, node_guid, nd);
+ nodename = lookup_switch_name(switch_map, node_guid, nd);
else
nodename = clean_nodedesc(nd);
@@ -458,7 +458,7 @@ main(int argc, char **argv)
break;
switch(ch) {
case 1:
- switch_map = strdup(optarg);
+ switch_map_name = strdup(optarg);
break;
case 'd':
ibdebug++;
@@ -514,7 +514,7 @@ main(int argc, char **argv)
IBERROR("operation '%s' not supported", argv[0]);
madrpc_init(ca, ca_port, mgmt_classes, 3);
- switch_map_fp = open_switch_map(switch_map);
+ switch_map = create_switch_map(switch_map_name);
if (dest_type != IB_DEST_DRSLID) {
if (ib_resolve_portid_str(&portid, argv[1], dest_type, sm_id) < 0)
@@ -531,6 +531,6 @@ main(int argc, char **argv)
if ((err = fn(&portid, argv+3, argc-3)))
IBERROR("operation %s: %s", argv[0], err);
}
- close_switch_map(switch_map_fp);
+ free_switch_map(switch_map);
exit(0);
}
diff --git a/libibcommon/Makefile.am b/libibcommon/Makefile.am
index af60035..8d54437 100644
--- a/libibcommon/Makefile.am
+++ b/libibcommon/Makefile.am
@@ -13,7 +13,7 @@ else
libibcommon_version_script =
endif
-libibcommon_la_SOURCES = src/stack.c src/sysfs.c src/util.c src/time.c src/hash.c
+libibcommon_la_SOURCES = src/stack.c src/sysfs.c src/util.c src/time.c src/hash.c src/switch_map.c
libibcommon_la_LDFLAGS = -version-info $(ibcommon_api_version) \
-export-dynamic $(libibcommon_version_script)
libibcommon_la_DEPENDENCIES = $(srcdir)/src/libibcommon.map
diff --git a/libibcommon/include/infiniband/common.h b/libibcommon/include/infiniband/common.h
index bd78f41..f8e8549 100644
--- a/libibcommon/include/infiniband/common.h
+++ b/libibcommon/include/infiniband/common.h
@@ -126,21 +126,6 @@ void logmsg(const char *const fn, char *msg, ...) IBCOMMON_STRICT_FORMAT;
void xdump(FILE *file, char *msg, void *p, int size);
-/* NOTE: this modifies the parameter "nodedesc". */
-char *clean_nodedesc(char *nodedesc);
-
-/**
- * Switch map interface.
- * It is OK to pass NULL for the switch_map[_fp] parameters.
- */
-FILE *open_switch_map(char *switch_map);
-void close_switch_map(FILE *switch_map_fp);
-char *lookup_switch_name(FILE *switch_map_fp, uint64_t target_guid,
- char *nodedesc);
- /* NOTE: parameter "nodedesc" may be modified here.
- * return pointer must be free'd by caller
- */
-
/* sysfs.c: /sys utilities */
int sys_read_string(char *dir_name, char *file_name, char *str, int max_len);
int sys_read_guid(char *dir_name, char *file_name, uint64_t *net_guid);
@@ -158,6 +143,32 @@ uint64_t getcurrenttime(void);
/* hash.c */
uint32_t fhash(uint8_t *k, int length, uint32_t initval);
+
+/* switch_map.c */
+typedef struct _sw_name_ent {
+ uint64_t guid;
+ char *name;
+} sw_name_ent_t;
+typedef struct _switch_map {
+ FILE *fp;
+ int num;
+ sw_name_ent_t names[1]; /* MUST BE LAST */
+} sw_map_t;
+
+/*
+ * create and free ARE NOT thread safe
+ * However lookup_switch_name IS thread safe as long as free is not called
+ * during lookup.
+ */
+sw_map_t *create_switch_map(char *switch_map_name);
+void free_switch_map(sw_map_t *map);
+char *lookup_switch_name(sw_map_t *map,
+ uint64_t target_guid,
+ char *nodedesc /* "nodedesc" may be modified */
+ );
+/* NOTE: this modifies the parameter "nodedesc". */
+char *clean_nodedesc(char *nodedesc);
+
END_C_DECLS
#endif /* __COMMON_H__ */
diff --git a/libibcommon/src/libibcommon.map b/libibcommon/src/libibcommon.map
index afd8e6d..7415233 100644
--- a/libibcommon/src/libibcommon.map
+++ b/libibcommon/src/libibcommon.map
@@ -14,8 +14,8 @@ IBCOMMON_1.0 {
ibwarn;
xdump;
clean_nodedesc;
- open_switch_map;
- close_switch_map;
+ create_switch_map;
+ free_switch_map;
lookup_switch_name;
local: *;
};
diff --git a/libibcommon/src/switch_map.c b/libibcommon/src/switch_map.c
new file mode 100644
index 0000000..37fd60f
--- /dev/null
+++ b/libibcommon/src/switch_map.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2007 Lawrence Livermore National Laboratory (LLNL)
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <common.h>
+
+
+char *
+clean_nodedesc(char *nodedesc)
+{
+ int i = 0;
+
+ nodedesc[63] = '\0';
+ while (nodedesc[i]) {
+ if (!isprint(nodedesc[i]))
+ nodedesc[i] = ' ';
+ i++;
+ }
+
+ return (nodedesc);
+}
+
+static sw_map_t *
+read_names(sw_map_t *map)
+{
+ char *line = NULL;
+ size_t len = 0;
+
+ rewind(map->fp);
+ while (getline(&line, &len, map->fp) != -1) {
+ char *guid_str = NULL;
+ char *name = NULL;
+ line[len-1] = '\0';
+ if (line[0] == '#')
+ goto next_one;
+
+ guid_str = strtok(line, "\"#");
+ name = strtok(NULL, "\"#");
+ if (!guid_str || !name)
+ goto next_one;
+
+ map->num++;
+ map = realloc(map, sizeof(*map) + (sizeof(sw_name_ent_t) * map->num));
+ map->names[map->num -1].guid = strtoull(guid_str, NULL, 0);
+ map->names[map->num -1].name = strdup(name);
+next_one:
+ free (line);
+ line = NULL;
+ }
+
+ return (map);
+}
+
+sw_map_t *
+create_switch_map(char *switch_map)
+{
+ FILE *tmp_fp = NULL;
+ sw_map_t *rc = NULL;
+
+ if (switch_map != NULL) {
+ tmp_fp = fopen(switch_map, "r");
+ if (tmp_fp == NULL) {
+ fprintf(stderr,
+ "WARNING failed to open switch map \"%s\" (%s)\n",
+ switch_map, strerror(errno));
+ }
+#ifdef HAVE_DEFAULT_SWITCH_MAP
+ } else {
+ tmp_fp = fopen(HAVE_DEFAULT_SWITCH_MAP, "r");
+#endif /* HAVE_DEFAULT_SWITCH_MAP */
+ }
+ if (!tmp_fp)
+ return (NULL);
+
+ rc = malloc(sizeof(*rc));
+ if (!rc)
+ return (NULL);
+ rc->fp = tmp_fp;
+ rc->num = 0;
+ rc = read_names(rc);
+ return (rc);
+}
+
+void
+free_switch_map(sw_map_t *map)
+{
+ int i = 0;
+ if (map == NULL)
+ return;
+ for (i = 0; i < map->num; i++)
+ free(map->names[i].name);
+ if (map->fp)
+ fclose(map->fp);
+ free(map);
+}
+
+char *
+lookup_switch_name(sw_map_t *map, uint64_t target_guid, char *nodedesc)
+{
+ int i = 0;
+ char *rc = NULL;
+
+ if (map == NULL)
+ goto done;
+
+ for (i = 0; i < map->num; i++)
+ if (map->names[i].guid == target_guid)
+ return (map->names[i].name);
+done:
+ if (rc == NULL)
+ rc = clean_nodedesc(nodedesc);
+ return (rc);
+}
+
diff --git a/libibcommon/src/util.c b/libibcommon/src/util.c
index e2f45f4..7da967e 100644
--- a/libibcommon/src/util.c
+++ b/libibcommon/src/util.c
@@ -133,86 +133,3 @@ xdump(FILE *file, char *msg, void *p, int size)
fputc('\n', file);
}
}
-
-char *
-clean_nodedesc(char *nodedesc)
-{
- int i = 0;
-
- nodedesc[63] = '\0';
- while (nodedesc[i]) {
- if (!isprint(nodedesc[i]))
- nodedesc[i] = ' ';
- i++;
- }
-
- return (nodedesc);
-}
-
-FILE *
-open_switch_map(char *switch_map)
-{
- FILE *rc = NULL;
-
- if (switch_map != NULL) {
- rc = fopen(switch_map, "r");
- if (rc == NULL) {
- fprintf(stderr,
- "WARNING failed to open switch map \"%s\" (%s)\n",
- switch_map, strerror(errno));
- }
-#ifdef HAVE_DEFAULT_SWITCH_MAP
- } else {
- rc = fopen(HAVE_DEFAULT_SWITCH_MAP, "r");
-#endif /* HAVE_DEFAULT_SWITCH_MAP */
- }
- return (rc);
-}
-
-void
-close_switch_map(FILE *fp)
-{
- if (fp)
- fclose(fp);
-}
-
-char *
-lookup_switch_name(FILE *switch_map_fp, uint64_t target_guid, char *nodedesc)
-{
-#define NAME_LEN (256)
- char *line = NULL;
- size_t len = 0;
- uint64_t guid = 0;
- char *rc = NULL;
- int line_count = 0;
-
- if (switch_map_fp == NULL)
- goto done;
-
- rewind(switch_map_fp);
- for (line_count = 1;
- getline(&line, &len, switch_map_fp) != -1;
- line_count++) {
- line[len-1] = '\0';
- if (line[0] == '#')
- goto next_one;
- char *guid_str = strtok(line, "\"#");
- char *name = strtok(NULL, "\"#");
- if (!guid_str || !name)
- goto next_one;
- guid = strtoull(guid_str, NULL, 0);
- if (target_guid == guid) {
- rc = strdup(name);
- free (line);
- goto done;
- }
-next_one:
- free (line);
- line = NULL;
- }
-done:
- if (rc == NULL)
- rc = strdup(clean_nodedesc(nodedesc));
- return (rc);
-}
-
--
1.5.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Improve-the-switch_map-by-storing-the-map-file-in-me.patch
Type: application/octet-stream
Size: 19331 bytes
Desc: not available
URL: <http://lists.openfabrics.org/pipermail/general/attachments/20071025/6528c152/attachment.obj>
More information about the general
mailing list