Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2547

kernel-2.6.18-238.el5.src.rpm

From: Andy Gospodarek <gospo@redhat.com>
Date: Tue, 4 Mar 2008 15:37:17 -0500
Subject: [net] cxgb3: rdma arp and loopback fixes
Message-id: 20080304203717.GI564@gospo.usersys.redhat.com
O-Subject: [RHEL5.2 PATCH] cxgb3: rdma arp and loopback fixes
Bugzilla: 253449

Divy Le Ray (from Chelsio) has encouraged us to take these patches since
they resolve a cluster startup issues and a panic when using loopback
interfaces.  He claims these fixes are critical and should be included
in 5.2.  Here is the upstream commit info for these backported changes.

commit 4eb61e0231be536d8116457b67b3e447bbd510dc
Author: Steve Wise <swise@opengridcomputing.com>
Date:   Wed Feb 6 12:05:19 2008 -0600

    cxgb3: Handle ARP completions that mark neighbors stale.

    When ARP completes due to a request rather than a reply the neighbor is
    marked NUD_STALE instead of reachable (see arp_process()).  The handler
    for the resulting netevent needs to check also for NUD_STALE.

    Failure to use the arp entry can cause RDMA connection failures.

commit 8704e9a8790cc9e394198663c1c9150c899fb9a2
Author: Steve Wise <swise@opengridcomputing.com>
Date:   Tue Feb 12 16:09:29 2008 -0600

    RDMA/cxgb3: Fail loopback connections

    The cxgb3 HW and driver don't support loopback RDMA connections.  So
    fail any connection attempt where the destination address is local.

This will resolve the request in 253449.

Acked-by: Neil Horman <nhorman@redhat.com>

diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index d80daec..6798f2c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -35,6 +35,7 @@
 #include <linux/skbuff.h>
 #include <linux/timer.h>
 #include <linux/notifier.h>
+#include <linux/inetdevice.h>
 
 #include <net/neighbour.h>
 #include <net/netevent.h>
@@ -1786,6 +1787,17 @@ err:
 	return err;
 }
 
+static int is_loopback_dst(struct iw_cm_id *cm_id)
+{
+	struct net_device *dev;
+
+	dev = ip_dev_find(cm_id->remote_addr.sin_addr.s_addr);
+	if (!dev)
+		return 0;
+	dev_put(dev);
+	return 1;
+}
+
 int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 {
 	int err = 0;
@@ -1793,6 +1805,11 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	struct iwch_ep *ep;
 	struct rtable *rt;
 
+	if (is_loopback_dst(cm_id)) {
+		err = -ENOSYS;
+		goto out;
+	}
+
 	ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
 	if (!ep) {
 		printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __FUNCTION__);
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index d660af7..d80bbdb 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -404,7 +404,7 @@ found:
 			if (neigh->nud_state & NUD_FAILED) {
 				arpq = e->arpq_head;
 				e->arpq_head = e->arpq_tail = NULL;
-			} else if (neigh_is_connected(neigh))
+			} else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE))
 				setup_l2e_send_pending(dev, NULL, e);
 		} else {
 			e->state = neigh_is_connected(neigh) ?