diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 24 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 3 |
3 files changed, 20 insertions, 11 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 6545fa798b12..1b3327ad6bc4 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -349,6 +349,7 @@ struct ipoib_neigh { | |||
349 | struct sk_buff_head queue; | 349 | struct sk_buff_head queue; |
350 | 350 | ||
351 | struct neighbour *neighbour; | 351 | struct neighbour *neighbour; |
352 | struct net_device *dev; | ||
352 | 353 | ||
353 | struct list_head list; | 354 | struct list_head list; |
354 | }; | 355 | }; |
@@ -365,7 +366,8 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh) | |||
365 | INFINIBAND_ALEN, sizeof(void *)); | 366 | INFINIBAND_ALEN, sizeof(void *)); |
366 | } | 367 | } |
367 | 368 | ||
368 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh); | 369 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh, |
370 | struct net_device *dev); | ||
369 | void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh); | 371 | void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh); |
370 | 372 | ||
371 | extern struct workqueue_struct *ipoib_workqueue; | 373 | extern struct workqueue_struct *ipoib_workqueue; |
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 | ||
841 | struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) | 845 | struct 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); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 827820ec66d1..9bcfc7ad6aa6 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -705,7 +705,8 @@ out: | |||
705 | if (skb->dst && | 705 | if (skb->dst && |
706 | skb->dst->neighbour && | 706 | skb->dst->neighbour && |
707 | !*to_ipoib_neigh(skb->dst->neighbour)) { | 707 | !*to_ipoib_neigh(skb->dst->neighbour)) { |
708 | struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour); | 708 | struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour, |
709 | skb->dev); | ||
709 | 710 | ||
710 | if (neigh) { | 711 | if (neigh) { |
711 | kref_get(&mcast->ah->ref); | 712 | kref_get(&mcast->ah->ref); |