diff options
author | Christoph Lameter <cl@linux.com> | 2015-10-11 19:49:42 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-10-13 16:43:59 -0400 |
commit | 0b5c9279e568d90903acedc2b9b832d8d78e8288 (patch) | |
tree | 6dca079bc1801a09f1ac2d5246a62051ad77228a | |
parent | b8cab5dab15ff5c2acc3faefdde28919b0341c11 (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.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 2 |
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); | |||
495 | void ipoib_mcast_join_task(struct work_struct *work); | 495 | void ipoib_mcast_join_task(struct work_struct *work); |
496 | void ipoib_mcast_carrier_on_task(struct work_struct *work); | 496 | void ipoib_mcast_carrier_on_task(struct work_struct *work); |
497 | void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); | 497 | void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); |
498 | void ipoib_mcast_free(struct ipoib_mcast *mc); | ||
498 | 499 | ||
499 | void ipoib_mcast_restart_task(struct work_struct *work); | 500 | void ipoib_mcast_restart_task(struct work_struct *work); |
500 | int ipoib_mcast_start_thread(struct net_device *dev); | 501 | int 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 | ||
1208 | out_unlock: | 1208 | out_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 | ||
1214 | static void ipoib_reap_neigh(struct work_struct *work) | 1216 | static 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 | ||
109 | static void ipoib_mcast_free(struct ipoib_mcast *mcast) | 109 | void 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; |