Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp5308751ybl; Wed, 22 Jan 2020 14:27:08 -0800 (PST) X-Google-Smtp-Source: APXvYqxfVm0tj8L+AsM65LPDFjVDo6vASls/oMnXiMbiehyRF6izvEnlS7lOupZWEjJSwEYHKUoT X-Received: by 2002:aca:5d57:: with SMTP id r84mr8578628oib.42.1579732028434; Wed, 22 Jan 2020 14:27:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579732028; cv=none; d=google.com; s=arc-20160816; b=UcU/K5PIwF4tRgi5Zc3pbrICh/kOYMfpX/D1srSmIIPaeI+3WMlwBjFvVhlhN8w/tB BS/5zj9Rwc2MBktl7Y/CJFM8EXgr4h5zAjY/qzB+yPacIw9Gz7LScp71CcfikVIp0B80 NqRtowQQdCRVjekgPE8Ix1bWyZTYgBAcNqWyUqJglQuw4v9GfRE7Z92MONc9uSlcEd8U vvpmqmbEA1pOzKwMee5Jfet81FDaXrPGRyRbdIZLGyaA6ya0k0IjNQWYBdiLzmX4lnvs NI0GskkFTRFRyJ+YyLMUY8Rl4ZFj9G8nxHUU9efws7e7H6lLqhl/nyLx47VKEeKBylwK MaGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:subject:from:references:in-reply-to :message-id:cc:to; bh=jGWv/KYlTQIiV6H919n7buVjeio7Uo+Zq+BoIlgphiQ=; b=U6Eufx9i2q0nzor5B8X8VjgQwQ0leHYf+e6qWrRsUrj2uegLu8jdQl5J++DLnwdP95 fjaOIOPO7Exgd9XMSTmlC3GVun1uDn/1aW6kHRAy07Y7OQV1+AmkMVt4WACi0UOz4tNN Ze05aZc9RKog1YVz4EM1KL93lX6TPCO7SyiRyrTRPoFWyUvEN2/9mUgAO1MXnE2IkmtO U/O0MutDNdMJGrCMUkGexCjPuDmFYOnwc1fV5eGsSV9AqT3CNjjEfOsk7w3pcDARoYdi idB7DADRv2B7tiyaeUYdf0LvVFeTunFLMrvBM91Ug9XqIJ6BSKlp35kRhleeWf2qrVGU 0w4Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z18si73760otk.206.2020.01.22.14.26.55; Wed, 22 Jan 2020 14:27:08 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726118AbgAVWY6 (ORCPT + 99 others); Wed, 22 Jan 2020 17:24:58 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:47776 "EHLO kvm5.telegraphics.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726061AbgAVWYC (ORCPT ); Wed, 22 Jan 2020 17:24:02 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 4DA5B299A6; Wed, 22 Jan 2020 17:23:59 -0500 (EST) To: "David S. Miller" Cc: Thomas Bogendoerfer , Chris Zankel , Laurent Vivier , Geert Uytterhoeven , Eric Dumazet , Stephen Hemminger , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Message-Id: <7927d3de3f46e660c0112aefb1a63bf1584c187d.1579730846.git.fthain@telegraphics.com.au> In-Reply-To: References: From: Finn Thain Subject: [PATCH net v3 02/12] net/sonic: Clear interrupt flags immediately Date: Thu, 23 Jan 2020 09:07:26 +1100 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The chip can change a packet's descriptor status flags at any time. However, an active interrupt flag gets cleared rather late. This allows a race condition that could theoretically lose an interrupt. Fix this by clearing asserted interrupt flags immediately. Fixes: efcce839360f ("[PATCH] macsonic/jazzsonic network drivers update") Tested-by: Stan Johnson Signed-off-by: Finn Thain --- drivers/net/ethernet/natsemi/sonic.c | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c index 8a7cff516281..1109070a5154 100644 --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -304,10 +304,11 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id) } do { + SONIC_WRITE(SONIC_ISR, status); /* clear the interrupt(s) */ + if (status & SONIC_INT_PKTRX) { netif_dbg(lp, intr, dev, "%s: packet rx\n", __func__); sonic_rx(dev); /* got packet(s) */ - SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */ } if (status & SONIC_INT_TXDN) { @@ -362,7 +363,6 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id) if (freed_some || lp->tx_skb[entry] == NULL) netif_wake_queue(dev); /* The ring is no longer full */ lp->cur_tx = entry; - SONIC_WRITE(SONIC_ISR, SONIC_INT_TXDN); /* clear the interrupt */ } /* @@ -372,42 +372,31 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id) netif_dbg(lp, rx_err, dev, "%s: rx fifo overrun\n", __func__); lp->stats.rx_fifo_errors++; - SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */ } if (status & SONIC_INT_RDE) { netif_dbg(lp, rx_err, dev, "%s: rx descriptors exhausted\n", __func__); lp->stats.rx_dropped++; - SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */ } if (status & SONIC_INT_RBAE) { netif_dbg(lp, rx_err, dev, "%s: rx buffer area exceeded\n", __func__); lp->stats.rx_dropped++; - SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */ } /* counter overruns; all counters are 16bit wide */ - if (status & SONIC_INT_FAE) { + if (status & SONIC_INT_FAE) lp->stats.rx_frame_errors += 65536; - SONIC_WRITE(SONIC_ISR, SONIC_INT_FAE); /* clear the interrupt */ - } - if (status & SONIC_INT_CRC) { + if (status & SONIC_INT_CRC) lp->stats.rx_crc_errors += 65536; - SONIC_WRITE(SONIC_ISR, SONIC_INT_CRC); /* clear the interrupt */ - } - if (status & SONIC_INT_MP) { + if (status & SONIC_INT_MP) lp->stats.rx_missed_errors += 65536; - SONIC_WRITE(SONIC_ISR, SONIC_INT_MP); /* clear the interrupt */ - } /* transmit error */ - if (status & SONIC_INT_TXER) { + if (status & SONIC_INT_TXER) if (SONIC_READ(SONIC_TCR) & SONIC_TCR_FU) netif_dbg(lp, tx_err, dev, "%s: tx fifo underrun\n", __func__); - SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */ - } /* bus retry */ if (status & SONIC_INT_BR) { @@ -416,13 +405,8 @@ static irqreturn_t sonic_interrupt(int irq, void *dev_id) /* ... to help debug DMA problems causing endless interrupts. */ /* Bounce the eth interface to turn on the interrupt again. */ SONIC_WRITE(SONIC_IMR, 0); - SONIC_WRITE(SONIC_ISR, SONIC_INT_BR); /* clear the interrupt */ } - /* load CAM done */ - if (status & SONIC_INT_LCD) - SONIC_WRITE(SONIC_ISR, SONIC_INT_LCD); /* clear the interrupt */ - status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT; } while (status); -- 2.24.1