[ofa-general] [PATCH RFC v2] IB/ipoib: enable IGMP for userpsace multicast IB apps

Or Gerlitz ogerlitz at voltaire.com
Thu Sep 20 06:16:50 PDT 2007


changes from v1 - http://lists.openfabrics.org/pipermail/general/2007-September/040250.html

- added module param to control the umcast bit in the device priv flags
- changed the umcast bit name to IPOIB_FLAG_ADMIN_UMCAST_ALLOWED
- the sysfs attribute has now values 0 and 1 instead of "allowed" and "disallowed"

please review and consider for merge to 2.6.24

-----

The kernel IB stack allows (through the RDMA CM) user space multicast applications
to interoperate with IP based apps optionally running at a different IP subnet.

To support this inter-op for the case where the receiving party resides at
the IB side, there is a need to handle IGMP (reports/queries) else the local
IP router would not forward multicast traffic towards the IB network.

This patch does a lookup on the database used for multicast reference counting and
enhances IPoIB to ignore mulicast group which is already handled by user space, all
this under a per device policy flag. That is when the policy flag allows it, IPoIB
will not join and attach its QP to a multicast group which has an entry on the database.

For each IPoIB device, the /sys/class/net/$dev/umcast attribute controls the
policy flag where the default value follows the umcast_allowed module param
(whose default value is zero). The flag can be read and set/unset through sysfs.

Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>

Index: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
Index: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2007-09-20 11:44:58.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2007-09-20 12:03:24.000000000 +0300
@@ -783,6 +783,7 @@ void ipoib_mcast_restart_task(struct wor
 	struct ipoib_mcast *mcast, *tmcast;
 	LIST_HEAD(remove_list);
 	unsigned long flags;
+	struct ib_sa_mcmember_rec rec;

 	ipoib_dbg_mcast(priv, "restarting multicast task\n");

@@ -816,6 +817,15 @@ void ipoib_mcast_restart_task(struct wor
 		if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
 			struct ipoib_mcast *nmcast;

+			/* ignore group which is directly joined by user space */
+			if (test_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags) &&
+			    !ib_sa_get_mcmember_rec(priv->ca, priv->port, &mgid, &rec))
+			{
+				ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid "
+						IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+				continue;
+			}
+
 			/* Not found or send-only group, let's add a new entry */
 			ipoib_dbg_mcast(priv, "adding multicast entry for mgid "
 					IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
Index: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib.h	2007-09-20 11:44:58.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib.h	2007-09-20 11:49:44.000000000 +0300
@@ -86,6 +86,7 @@ enum {
 	IPOIB_MCAST_STARTED       = 8,
 	IPOIB_FLAG_NETIF_STOPPED  = 9,
 	IPOIB_FLAG_ADMIN_CM 	  = 10,
+	IPOIB_FLAG_ADMIN_UMCAST_ALLOWED	= 11,

 	IPOIB_MAX_BACKOFF_SECONDS = 16,

@@ -364,6 +365,7 @@ static inline void ipoib_put_ah(struct i

 int ipoib_open(struct net_device *dev);
 int ipoib_add_pkey_attr(struct net_device *dev);
+int ipoib_add_umcast_attr(struct net_device *dev);

 void ipoib_send(struct net_device *dev, struct sk_buff *skb,
 		struct ipoib_ah *address, u32 qpn);
Index: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c	2007-09-20 11:44:58.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_main.c	2007-09-20 11:55:54.000000000 +0300
@@ -61,6 +61,10 @@ MODULE_PARM_DESC(send_queue_size, "Numbe
 module_param_named(recv_queue_size, ipoib_recvq_size, int, 0444);
 MODULE_PARM_DESC(recv_queue_size, "Number of descriptors in receive queue");

+int ipoib_umcast_allowed = 0;
+module_param_named(umcast_allowed, ipoib_umcast_allowed, int, 0444);
+MODULE_PARM_DESC(umcast_allowed, "allow ignoring mulicast group which is already handled by user space");
+
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
 int ipoib_debug_level;

@@ -901,6 +905,9 @@ int ipoib_dev_init(struct net_device *de
 	if (ipoib_ib_dev_init(dev, ca, port))
 		goto out_tx_ring_cleanup;

+	if (ipoib_umcast_allowed)
+		set_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags);
+
 	return 0;

 out_tx_ring_cleanup:
@@ -1017,6 +1024,44 @@ static ssize_t show_pkey(struct device *
 }
 static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);

+static ssize_t show_umcast(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+
+	if (test_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags))
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static ssize_t set_umcast(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+ 	struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
+
+ 	if (!strcmp(buf, "1\n")) {
+ 		set_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags);
+ 		ipoib_warn(priv, "ignoring multicast groups joined directly "
+ 				"by user space\n");
+ 		return count;
+ 	}
+
+ 	if (!strcmp(buf, "0\n")) {
+ 		clear_bit(IPOIB_FLAG_ADMIN_UMCAST_ALLOWED, &priv->flags);
+ 		return count;
+ 	}
+
+ 	return -EINVAL;
+}
+static DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
+
+int ipoib_add_umcast_attr(struct net_device *dev)
+{
+	return device_create_file(&dev->dev, &dev_attr_umcast);
+}
+
 static ssize_t create_child(struct device *dev,
 			    struct device_attribute *attr,
 			    const char *buf, size_t count)
@@ -1134,6 +1179,8 @@ static struct net_device *ipoib_add_port
 		goto sysfs_failed;
 	if (ipoib_add_pkey_attr(priv->dev))
 		goto sysfs_failed;
+	if (ipoib_add_umcast_attr(priv->dev))
+		goto sysfs_failed;
 	if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
 		goto sysfs_failed;
 	if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
Index: linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
===================================================================
--- linux-2.6.23-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2007-09-20 11:44:58.000000000 +0300
+++ linux-2.6.23-rc5/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2007-09-20 11:45:46.000000000 +0300
@@ -119,6 +119,8 @@ int ipoib_vlan_add(struct net_device *pd
 		goto sysfs_failed;
 	if (ipoib_add_pkey_attr(priv->dev))
 		goto sysfs_failed;
+	if (ipoib_add_umcast_attr(priv->dev))
+		goto sysfs_failed;

 	if (device_create_file(&priv->dev->dev, &dev_attr_parent))
 		goto sysfs_failed;




More information about the general mailing list