From patchwork Fri Oct 31 00:41:16 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jay Vosburgh X-Patchwork-Id: 6636 X-Patchwork-Delegate: jgarzik@pobox.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 24621DDE04 for ; Fri, 31 Oct 2008 11:41:29 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755595AbYJaAl0 (ORCPT ); Thu, 30 Oct 2008 20:41:26 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754961AbYJaAlY (ORCPT ); Thu, 30 Oct 2008 20:41:24 -0400 Received: from e33.co.us.ibm.com ([32.97.110.151]:60839 "EHLO e33.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754752AbYJaAlV (ORCPT ); Thu, 30 Oct 2008 20:41:21 -0400 Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e33.co.us.ibm.com (8.13.1/8.13.1) with ESMTP id m9V0f03P023727 for ; Thu, 30 Oct 2008 18:41:00 -0600 Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id m9V0fKnC122206 for ; Thu, 30 Oct 2008 18:41:20 -0600 Received: from d03av03.boulder.ibm.com (loopback [127.0.0.1]) by d03av03.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m9V0fJKU014930 for ; Thu, 30 Oct 2008 18:41:19 -0600 Received: from localhost.localdomain (sig-9-65-52-72.mts.ibm.com [9.65.52.72]) by d03av03.boulder.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m9V0fHFr014881; Thu, 30 Oct 2008 18:41:19 -0600 From: Jay Vosburgh To: netdev@vger.kernel.org Cc: Jeff Garzik , Andy Gospodarek Subject: [PATCH 3/3] bonding: fix panic when taking bond interface down before removing module Date: Thu, 30 Oct 2008 17:41:16 -0700 Message-Id: <1225413676-13579-4-git-send-email-fubar@us.ibm.com> X-Mailer: git-send-email 1.5.4.5 In-Reply-To: <1225413676-13579-3-git-send-email-fubar@us.ibm.com> References: <1225413676-13579-1-git-send-email-fubar@us.ibm.com> <1225413676-13579-2-git-send-email-fubar@us.ibm.com> <1225413676-13579-3-git-send-email-fubar@us.ibm.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Andy Gospodarek 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 Signed-off-by: Jay Vosburgh --- 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 ade5f3f..87437c7 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_ /* 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);