From patchwork Fri Mar 7 20:59:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 328087 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.180.67]) by ozlabs.org (Postfix) with ESMTP id C77FB2C00B7 for ; Sat, 8 Mar 2014 08:40:23 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753658AbaCGVkO (ORCPT ); Fri, 7 Mar 2014 16:40:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50553 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753594AbaCGVkK (ORCPT ); Fri, 7 Mar 2014 16:40:10 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s27LdpEH002692 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 7 Mar 2014 16:39:51 -0500 Received: from amt.cnet (vpn1-6-56.gru2.redhat.com [10.97.6.56]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s27L0Mf5010668; Fri, 7 Mar 2014 16:00:23 -0500 Received: from amt.cnet (localhost [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 12ACB104B13; Fri, 7 Mar 2014 17:59:29 -0300 (BRT) Received: (from marcelo@localhost) by amt.cnet (8.14.6/8.14.6/Submit) id s27KxRjf005251; Fri, 7 Mar 2014 17:59:27 -0300 Date: Fri, 7 Mar 2014 17:59:26 -0300 From: Marcelo Tosatti To: Jeff Kirsher Cc: Vladimir Davydov , e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org Subject: [PATCH] e1000: do not allow watchdog to reenable transmits on shutdown (v2) Message-ID: <20140307205926.GA5041@amt.cnet> References: <20140307020420.GA10797@amt.cnet> <1394162671.2214.36.camel@jtkirshe-mobl> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1394162671.2214.36.camel@jtkirshe-mobl> User-Agent: Mutt/1.5.21 (2010-09-15) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org There is a race on the shutdown path of the e1000 driver that allows the card to DMA into free'd memory. The symptoms are similar to those described at commit d5bc77a223b0e9b9dfb002048d2b34a79e7d0b48, "e1000: don't enable dma receives until after dma address has been setup", where memory corruption is visible due to E1000_RXD_STAT_DD being written to the DMA transfer descriptor. Fix by not allowing the watchdog and tx fifo stall detector to re-enable E1000_TCTL_EN. Signed-off-by: Marcelo Tosatti --- 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/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 10a0f22..bb5dc1a 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -321,7 +321,8 @@ struct e1000_adapter { enum e1000_state_t { __E1000_TESTING, __E1000_RESETTING, - __E1000_DOWN + __E1000_DOWN, + __E1000_NOTX = 4, }; #undef pr_fmt diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 46e6544..a39484f 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -414,6 +414,7 @@ int e1000_up(struct e1000_adapter *adapter) e1000_configure(adapter); clear_bit(__E1000_DOWN, &adapter->flags); + clear_bit(__E1000_NOTX, &adapter->flags); napi_enable(&adapter->napi); @@ -524,6 +525,11 @@ void e1000_down(struct e1000_adapter *adapter) netif_tx_disable(netdev); + /* do not allow watchdog to reenable transmits between + * clearing E1000_TCTL_EN below and setting E1000_DOWN + */ + set_bit(__E1000_NOTX, &adapter->flags); + /* disable transmits in the hardware */ tctl = er32(TCTL); tctl &= ~E1000_TCTL_EN; @@ -2339,6 +2345,9 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) struct net_device *netdev = adapter->netdev; u32 tctl; + if (test_bit(__E1000_NOTX, &adapter->flags)) + return; + if (atomic_read(&adapter->tx_fifo_stall)) { if ((er32(TDT) == er32(TDH)) && (er32(TDFT) == er32(TDFH)) && @@ -2412,6 +2421,9 @@ static void e1000_watchdog(struct work_struct *work) struct e1000_tx_ring *txdr = adapter->tx_ring; u32 link, tctl; + if (test_bit(__E1000_NOTX, &adapter->flags)) + return; + link = e1000_has_link(adapter); if ((netif_carrier_ok(netdev)) && link) goto link_up;