IPoIB: Fix memory leak of multicast group structures

The current handling of multicast groups in IPoIB ends up never
freeing send-only multicast groups. It turns out the logic was much
more complicated than it needed to be; we can fix this bug and
completely kill ipoib_mcast_dev_down() at the same time.

Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by Eli Cohen and committed by Roland Dreier 988bd503 78bfe0b5

+9 -65
+1 -12
drivers/infiniband/ulp/ipoib/ipoib_ib.c
··· 453 453 } 454 454 455 455 ipoib_mcast_stop_thread(dev, 1); 456 - 457 - /* 458 - * Flush the multicast groups first so we stop any multicast joins. The 459 - * completion thread may have already died and we may deadlock waiting 460 - * for the completion thread to finish some multicast joins. 461 - */ 462 456 ipoib_mcast_dev_flush(dev); 463 - 464 - /* Delete broadcast and local addresses since they will be recreated */ 465 - ipoib_mcast_dev_down(dev); 466 457 467 458 ipoib_flush_paths(dev); 468 459 ··· 615 624 ipoib_dbg(priv, "cleaning up ib_dev\n"); 616 625 617 626 ipoib_mcast_stop_thread(dev, 1); 618 - 619 - /* Delete the broadcast address and the local address */ 620 - ipoib_mcast_dev_down(dev); 627 + ipoib_mcast_dev_flush(dev); 621 628 622 629 ipoib_transport_dev_cleanup(dev); 623 630 }
+8 -53
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
··· 742 742 { 743 743 struct ipoib_dev_priv *priv = netdev_priv(dev); 744 744 LIST_HEAD(remove_list); 745 - struct ipoib_mcast *mcast, *tmcast, *nmcast; 745 + struct ipoib_mcast *mcast, *tmcast; 746 746 unsigned long flags; 747 747 748 748 ipoib_dbg_mcast(priv, "flushing multicast list\n"); 749 749 750 750 spin_lock_irqsave(&priv->lock, flags); 751 + 751 752 list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) { 752 - nmcast = ipoib_mcast_alloc(dev, 0); 753 - if (nmcast) { 754 - nmcast->flags = 755 - mcast->flags & (1 << IPOIB_MCAST_FLAG_SENDONLY); 756 - 757 - nmcast->mcmember.mgid = mcast->mcmember.mgid; 758 - 759 - /* Add the new group in before the to-be-destroyed group */ 760 - list_add_tail(&nmcast->list, &mcast->list); 761 - list_del_init(&mcast->list); 762 - 763 - rb_replace_node(&mcast->rb_node, &nmcast->rb_node, 764 - &priv->multicast_tree); 765 - 766 - list_add_tail(&mcast->list, &remove_list); 767 - } else { 768 - ipoib_warn(priv, "could not reallocate multicast group " 769 - IPOIB_GID_FMT "\n", 770 - IPOIB_GID_ARG(mcast->mcmember.mgid)); 771 - } 753 + list_del(&mcast->list); 754 + rb_erase(&mcast->rb_node, &priv->multicast_tree); 755 + list_add_tail(&mcast->list, &remove_list); 772 756 } 773 757 774 758 if (priv->broadcast) { 775 - nmcast = ipoib_mcast_alloc(dev, 0); 776 - if (nmcast) { 777 - nmcast->mcmember.mgid = priv->broadcast->mcmember.mgid; 778 - 779 - rb_replace_node(&priv->broadcast->rb_node, 780 - &nmcast->rb_node, 781 - &priv->multicast_tree); 782 - 783 - list_add_tail(&priv->broadcast->list, &remove_list); 784 - priv->broadcast = nmcast; 785 - } else 786 - ipoib_warn(priv, "could not reallocate broadcast group " 787 - IPOIB_GID_FMT "\n", 788 - IPOIB_GID_ARG(priv->broadcast->mcmember.mgid)); 759 + rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); 760 + list_add_tail(&priv->broadcast->list, &remove_list); 761 + priv->broadcast = NULL; 789 762 } 790 763 791 764 spin_unlock_irqrestore(&priv->lock, flags); ··· 766 793 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { 767 794 ipoib_mcast_leave(dev, mcast); 768 795 ipoib_mcast_free(mcast); 769 - } 770 - } 771 - 772 - void ipoib_mcast_dev_down(struct net_device *dev) 773 - { 774 - struct ipoib_dev_priv *priv = netdev_priv(dev); 775 - unsigned long flags; 776 - 777 - /* Delete broadcast since it will be recreated */ 778 - if (priv->broadcast) { 779 - ipoib_dbg_mcast(priv, "deleting broadcast group\n"); 780 - 781 - spin_lock_irqsave(&priv->lock, flags); 782 - rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); 783 - spin_unlock_irqrestore(&priv->lock, flags); 784 - ipoib_mcast_leave(dev, priv->broadcast); 785 - ipoib_mcast_free(priv->broadcast); 786 - priv->broadcast = NULL; 787 796 } 788 797 } 789 798