diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_main.c')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index e072f3c32ce6..362610d870e4 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); |
@@ -692,9 +692,10 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
692 | goto out; | 692 | goto out; |
693 | } | 693 | } |
694 | } else if (neigh->ah) { | 694 | } else if (neigh->ah) { |
695 | if (unlikely(memcmp(&neigh->dgid.raw, | 695 | if (unlikely((memcmp(&neigh->dgid.raw, |
696 | skb->dst->neighbour->ha + 4, | 696 | skb->dst->neighbour->ha + 4, |
697 | sizeof(union ib_gid)))) { | 697 | sizeof(union ib_gid))) || |
698 | (neigh->dev != dev))) { | ||
698 | spin_lock(&priv->lock); | 699 | spin_lock(&priv->lock); |
699 | /* | 700 | /* |
700 | * It's safe to call ipoib_put_ah() inside | 701 | * It's safe to call ipoib_put_ah() inside |
@@ -817,6 +818,13 @@ static void ipoib_neigh_cleanup(struct neighbour *n) | |||
817 | unsigned long flags; | 818 | unsigned long flags; |
818 | struct ipoib_ah *ah = NULL; | 819 | struct ipoib_ah *ah = NULL; |
819 | 820 | ||
821 | neigh = *to_ipoib_neigh(n); | ||
822 | if (neigh) { | ||
823 | priv = netdev_priv(neigh->dev); | ||
824 | ipoib_dbg(priv, "neigh_destructor for bonding device: %s\n", | ||
825 | n->dev->name); | ||
826 | } else | ||
827 | return; | ||
820 | ipoib_dbg(priv, | 828 | ipoib_dbg(priv, |
821 | "neigh_cleanup for %06x " IPOIB_GID_FMT "\n", | 829 | "neigh_cleanup for %06x " IPOIB_GID_FMT "\n", |
822 | IPOIB_QPN(n->ha), | 830 | IPOIB_QPN(n->ha), |
@@ -824,13 +832,10 @@ static void ipoib_neigh_cleanup(struct neighbour *n) | |||
824 | 832 | ||
825 | spin_lock_irqsave(&priv->lock, flags); | 833 | spin_lock_irqsave(&priv->lock, flags); |
826 | 834 | ||
827 | neigh = *to_ipoib_neigh(n); | 835 | if (neigh->ah) |
828 | if (neigh) { | 836 | ah = neigh->ah; |
829 | if (neigh->ah) | 837 | list_del(&neigh->list); |
830 | ah = neigh->ah; | 838 | ipoib_neigh_free(n->dev, neigh); |
831 | list_del(&neigh->list); | ||
832 | ipoib_neigh_free(n->dev, neigh); | ||
833 | } | ||
834 | 839 | ||
835 | spin_unlock_irqrestore(&priv->lock, flags); | 840 | spin_unlock_irqrestore(&priv->lock, flags); |
836 | 841 | ||
@@ -838,7 +843,8 @@ static void ipoib_neigh_cleanup(struct neighbour *n) | |||
838 | ipoib_put_ah(ah); | 843 | ipoib_put_ah(ah); |
839 | } | 844 | } |
840 | 845 | ||
841 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) | 846 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour, |
847 | struct net_device *dev) | ||
842 | { | 848 | { |
843 | struct ipoib_neigh *neigh; | 849 | struct ipoib_neigh *neigh; |
844 | 850 | ||
@@ -847,6 +853,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) | |||
847 | return NULL; | 853 | return NULL; |
848 | 854 | ||
849 | neigh->neighbour = neighbour; | 855 | neigh->neighbour = neighbour; |
856 | neigh->dev = dev; | ||
850 | *to_ipoib_neigh(neighbour) = neigh; | 857 | *to_ipoib_neigh(neighbour) = neigh; |
851 | skb_queue_head_init(&neigh->queue); | 858 | skb_queue_head_init(&neigh->queue); |
852 | ipoib_cm_set(neigh, NULL); | 859 | ipoib_cm_set(neigh, NULL); |