aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAndy Gospodarek <andy@greyhouse.net>2008-10-30 20:41:16 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-10-31 00:46:12 -0400
commitce39a800ea87c655de49af021c8b20ee323cb40d (patch)
treef461c679d9c03639256501a221bbd8542fe65858 /drivers/net
parenta434e43f3d844192bc23bd7b408bac979c40efe7 (diff)
bonding: fix panic when taking bond interface down before removing module
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_alb.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index ade5f3f6693b..87437c788476 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -169,11 +169,14 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_
169 /* clear slave from tx_hashtbl */ 169 /* clear slave from tx_hashtbl */
170 tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; 170 tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
171 171
172 index = SLAVE_TLB_INFO(slave).head; 172 /* skip this if we've already freed the tx hash table */
173 while (index != TLB_NULL_INDEX) { 173 if (tx_hash_table) {
174 u32 next_index = tx_hash_table[index].next; 174 index = SLAVE_TLB_INFO(slave).head;
175 tlb_init_table_entry(&tx_hash_table[index], save_load); 175 while (index != TLB_NULL_INDEX) {
176 index = next_index; 176 u32 next_index = tx_hash_table[index].next;
177 tlb_init_table_entry(&tx_hash_table[index], save_load);
178 index = next_index;
179 }
177 } 180 }
178 181
179 tlb_init_slave(slave); 182 tlb_init_slave(slave);