[ofa-general] [PATCH] ipoib: refresh path when remote lid changes

Yossi Etigin yosefe at voltaire.com
Mon Jul 27 10:11:42 PDT 2009


  If the LID of an ipoib neighbour changes without a SM event on the local node,
IPoIB will keep caching the invalid path until the device is flushed. The patch
below will remove the path for every incoming ARP packet where the sender hardware
address does not match the cached lid.

  It works because the IP stack has a periodical arp refresh which will eventually
cause the remote node to send an ARP reply. This is better that a periodic refresh
mechanism, because it will not overwhelm the SM. 

Signed-off-by: Yossi Etigin <yosefe at voltaire.com>

---

Index: b/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib.h	2009-07-27 19:44:40.000000000 +0300
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h	2009-07-27 20:01:03.000000000 +0300
@@ -444,6 +444,7 @@ void ipoib_reap_ah(struct work_struct *w
 
 void ipoib_mark_paths_invalid(struct net_device *dev);
 void ipoib_flush_paths(struct net_device *dev);
+void ipoib_path_refresh(struct net_device *dev, void *gid, u16 lid);
 struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
 
 int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
Index: b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2009-07-27 19:44:40.000000000 +0300
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2009-07-27 19:44:45.000000000 +0300
@@ -36,6 +36,7 @@
 #include <linux/icmpv6.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
+#include <linux/if_arp.h>
 
 #include "ipoib.h"
 
@@ -662,6 +663,10 @@ copied:
 	skb_reset_mac_header(skb);
 	skb_pull(skb, IPOIB_ENCAP_LEN);
 
+	if (skb->protocol == htons(ETH_P_ARP))
+		ipoib_path_refresh(dev, skb->data + sizeof(struct arphdr) + 4,
+				   wc->slid);
+
 	dev->last_rx = jiffies;
 	++dev->stats.rx_packets;
 	dev->stats.rx_bytes += skb->len;
Index: b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-07-27 19:44:40.000000000 +0300
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-07-27 19:44:45.000000000 +0300
@@ -38,6 +38,7 @@
 
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/if_arp.h>
 
 #include "ipoib.h"
 
@@ -276,6 +277,10 @@ static void ipoib_ib_handle_rx_wc(struct
 	skb_reset_mac_header(skb);
 	skb_pull(skb, IPOIB_ENCAP_LEN);
 
+	if (skb->protocol == htons(ETH_P_ARP))
+		ipoib_path_refresh(dev, skb->data + sizeof(struct arphdr) + 4,
+				   wc->slid);
+
 	dev->last_rx = jiffies;
 	++dev->stats.rx_packets;
 	dev->stats.rx_bytes += skb->len;
Index: b/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-07-27 19:44:40.000000000 +0300
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-07-27 19:44:45.000000000 +0300
@@ -399,6 +399,35 @@ void ipoib_flush_paths(struct net_device
 	netif_tx_unlock_bh(dev);
 }
 
+void ipoib_path_refresh(struct net_device *dev, void *gid, u16 lid)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	struct ipoib_path *path;
+
+	netif_tx_lock_bh(dev);
+	spin_lock_irqsave(&priv->lock, flags);
+
+	path = __path_find(dev, gid);
+	if (!path || path->query || !path->ah ||
+	    be16_to_cpu(path->pathrec.dlid) == lid) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		netif_tx_unlock_bh(dev);
+		return;
+	}
+
+	ipoib_dbg(priv, "Path %pI6: LID changed from 0x%04x to 0x%04x\n",
+		  path->pathrec.dgid.raw, be16_to_cpu(path->pathrec.dlid), lid);
+
+	list_del(&path->list);
+	rb_erase(&path->rb_node, &priv->path_tree);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	netif_tx_unlock_bh(dev);
+
+	path_free(dev, path);
+}
+
 static void path_rec_completion(int status,
 				struct ib_sa_path_rec *pathrec,
 				void *path_ptr)



More information about the general mailing list