* [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups.
@ 2008-04-29 14:51 Pavel Emelyanov
2008-04-29 14:54 ` [PATCH 1/8][BONDING]: Do not call free_netdev for already registered device Pavel Emelyanov
` (8 more replies)
0 siblings, 9 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 14:51 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
Hi Jay, Dave.
While looking at the bonding driver I found four bugs visible with
the unaided eye. Here are the fixes, but I also cleaned up some
places, I just couldn't come by. If you consider those cleanups to
be for next merge window, just kick me and I'll resubmit this set
without them.
Found BUGs summary:
1. Bad error path in bond_create - the registered device should
not be released with free_netdev;
2. Specifying the 'bond%d' name when creating a new device results
in a new device with literally 'bond%d' name, not bond<digit>
like for other drivers;
3. Lost unlock of rtnl and bonding_rwsem in bonding_store_bonds;
4. Deadlock between bonding_store_bonds and bond_destroy_sysfs
on module unload.
The clean ups are
1. Minor alloc_netdev consolidation after fix #2
2. Redundant 3rd argument for bond_create;
3. Unneeded _safe list iterations in some places;
4. Unneeded list_empty checks in some places.
Details in patches.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/8][BONDING]: Do not call free_netdev for already registered device.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
@ 2008-04-29 14:54 ` Pavel Emelyanov
2008-04-29 14:56 ` [PATCH 2/8][BONDING]: Don't create bondings with % in their names Pavel Emelyanov
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 14:54 UTC (permalink / raw)
Cc: Jay Vosburgh, David Miller, bonding-devel, Linux Netdev List
If the call to bond_create_sysfs_entry in bond_create fails, the
proper rollback is to call unregister_netdevice, not free_netdev.
Otherwise - kernel BUG at net/core/dev.c:4057!
Checked with artificial failures injected into bond_create_sysfs_entry.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6e91b4b..36121b6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4936,14 +4936,18 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
up_write(&bonding_rwsem);
rtnl_unlock(); /* allows sysfs registration of net device */
res = bond_create_sysfs_entry(bond_dev->priv);
- if (res < 0) {
- rtnl_lock();
- down_write(&bonding_rwsem);
- goto out_bond;
- }
+ if (res < 0)
+ goto out_unreg;
return 0;
+out_unreg:
+ rtnl_lock();
+ down_write(&bonding_rwsem);
+ bond_deinit(bond_dev);
+ unregister_netdevice(bond_dev);
+ goto out_rtnl;
+
out_bond:
bond_deinit(bond_dev);
out_netdev:
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/8][BONDING]: Don't create bondings with % in their names.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
2008-04-29 14:54 ` [PATCH 1/8][BONDING]: Do not call free_netdev for already registered device Pavel Emelyanov
@ 2008-04-29 14:56 ` Pavel Emelyanov
2008-04-29 14:58 ` [PATCH 3/8][BONDING]: Merge two calls to dev_alloc_name Pavel Emelyanov
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 14:56 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
Type
# echo '+bond%d' > /sys/class/net/bonding_masters
and get the 'bond%d' device in the ip l l output.
Other drivers do not play such jokes on user :)
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 36121b6..2072910 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4909,6 +4909,10 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
res = dev_alloc_name(bond_dev, "bond%d");
if (res < 0)
goto out_netdev;
+ } else if (strchr(name, '%')) {
+ res = dev_alloc_name(bond_dev, name);
+ if (res < 0)
+ goto out_netdev;
}
/* bond_init() must be called after dev_alloc_name() (for the
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/8][BONDING]: Merge two calls to dev_alloc_name.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
2008-04-29 14:54 ` [PATCH 1/8][BONDING]: Do not call free_netdev for already registered device Pavel Emelyanov
2008-04-29 14:56 ` [PATCH 2/8][BONDING]: Don't create bondings with % in their names Pavel Emelyanov
@ 2008-04-29 14:58 ` Pavel Emelyanov
2008-04-29 15:01 ` [PATCH 4/8][BONDING]: Remove redundant argument from bond_create Pavel Emelyanov
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 14:58 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
Just reduce the amount of code after the previous patch.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2072910..0907f43 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4905,11 +4905,10 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
goto out_rtnl;
}
- if (!name) {
- res = dev_alloc_name(bond_dev, "bond%d");
- if (res < 0)
- goto out_netdev;
- } else if (strchr(name, '%')) {
+ if (!name)
+ name = "bond%d";
+
+ if (strchr(name, '%')) {
res = dev_alloc_name(bond_dev, name);
if (res < 0)
goto out_netdev;
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/8][BONDING]: Remove redundant argument from bond_create.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
` (2 preceding siblings ...)
2008-04-29 14:58 ` [PATCH 3/8][BONDING]: Merge two calls to dev_alloc_name Pavel Emelyanov
@ 2008-04-29 15:01 ` Pavel Emelyanov
2008-04-29 15:02 ` [PATCH 5/8][BONDING]: Lost semaphores unlock in one of bonding_store_bonds error paths Pavel Emelyanov
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 15:01 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
While we're fixing the bond_create, I hope it's OK to polish it
a bit after the fixes.
The third argument is NULL at the first caller and is ignored by
the second one, so remove it.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 7 ++-----
drivers/net/bonding/bond_sysfs.c | 2 +-
drivers/net/bonding/bonding.h | 2 +-
3 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 0907f43..c6661a9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4874,7 +4874,7 @@ static struct lock_class_key bonding_netdev_xmit_lock_key;
* Caller must NOT hold rtnl_lock; we need to release it here before we
* set up our sysfs entries.
*/
-int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
+int bond_create(char *name, struct bond_params *params)
{
struct net_device *bond_dev;
struct bonding *bond, *nxt;
@@ -4931,9 +4931,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key);
- if (newbond)
- *newbond = bond_dev->priv;
-
netif_carrier_off(bond_dev);
up_write(&bonding_rwsem);
@@ -4981,7 +4978,7 @@ static int __init bonding_init(void)
init_rwsem(&bonding_rwsem);
for (i = 0; i < max_bonds; i++) {
- res = bond_create(NULL, &bonding_defaults, NULL);
+ res = bond_create(NULL, &bonding_defaults);
if (res)
goto err;
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 979c2d0..88de27f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -122,7 +122,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
if (command[0] == '+') {
printk(KERN_INFO DRV_NAME
": %s is being created...\n", ifname);
- rv = bond_create(ifname, &bonding_defaults, &bond);
+ rv = bond_create(ifname, &bonding_defaults);
if (rv) {
printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
res = rv;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index a3c74e2..0ce7f4a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -301,7 +301,7 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+int bond_create(char *name, struct bond_params *params);
void bond_destroy(struct bonding *bond);
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_create_sysfs(void);
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/8][BONDING]: Lost semaphores unlock in one of bonding_store_bonds error paths.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
` (3 preceding siblings ...)
2008-04-29 15:01 ` [PATCH 4/8][BONDING]: Remove redundant argument from bond_create Pavel Emelyanov
@ 2008-04-29 15:02 ` Pavel Emelyanov
2008-04-29 15:05 ` [PATCH 6/8][BONDING]: Relax unneeded _safe lists iterations Pavel Emelyanov
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 15:02 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
The out: label just makes return. Wipe things up.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_sysfs.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 88de27f..752e43b 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -146,12 +146,12 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
": Unable remove bond %s due to open references.\n",
ifname);
res = -EPERM;
- goto out;
+ } else {
+ printk(KERN_INFO DRV_NAME
+ ": %s is being deleted...\n",
+ bond->dev->name);
+ bond_destroy(bond);
}
- printk(KERN_INFO DRV_NAME
- ": %s is being deleted...\n",
- bond->dev->name);
- bond_destroy(bond);
up_write(&bonding_rwsem);
rtnl_unlock();
goto out;
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/8][BONDING]: Relax unneeded _safe lists iterations.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
` (4 preceding siblings ...)
2008-04-29 15:02 ` [PATCH 5/8][BONDING]: Lost semaphores unlock in one of bonding_store_bonds error paths Pavel Emelyanov
@ 2008-04-29 15:05 ` Pavel Emelyanov
2008-04-29 15:06 ` [PATCH 7/8][BONDING]: Remove unneeded list_empty checks Pavel Emelyanov
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 15:05 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
Many places either do not modify the list under the list_for_each_xxx,
or break out of the loop as soon as the first element is removed.
Thus, this _safe iteration just occupies some unneeded .text space
and requires an additional variable.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 36 ++++++++++++++++--------------------
drivers/net/bonding/bond_sysfs.c | 3 +--
2 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c6661a9..8623e47 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -261,14 +261,14 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
*/
static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
{
- struct vlan_entry *vlan, *next;
+ struct vlan_entry *vlan;
int res = -ENODEV;
dprintk("bond: %s, vlan id %d\n", bond->dev->name, vlan_id);
write_lock_bh(&bond->lock);
- list_for_each_entry_safe(vlan, next, &bond->vlan_list, vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (vlan->vlan_id == vlan_id) {
list_del(&vlan->vlan_list);
@@ -2428,7 +2428,7 @@ out:
static int bond_has_ip(struct bonding *bond)
{
- struct vlan_entry *vlan, *vlan_next;
+ struct vlan_entry *vlan;
if (bond->master_ip)
return 1;
@@ -2436,8 +2436,7 @@ static int bond_has_ip(struct bonding *bond)
if (list_empty(&bond->vlan_list))
return 0;
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (vlan->vlan_ip)
return 1;
}
@@ -2447,7 +2446,7 @@ static int bond_has_ip(struct bonding *bond)
static int bond_has_this_ip(struct bonding *bond, __be32 ip)
{
- struct vlan_entry *vlan, *vlan_next;
+ struct vlan_entry *vlan;
if (ip == bond->master_ip)
return 1;
@@ -2455,8 +2454,7 @@ static int bond_has_this_ip(struct bonding *bond, __be32 ip)
if (list_empty(&bond->vlan_list))
return 0;
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (ip == vlan->vlan_ip)
return 1;
}
@@ -2498,7 +2496,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
{
int i, vlan_id, rv;
__be32 *targets = bond->params.arp_targets;
- struct vlan_entry *vlan, *vlan_next;
+ struct vlan_entry *vlan;
struct net_device *vlan_dev;
struct flowi fl;
struct rtable *rt;
@@ -2545,8 +2543,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
}
vlan_id = 0;
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
if (vlan_dev == rt->u.dst.dev) {
vlan_id = vlan->vlan_id;
@@ -3503,13 +3500,13 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
{
struct in_ifaddr *ifa = ptr;
struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
- struct bonding *bond, *bond_next;
- struct vlan_entry *vlan, *vlan_next;
+ struct bonding *bond;
+ struct vlan_entry *vlan;
if (dev_net(ifa->ifa_dev->dev) != &init_net)
return NOTIFY_DONE;
- list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) {
+ list_for_each_entry(bond, &bond_dev_list, bond_list) {
if (bond->dev == event_dev) {
switch (event) {
case NETDEV_UP:
@@ -3526,8 +3523,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
if (list_empty(&bond->vlan_list))
continue;
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
if (vlan_dev == event_dev) {
switch (event) {
@@ -4877,7 +4873,7 @@ static struct lock_class_key bonding_netdev_xmit_lock_key;
int bond_create(char *name, struct bond_params *params)
{
struct net_device *bond_dev;
- struct bonding *bond, *nxt;
+ struct bonding *bond;
int res;
rtnl_lock();
@@ -4885,7 +4881,7 @@ int bond_create(char *name, struct bond_params *params)
/* Check to see if the bond already exists. */
if (name) {
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+ list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
printk(KERN_ERR DRV_NAME
": cannot add bond %s; it already exists\n",
@@ -4962,7 +4958,7 @@ static int __init bonding_init(void)
{
int i;
int res;
- struct bonding *bond, *nxt;
+ struct bonding *bond;
printk(KERN_INFO "%s", version);
@@ -4992,7 +4988,7 @@ static int __init bonding_init(void)
goto out;
err:
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+ list_for_each_entry(bond, &bond_dev_list, bond_list) {
bond_work_cancel_all(bond);
destroy_workqueue(bond->wq);
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 752e43b..8133855 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -111,7 +111,6 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
char *ifname;
int rv, res = count;
struct bonding *bond;
- struct bonding *nxt;
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
@@ -134,7 +133,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
rtnl_lock();
down_write(&bonding_rwsem);
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+ list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
/* check the ref count on the bond's kobject.
* If it's > expected, then there's a file open,
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/8][BONDING]: Remove unneeded list_empty checks.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
` (5 preceding siblings ...)
2008-04-29 15:05 ` [PATCH 6/8][BONDING]: Relax unneeded _safe lists iterations Pavel Emelyanov
@ 2008-04-29 15:06 ` Pavel Emelyanov
2008-04-29 15:11 ` [PATCH 8/8][BONDING]: Deadlock between bonding_store_bonds and bond_destroy_sysfs Pavel Emelyanov
2008-05-03 0:06 ` [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups David Miller
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 15:06 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
Some places iterate over the checked list right after the check
itself, so even if the list is empty, the list_for_each_xxx
iterator will make everything right by himself.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 9 ---------
1 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8623e47..4d852ab 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2433,9 +2433,6 @@ static int bond_has_ip(struct bonding *bond)
if (bond->master_ip)
return 1;
- if (list_empty(&bond->vlan_list))
- return 0;
-
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (vlan->vlan_ip)
return 1;
@@ -2451,9 +2448,6 @@ static int bond_has_this_ip(struct bonding *bond, __be32 ip)
if (ip == bond->master_ip)
return 1;
- if (list_empty(&bond->vlan_list))
- return 0;
-
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (ip == vlan->vlan_ip)
return 1;
@@ -3520,9 +3514,6 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
}
}
- if (list_empty(&bond->vlan_list))
- continue;
-
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
if (vlan_dev == event_dev) {
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 8/8][BONDING]: Deadlock between bonding_store_bonds and bond_destroy_sysfs.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
` (6 preceding siblings ...)
2008-04-29 15:06 ` [PATCH 7/8][BONDING]: Remove unneeded list_empty checks Pavel Emelyanov
@ 2008-04-29 15:11 ` Pavel Emelyanov
2008-05-03 0:06 ` [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups David Miller
8 siblings, 0 replies; 11+ messages in thread
From: Pavel Emelyanov @ 2008-04-29 15:11 UTC (permalink / raw)
To: Jay Vosburgh, David Miller; +Cc: bonding-devel, Linux Netdev List
The sysfs layer has an internal protection, that ensures, that
all the process sitting inside ->sore/->show callback exits
before the appropriate entry is unregistered (the calltraces
are rather big, but I can provide them if required).
On the other hand, bonding takes rtnl_lock in
a) the bonding_store_bonds, i.e. in ->store callback,
b) module exit before calling the sysfs unregister routines.
Thus, the classical AB-BA deadlock may occur. To reproduce run
# while :; do modprobe bonding; rmmod bonding; done
and
# while :; do echo '+bond%d' > /sys/class/net/bonding_masters ; done
in parallel.
The fix is to move the bond_destroy_sysfs out of the rtnl_lock,
but _before_ bond_free_all to make sure no bonding devices exist
after module unload.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
drivers/net/bonding/bond_main.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4d852ab..7e7b0b8 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4984,9 +4984,10 @@ err:
destroy_workqueue(bond->wq);
}
+ bond_destroy_sysfs();
+
rtnl_lock();
bond_free_all();
- bond_destroy_sysfs();
rtnl_unlock();
out:
return res;
@@ -4998,9 +4999,10 @@ static void __exit bonding_exit(void)
unregister_netdevice_notifier(&bond_netdev_notifier);
unregister_inetaddr_notifier(&bond_inetaddr_notifier);
+ bond_destroy_sysfs();
+
rtnl_lock();
bond_free_all();
- bond_destroy_sysfs();
rtnl_unlock();
}
--
1.5.3.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups.
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
` (7 preceding siblings ...)
2008-04-29 15:11 ` [PATCH 8/8][BONDING]: Deadlock between bonding_store_bonds and bond_destroy_sysfs Pavel Emelyanov
@ 2008-05-03 0:06 ` David Miller
2008-05-03 0:25 ` Jay Vosburgh
8 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2008-05-03 0:06 UTC (permalink / raw)
To: xemul; +Cc: fubar, bonding-devel, netdev
From: Pavel Emelyanov <xemul@openvz.org>
Date: Tue, 29 Apr 2008 18:51:32 +0400
> While looking at the bonding driver I found four bugs visible with
> the unaided eye. Here are the fixes, but I also cleaned up some
> places, I just couldn't come by. If you consider those cleanups to
> be for next merge window, just kick me and I'll resubmit this set
> without them.
I think all of these patches are excellent.
Jay, et al., can you make sure these go to Jeff and
get integrated?
Thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups.
2008-05-03 0:06 ` [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups David Miller
@ 2008-05-03 0:25 ` Jay Vosburgh
0 siblings, 0 replies; 11+ messages in thread
From: Jay Vosburgh @ 2008-05-03 0:25 UTC (permalink / raw)
To: David Miller; +Cc: xemul, bonding-devel, netdev
David Miller <davem@davemloft.net> wrote:
>From: Pavel Emelyanov <xemul@openvz.org>
>Date: Tue, 29 Apr 2008 18:51:32 +0400
>
>> While looking at the bonding driver I found four bugs visible with
>> the unaided eye. Here are the fixes, but I also cleaned up some
>> places, I just couldn't come by. If you consider those cleanups to
>> be for next merge window, just kick me and I'll resubmit this set
>> without them.
>
>I think all of these patches are excellent.
>
>Jay, et al., can you make sure these go to Jeff and
>get integrated?
Yep, I played with them today, and am passing on the bug fixes
for 2.6.26 and the cleanups for -next.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-05-03 0:26 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-29 14:51 [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups Pavel Emelyanov
2008-04-29 14:54 ` [PATCH 1/8][BONDING]: Do not call free_netdev for already registered device Pavel Emelyanov
2008-04-29 14:56 ` [PATCH 2/8][BONDING]: Don't create bondings with % in their names Pavel Emelyanov
2008-04-29 14:58 ` [PATCH 3/8][BONDING]: Merge two calls to dev_alloc_name Pavel Emelyanov
2008-04-29 15:01 ` [PATCH 4/8][BONDING]: Remove redundant argument from bond_create Pavel Emelyanov
2008-04-29 15:02 ` [PATCH 5/8][BONDING]: Lost semaphores unlock in one of bonding_store_bonds error paths Pavel Emelyanov
2008-04-29 15:05 ` [PATCH 6/8][BONDING]: Relax unneeded _safe lists iterations Pavel Emelyanov
2008-04-29 15:06 ` [PATCH 7/8][BONDING]: Remove unneeded list_empty checks Pavel Emelyanov
2008-04-29 15:11 ` [PATCH 8/8][BONDING]: Deadlock between bonding_store_bonds and bond_destroy_sysfs Pavel Emelyanov
2008-05-03 0:06 ` [PATCH 0/8][BONDING]: Some BUGs and deadlocks fixes and a bit of concomitant cleanups David Miller
2008-05-03 0:25 ` Jay Vosburgh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).