From: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
To: "linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
<linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Cc: Jason Gunthorpe
<jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>,
Hal Rosenstock
<hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: [PATCH 2/3] infiniband-diags: libibnetdisc Allow a DR Path partial fabric query starting at a CA
Date: Wed, 20 Jul 2011 16:16:55 -0700 [thread overview]
Message-ID: <20110720161655.1ed38052.weiny2@llnl.gov> (raw)
The old algorithm would attempt to extend a DR path through the CA and fail.
The new algorithm retracts the path properly.
This does not work when combined routing is used with the CA as a starting
point. :-(
Signed-off-by: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
---
libibnetdisc/src/ibnetdisc.c | 83 ++++++++++++++++++++++++++++++++----------
libibnetdisc/src/internal.h | 1 +
2 files changed, 64 insertions(+), 20 deletions(-)
diff --git a/libibnetdisc/src/ibnetdisc.c b/libibnetdisc/src/ibnetdisc.c
index b7fa75a..07f2a3f 100644
--- a/libibnetdisc/src/ibnetdisc.c
+++ b/libibnetdisc/src/ibnetdisc.c
@@ -56,8 +56,13 @@
#include "chassis.h"
/* forward declare */
+struct ni_cbdata
+{
+ ibnd_node_t *node;
+ int port_num;
+};
static int query_node_info(smp_engine_t * engine, ib_portid_t * portid,
- ibnd_node_t * node);
+ struct ni_cbdata * cbdata);
static int recv_switch_info(smp_engine_t * engine, ibnd_smp_t * smp,
uint8_t * mad, void *cb_data)
@@ -87,6 +92,26 @@ static int add_port_to_dpath(ib_dr_path_t * path, int nextport)
return path->cnt;
}
+static int retract_dpath(smp_engine_t * engine, ib_portid_t * portid)
+{
+ ibnd_scan_t *scan = engine->user_data;
+ ibnd_fabric_t *fabric = scan->fabric;
+
+ if (scan->cfg->max_hops &&
+ fabric->maxhops_discovered > scan->cfg->max_hops)
+ return 0;
+
+ /* this may seem wrong but the only time we would retract the path is
+ * if the user specified a CA for the DR path and we are retracting
+ * from that to find the node it is connected to. This counts as a
+ * positive hop discovered
+ */
+ fabric->maxhops_discovered++;
+ portid->drpath.p[portid->drpath.cnt] = 0;
+ portid->drpath.cnt--;
+ return 1;
+}
+
static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
int nextport)
{
@@ -115,8 +140,9 @@ static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
return -1;
}
- if ((unsigned) portid->drpath.cnt > fabric->maxhops_discovered)
- fabric->maxhops_discovered = portid->drpath.cnt;
+ if (((unsigned) portid->drpath.cnt - scan->initial_hops) >
+ fabric->maxhops_discovered)
+ fabric->maxhops_discovered++;
return 1;
}
@@ -202,9 +228,26 @@ static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
== IB_PORT_PHYS_STATE_LINKUP
&& ((node->type == IB_NODE_SWITCH && port_num != local_port) ||
(node == fabric->from_node && port_num == fabric->from_portnum))) {
+
+ int rc = 0;
ib_portid_t path = smp->path;
- if (extend_dpath(engine, &path, port_num) > 0)
- query_node_info(engine, &path, node);
+
+ if (node->type != IB_NODE_SWITCH &&
+ node == fabric->from_node &&
+ path.drpath.cnt > 1)
+ rc = retract_dpath(engine, &path);
+ else {
+ /* we can't proceed through an HCA with DR */
+ if (path.lid == 0 || node->type == IB_NODE_SWITCH)
+ rc = extend_dpath(engine, &path, port_num);
+ }
+
+ if (rc > 0) {
+ struct ni_cbdata * cbdata = malloc(sizeof(*cbdata));
+ cbdata->node = node;
+ cbdata->port_num = port_num;
+ query_node_info(engine, &path, cbdata);
+ }
}
return 0;
@@ -255,11 +298,6 @@ static ibnd_node_t *create_node(smp_engine_t * engine, ib_portid_t * path,
return rc;
}
-static int get_last_port(ib_portid_t * path)
-{
- return path->drpath.p[path->drpath.cnt];
-}
-
static void link_ports(ibnd_node_t * node, ibnd_port_t * port,
ibnd_node_t * remotenode, ibnd_port_t * remoteport)
{
@@ -294,7 +332,9 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
ibnd_fabric_t *fabric = scan->fabric;
int i = 0;
uint8_t *node_info = mad + IB_SMP_DATA_OFFS;
- ibnd_node_t *rem_node = cb_data;
+ struct ni_cbdata *ni_cbdata = (struct ni_cbdata *)cb_data;
+ ibnd_node_t *rem_node = NULL;
+ int rem_port_num = 0;
ibnd_node_t *node;
int node_is_new = 0;
uint64_t node_guid = mad_get_field64(node_info, 0, IB_NODE_GUID_F);
@@ -302,6 +342,12 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
int port_num = mad_get_field(node_info, 0, IB_NODE_LOCAL_PORT_F);
ibnd_port_t *port = NULL;
+ if (ni_cbdata) {
+ rem_node = ni_cbdata->node;
+ rem_port_num = ni_cbdata->port_num;
+ free(ni_cbdata);
+ }
+
node = ibnd_find_node_guid(fabric, node_guid);
if (!node) {
node = create_node(engine, &smp->path, node_info);
@@ -333,8 +379,6 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
fabric->from_portnum = port_num;
} else {
/* link ports... */
- int rem_port_num = get_last_port(&smp->path);
-
if (!rem_node->ports[rem_port_num]) {
IBND_ERROR("Internal Error; "
"Node(%p) 0x%" PRIx64
@@ -363,11 +407,11 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
}
static int query_node_info(smp_engine_t * engine, ib_portid_t * portid,
- ibnd_node_t * node)
+ struct ni_cbdata * cbdata)
{
IBND_DEBUG("Query Node Info; %s\n", portid2str(portid));
return issue_smp(engine, portid, IB_ATTR_NODE_INFO, 0,
- recv_node_info, node);
+ recv_node_info, (void *)cbdata);
}
ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
@@ -430,8 +474,7 @@ void add_to_type_list(ibnd_node_t * node, ibnd_fabric_t * fabric)
}
}
-static int set_config(struct ibnd_config *config, struct ibnd_config *cfg,
- int initial_hops)
+static int set_config(struct ibnd_config *config, struct ibnd_config *cfg)
{
if (!config)
return (-EINVAL);
@@ -445,8 +488,6 @@ static int set_config(struct ibnd_config *config, struct ibnd_config *cfg,
config->timeout_ms = DEFAULT_TIMEOUT;
if (!config->retries)
config->retries = DEFAULT_RETRIES;
- if (config->max_hops)
- config->max_hops += initial_hops;
return (0);
}
@@ -467,7 +508,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
if (!from)
from = &my_portid;
- if (set_config(&config, cfg, from->drpath.cnt)) {
+ if (set_config(&config, cfg)) {
IBND_ERROR("Invalid ibnd_config\n");
return NULL;
}
@@ -483,6 +524,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
memset(&scan.selfportid, 0, sizeof(scan.selfportid));
scan.fabric = fabric;
scan.cfg = &config;
+ scan.initial_hops = from->drpath.cnt;
if (smp_engine_init(&engine, ca_name, ca_port, &scan, &config)) {
free(fabric);
@@ -505,6 +547,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
goto error;
fabric->total_mads_used = engine.total_smps;
+ fabric->maxhops_discovered += scan.initial_hops;
if (group_nodes(fabric))
goto error;
diff --git a/libibnetdisc/src/internal.h b/libibnetdisc/src/internal.h
index 3c599ec..80918c4 100644
--- a/libibnetdisc/src/internal.h
+++ b/libibnetdisc/src/internal.h
@@ -62,6 +62,7 @@ typedef struct ibnd_scan {
ibnd_fabric_t *fabric;
struct ibnd_config *cfg;
struct ibmad_port *ibmad_port;
+ unsigned initial_hops;
} ibnd_scan_t;
typedef struct ibnd_smp ibnd_smp_t;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next reply other threads:[~2011-07-20 23:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-20 23:16 Ira Weiny [this message]
[not found] ` <20110720161655.1ed38052.weiny2-i2BcT+NCU+M@public.gmane.org>
2011-07-20 23:34 ` [PATCH 2/3] infiniband-diags: libibnetdisc Allow a DR Path partial fabric query starting at a CA Jason Gunthorpe
[not found] ` <20110720233451.GL18090-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2011-07-20 23:53 ` Ira Weiny
[not found] ` <20110720165336.894b1298.weiny2-i2BcT+NCU+M@public.gmane.org>
2011-07-21 3:17 ` Jason Gunthorpe
2011-07-22 13:21 ` Hal Rosenstock
[not found] ` <4E297949.2000607-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2011-07-22 17:29 ` Jason Gunthorpe
[not found] ` <20110722172945.GP18090-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2011-07-22 22:00 ` Ira Weiny
[not found] ` <20110722150049.ba8e592f.weiny2-i2BcT+NCU+M@public.gmane.org>
2011-07-22 22:13 ` Jason Gunthorpe
[not found] ` <20110722221349.GT18090-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2011-07-22 22:26 ` Ira Weiny
2011-07-22 22:02 ` Hal Rosenstock
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110720161655.1ed38052.weiny2@llnl.gov \
--to=weiny2-i2bct+ncu+m@public.gmane.org \
--cc=hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org \
--cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox