From patchwork Thu Mar 26 07:59:22 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirsher, Jeffrey T" X-Patchwork-Id: 25132 X-Patchwork-Delegate: davem@davemloft.net 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 E2556DDD1C for ; Thu, 26 Mar 2009 18:59:59 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755432AbZCZH7q (ORCPT ); Thu, 26 Mar 2009 03:59:46 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755205AbZCZH7p (ORCPT ); Thu, 26 Mar 2009 03:59:45 -0400 Received: from qmta04.westchester.pa.mail.comcast.net ([76.96.62.40]:47501 "EHLO QMTA04.westchester.pa.mail.comcast.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755038AbZCZH7o (ORCPT ); Thu, 26 Mar 2009 03:59:44 -0400 Received: from OMTA08.westchester.pa.mail.comcast.net ([76.96.62.12]) by QMTA04.westchester.pa.mail.comcast.net with comcast id XjzH1b0010Fqzac54jzjbf; Thu, 26 Mar 2009 07:59:43 +0000 Received: from lost.foo-projects.org ([63.64.152.142]) by OMTA08.westchester.pa.mail.comcast.net with comcast id Xk1y1b00134bfcX3Uk20xr; Thu, 26 Mar 2009 08:02:15 +0000 From: Jeff Kirsher Subject: [net-next PATCH 3/3] e1000: fix close race with interrupt To: davem@davemloft.net Cc: netdev@vger.kernel.org, gospo@redhat.com, Alan Cox , Jesse Brandeburg , Jeff Kirsher Date: Thu, 26 Mar 2009 00:59:22 -0700 Message-ID: <20090326075922.30121.40411.stgit@lost.foo-projects.org> In-Reply-To: <20090326075844.30121.48999.stgit@lost.foo-projects.org> References: <20090326075844.30121.48999.stgit@lost.foo-projects.org> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jesse Brandeburg this is in regards to http://bugzilla.kernel.org/show_bug.cgi?id=12876 where it appears that e1000 can leave its interrupt enabled after exiting the driver. Fix the bug by making the interrupt enable paths more aware of the driver exiting. Thanks to Alan Cox for the poke and initial investigation. CC: Alan Cox Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/e1000/e1000_main.c | 28 ++++++++++++++++++++++++---- 1 files changed, 24 insertions(+), 4 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5c61b92..93b861d 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -577,12 +577,30 @@ out: void e1000_down(struct e1000_adapter *adapter) { + struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; + u32 rctl, tctl; /* signal that we're down so the interrupt handler does not * reschedule our watchdog timer */ set_bit(__E1000_DOWN, &adapter->flags); + /* disable receives in the hardware */ + rctl = er32(RCTL); + ew32(RCTL, rctl & ~E1000_RCTL_EN); + /* flush and sleep below */ + + /* can be netif_tx_disable when NETIF_F_LLTX is removed */ + netif_stop_queue(netdev); + + /* disable transmits in the hardware */ + tctl = er32(TCTL); + tctl &= ~E1000_TCTL_EN; + ew32(TCTL, tctl); + /* flush both disables and wait for them to finish */ + E1000_WRITE_FLUSH(); + msleep(10); + napi_disable(&adapter->napi); e1000_irq_disable(adapter); @@ -595,7 +613,6 @@ void e1000_down(struct e1000_adapter *adapter) adapter->link_speed = 0; adapter->link_duplex = 0; netif_carrier_off(netdev); - netif_stop_queue(netdev); e1000_reset(adapter); e1000_clean_all_tx_rings(adapter); @@ -3744,10 +3761,12 @@ static irqreturn_t e1000_intr(int irq, void *data) adapter->total_rx_bytes = 0; adapter->total_rx_packets = 0; __napi_schedule(&adapter->napi); - } else + } else { /* this really should not happen! if it does it is basically a * bug, but not a hard error, so enable ints and continue */ - e1000_irq_enable(adapter); + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_enable(adapter); + } return IRQ_HANDLED; } @@ -3777,7 +3796,8 @@ static int e1000_clean(struct napi_struct *napi, int budget) if (likely(adapter->itr_setting & 3)) e1000_set_itr(adapter); napi_complete(napi); - e1000_irq_enable(adapter); + if (!test_bit(__E1000_DOWN, &adapter->flags)) + e1000_irq_enable(adapter); } return work_done;