From patchwork Tue Jun 2 01:40:12 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike McCormack X-Patchwork-Id: 27928 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 457DFB707D for ; Tue, 2 Jun 2009 11:49:20 +1000 (EST) Received: by ozlabs.org (Postfix) id 384B5DDDE2; Tue, 2 Jun 2009 11:49:20 +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 C74C5DDDD4 for ; Tue, 2 Jun 2009 11:49:19 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758888AbZFBBr5 (ORCPT ); Mon, 1 Jun 2009 21:47:57 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758731AbZFBBr4 (ORCPT ); Mon, 1 Jun 2009 21:47:56 -0400 Received: from mail-bw0-f222.google.com ([209.85.218.222]:45929 "EHLO mail-bw0-f222.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758846AbZFBBrz (ORCPT ); Mon, 1 Jun 2009 21:47:55 -0400 Received: by bwz22 with SMTP id 22so7837102bwz.37 for ; Mon, 01 Jun 2009 18:47:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=GH7EBskjcUb3puUoLCiCl19BtAQEjSyV0tgABqczwMQ=; b=Vs7cxQn5MhSK3YUpdAxsJ9xEk+qPxMtL+jp5dU4Hj0hwb+ynqNBgKzDKiaNTZX9nq9 dDWg2RJi4UxkwI6BIWCKbfaeyju9/T47eVcIiBNKVRx06OwsbBsw8jayYx+1NiMZ0nwZ C09yD8suzQeYMWhiljBXmmA9KiqMleyvR2hmY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:cc:content-type:content-transfer-encoding; b=uqMD6Cv1QWL//E3aEdItp/2vhpKo1KLHVq2OGfTxvigx2sN1X5F8eLoomIf2KvXgy+ qDkp3rUX9Jbws4lkPPTUsiuJ8ATvexaRxL1VsmdfURi+lbmh95w3eDbgGxyLSF4Z3euQ sFRgwH6aXWoCzs1vhPweZQhgAxST+VxkF10VA= MIME-Version: 1.0 Received: by 10.103.169.18 with SMTP id w18mr3557159muo.73.1243906812351; Mon, 01 Jun 2009 18:40:12 -0700 (PDT) Date: Tue, 2 Jun 2009 10:40:12 +0900 X-Google-Sender-Auth: 604bbaf889afa607 Message-ID: <392fb48f0906011840n4914ef32x8aa316358b2ceacc@mail.gmail.com> Subject: [PATCH] Fix a race between sky2_down and sky2_poll. From: Mike McCormack To: shemminger@linux-foundation.org Cc: netdev@vger.kernel.org Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If sky2_down was called between an interrupt and the corresponding sky2_poll, rx_ring will have been free'd and we'll crash. Deal with rx_ring being NULL in sky2_status_intr rather than trying to force napi polls to complete before freeing rx_ring. Signed-off-by: Mike McCormack --- drivers/net/sky2.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) case OP_RXSTAT: diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a2ff9cb..1f2a5ab 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1822,8 +1822,8 @@ static int sky2_down(struct net_device *dev) ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); gma_write16(hw, port, GM_GP_CTRL, ctrl); - /* Make sure no packets are pending */ - napi_synchronize(&hw->napi); + /* disable soft interrupts */ + napi_disable(&hw->napi); sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); @@ -1878,6 +1878,9 @@ static int sky2_down(struct net_device *dev) sky2->rx_ring = NULL; sky2->tx_ring = NULL; + /* re-enable soft interrupts */ + napi_enable(&hw->napi); + return 0; } @@ -2372,6 +2375,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) length = le16_to_cpu(le->length); status = le32_to_cpu(le->status); + /* + * rx_ring may have been free'd in sky2_down + * if we are responding to an interrupt queued to + * napi before interrupts were disabled + */ + if (!sky2->rx_ring) { + work_done = to_do; + break; + } + le->opcode = 0; switch (opcode & ~HW_OWNER) {