aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Lameter <cl@linux.com>2015-10-11 19:49:42 -0400
committerDoug Ledford <dledford@redhat.com>2015-10-13 16:43:59 -0400
commit0b5c9279e568d90903acedc2b9b832d8d78e8288 (patch)
tree6dca079bc1801a09f1ac2d5246a62051ad77228a
parentb8cab5dab15ff5c2acc3faefdde28919b0341c11 (diff)
IB/ipoib: For sendonly join free the multicast group on leave
When we leave the multicast group on expiration of a neighbor we do not free the mcast structure. This results in a memory leak that causes ib_dealloc_pd to fail and print a WARN_ON message and backtrace. Fixes: bd99b2e05c4d (IB/ipoib: Expire sendonly multicast joins) Signed-off-by: Christoph Lameter <cl@linux.com> Tested-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c2
3 files changed, 5 insertions, 2 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 4cd5428a2399..edc5b8565d6d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -495,6 +495,7 @@ void ipoib_dev_cleanup(struct net_device *dev);
495void ipoib_mcast_join_task(struct work_struct *work); 495void ipoib_mcast_join_task(struct work_struct *work);
496void ipoib_mcast_carrier_on_task(struct work_struct *work); 496void ipoib_mcast_carrier_on_task(struct work_struct *work);
497void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); 497void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb);
498void ipoib_mcast_free(struct ipoib_mcast *mc);
498 499
499void ipoib_mcast_restart_task(struct work_struct *work); 500void ipoib_mcast_restart_task(struct work_struct *work);
500int ipoib_mcast_start_thread(struct net_device *dev); 501int ipoib_mcast_start_thread(struct net_device *dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f74316e679d2..babba05d7a0e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1207,8 +1207,10 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
1207 1207
1208out_unlock: 1208out_unlock:
1209 spin_unlock_irqrestore(&priv->lock, flags); 1209 spin_unlock_irqrestore(&priv->lock, flags);
1210 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) 1210 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
1211 ipoib_mcast_leave(dev, mcast); 1211 ipoib_mcast_leave(dev, mcast);
1212 ipoib_mcast_free(mcast);
1213 }
1212} 1214}
1213 1215
1214static void ipoib_reap_neigh(struct work_struct *work) 1216static void ipoib_reap_neigh(struct work_struct *work)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 136cbefe00f8..d750a86042f3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -106,7 +106,7 @@ static void __ipoib_mcast_schedule_join_thread(struct ipoib_dev_priv *priv,
106 queue_delayed_work(priv->wq, &priv->mcast_task, 0); 106 queue_delayed_work(priv->wq, &priv->mcast_task, 0);
107} 107}
108 108
109static void ipoib_mcast_free(struct ipoib_mcast *mcast) 109void ipoib_mcast_free(struct ipoib_mcast *mcast)
110{ 110{
111 struct net_device *dev = mcast->dev; 111 struct net_device *dev = mcast->dev;
112 int tx_dropped = 0; 112 int tx_dropped = 0;