[ofa-general] question regarding umad_recv

Sasha Khapyorsky sashak at voltaire.com
Sun Oct 14 08:11:15 PDT 2007


On 04:50 Fri 12 Oct     , Hal Rosenstock wrote:
> On Fri, 2007-10-12 at 12:09 +0530, Sumit Gaur - Sun Microsystem wrote:
> > Hi ,
> > 
> > Sean Hefty wrote:
> > >>There is no per thread demuxing. You would need two different mad agents
> > >>to do this with one looking at the SMI side and the other the GSI side.
> > >>I haven't looked at libibmad in terms of using this model though.
> > > 
> > > 
> > > umad_receive() doesn't take the mad_agent as an input parameter.  The only
> > > possibility I see is calling umad_open_port() twice for the same port, with the
> > > GSI/SMI registrations going to separate port_id's.
> > I think this solution is also not possible as calling umad_open_port() twice for 
> > the same port and ca_name is always gives error in port_alloc because 
> > dev_to_umad_id generate same umad_id for same ca_name and portnum.
> > 
> > ibwarn: [9634] port_alloc: umad port id 1 is already allocated for mthca0 2
> > 
> > So looks like it is impossible to generate two separate portid for the same port.
> 
> It might be possible to support this with some changes to libibumad.
> Sasha ?

Yes, it could be possible this way.

Sumit, could you try this patch?

Sasha


diff --git a/libibumad/src/umad.c b/libibumad/src/umad.c
index 589684c..5ccdcfb 100644
--- a/libibumad/src/umad.c
+++ b/libibumad/src/umad.c
@@ -82,6 +82,7 @@ int umaddebug = 0;
 
 #define UMAD_DEV_NAME_SZ	32
 #define UMAD_DEV_FILE_SZ	256
+#define MAX_OPEN_PORTS 2048
 
 static char *def_ca_name = "mthca0";
 static int def_ca_port = 1;
@@ -94,54 +95,18 @@ typedef struct Port {
 	int id;
 } Port;
 
-static Port ports[UMAD_MAX_PORTS];
+static Port *open_ports[MAX_OPEN_PORTS];
 
 /*************************************
  * Port
  */
 static Port *
-port_alloc(int portid, char *dev, int portnum)
-{
-	Port *port = ports + portid;
-
-	if (portid < 0 || portid >= UMAD_MAX_PORTS) {
-		IBWARN("bad umad portid %d", portid);
-		errno = EINVAL;
-		return 0;
-	}
-
-	if (port->dev_name[0]) {
-		IBWARN("umad port id %d is already allocated for %s %d",
-			portid, port->dev_name, port->dev_port);
-		errno = EBUSY;
-		return 0;
-	}
-
-	strncpy(port->dev_name, dev, UMAD_CA_NAME_LEN);
-	port->dev_port = portnum;
-	port->id = portid;
-
-	return port;
-}
-
-static Port *
 port_get(int portid)
 {
-	Port *port = ports + portid;
-
-	if (portid < 0 || portid >= UMAD_MAX_PORTS)
-		return 0;
-
-	if (port->dev_name[0] == 0)
-		return 0;
-
-	return port;
-}
+	if (portid < 0 || portid >= MAX_OPEN_PORTS)
+		return NULL;
 
-static void
-port_free(Port *port)
-{
-	memset(port, 0, sizeof *port);
+	return open_ports[portid];
 }
 
 static int
@@ -571,7 +536,7 @@ umad_get_ca_portguids(char *ca_name, uint64_t *portguids, int max)
 int
 umad_open_port(char *ca_name, int portnum)
 {
-	int umad_id;
+	int umad_id, fd;
 	Port *port;
 
 	TRACE("ca %s port %d", ca_name, portnum);
@@ -584,19 +549,35 @@ umad_open_port(char *ca_name, int portnum)
 	if ((umad_id = dev_to_umad_id(ca_name, portnum)) < 0)
 		return -EINVAL;
 
-	if (!(port = port_alloc(umad_id, ca_name, portnum)))
-		return -errno;
+	port = malloc(sizeof(*port));
+	if (!port)
+		return -ENOMEM;
+	memset(port, 0, sizeof(*port));
 
 	snprintf(port->dev_file, sizeof port->dev_file - 1, "%s/umad%d",
 		 UMAD_DEV_DIR , umad_id);
 
-	if ((port->dev_fd = open(port->dev_file, O_RDWR|O_NONBLOCK)) < 0) {
+	fd = open(port->dev_file, O_RDWR|O_NONBLOCK);
+	if (fd < 0) {
 		DEBUG("open %s failed: %s", port->dev_file, strerror(errno));
+		free(port);
 		return -EIO;
+	} else if (fd >= MAX_OPEN_PORTS) {
+		DEBUG("no ports space for %s", port->dev_file);
+		errno = ENOMEM;
+		free(port);
+		return -ENOMEM;
 	}
 
+	port->id = umad_id;
+	port->dev_port = portnum;
+	port->dev_fd = fd;
+	strncpy(port->dev_name, ca_name, UMAD_CA_NAME_LEN);
+
+	open_ports[fd] = port;
+
 	DEBUG("opened %s fd %d portid %d", port->dev_file, port->dev_fd, port->id);
-	return port->id;
+	return fd;
 }
 
 int
@@ -677,7 +658,8 @@ umad_close_port(int portid)
 
 	close(port->dev_fd);
 
-	port_free(port);
+	open_ports[portid] = NULL;
+	free(port);
 
 	DEBUG("closed %s fd %d", port->dev_file, port->dev_fd);
 	return 0;



More information about the general mailing list