From 9d34d1a20e8171be819a6c8c4de4eea6104d174e Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 8 May 2009 11:49:11 +0000 Subject: bonding: fix panic if initialization fails If module initialisation failed (e.g. because the bonding sysfs entry cannot be created), kernel panics: IP: [] destroy_workqueue+0x2d/0x146 Call Trace: [] bond_destructor+0x28/0x78 [] netdev_run_todo+0x231/0x25a [] rtnl_unlock+0x9/0xb [] bonding_init+0x83e/0x84a Remove the calls to bond_work_cancel_all() and destroy_workqueue(); both are also called/scheduled via bond_free_all(). bond_destroy_sysfs is unecessary because the sysfs entry has not been created in the error case. Signed-off-by: Florian Westphal Signed-off-by: Jay Vosburgh Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2188a96fc09..74824028f85 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5181,7 +5181,6 @@ static int __init bonding_init(void) { int i; int res; - struct bonding *bond; printk(KERN_INFO "%s", version); @@ -5212,13 +5211,6 @@ static int __init bonding_init(void) goto out; err: - list_for_each_entry(bond, &bond_dev_list, bond_list) { - bond_work_cancel_all(bond); - destroy_workqueue(bond->wq); - } - - bond_destroy_sysfs(); - rtnl_lock(); bond_free_all(); rtnl_unlock(); -- cgit v1.2.3 From 4cd6fe1c6483cde93e2ec91f58b7af9c9eea51ad Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 15 May 2009 08:44:32 +0000 Subject: bonding: fix link down handling in 802.3ad mode One of the purposes of bonding is to allow for redundant links, and failover correctly if the cable is pulled. If all the members of a bonded device have no carrier present, the bonded device itself needs to report no carrier present to user space so management tools (like routing daemons) can respond. Bonding in 802.3ad mode does not work correctly for this because it incorrectly chooses a link that is down as a possible aggregator. Signed-off-by: Stephen Hemminger Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 8c2e5ab51f0..faf094abef7 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1465,6 +1465,12 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, return best; } +static int agg_device_up(const struct aggregator *agg) +{ + return (netif_running(agg->slave->dev) && + netif_carrier_ok(agg->slave->dev)); +} + /** * ad_agg_selection_logic - select an aggregation group for a team * @aggregator: the aggregator we're looking at @@ -1496,14 +1502,13 @@ static void ad_agg_selection_logic(struct aggregator *agg) struct port *port; origin = agg; - active = __get_active_agg(agg); - best = active; + best = (active && agg_device_up(active)) ? active : NULL; do { agg->is_active = 0; - if (agg->num_of_ports) + if (agg->num_of_ports && agg_device_up(agg)) best = ad_agg_selection_test(best, agg); } while ((agg = __get_next_agg(agg))); -- cgit v1.2.3