aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2007-12-07 02:40:35 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-07 15:00:34 -0500
commitfdaea7a93d097b066e76c7db6091228a84f87ec2 (patch)
treeb339439c29b8696b57cd83644f355dbb34008f70 /drivers
parent6f6652be183c8c7cb99c646dd7494ab45e4833ba (diff)
bonding: Fix race at module unload
Fixes a race condition in module unload. Without this change, workqueue events may fire while bonding data structures are partially freed but before bond_close() is invoked by unregister_netdevice(). Update version to 3.2.3. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c43
-rw-r--r--drivers/net/bonding/bonding.h2
2 files changed, 23 insertions, 22 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 08879d552ae0..b0b26036266b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4492,6 +4492,27 @@ static void bond_deinit(struct net_device *bond_dev)
4492#endif 4492#endif
4493} 4493}
4494 4494
4495static void bond_work_cancel_all(struct bonding *bond)
4496{
4497 write_lock_bh(&bond->lock);
4498 bond->kill_timers = 1;
4499 write_unlock_bh(&bond->lock);
4500
4501 if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
4502 cancel_delayed_work(&bond->mii_work);
4503
4504 if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
4505 cancel_delayed_work(&bond->arp_work);
4506
4507 if (bond->params.mode == BOND_MODE_ALB &&
4508 delayed_work_pending(&bond->alb_work))
4509 cancel_delayed_work(&bond->alb_work);
4510
4511 if (bond->params.mode == BOND_MODE_8023AD &&
4512 delayed_work_pending(&bond->ad_work))
4513 cancel_delayed_work(&bond->ad_work);
4514}
4515
4495/* Unregister and free all bond devices. 4516/* Unregister and free all bond devices.
4496 * Caller must hold rtnl_lock. 4517 * Caller must hold rtnl_lock.
4497 */ 4518 */
@@ -4502,6 +4523,7 @@ static void bond_free_all(void)
4502 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { 4523 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
4503 struct net_device *bond_dev = bond->dev; 4524 struct net_device *bond_dev = bond->dev;
4504 4525
4526 bond_work_cancel_all(bond);
4505 bond_mc_list_destroy(bond); 4527 bond_mc_list_destroy(bond);
4506 /* Release the bonded slaves */ 4528 /* Release the bonded slaves */
4507 bond_release_all(bond_dev); 4529 bond_release_all(bond_dev);
@@ -4902,27 +4924,6 @@ out_rtnl:
4902 return res; 4924 return res;
4903} 4925}
4904 4926
4905static void bond_work_cancel_all(struct bonding *bond)
4906{
4907 write_lock_bh(&bond->lock);
4908 bond->kill_timers = 1;
4909 write_unlock_bh(&bond->lock);
4910
4911 if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
4912 cancel_delayed_work(&bond->mii_work);
4913
4914 if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
4915 cancel_delayed_work(&bond->arp_work);
4916
4917 if (bond->params.mode == BOND_MODE_ALB &&
4918 delayed_work_pending(&bond->alb_work))
4919 cancel_delayed_work(&bond->alb_work);
4920
4921 if (bond->params.mode == BOND_MODE_8023AD &&
4922 delayed_work_pending(&bond->ad_work))
4923 cancel_delayed_work(&bond->ad_work);
4924}
4925
4926static int __init bonding_init(void) 4927static int __init bonding_init(void)
4927{ 4928{
4928 int i; 4929 int i;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ccafc74c5a2b..e1e4734e23ce 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,7 +22,7 @@
22#include "bond_3ad.h" 22#include "bond_3ad.h"
23#include "bond_alb.h" 23#include "bond_alb.h"
24 24
25#define DRV_VERSION "3.2.2" 25#define DRV_VERSION "3.2.3"
26#define DRV_RELDATE "December 6, 2007" 26#define DRV_RELDATE "December 6, 2007"
27#define DRV_NAME "bonding" 27#define DRV_NAME "bonding"
28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"