lkml.org 
[lkml]   [2008]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 56/57] bonding: fix panic when taking bond interface down before removing module
2.6.27-stable review patch.  If anyone has any objections, please let us know.

------------------
From: Andy Gospodarek <andy@greyhouse.net>

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>

---
drivers/net/bonding/bond_alb.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -167,11 +167,14 @@ static void tlb_clear_slave(struct bondi
/* 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);
--


\
 
 \ /
  Last update: 2008-11-05 01:01    [W:0.403 / U:0.352 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site