diff options
author | Jay Vosburgh <fubar@us.ibm.com> | 2007-12-07 02:40:35 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-12-07 15:00:34 -0500 |
commit | fdaea7a93d097b066e76c7db6091228a84f87ec2 (patch) | |
tree | b339439c29b8696b57cd83644f355dbb34008f70 /drivers | |
parent | 6f6652be183c8c7cb99c646dd7494ab45e4833ba (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.c | 43 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 2 |
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 | ||
4495 | static 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 | ||
4905 | static 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 | |||
4926 | static int __init bonding_init(void) | 4927 | static 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" |