public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's
@ 2010-05-11 23:48 Ira Weiny
       [not found] ` <20100511164812.e16e41e6.weiny2-i2BcT+NCU+M@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Ira Weiny @ 2010-05-11 23:48 UTC (permalink / raw)
  To: Sasha Khapyorsky; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org


From: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
Date: Tue, 11 May 2010 15:36:08 -0700
Subject: [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's

	Specify CA/Port to use which allows parallel scanning to other operations.

Signed-off-by: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
---
 .../libibnetdisc/include/infiniband/ibnetdisc.h    |   15 ++--
 infiniband-diags/libibnetdisc/src/ibnetdisc.c      |   52 +++++++-----
 infiniband-diags/libibnetdisc/src/internal.h       |   11 ++-
 infiniband-diags/libibnetdisc/src/query_smp.c      |   83 ++++++++++++++++----
 infiniband-diags/libibnetdisc/test/testleaks.c     |   16 +---
 infiniband-diags/src/iblinkinfo.c                  |    8 +-
 infiniband-diags/src/ibnetdiscover.c               |   14 +---
 infiniband-diags/src/ibqueryerrors.c               |   11 ++-
 8 files changed, 134 insertions(+), 76 deletions(-)

diff --git a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
index 2735224..83d0ba7 100644
--- a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
+++ b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
@@ -134,7 +134,9 @@ typedef struct ibnd_config {
 	unsigned show_progress;
 	unsigned max_hops;
 	unsigned debug;
-	uint8_t pad[64];
+	unsigned timeout_ms;
+	unsigned retries;
+	uint8_t pad[56];
 } ibnd_config_t;
 
 /** =========================================================================
@@ -166,15 +168,16 @@ typedef struct ibnd_fabric {
  * Initialization (fabric operations)
  */
 
-MAD_EXPORT ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port *ibmad_port,
+MAD_EXPORT ibnd_fabric_t *ibnd_discover_fabric(char * ca_name,
+					       int ca_port,
 					       ib_portid_t * from,
 					       struct ibnd_config *config);
 	/**
-	 * open: (required) ibmad_port object from libibmad
+	 * ca_name: (optional) name of the CA to use
+	 * ca_port: (optional) CA port to use
 	 * from: (optional) specify the node to start scanning from.
-	 *       If NULL start from the node we are running on.
-	 * hops: (optional) Specify how much of the fabric to traverse.
-	 *       negative value == scan entire fabric
+	 *       If NULL start from the CA/CA port specified
+	 * config: (optional) additional config options for the scan
 	 */
 MAD_EXPORT void ibnd_destroy_fabric(ibnd_fabric_t * fabric);
 
diff --git a/infiniband-diags/libibnetdisc/src/ibnetdisc.c b/infiniband-diags/libibnetdisc/src/ibnetdisc.c
index 98801de..3c374c7 100644
--- a/infiniband-diags/libibnetdisc/src/ibnetdisc.c
+++ b/infiniband-diags/libibnetdisc/src/ibnetdisc.c
@@ -380,21 +380,6 @@ ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
 	return NULL;
 }
 
-static int _check_ibmad_port(struct ibmad_port *ibmad_port)
-{
-	if (!ibmad_port) {
-		IBND_DEBUG("ibmad_port must be specified\n");
-		return -1;
-	}
-	if (mad_rpc_class_agent(ibmad_port, IB_SMI_CLASS) == -1
-	    || mad_rpc_class_agent(ibmad_port, IB_SMI_DIRECT_CLASS) == -1) {
-		IBND_DEBUG("ibmad_port must be opened with "
-			   "IB_SMI_CLASS && IB_SMI_DIRECT_CLASS\n");
-		return -1;
-	}
-	return 0;
-}
-
 ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str)
 {
 	int i = 0;
@@ -462,17 +447,38 @@ void add_to_type_list(ibnd_node_t * node, ibnd_fabric_t * fabric)
 	}
 }
 
-ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port *ibmad_port,
-				    ib_portid_t * from, struct ibnd_config *cfg)
+static int set_config(struct ibnd_config *config, struct ibnd_config *cfg)
 {
-	struct ibnd_config default_config = { 0 };
+	if (!config)
+		return (-EINVAL);
+
+	if (cfg)
+		memcpy(config, cfg, sizeof(*config));
+
+	if (!config->max_smps)
+		config->max_smps = DEFAULT_MAX_SMP_ON_WIRE;
+	if (!config->timeout_ms)
+		config->timeout_ms = DEFAULT_TIMEOUT;
+	if (!config->retries)
+		config->retries = DEFAULT_RETRIES;
+
+	return (0);
+}
+
+ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
+				    ib_portid_t * from,
+				    struct ibnd_config *cfg)
+{
+	struct ibnd_config config = { 0 };
 	ibnd_fabric_t *fabric = NULL;
 	ib_portid_t my_portid = { 0 };
 	smp_engine_t engine;
 	ibnd_scan_t scan;
 
-	if (_check_ibmad_port(ibmad_port) < 0)
+	if (set_config(&config, cfg)) {
+		IBND_ERROR("Invalid ibnd_config\n");
 		return NULL;
+	}
 
 	/* If not specified start from "my" port */
 	if (!from)
@@ -488,10 +494,12 @@ ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port *ibmad_port,
 
 	memset(&scan.selfportid, 0, sizeof(scan.selfportid));
 	scan.fabric = fabric;
-	scan.cfg = cfg ? cfg : &default_config;
+	scan.cfg = &config;
 
-	smp_engine_init(&engine, ibmad_port, &scan, cfg->max_smps ?
-			cfg->max_smps : DEFAULT_MAX_SMP_ON_WIRE);
+	if (smp_engine_init(&engine, ca_name, ca_port, &scan, &config)) {
+		free(fabric);
+		return (NULL);
+	}
 
 	IBND_DEBUG("from %s\n", portid2str(from));
 
diff --git a/infiniband-diags/libibnetdisc/src/internal.h b/infiniband-diags/libibnetdisc/src/internal.h
index 2cfde02..d037a60 100644
--- a/infiniband-diags/libibnetdisc/src/internal.h
+++ b/infiniband-diags/libibnetdisc/src/internal.h
@@ -54,6 +54,8 @@
 #define MAXHOPS         63
 
 #define DEFAULT_MAX_SMP_ON_WIRE 2
+#define DEFAULT_TIMEOUT 1000
+#define DEFAULT_RETRIES 3
 
 typedef struct ibnd_scan {
 	ib_portid_t selfportid;
@@ -76,16 +78,19 @@ struct ibnd_smp {
 
 struct smp_engine {
 	struct ibmad_port *ibmad_port;
+	int umad_fd;
+	int smi_agent;
+	int smi_dir_agent;
 	ibnd_smp_t *smp_queue_head;
 	ibnd_smp_t *smp_queue_tail;
 	void *user_data;
 	cl_qmap_t smps_on_wire;
-	int max_smps_on_wire;
+	struct ibnd_config *cfg;
 	unsigned total_smps;
 };
 
-void smp_engine_init(smp_engine_t * engine, struct ibmad_port *ibmad_port,
-		     void *user_data, int max_smps_on_wire);
+int smp_engine_init(smp_engine_t * engine, char * ca_name, int ca_port,
+		    void *user_data, ibnd_config_t *cfg);
 int issue_smp(smp_engine_t * engine, ib_portid_t * portid,
 	      unsigned attrid, unsigned mod, smp_comp_cb_t cb, void *cb_data);
 int process_mads(smp_engine_t * engine);
diff --git a/infiniband-diags/libibnetdisc/src/query_smp.c b/infiniband-diags/libibnetdisc/src/query_smp.c
index 7234844..4dbfa0d 100644
--- a/infiniband-diags/libibnetdisc/src/query_smp.c
+++ b/infiniband-diags/libibnetdisc/src/query_smp.c
@@ -61,25 +61,32 @@ static ibnd_smp_t *get_smp(smp_engine_t * engine)
 	return rc;
 }
 
-static int send_smp(ibnd_smp_t * smp, struct ibmad_port *srcport)
+static int send_smp(ibnd_smp_t * smp, smp_engine_t * engine)
 {
 	int rc = 0;
 	uint8_t umad[1024];
 	ib_rpc_t *rpc = &smp->rpc;
+	int agent = 0;
 
 	memset(umad, 0, umad_size() + IB_MAD_SIZE);
 
+	if (rpc->mgtclass == IB_SMI_CLASS) {
+		agent = engine->smi_agent;
+	} else if (rpc->mgtclass == IB_SMI_DIRECT_CLASS) {
+		agent = engine->smi_dir_agent;
+	} else {
+		IBND_ERROR("Invalid class for RPC\n");
+		return (-EIO);
+	}
+
 	if ((rc = mad_build_pkt(umad, &smp->rpc, &smp->path, NULL, NULL))
 	    < 0) {
 		IBND_ERROR("mad_build_pkt failed; %d\n", rc);
 		return rc;
 	}
 
-	if ((rc = umad_send(mad_rpc_portid(srcport),
-			    mad_rpc_class_agent(srcport, rpc->mgtclass),
-			    umad, IB_MAD_SIZE,
-			    mad_get_timeout(srcport, rpc->timeout),
-			    mad_get_retries(srcport))) < 0) {
+	if ((rc = umad_send(engine->umad_fd, agent, umad, IB_MAD_SIZE,
+			    engine->cfg->timeout_ms, engine->cfg->retries)) < 0) {
 		IBND_ERROR("send failed; %d\n", rc);
 		return rc;
 	}
@@ -91,12 +98,13 @@ static int process_smp_queue(smp_engine_t * engine)
 {
 	int rc = 0;
 	ibnd_smp_t *smp;
-	while (cl_qmap_count(&engine->smps_on_wire) < engine->max_smps_on_wire) {
+	while (cl_qmap_count(&engine->smps_on_wire)
+	       < engine->cfg->max_smps) {
 		smp = get_smp(engine);
 		if (!smp)
 			return 0;
 
-		if ((rc = send_smp(smp, engine->ibmad_port)) != 0) {
+		if ((rc = send_smp(smp, engine)) != 0) {
 			free(smp);
 			return rc;
 		}
@@ -122,7 +130,7 @@ int issue_smp(smp_engine_t * engine, ib_portid_t * portid,
 	smp->rpc.method = IB_MAD_METHOD_GET;
 	smp->rpc.attr.id = attrid;
 	smp->rpc.attr.mod = mod;
-	smp->rpc.timeout = mad_get_timeout(engine->ibmad_port, 0);
+	smp->rpc.timeout = engine->cfg->timeout_ms;
 	smp->rpc.datasz = IB_SMP_DATA_SIZE;
 	smp->rpc.dataoffs = IB_SMP_DATA_OFFS;
 	smp->rpc.trid = mad_trid();
@@ -153,7 +161,7 @@ static int process_one_recv(smp_engine_t * engine)
 	memset(umad, 0, sizeof(umad));
 
 	/* wait for the next message */
-	if ((rc = umad_recv(mad_rpc_portid(engine->ibmad_port), umad, &length,
+	if ((rc = umad_recv(engine->umad_fd, umad, &length,
 			    0)) < 0) {
 		if (rc == -EWOULDBLOCK)
 			return 0;
@@ -190,14 +198,58 @@ error:
 	return rc;
 }
 
-void smp_engine_init(smp_engine_t * engine, struct ibmad_port *ibmad_port,
-		     void *user_data, int max_smps_on_wire)
+int smp_engine_init(smp_engine_t * engine, char * ca_name, int ca_port,
+		    void *user_data, ibnd_config_t *cfg)
 {
+	int nc = 2;
+	int mc[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
+
 	memset(engine, 0, sizeof(*engine));
-	engine->ibmad_port = ibmad_port;
+
+	engine->ibmad_port = mad_rpc_open_port(ca_name, ca_port, mc, nc);
+	if (!engine->ibmad_port) {
+		IBND_ERROR("can't open MAD port (%s:%d)\n", ca_name, ca_port);
+		return -EIO;
+	}
+	mad_rpc_set_timeout(engine->ibmad_port, cfg->timeout_ms);
+	mad_rpc_set_retries(engine->ibmad_port, cfg->retries);
+
+	if (umad_init() < 0) {
+		IBND_ERROR("umad_init failed\n");
+		mad_rpc_close_port(engine->ibmad_port);
+		return -EIO;
+	}
+
+	engine->umad_fd = umad_open_port(ca_name, ca_port);
+	if (engine->umad_fd < 0) {
+		IBND_ERROR("can't open UMAD port (%s:%d)\n", ca_name, ca_port);
+		mad_rpc_close_port(engine->ibmad_port);
+		return -EIO;
+	}
+
+	if ((engine->smi_agent = umad_register(engine->umad_fd,
+	     IB_SMI_CLASS, 1, 0, 0)) < 0) {
+		IBND_ERROR("Failed to register SMI agent on (%s:%d)\n",
+			   ca_name, ca_port);
+		goto eio_close;
+	}
+
+	if ((engine->smi_dir_agent = umad_register(engine->umad_fd,
+	     IB_SMI_DIRECT_CLASS, 1, 0, 0)) < 0) {
+		IBND_ERROR("Failed to register SMI_DIRECT agent on (%s:%d)\n",
+			   ca_name, ca_port);
+		goto eio_close;
+	}
+
 	engine->user_data = user_data;
 	cl_qmap_init(&engine->smps_on_wire);
-	engine->max_smps_on_wire = max_smps_on_wire;
+	engine->cfg = cfg;
+	return (0);
+
+eio_close:
+	mad_rpc_close_port(engine->ibmad_port);
+	umad_close_port(engine->umad_fd);
+	return (-EIO);
 }
 
 void smp_engine_destroy(smp_engine_t * engine)
@@ -221,6 +273,9 @@ void smp_engine_destroy(smp_engine_t * engine)
 		cl_qmap_remove_item(&engine->smps_on_wire, item);
 		free(item);
 	}
+
+	umad_close_port(engine->umad_fd);
+	mad_rpc_close_port(engine->ibmad_port);
 }
 
 int process_mads(smp_engine_t * engine)
diff --git a/infiniband-diags/libibnetdisc/test/testleaks.c b/infiniband-diags/libibnetdisc/test/testleaks.c
index da2fc0a..9a91f50 100644
--- a/infiniband-diags/libibnetdisc/test/testleaks.c
+++ b/infiniband-diags/libibnetdisc/test/testleaks.c
@@ -54,8 +54,6 @@
 char *argv0 = "iblinkinfotest";
 static FILE *f;
 
-static int timeout_ms = 500;
-
 void usage(void)
 {
 	fprintf(stderr,
@@ -88,9 +86,6 @@ int main(int argc, char **argv)
 	ib_portid_t port_id;
 	int iters = -1;
 
-	struct ibmad_port *ibmad_port;
-	int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
-
 	static char const str_opts[] = "S:D:n:C:P:t:shuf:i:";
 	static const struct option long_opts[] = {
 		{"S", 1, 0, 'S'},
@@ -139,7 +134,7 @@ int main(int argc, char **argv)
 			iters = (int)strtol(optarg, NULL, 0);
 			break;
 		case 't':
-			timeout_ms = strtoul(optarg, 0, 0);
+			config.timeout_ms = strtoul(optarg, 0, 0);
 			break;
 		case 'S':
 			guid = (uint64_t) strtoull(optarg, 0, 0);
@@ -152,15 +147,11 @@ int main(int argc, char **argv)
 	argc -= optind;
 	argv += optind;
 
-	ibmad_port = mad_rpc_open_port(ca, ca_port, mgmt_classes, 2);
-
-	mad_rpc_set_timeout(ibmad_port, timeout_ms);
-
 	while (iters == -1 || iters-- > 0) {
 		if (from) {
 			/* only scan part of the fabric */
 			str2drpath(&(port_id.drpath), from, 0, 0);
-			if ((fabric = ibnd_discover_fabric(ibmad_port,
+			if ((fabric = ibnd_discover_fabric(ca, ca_port,
 							   &port_id, &config))
 			    == NULL) {
 				fprintf(stderr, "discover failed\n");
@@ -168,7 +159,7 @@ int main(int argc, char **argv)
 				goto close_port;
 			}
 			guid = 0;
-		} else if ((fabric = ibnd_discover_fabric(ibmad_port, NULL,
+		} else if ((fabric = ibnd_discover_fabric(ca, ca_port, NULL,
 							  &config)) == NULL) {
 			fprintf(stderr, "discover failed\n");
 			rc = 1;
@@ -179,6 +170,5 @@ int main(int argc, char **argv)
 	}
 
 close_port:
-	mad_rpc_close_port(ibmad_port);
 	exit(rc);
 }
diff --git a/infiniband-diags/src/iblinkinfo.c b/infiniband-diags/src/iblinkinfo.c
index 029573f..d0c9b13 100644
--- a/infiniband-diags/src/iblinkinfo.c
+++ b/infiniband-diags/src/iblinkinfo.c
@@ -337,8 +337,10 @@ int main(int argc, char **argv)
 		exit(1);
 	}
 
-	if (ibd_timeout)
+	if (ibd_timeout) {
 		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
+		config.timeout_ms = ibd_timeout;
+	}
 
 	node_name_map = open_node_name_map(node_name_map_file);
 
@@ -371,12 +373,12 @@ int main(int argc, char **argv)
 	} else {
 		if (resolved >= 0 &&
 		    !(fabric =
-		      ibnd_discover_fabric(ibmad_port, &port_id, &config)))
+		      ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
 			IBWARN("Single node discover failed;"
 			       " attempting full scan\n");
 
 		if (!fabric &&
-		    !(fabric = ibnd_discover_fabric(ibmad_port, NULL, &config))) {
+		    !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config))) {
 			fprintf(stderr, "discover failed\n");
 			rc = 1;
 			goto close_port;
diff --git a/infiniband-diags/src/ibnetdiscover.c b/infiniband-diags/src/ibnetdiscover.c
index 57f9625..8f08f06 100644
--- a/infiniband-diags/src/ibnetdiscover.c
+++ b/infiniband-diags/src/ibnetdiscover.c
@@ -67,8 +67,6 @@
 #define DIFF_FLAG_DEFAULT (DIFF_FLAG_SWITCH | DIFF_FLAG_CA | DIFF_FLAG_ROUTER \
 			   | DIFF_FLAG_PORT_CONNECTION)
 
-struct ibmad_port *srcport;
-
 static FILE *f;
 
 static char *node_name_map_file = NULL;
@@ -938,9 +936,6 @@ int main(int argc, char **argv)
 	ibnd_fabric_t *fabric = NULL;
 	ibnd_fabric_t *diff_fabric = NULL;
 
-	struct ibmad_port *ibmad_port;
-	int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
-
 	const struct ibdiag_opt opts[] = {
 		{"show", 's', 0, NULL, "show more information"},
 		{"list", 'l', 0, NULL, "list of connected nodes"},
@@ -975,12 +970,8 @@ int main(int argc, char **argv)
 	argc -= optind;
 	argv += optind;
 
-	ibmad_port = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
-	if (!ibmad_port)
-		IBERROR("Failed to open %s port %d", ibd_ca, ibd_ca_port);
-
 	if (ibd_timeout)
-		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
+		config.timeout_ms = ibd_timeout;
 
 	if (argc && !(f = fopen(argv[0], "w")))
 		IBERROR("can't open file %s for writing", argv[0]);
@@ -996,7 +987,7 @@ int main(int argc, char **argv)
 			IBERROR("loading cached fabric failed\n");
 	} else {
 		if ((fabric =
-		     ibnd_discover_fabric(ibmad_port, NULL, &config)) == NULL)
+		     ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config)) == NULL)
 			IBERROR("discover failed\n");
 	}
 
@@ -1017,6 +1008,5 @@ int main(int argc, char **argv)
 	if (diff_fabric)
 		ibnd_destroy_fabric(diff_fabric);
 	close_node_name_map(node_name_map);
-	mad_rpc_close_port(ibmad_port);
 	exit(0);
 }
diff --git a/infiniband-diags/src/ibqueryerrors.c b/infiniband-diags/src/ibqueryerrors.c
index e896254..f04e47f 100644
--- a/infiniband-diags/src/ibqueryerrors.c
+++ b/infiniband-diags/src/ibqueryerrors.c
@@ -600,8 +600,10 @@ int main(int argc, char **argv)
 	if (!ibmad_port)
 		IBERROR("Failed to open port; %s:%d\n", ibd_ca, ibd_ca_port);
 
-	if (ibd_timeout)
+	if (ibd_timeout) {
 		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
+		config.timeout_ms = ibd_timeout;
+	}
 
 	node_name_map = open_node_name_map(node_name_map_file);
 
@@ -633,11 +635,14 @@ int main(int argc, char **argv)
 		}
 	} else {
 		if (resolved >= 0 &&
-		    !(fabric = ibnd_discover_fabric(ibmad_port, &portid, 0)))
+		    !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
+						    &portid, &config)))
 			IBWARN("Single node discover failed;"
 			       " attempting full scan");
 
-		if (!fabric && !(fabric = ibnd_discover_fabric(ibmad_port, NULL,
+		if (!fabric && !(fabric = ibnd_discover_fabric(ibd_ca,
+							       ibd_ca_port,
+							       NULL,
 							       &config))) {
 			fprintf(stderr, "discover failed\n");
 			rc = 1;
-- 
1.5.4.5

--
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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's
       [not found] ` <20100511164812.e16e41e6.weiny2-i2BcT+NCU+M@public.gmane.org>
@ 2010-05-22 14:40   ` Sasha Khapyorsky
  2010-05-25 17:45     ` Ira Weiny
  0 siblings, 1 reply; 3+ messages in thread
From: Sasha Khapyorsky @ 2010-05-22 14:40 UTC (permalink / raw)
  To: Ira Weiny; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

On 16:48 Tue 11 May     , Ira Weiny wrote:
> 
> From: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
> Date: Tue, 11 May 2010 15:36:08 -0700
> Subject: [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's
> 
> 	Specify CA/Port to use which allows parallel scanning to other operations.
> 
> Signed-off-by: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>

Applied. Thanks.

However see a minor comment below.

> ---
>  .../libibnetdisc/include/infiniband/ibnetdisc.h    |   15 ++--
>  infiniband-diags/libibnetdisc/src/ibnetdisc.c      |   52 +++++++-----
>  infiniband-diags/libibnetdisc/src/internal.h       |   11 ++-
>  infiniband-diags/libibnetdisc/src/query_smp.c      |   83 ++++++++++++++++----
>  infiniband-diags/libibnetdisc/test/testleaks.c     |   16 +---
>  infiniband-diags/src/iblinkinfo.c                  |    8 +-
>  infiniband-diags/src/ibnetdiscover.c               |   14 +---
>  infiniband-diags/src/ibqueryerrors.c               |   11 ++-
>  8 files changed, 134 insertions(+), 76 deletions(-)

[snip]

> diff --git a/infiniband-diags/libibnetdisc/src/internal.h b/infiniband-diags/libibnetdisc/src/internal.h
> index 2cfde02..d037a60 100644
> --- a/infiniband-diags/libibnetdisc/src/internal.h
> +++ b/infiniband-diags/libibnetdisc/src/internal.h
> @@ -54,6 +54,8 @@
>  #define MAXHOPS         63
>  
>  #define DEFAULT_MAX_SMP_ON_WIRE 2
> +#define DEFAULT_TIMEOUT 1000
> +#define DEFAULT_RETRIES 3
>  
>  typedef struct ibnd_scan {
>  	ib_portid_t selfportid;
> @@ -76,16 +78,19 @@ struct ibnd_smp {
>  
>  struct smp_engine {
>  	struct ibmad_port *ibmad_port;

After this patch ibmad_port is not used by smp_engine, but instead by an
"upper" layer (ibnetdisc). So I would suggest to move this there (for
example to be a member of scan struct).

Sasha

> +	int umad_fd;
> +	int smi_agent;
> +	int smi_dir_agent;
>  	ibnd_smp_t *smp_queue_head;
>  	ibnd_smp_t *smp_queue_tail;
>  	void *user_data;
>  	cl_qmap_t smps_on_wire;
> -	int max_smps_on_wire;
> +	struct ibnd_config *cfg;
>  	unsigned total_smps;
>  };
>  
> -void smp_engine_init(smp_engine_t * engine, struct ibmad_port *ibmad_port,
> -		     void *user_data, int max_smps_on_wire);
> +int smp_engine_init(smp_engine_t * engine, char * ca_name, int ca_port,
> +		    void *user_data, ibnd_config_t *cfg);
>  int issue_smp(smp_engine_t * engine, ib_portid_t * portid,
>  	      unsigned attrid, unsigned mod, smp_comp_cb_t cb, void *cb_data);
>  int process_mads(smp_engine_t * engine);
> diff --git a/infiniband-diags/libibnetdisc/src/query_smp.c b/infiniband-diags/libibnetdisc/src/query_smp.c
> index 7234844..4dbfa0d 100644
> --- a/infiniband-diags/libibnetdisc/src/query_smp.c
> +++ b/infiniband-diags/libibnetdisc/src/query_smp.c
> @@ -61,25 +61,32 @@ static ibnd_smp_t *get_smp(smp_engine_t * engine)
>  	return rc;
>  }
>  
> -static int send_smp(ibnd_smp_t * smp, struct ibmad_port *srcport)
> +static int send_smp(ibnd_smp_t * smp, smp_engine_t * engine)
>  {
>  	int rc = 0;
>  	uint8_t umad[1024];
>  	ib_rpc_t *rpc = &smp->rpc;
> +	int agent = 0;
>  
>  	memset(umad, 0, umad_size() + IB_MAD_SIZE);
>  
> +	if (rpc->mgtclass == IB_SMI_CLASS) {
> +		agent = engine->smi_agent;
> +	} else if (rpc->mgtclass == IB_SMI_DIRECT_CLASS) {
> +		agent = engine->smi_dir_agent;
> +	} else {
> +		IBND_ERROR("Invalid class for RPC\n");
> +		return (-EIO);
> +	}
> +
>  	if ((rc = mad_build_pkt(umad, &smp->rpc, &smp->path, NULL, NULL))
>  	    < 0) {
>  		IBND_ERROR("mad_build_pkt failed; %d\n", rc);
>  		return rc;
>  	}
>  
> -	if ((rc = umad_send(mad_rpc_portid(srcport),
> -			    mad_rpc_class_agent(srcport, rpc->mgtclass),
> -			    umad, IB_MAD_SIZE,
> -			    mad_get_timeout(srcport, rpc->timeout),
> -			    mad_get_retries(srcport))) < 0) {
> +	if ((rc = umad_send(engine->umad_fd, agent, umad, IB_MAD_SIZE,
> +			    engine->cfg->timeout_ms, engine->cfg->retries)) < 0) {
>  		IBND_ERROR("send failed; %d\n", rc);
>  		return rc;
>  	}
> @@ -91,12 +98,13 @@ static int process_smp_queue(smp_engine_t * engine)
>  {
>  	int rc = 0;
>  	ibnd_smp_t *smp;
> -	while (cl_qmap_count(&engine->smps_on_wire) < engine->max_smps_on_wire) {
> +	while (cl_qmap_count(&engine->smps_on_wire)
> +	       < engine->cfg->max_smps) {
>  		smp = get_smp(engine);
>  		if (!smp)
>  			return 0;
>  
> -		if ((rc = send_smp(smp, engine->ibmad_port)) != 0) {
> +		if ((rc = send_smp(smp, engine)) != 0) {
>  			free(smp);
>  			return rc;
>  		}
> @@ -122,7 +130,7 @@ int issue_smp(smp_engine_t * engine, ib_portid_t * portid,
>  	smp->rpc.method = IB_MAD_METHOD_GET;
>  	smp->rpc.attr.id = attrid;
>  	smp->rpc.attr.mod = mod;
> -	smp->rpc.timeout = mad_get_timeout(engine->ibmad_port, 0);
> +	smp->rpc.timeout = engine->cfg->timeout_ms;
>  	smp->rpc.datasz = IB_SMP_DATA_SIZE;
>  	smp->rpc.dataoffs = IB_SMP_DATA_OFFS;
>  	smp->rpc.trid = mad_trid();
> @@ -153,7 +161,7 @@ static int process_one_recv(smp_engine_t * engine)
>  	memset(umad, 0, sizeof(umad));
>  
>  	/* wait for the next message */
> -	if ((rc = umad_recv(mad_rpc_portid(engine->ibmad_port), umad, &length,
> +	if ((rc = umad_recv(engine->umad_fd, umad, &length,
>  			    0)) < 0) {
>  		if (rc == -EWOULDBLOCK)
>  			return 0;
> @@ -190,14 +198,58 @@ error:
>  	return rc;
>  }
>  
> -void smp_engine_init(smp_engine_t * engine, struct ibmad_port *ibmad_port,
> -		     void *user_data, int max_smps_on_wire)
> +int smp_engine_init(smp_engine_t * engine, char * ca_name, int ca_port,
> +		    void *user_data, ibnd_config_t *cfg)
>  {
> +	int nc = 2;
> +	int mc[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
> +
>  	memset(engine, 0, sizeof(*engine));
> -	engine->ibmad_port = ibmad_port;
> +
> +	engine->ibmad_port = mad_rpc_open_port(ca_name, ca_port, mc, nc);
> +	if (!engine->ibmad_port) {
> +		IBND_ERROR("can't open MAD port (%s:%d)\n", ca_name, ca_port);
> +		return -EIO;
> +	}
> +	mad_rpc_set_timeout(engine->ibmad_port, cfg->timeout_ms);
> +	mad_rpc_set_retries(engine->ibmad_port, cfg->retries);
> +
> +	if (umad_init() < 0) {
> +		IBND_ERROR("umad_init failed\n");
> +		mad_rpc_close_port(engine->ibmad_port);
> +		return -EIO;
> +	}
> +
> +	engine->umad_fd = umad_open_port(ca_name, ca_port);
> +	if (engine->umad_fd < 0) {
> +		IBND_ERROR("can't open UMAD port (%s:%d)\n", ca_name, ca_port);
> +		mad_rpc_close_port(engine->ibmad_port);
> +		return -EIO;
> +	}
> +
> +	if ((engine->smi_agent = umad_register(engine->umad_fd,
> +	     IB_SMI_CLASS, 1, 0, 0)) < 0) {
> +		IBND_ERROR("Failed to register SMI agent on (%s:%d)\n",
> +			   ca_name, ca_port);
> +		goto eio_close;
> +	}
> +
> +	if ((engine->smi_dir_agent = umad_register(engine->umad_fd,
> +	     IB_SMI_DIRECT_CLASS, 1, 0, 0)) < 0) {
> +		IBND_ERROR("Failed to register SMI_DIRECT agent on (%s:%d)\n",
> +			   ca_name, ca_port);
> +		goto eio_close;
> +	}
> +
>  	engine->user_data = user_data;
>  	cl_qmap_init(&engine->smps_on_wire);
> -	engine->max_smps_on_wire = max_smps_on_wire;
> +	engine->cfg = cfg;
> +	return (0);
> +
> +eio_close:
> +	mad_rpc_close_port(engine->ibmad_port);
> +	umad_close_port(engine->umad_fd);
> +	return (-EIO);
>  }
>  
>  void smp_engine_destroy(smp_engine_t * engine)
> @@ -221,6 +273,9 @@ void smp_engine_destroy(smp_engine_t * engine)
>  		cl_qmap_remove_item(&engine->smps_on_wire, item);
>  		free(item);
>  	}
> +
> +	umad_close_port(engine->umad_fd);
> +	mad_rpc_close_port(engine->ibmad_port);
>  }
>  
>  int process_mads(smp_engine_t * engine)
> diff --git a/infiniband-diags/libibnetdisc/test/testleaks.c b/infiniband-diags/libibnetdisc/test/testleaks.c
> index da2fc0a..9a91f50 100644
> --- a/infiniband-diags/libibnetdisc/test/testleaks.c
> +++ b/infiniband-diags/libibnetdisc/test/testleaks.c
> @@ -54,8 +54,6 @@
>  char *argv0 = "iblinkinfotest";
>  static FILE *f;
>  
> -static int timeout_ms = 500;
> -
>  void usage(void)
>  {
>  	fprintf(stderr,
> @@ -88,9 +86,6 @@ int main(int argc, char **argv)
>  	ib_portid_t port_id;
>  	int iters = -1;
>  
> -	struct ibmad_port *ibmad_port;
> -	int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
> -
>  	static char const str_opts[] = "S:D:n:C:P:t:shuf:i:";
>  	static const struct option long_opts[] = {
>  		{"S", 1, 0, 'S'},
> @@ -139,7 +134,7 @@ int main(int argc, char **argv)
>  			iters = (int)strtol(optarg, NULL, 0);
>  			break;
>  		case 't':
> -			timeout_ms = strtoul(optarg, 0, 0);
> +			config.timeout_ms = strtoul(optarg, 0, 0);
>  			break;
>  		case 'S':
>  			guid = (uint64_t) strtoull(optarg, 0, 0);
> @@ -152,15 +147,11 @@ int main(int argc, char **argv)
>  	argc -= optind;
>  	argv += optind;
>  
> -	ibmad_port = mad_rpc_open_port(ca, ca_port, mgmt_classes, 2);
> -
> -	mad_rpc_set_timeout(ibmad_port, timeout_ms);
> -
>  	while (iters == -1 || iters-- > 0) {
>  		if (from) {
>  			/* only scan part of the fabric */
>  			str2drpath(&(port_id.drpath), from, 0, 0);
> -			if ((fabric = ibnd_discover_fabric(ibmad_port,
> +			if ((fabric = ibnd_discover_fabric(ca, ca_port,
>  							   &port_id, &config))
>  			    == NULL) {
>  				fprintf(stderr, "discover failed\n");
> @@ -168,7 +159,7 @@ int main(int argc, char **argv)
>  				goto close_port;
>  			}
>  			guid = 0;
> -		} else if ((fabric = ibnd_discover_fabric(ibmad_port, NULL,
> +		} else if ((fabric = ibnd_discover_fabric(ca, ca_port, NULL,
>  							  &config)) == NULL) {
>  			fprintf(stderr, "discover failed\n");
>  			rc = 1;
> @@ -179,6 +170,5 @@ int main(int argc, char **argv)
>  	}
>  
>  close_port:
> -	mad_rpc_close_port(ibmad_port);
>  	exit(rc);
>  }
> diff --git a/infiniband-diags/src/iblinkinfo.c b/infiniband-diags/src/iblinkinfo.c
> index 029573f..d0c9b13 100644
> --- a/infiniband-diags/src/iblinkinfo.c
> +++ b/infiniband-diags/src/iblinkinfo.c
> @@ -337,8 +337,10 @@ int main(int argc, char **argv)
>  		exit(1);
>  	}
>  
> -	if (ibd_timeout)
> +	if (ibd_timeout) {
>  		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
> +		config.timeout_ms = ibd_timeout;
> +	}
>  
>  	node_name_map = open_node_name_map(node_name_map_file);
>  
> @@ -371,12 +373,12 @@ int main(int argc, char **argv)
>  	} else {
>  		if (resolved >= 0 &&
>  		    !(fabric =
> -		      ibnd_discover_fabric(ibmad_port, &port_id, &config)))
> +		      ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
>  			IBWARN("Single node discover failed;"
>  			       " attempting full scan\n");
>  
>  		if (!fabric &&
> -		    !(fabric = ibnd_discover_fabric(ibmad_port, NULL, &config))) {
> +		    !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config))) {
>  			fprintf(stderr, "discover failed\n");
>  			rc = 1;
>  			goto close_port;
> diff --git a/infiniband-diags/src/ibnetdiscover.c b/infiniband-diags/src/ibnetdiscover.c
> index 57f9625..8f08f06 100644
> --- a/infiniband-diags/src/ibnetdiscover.c
> +++ b/infiniband-diags/src/ibnetdiscover.c
> @@ -67,8 +67,6 @@
>  #define DIFF_FLAG_DEFAULT (DIFF_FLAG_SWITCH | DIFF_FLAG_CA | DIFF_FLAG_ROUTER \
>  			   | DIFF_FLAG_PORT_CONNECTION)
>  
> -struct ibmad_port *srcport;
> -
>  static FILE *f;
>  
>  static char *node_name_map_file = NULL;
> @@ -938,9 +936,6 @@ int main(int argc, char **argv)
>  	ibnd_fabric_t *fabric = NULL;
>  	ibnd_fabric_t *diff_fabric = NULL;
>  
> -	struct ibmad_port *ibmad_port;
> -	int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
> -
>  	const struct ibdiag_opt opts[] = {
>  		{"show", 's', 0, NULL, "show more information"},
>  		{"list", 'l', 0, NULL, "list of connected nodes"},
> @@ -975,12 +970,8 @@ int main(int argc, char **argv)
>  	argc -= optind;
>  	argv += optind;
>  
> -	ibmad_port = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
> -	if (!ibmad_port)
> -		IBERROR("Failed to open %s port %d", ibd_ca, ibd_ca_port);
> -
>  	if (ibd_timeout)
> -		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
> +		config.timeout_ms = ibd_timeout;
>  
>  	if (argc && !(f = fopen(argv[0], "w")))
>  		IBERROR("can't open file %s for writing", argv[0]);
> @@ -996,7 +987,7 @@ int main(int argc, char **argv)
>  			IBERROR("loading cached fabric failed\n");
>  	} else {
>  		if ((fabric =
> -		     ibnd_discover_fabric(ibmad_port, NULL, &config)) == NULL)
> +		     ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config)) == NULL)
>  			IBERROR("discover failed\n");
>  	}
>  
> @@ -1017,6 +1008,5 @@ int main(int argc, char **argv)
>  	if (diff_fabric)
>  		ibnd_destroy_fabric(diff_fabric);
>  	close_node_name_map(node_name_map);
> -	mad_rpc_close_port(ibmad_port);
>  	exit(0);
>  }
> diff --git a/infiniband-diags/src/ibqueryerrors.c b/infiniband-diags/src/ibqueryerrors.c
> index e896254..f04e47f 100644
> --- a/infiniband-diags/src/ibqueryerrors.c
> +++ b/infiniband-diags/src/ibqueryerrors.c
> @@ -600,8 +600,10 @@ int main(int argc, char **argv)
>  	if (!ibmad_port)
>  		IBERROR("Failed to open port; %s:%d\n", ibd_ca, ibd_ca_port);
>  
> -	if (ibd_timeout)
> +	if (ibd_timeout) {
>  		mad_rpc_set_timeout(ibmad_port, ibd_timeout);
> +		config.timeout_ms = ibd_timeout;
> +	}
>  
>  	node_name_map = open_node_name_map(node_name_map_file);
>  
> @@ -633,11 +635,14 @@ int main(int argc, char **argv)
>  		}
>  	} else {
>  		if (resolved >= 0 &&
> -		    !(fabric = ibnd_discover_fabric(ibmad_port, &portid, 0)))
> +		    !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
> +						    &portid, &config)))
>  			IBWARN("Single node discover failed;"
>  			       " attempting full scan");
>  
> -		if (!fabric && !(fabric = ibnd_discover_fabric(ibmad_port, NULL,
> +		if (!fabric && !(fabric = ibnd_discover_fabric(ibd_ca,
> +							       ibd_ca_port,
> +							       NULL,
>  							       &config))) {
>  			fprintf(stderr, "discover failed\n");
>  			rc = 1;
> -- 
> 1.5.4.5
> 
--
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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's
  2010-05-22 14:40   ` Sasha Khapyorsky
@ 2010-05-25 17:45     ` Ira Weiny
  0 siblings, 0 replies; 3+ messages in thread
From: Ira Weiny @ 2010-05-25 17:45 UTC (permalink / raw)
  To: Sasha Khapyorsky; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

On Sat, 22 May 2010 07:40:10 -0700
Sasha Khapyorsky <sashak-smomgflXvOZWk0Htik3J/w@public.gmane.org> wrote:

> On 16:48 Tue 11 May     , Ira Weiny wrote:
> >
> > From: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
> > Date: Tue, 11 May 2010 15:36:08 -0700
> > Subject: [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's
> >
> >       Specify CA/Port to use which allows parallel scanning to other operations.
> >
> > Signed-off-by: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
> 
> Applied. Thanks.
> 
> However see a minor comment below.
> 
> > ---
> >  .../libibnetdisc/include/infiniband/ibnetdisc.h    |   15 ++--
> >  infiniband-diags/libibnetdisc/src/ibnetdisc.c      |   52 +++++++-----
> >  infiniband-diags/libibnetdisc/src/internal.h       |   11 ++-
> >  infiniband-diags/libibnetdisc/src/query_smp.c      |   83 ++++++++++++++++----
> >  infiniband-diags/libibnetdisc/test/testleaks.c     |   16 +---
> >  infiniband-diags/src/iblinkinfo.c                  |    8 +-
> >  infiniband-diags/src/ibnetdiscover.c               |   14 +---
> >  infiniband-diags/src/ibqueryerrors.c               |   11 ++-
> >  8 files changed, 134 insertions(+), 76 deletions(-)
> 
> [snip]
> 
> > diff --git a/infiniband-diags/libibnetdisc/src/internal.h b/infiniband-diags/libibnetdisc/src/internal.h
> > index 2cfde02..d037a60 100644
> > --- a/infiniband-diags/libibnetdisc/src/internal.h
> > +++ b/infiniband-diags/libibnetdisc/src/internal.h
> > @@ -54,6 +54,8 @@
> >  #define MAXHOPS         63
> >
> >  #define DEFAULT_MAX_SMP_ON_WIRE 2
> > +#define DEFAULT_TIMEOUT 1000
> > +#define DEFAULT_RETRIES 3
> >
> >  typedef struct ibnd_scan {
> >       ib_portid_t selfportid;
> > @@ -76,16 +78,19 @@ struct ibnd_smp {
> >
> >  struct smp_engine {
> >       struct ibmad_port *ibmad_port;
> 
> After this patch ibmad_port is not used by smp_engine, but instead by an
> "upper" layer (ibnetdisc). So I would suggest to move this there (for
> example to be a member of scan struct).

Agreed.  I was trying to minimize the changes by this patch because it was
mainly a bug fix.

Ira

> 
> Sasha
> 

[snip]

--
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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-05-25 17:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-11 23:48 [PATCH] ibnetdisc: Separate calls to umad and mad layer to avoid race condition on response MAD's Ira Weiny
     [not found] ` <20100511164812.e16e41e6.weiny2-i2BcT+NCU+M@public.gmane.org>
2010-05-22 14:40   ` Sasha Khapyorsky
2010-05-25 17:45     ` Ira Weiny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox