[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