From patchwork Fri Dec 14 12:14:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Greene X-Patchwork-Id: 206423 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 3B9612C0095 for ; Fri, 14 Dec 2012 23:16:39 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754162Ab2LNMQg (ORCPT ); Fri, 14 Dec 2012 07:16:36 -0500 Received: from cpe-075-189-159-031.nc.res.rr.com ([75.189.159.31]:36532 "EHLO jgpicker" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753580Ab2LNMQg (ORCPT ); Fri, 14 Dec 2012 07:16:36 -0500 Received: from jgpicker (localhost.localdomain [127.0.0.1]) by jgpicker (8.14.5/8.14.5) with ESMTP id qBECGRmW009699; Fri, 14 Dec 2012 07:16:27 -0500 Received: (from jogreene@localhost) by jgpicker (8.14.5/8.14.5/Submit) id qBECFQ7w009684; Fri, 14 Dec 2012 07:15:26 -0500 X-Authentication-Warning: jgpicker: jogreene set sender to jogreene@redhat.com using -f From: John Greene To: netdev@vger.kernel.org Cc: John Greene , "David S. Miller" , "David Woodhouse" Subject: [RFT PATCH] 8139cp: Fix possible dev_close / cp_interrupt race during MTU change Date: Fri, 14 Dec 2012 07:14:24 -0500 Message-Id: <1355487264-9649-1-git-send-email-jogreene@redhat.com> X-Mailer: git-send-email 1.7.11.7 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org commit: cb64edb6b89491edfdbae52ba7db9a8b8391d339 upstream Above commit may introduce a race between cp_interrupt and dev_close / change MTU / dev_open up state. Changes cp_interrupt to tolerate this. Change spin_locking in cp_interrupt to avoid possible but unobserved race. Reported-by: "Francois Romieu" Tested on virtual hardware, Tx MTU size up to 4096, max tx payload was ping -s 4068 for MTU of 4096. No real hardware, need test assist. Signed-off-by: "John Greene" CC: "David S. Miller" CC: "David Woodhouse" --- drivers/net/ethernet/realtek/8139cp.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index 0da3f5e..585c35c 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c @@ -577,28 +577,30 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) { struct net_device *dev = dev_instance; struct cp_private *cp; + int handled = 0; u16 status; if (unlikely(dev == NULL)) return IRQ_NONE; cp = netdev_priv(dev); + spin_lock(&cp->lock); + status = cpr16(IntrStatus); if (!status || (status == 0xFFFF)) - return IRQ_NONE; + goto out_unlock; + + handled = 1; netif_dbg(cp, intr, dev, "intr, status %04x cmd %02x cpcmd %04x\n", status, cpr8(Cmd), cpr16(CpCmd)); cpw16(IntrStatus, status & ~cp_rx_intr_mask); - spin_lock(&cp->lock); - /* close possible race's with dev_close */ if (unlikely(!netif_running(dev))) { cpw16(IntrMask, 0); - spin_unlock(&cp->lock); - return IRQ_HANDLED; + goto out_unlock; } if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) @@ -612,7 +614,6 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) if (status & LinkChg) mii_check_media(&cp->mii_if, netif_msg_link(cp), false); - spin_unlock(&cp->lock); if (status & PciErr) { u16 pci_status; @@ -625,7 +626,10 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) /* TODO: reset hardware */ } - return IRQ_HANDLED; +out_unlock: + spin_unlock(&cp->lock); + + return IRQ_RETVAL(handled); } #ifdef CONFIG_NET_POLL_CONTROLLER