diff options
author | Andy Gospodarek <andy@greyhouse.net> | 2008-10-30 17:41:16 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-11-06 19:05:55 -0800 |
commit | c17c98e2755a57e09f16432654f40027780cbacd (patch) | |
tree | ef49df151f3392ba63607f700d03debd20bf7686 /drivers/net | |
parent | c4305ddcd753bd84a465a2a319e7846f7783b439 (diff) |
bonding: fix panic when taking bond interface down before removing module
commit ce39a800ea87c655de49af021c8b20ee323cb40d upstream.
A panic was discovered with bonding when using mode 5 or 6 and trying to
remove the slaves from the bond after the interface was taken down.
When calling 'ifconfig bond0 down' the following happens:
bond_close()
bond_alb_deinitialize()
tlb_deinitialize()
kfree(bond_info->tx_hashtbl)
bond_info->tx_hashtbl = NULL
Unfortunately if there are still slaves in the bond, when removing the
module the following happens:
bonding_exit()
bond_free_all()
bond_release_all()
bond_alb_deinit_slave()
tlb_clear_slave()
tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl
u32 next_index = tx_hash_table[index].next
As you might guess we panic when trying to access a few entries into the
table that no longer exists.
I experimented with several options (like moving the calls to
tlb_deinitialize somewhere else), but it really makes the most sense to
be part of the bond_close routine. It also didn't seem logical move
tlb_clear_slave around too much, so the simplest option seems to add a
check in tlb_clear_slave to make sure we haven't already wiped the
tx_hashtbl away before searching for all the non-existent hash-table
entries that used to point to the slave as the output interface.
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index b211486a0ca3..4489e586be1d 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -167,11 +167,14 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_ /* clear slave from tx_hashtbl */ tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; - index = SLAVE_TLB_INFO(slave).head; - while (index != TLB_NULL_INDEX) { - u32 next_index = tx_hash_table[index].next; - tlb_init_table_entry(&tx_hash_table[index], save_load); - index = next_index; + /* skip this if we've already freed the tx hash table */ + if (tx_hash_table) { + index = SLAVE_TLB_INFO(slave).head; + while (index != TLB_NULL_INDEX) { + u32 next_index = tx_hash_table[index].next; + tlb_init_table_entry(&tx_hash_table[index], save_load); + index = next_index; + } } tlb_init_slave(slave); |