aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c24
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c3
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
368struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh); 369struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
370 struct net_device *dev);
369void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh); 371void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
370 372
371extern struct workqueue_struct *ipoib_workqueue; 373extern 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
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);
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);