aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_main.c
diff options
context:
space:
mode:
authorMoni Shoua <monis@voltaire.com>2007-10-09 22:43:36 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-15 14:20:45 -0400
commit732a2170f499ce7cf5f0bdd4f9e0b0c8337b67e1 (patch)
treedb71c08db18421709b829aa1ea87803bbaf3e752 /drivers/infiniband/ulp/ipoib/ipoib_main.c
parenta8a935dae5de65a8f5a5371a58ad2aa73a0ea2da (diff)
IB/ipoib: Bound the net device to the ipoib_neigh structue
IPoIB uses a two layer neighboring scheme, such that for each struct neighbour whose device is an ipoib one, there is a struct ipoib_neigh buddy which is created on demand at the tx flow by an ipoib_neigh_alloc(skb->dst->neighbour) call. When using the bonding driver, neighbours are created by the net stack on behalf of the bonding (master) device. On the tx flow the bonding code gets an skb such that skb->dev points to the master device, it changes this skb to point on the slave device and calls the slave hard_start_xmit function. Under this scheme, ipoib_neigh_destructor assumption that for each struct neighbour it gets, n->dev is an ipoib device and hence netdev_priv(n->dev) can be casted to struct ipoib_dev_priv is buggy. To fix it, this patch adds a dev field to struct ipoib_neigh which is used instead of the struct neighbour dev one, when n->dev->flags has the IFF_MASTER bit set. Signed-off-by: Moni Shoua <monis at voltaire.com> Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com> Acked-by: Roland Dreier <rdreier@cisco.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_main.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index e072f3c32ce6..cae026c4ebe8 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -517,7 +517,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
517 struct ipoib_path *path; 517 struct ipoib_path *path;
518 struct ipoib_neigh *neigh; 518 struct ipoib_neigh *neigh;
519 519
520 neigh = ipoib_neigh_alloc(skb->dst->neighbour); 520 neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
521 if (!neigh) { 521 if (!neigh) {
522 ++dev->stats.tx_dropped; 522 ++dev->stats.tx_dropped;
523 dev_kfree_skb_any(skb); 523 dev_kfree_skb_any(skb);
@@ -817,6 +817,13 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
817 unsigned long flags; 817 unsigned long flags;
818 struct ipoib_ah *ah = NULL; 818 struct ipoib_ah *ah = NULL;
819 819
820 neigh = *to_ipoib_neigh(n);
821 if (neigh) {
822 priv = netdev_priv(neigh->dev);
823 ipoib_dbg(priv, "neigh_destructor for bonding device: %s\n",
824 n->dev->name);
825 } else
826 return;
820 ipoib_dbg(priv, 827 ipoib_dbg(priv,
821 "neigh_cleanup for %06x " IPOIB_GID_FMT "\n", 828 "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
822 IPOIB_QPN(n->ha), 829 IPOIB_QPN(n->ha),
@@ -824,13 +831,10 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
824 831
825 spin_lock_irqsave(&priv->lock, flags); 832 spin_lock_irqsave(&priv->lock, flags);
826 833
827 neigh = *to_ipoib_neigh(n); 834 if (neigh->ah)
828 if (neigh) { 835 ah = neigh->ah;
829 if (neigh->ah) 836 list_del(&neigh->list);
830 ah = neigh->ah; 837 ipoib_neigh_free(n->dev, neigh);
831 list_del(&neigh->list);
832 ipoib_neigh_free(n->dev, neigh);
833 }
834 838
835 spin_unlock_irqrestore(&priv->lock, flags); 839 spin_unlock_irqrestore(&priv->lock, flags);
836 840
@@ -838,7 +842,8 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
838 ipoib_put_ah(ah); 842 ipoib_put_ah(ah);
839} 843}
840 844
841struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) 845struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour,
846 struct net_device *dev)
842{ 847{
843 struct ipoib_neigh *neigh; 848 struct ipoib_neigh *neigh;
844 849
@@ -847,6 +852,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
847 return NULL; 852 return NULL;
848 853
849 neigh->neighbour = neighbour; 854 neigh->neighbour = neighbour;
855 neigh->dev = dev;
850 *to_ipoib_neigh(neighbour) = neigh; 856 *to_ipoib_neigh(neighbour) = neigh;
851 skb_queue_head_init(&neigh->queue); 857 skb_queue_head_init(&neigh->queue);
852 ipoib_cm_set(neigh, NULL); 858 ipoib_cm_set(neigh, NULL);