[openib-general] [PATCH] multicast: add support for MGID 0
Sean Hefty
sean.hefty at intel.com
Wed Jul 26 17:10:26 PDT 2006
Add support to join a multicast group with MGID = 0, with the actual
MGID of the group returned by the SA. The multicast module must be able
to handle multiple requests for MGID = 0, with each request causing a
new multicast group to be created.
Also enhance the API for ib_get_mcmember_rec() to support a requested
MGID of 0. In this case, a default MCMemberRecord is returned to the
user and may be used when creating a new multicast group. Currently,
the default values are hard-coded by the multicast module, but that can
be extended in the future or overridden by the user before creating
the group.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: include/rdma/ib_multicast.h
===================================================================
--- include/rdma/ib_multicast.h (revision 8647)
+++ include/rdma/ib_multicast.h (working copy)
@@ -88,8 +88,13 @@ void ib_free_multicast(struct ib_multica
* @device: Device associated with the multicast group.
* @port_num: Port on the specified device to associate with the multicast
* group.
- * @mgid: MGID of multicast group.
+ * @mgid: optional MGID of multicast group.
* @rec: Location to copy SA multicast member record.
+ *
+ * If an MGID is specified, returns an existing multicast member record if
+ * one is found for the local port. If no MGID is specified, or the specified
+ * MGID is 0, returns a multicast member record filled in with default values
+ * that may be used to create a new multicast group.
*/
int ib_get_mcmember_rec(struct ib_device *device, u8 port_num,
union ib_gid *mgid, struct ib_sa_mcmember_rec *rec);
Index: core/multicast.c
===================================================================
--- core/multicast.c (revision 8695)
+++ core/multicast.c (working copy)
@@ -37,8 +37,10 @@
#include <linux/index.h>
#include <linux/pci.h>
#include <linux/bitops.h>
+#include <linux/random.h>
#include <rdma/ib_multicast.h>
+#include <rdma/ib_cache.h>
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("InfiniBand multicast membership handling");
@@ -63,6 +65,7 @@ static struct ib_client mcast_client = {
static struct ib_event_handler event_handler;
static struct workqueue_struct *mcast_wq;
+static union ib_gid mgid0;
struct mcast_device;
@@ -144,7 +147,8 @@ static struct mcast_group *mcast_find(st
}
static struct mcast_group *mcast_insert(struct mcast_port *port,
- struct mcast_group *group)
+ struct mcast_group *group,
+ int allow_duplicates)
{
struct rb_node **link = &port->table.rb_node;
struct rb_node *parent = NULL;
@@ -161,6 +165,8 @@ static struct mcast_group *mcast_insert(
link = &(*link)->rb_left;
else if (ret > 0)
link = &(*link)->rb_right;
+ else if (allow_duplicates)
+ link = &(*link)->rb_left;
else
return cur_group;
}
@@ -476,6 +482,10 @@ static void join_handler(int status, str
else {
spin_lock_irq(&group->port->lock);
group->rec = *rec;
+ if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) {
+ rb_erase(&group->node, &group->port->table);
+ mcast_insert(group->port, group, 1);
+ }
spin_unlock_irq(&group->port->lock);
}
mcast_work_handler(group);
@@ -492,12 +502,16 @@ static struct mcast_group *acquire_group
{
struct mcast_group *group, *cur_group;
unsigned long flags;
+ int is_mgid0;
- spin_lock_irqsave(&port->lock, flags);
- group = mcast_find(port, mgid);
- if (group)
- goto found;
- spin_unlock_irqrestore(&port->lock, flags);
+ is_mgid0 = !memcmp(&mgid0, mgid, sizeof mgid0);
+ if (!is_mgid0) {
+ spin_lock_irqsave(&port->lock, flags);
+ group = mcast_find(port, mgid);
+ if (group)
+ goto found;
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
group = kzalloc(sizeof *group, gfp_mask);
if (!group)
@@ -511,7 +525,7 @@ static struct mcast_group *acquire_group
spin_lock_init(&group->lock);
spin_lock_irqsave(&port->lock, flags);
- cur_group = mcast_insert(port, group);
+ cur_group = mcast_insert(port, group, is_mgid0);
if (cur_group) {
kfree(group);
group = cur_group;
@@ -619,19 +633,30 @@ int ib_get_mcmember_rec(struct ib_device
struct mcast_port *port;
struct mcast_group *group;
unsigned long flags;
+ int ret = 0;
dev = ib_get_client_data(device, &mcast_client);
if (!dev)
return -ENODEV;
port = &dev->port[port_num - dev->start_port];
- spin_lock_irqsave(&port->lock, flags);
- group = mcast_find(port, mgid);
- if (group)
- *rec = group->rec;
- spin_unlock_irqrestore(&port->lock, flags);
+ if (mgid && memcmp(mgid, &mgid0, sizeof mgid0)) {
+ spin_lock_irqsave(&port->lock, flags);
+ group = mcast_find(port, mgid);
+ if (group)
+ *rec = group->rec;
+ else
+ ret = -EADDRNOTAVAIL;
+ spin_unlock_irqrestore(&port->lock, flags);
+ } else {
+ memset(rec, 0, sizeof *rec);
+ ib_get_cached_gid(device, port_num, 0, &rec->port_gid);
+ rec->pkey = 0xFFFF;
+ get_random_bytes(&rec->qkey, sizeof rec->qkey);
+ rec->join_state = 1;
+ }
- return group ? 0 : -EADDRNOTAVAIL;
+ return ret;
}
EXPORT_SYMBOL(ib_get_mcmember_rec);
More information about the general
mailing list