aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2008-10-30 20:41:15 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-10-31 00:46:04 -0400
commita434e43f3d844192bc23bd7b408bac979c40efe7 (patch)
treec14f191bafc78a1194815e0e9df5223dd52e8d99 /drivers/net/bonding
parentfba4acda35f3119328bcba28aacefae14245d2bb (diff)
bonding: Clean up resource leaks
This patch reworks the resource free logic performed at the time a bonding device is released. This (a) closes two resource leaks, one for workqueues and one for multicast lists, and (b) improves commonality of code between the "destroy one" and "destroy all" paths by performing final free activity via destructor instead of explicitly (and differently) in each path. "Sean E. Millichamp" <sean@bruenor.org> reported the workqueue leak, and included a different patch. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 85de1d04d1ee..a3efba59eee9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1979,6 +1979,20 @@ void bond_destroy(struct bonding *bond)
1979 unregister_netdevice(bond->dev); 1979 unregister_netdevice(bond->dev);
1980} 1980}
1981 1981
1982static void bond_destructor(struct net_device *bond_dev)
1983{
1984 struct bonding *bond = bond_dev->priv;
1985
1986 if (bond->wq)
1987 destroy_workqueue(bond->wq);
1988
1989 netif_addr_lock_bh(bond_dev);
1990 bond_mc_list_destroy(bond);
1991 netif_addr_unlock_bh(bond_dev);
1992
1993 free_netdev(bond_dev);
1994}
1995
1982/* 1996/*
1983* First release a slave and than destroy the bond if no more slaves iare left. 1997* First release a slave and than destroy the bond if no more slaves iare left.
1984* Must be under rtnl_lock when this function is called. 1998* Must be under rtnl_lock when this function is called.
@@ -4553,7 +4567,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
4553 4567
4554 bond_set_mode_ops(bond, bond->params.mode); 4568 bond_set_mode_ops(bond, bond->params.mode);
4555 4569
4556 bond_dev->destructor = free_netdev; 4570 bond_dev->destructor = bond_destructor;
4557 4571
4558 /* Initialize the device options */ 4572 /* Initialize the device options */
4559 bond_dev->tx_queue_len = 0; 4573 bond_dev->tx_queue_len = 0;
@@ -4592,20 +4606,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
4592 return 0; 4606 return 0;
4593} 4607}
4594 4608
4595/* De-initialize device specific data.
4596 * Caller must hold rtnl_lock.
4597 */
4598static void bond_deinit(struct net_device *bond_dev)
4599{
4600 struct bonding *bond = bond_dev->priv;
4601
4602 list_del(&bond->bond_list);
4603
4604#ifdef CONFIG_PROC_FS
4605 bond_remove_proc_entry(bond);
4606#endif
4607}
4608
4609static void bond_work_cancel_all(struct bonding *bond) 4609static void bond_work_cancel_all(struct bonding *bond)
4610{ 4610{
4611 write_lock_bh(&bond->lock); 4611 write_lock_bh(&bond->lock);
@@ -4627,6 +4627,22 @@ static void bond_work_cancel_all(struct bonding *bond)
4627 cancel_delayed_work(&bond->ad_work); 4627 cancel_delayed_work(&bond->ad_work);
4628} 4628}
4629 4629
4630/* De-initialize device specific data.
4631 * Caller must hold rtnl_lock.
4632 */
4633static void bond_deinit(struct net_device *bond_dev)
4634{
4635 struct bonding *bond = bond_dev->priv;
4636
4637 list_del(&bond->bond_list);
4638
4639 bond_work_cancel_all(bond);
4640
4641#ifdef CONFIG_PROC_FS
4642 bond_remove_proc_entry(bond);
4643#endif
4644}
4645
4630/* Unregister and free all bond devices. 4646/* Unregister and free all bond devices.
4631 * Caller must hold rtnl_lock. 4647 * Caller must hold rtnl_lock.
4632 */ 4648 */
@@ -4638,9 +4654,6 @@ static void bond_free_all(void)
4638 struct net_device *bond_dev = bond->dev; 4654 struct net_device *bond_dev = bond->dev;
4639 4655
4640 bond_work_cancel_all(bond); 4656 bond_work_cancel_all(bond);
4641 netif_addr_lock_bh(bond_dev);
4642 bond_mc_list_destroy(bond);
4643 netif_addr_unlock_bh(bond_dev);
4644 /* Release the bonded slaves */ 4657 /* Release the bonded slaves */
4645 bond_release_all(bond_dev); 4658 bond_release_all(bond_dev);
4646 bond_destroy(bond); 4659 bond_destroy(bond);