From patchwork Mon Jun 8 01:47:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 28214 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 75730B70B8 for ; Mon, 8 Jun 2009 11:47:22 +1000 (EST) Received: by ozlabs.org (Postfix) id 58A86DDDA0; Mon, 8 Jun 2009 11:47:22 +1000 (EST) 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 E9461DDD1C for ; Mon, 8 Jun 2009 11:47:21 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752979AbZFHBrJ (ORCPT ); Sun, 7 Jun 2009 21:47:09 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752234AbZFHBrI (ORCPT ); Sun, 7 Jun 2009 21:47:08 -0400 Received: from ftp.linux-mips.org ([213.58.128.207]:39747 "EHLO ftp.linux-mips.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752213AbZFHBrH (ORCPT ); Sun, 7 Jun 2009 21:47:07 -0400 Received: from localhost.localdomain ([127.0.0.1]:54551 "EHLO localhost.localdomain" rhost-flags-OK-OK-OK-OK) by ftp.linux-mips.org with ESMTP id S20023541AbZFHBrF (ORCPT ); Mon, 8 Jun 2009 02:47:05 +0100 Date: Mon, 8 Jun 2009 02:47:05 +0100 (WEST) From: "Maciej W. Rozycki" To: "David S. Miller" cc: netdev@vger.kernel.org, linux-mips@linux-mips.org Subject: [PATCH] declance: Restore tx descriptor ring locking Message-ID: User-Agent: Alpine 1.10 (LFD 962 2008-03-14) MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org A driver overhaul on 29 Feb 2000 (!) broke locking around fiddling with the tx descriptor ring in start_xmit(); a follow-on "fix" removed the broken remnants altogether. Here's a patch to restore proper locking in the function -- the complement in the interrupt handler has been correct all the time. This *may* have been the reason for the occasional confusion of the chip -- triggering a tx timeout followed by a chip reset sequence -- seen on R4k-based DECstations with the onboard Ethernet interface. Another theory is the confusion is due to an unindentified problem -- perhaps a silicon erratum -- associated with the variation of the MT ASIC used to interface the R4k CPU to the rest of the system on these computers; with its aggressive write-back buffering the design is particularly weakly ordered when it comes to MMIO (in the absence of ordering barriers uncached reads are allowed to bypass earlier uncached writes, even if to the same location), which may trigger all kinds of corner cases in peripheral hardware as well as software. Either way this piece of code is buggy. Signed-off-by: Maciej W. Rozycki --- Works for me. Dave, please apply. Maciej patch-mips-2.6.27-rc8-20081004-declance-lock-2 -- 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 Index: linux-mips-2.6.27-rc8-20081004-3maxp/drivers/net/declance.c =================================================================== --- linux-mips-2.6.27-rc8-20081004-3maxp.orig/drivers/net/declance.c +++ linux-mips-2.6.27-rc8-20081004-3maxp/drivers/net/declance.c @@ -906,6 +906,7 @@ static int lance_start_xmit(struct sk_bu struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; volatile u16 *ib = (volatile u16 *)dev->mem_start; + unsigned long flags; int entry, len; len = skb->len; @@ -918,6 +919,8 @@ static int lance_start_xmit(struct sk_bu dev->stats.tx_bytes += len; + spin_lock_irqsave(&lp->lock, flags); + entry = lp->tx_new; *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; @@ -936,6 +939,8 @@ static int lance_start_xmit(struct sk_bu /* Kick the lance: transmit now */ writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD); + spin_unlock_irqrestore(&lp->lock, flags); + dev->trans_start = jiffies; dev_kfree_skb(skb);