From patchwork Wed Jan 23 13:21:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuval Mintz X-Patchwork-Id: 214963 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 6EE4A2C007E for ; Thu, 24 Jan 2013 01:23:31 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756072Ab3AWOX2 (ORCPT ); Wed, 23 Jan 2013 09:23:28 -0500 Received: from mms2.broadcom.com ([216.31.210.18]:1448 "EHLO mms2.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755799Ab3AWOXR (ORCPT ); Wed, 23 Jan 2013 09:23:17 -0500 Received: from [10.9.208.26] by mms2.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.5)); Wed, 23 Jan 2013 06:20:00 -0800 X-Server-Uuid: 4500596E-606A-40F9-852D-14843D8201B2 Received: from mail-irva-13.broadcom.com (10.11.16.103) by IRVEXCHCAS05.corp.ad.broadcom.com (10.9.208.26) with Microsoft SMTP Server id 14.1.355.2; Wed, 23 Jan 2013 06:22:20 -0800 Received: from lb-tlvb-yuvalmin.il.broadcom.com ( lb-tlvb-yuvalmin.il.broadcom.com [10.185.6.94]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 6441E40FF1; Wed, 23 Jan 2013 06:22:18 -0800 (PST) From: "Yuval Mintz" To: davem@davemloft.net, netdev@vger.kernel.org cc: eilong@broadcom.com, ariele@broadcom.com, "Michael Chan" , "Yuval Mintz" Subject: [PATCH net-next 10/12] cnic, bnx2x: Add CNIC_DRV_STATE_HANDLES_IRQ to ethdev->drv_state Date: Wed, 23 Jan 2013 15:21:52 +0200 Message-ID: <1358947314-3851-11-git-send-email-yuvalmin@broadcom.com> X-Mailer: git-send-email 1.8.1.227.g44fe835 In-Reply-To: <1358947314-3851-1-git-send-email-yuvalmin@broadcom.com> References: <1358947314-3851-1-git-send-email-yuvalmin@broadcom.com> MIME-Version: 1.0 X-WSS-ID: 7CE12E053R41535035-17-01 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Michael Chan In INTA mode, cnic and bnx2x share the same IRQ. During chip reset, for example, cnic will stop servicing IRQs after it has shutdown the cnic hardware resources. However, the shared IRQ is still active as bnx2x needs to finish the reset. There is a window when bnx2x does not know that cnic is no longer handling IRQ and things don't always work properly. Add a flag to tell bnx2x that cnic is handling IRQ. The flag is set before the first cnic IRQ is expected and cleared when no more cnic IRQs are expected, so there should be no race conditions. Signed-off-by: Michael Chan Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 ++++++-------- drivers/net/ethernet/broadcom/cnic.c | 4 ++++ drivers/net/ethernet/broadcom/cnic_if.h | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index ac00ddc..c4daee1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1875,14 +1875,12 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) if (status & (mask | 0x1)) { struct cnic_ops *c_ops = NULL; - if (likely(bp->state == BNX2X_STATE_OPEN)) { - rcu_read_lock(); - c_ops = rcu_dereference(bp->cnic_ops); - if (c_ops) - c_ops->cnic_handler(bp->cnic_data, - NULL); - rcu_read_unlock(); - } + rcu_read_lock(); + c_ops = rcu_dereference(bp->cnic_ops); + if (c_ops && (bp->cnic_eth_dev.drv_state & + CNIC_DRV_STATE_HANDLES_IRQ)) + c_ops->cnic_handler(bp->cnic_data, NULL); + rcu_read_unlock(); status &= ~mask; } diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index df8c30d..1c4dadc 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -4816,6 +4816,8 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) return err; } + ethdev->drv_state |= CNIC_DRV_STATE_HANDLES_IRQ; + return 0; } @@ -5136,6 +5138,7 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return ret; + ethdev->drv_state |= CNIC_DRV_STATE_HANDLES_IRQ; return 0; } @@ -5387,6 +5390,7 @@ static void cnic_stop_hw(struct cnic_dev *dev) } cnic_shutdown_rings(dev); cp->stop_cm(dev); + cp->ethdev->drv_state &= ~CNIC_DRV_STATE_HANDLES_IRQ; clear_bit(CNIC_F_CNIC_UP, &dev->flags); RCU_INIT_POINTER(cp->ulp_ops[CNIC_ULP_L4], NULL); synchronize_rcu(); diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 2a35436..0c9367a 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -179,6 +179,7 @@ struct cnic_eth_dev { #define CNIC_DRV_STATE_NO_ISCSI_OOO 0x00000004 #define CNIC_DRV_STATE_NO_ISCSI 0x00000008 #define CNIC_DRV_STATE_NO_FCOE 0x00000010 +#define CNIC_DRV_STATE_HANDLES_IRQ 0x00000020 u32 chip_id; u32 max_kwqe_pending; struct pci_dev *pdev;