From patchwork Mon Dec 4 01:29:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 120470 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3864825qgn; Sun, 3 Dec 2017 17:30:59 -0800 (PST) X-Google-Smtp-Source: AGs4zMZ65L8cc8Hbq8AerdHR+Bx07NM9IR4bGD/rUYwNuSzONGJz4lRgW6eyHA3pnUFYeq6nh9KI X-Received: by 10.101.96.138 with SMTP id t10mr12712570pgu.335.1512351058938; Sun, 03 Dec 2017 17:30:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512351058; cv=none; d=google.com; s=arc-20160816; b=Y+281hXi5EdXyD5OvAGZLa36xGWM3GvN2EDVb3QnqPjLxOH5iLUNGJTH03whdrrHVL WoP7L/u764AFqrB3hgKcQdWUhElM5IBP6M2XHjiqdcLTiD7CeX540QC65gMev/pvQqHp jemxbldcdSmXEqfk9irSnRxtNqfoce2YvVCDG/eXxA0bWH0V+vGtFKnabH0j5EnaTO8Z uYk/xme16LstiBr7QSWE7pgKj0LTRrVPgLHC2Z54ccxVGhRYiEHp4WdTA12mK1J4K7sX UnwYmQlt9+3L0Am2zf3b/ftTB+GnL0WOFM0wqboNHaeobjYRmfN+Mqr7wLeWs/eJvMUp I8Jw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=d+lAOans+Y/+p73Q0LwVSNRbf/Rgs5FmxA4dXWW8+oc=; b=iKbNskhh+Vby8eiqn9dZGo+iW69RvBq/RNJcVDZ6apDHtXSYM6JmE/YFx/PLCsWxWp f6O7ejFp2H0Ht2xXHOT6MHA0kw3DUWxwl9//KjI++OC16jXUaLbXJjYwiVv4Hyq2DIKG 3il1LyoR6KIVZ508OJMekZGwyPeBlD6prT4fgA6ifGD1+6m26ijUZ78xGFSx7T4001Fv gwqW/mfnBsjucLkDhFFbmieoqImrqk0sOxxGnymmH3TKsboX4AhzV1gvYjvaeis1G1LZ q8CFQif+kSVs4Qx704XqGa40nuQrm4fFuXn0xfN4OFHr1z/OXYxiXkfbKiH4gSWOATxO yxSg== 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 76si8505421pgd.240.2017.12.03.17.30.58; Sun, 03 Dec 2017 17:30:58 -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 S1752914AbdLDBa5 (ORCPT + 28 others); Sun, 3 Dec 2017 20:30:57 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2250 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751322AbdLDBas (ORCPT ); Sun, 3 Dec 2017 20:30:48 -0500 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 8400486793DFD; Mon, 4 Dec 2017 09:30:42 +0800 (CST) Received: from S00293818-DELL1.china.huawei.com (10.47.83.141) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Mon, 4 Dec 2017 09:30:33 +0800 From: Salil Mehta To: CC: , , , , , , , Subject: [PATCH V2 net-next 1/3] net: hns3: Refactor of the reset interrupt handling logic Date: Mon, 4 Dec 2017 01:29:53 +0000 Message-ID: <20171204012955.17560-2-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20171204012955.17560-1-salil.mehta@huawei.com> References: <20171204012955.17560-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.47.83.141] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The reset interrupt event shares common miscellaneous interrupt Vector 0. In the existing reset interrupt handling we disable the Vector 0 interrupt in misc interrupt handler and re-enable them later in context to common service task. This also means other event sources like mailbox would also be deferred or if the interrupt event was due to mailbox(which shall be supported for VF soon), it could delay the reset handling. This patch reorganizes the reset interrupt handling logic and makes it more fair to other events. Signed-off-by: Salil Mehta Signed-off-by: lipeng --- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 103 ++++++++++++++------- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 7 ++ 2 files changed, 78 insertions(+), 32 deletions(-) -- 2.11.0 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 59ed806a52c3..0c0543e84957 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2362,6 +2362,46 @@ static void hclge_service_complete(struct hclge_dev *hdev) clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state); } +static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) +{ + u32 rst_src_reg; + + /* fetch the events from their corresponding regs */ + rst_src_reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG); + + /* check for vector0 reset event sources */ + if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_src_reg) { + set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending); + *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); + return HCLGE_VECTOR0_EVENT_RST; + } + + if (BIT(HCLGE_VECTOR0_CORERESET_INT_B) & rst_src_reg) { + set_bit(HNAE3_CORE_RESET, &hdev->reset_pending); + *clearval = BIT(HCLGE_VECTOR0_CORERESET_INT_B); + return HCLGE_VECTOR0_EVENT_RST; + } + + if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & rst_src_reg) { + set_bit(HNAE3_IMP_RESET, &hdev->reset_pending); + *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); + return HCLGE_VECTOR0_EVENT_RST; + } + + /* mailbox event sharing vector 0 interrupt would be placed here */ + + return HCLGE_VECTOR0_EVENT_OTHER; +} + +static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, + u32 regclr) +{ + if (event_type == HCLGE_VECTOR0_EVENT_RST) + hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); + + /* mailbox event sharing vector 0 interrupt would be placed here */ +} + static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable) { writel(enable ? 1 : 0, vector->addr); @@ -2370,10 +2410,28 @@ static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable) static irqreturn_t hclge_misc_irq_handle(int irq, void *data) { struct hclge_dev *hdev = data; + u32 event_cause; + u32 clearval; hclge_enable_vector(&hdev->misc_vector, false); - if (!test_and_set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state)) - schedule_work(&hdev->service_task); + event_cause = hclge_check_event_cause(hdev, &clearval); + + /* vector 0 interrupt is shared with reset and mailbox source events. + * For now, we are not handling mailbox events. + */ + switch (event_cause) { + case HCLGE_VECTOR0_EVENT_RST: + /* reset task to be scheduled here */ + break; + default: + dev_dbg(&hdev->pdev->dev, + "received unknown or unhandled event of vector0\n"); + break; + } + + /* we should clear the source of interrupt */ + hclge_clear_event_cause(hdev, event_cause, clearval); + hclge_enable_vector(&hdev->misc_vector, true); return IRQ_HANDLED; } @@ -2404,9 +2462,9 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) hclge_get_misc_vector(hdev); - ret = devm_request_irq(&hdev->pdev->dev, - hdev->misc_vector.vector_irq, - hclge_misc_irq_handle, 0, "hclge_misc", hdev); + /* this would be explicitly freed in the end */ + ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle, + 0, "hclge_misc", hdev); if (ret) { hclge_free_vector(hdev, 0); dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n", @@ -2416,6 +2474,12 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) return ret; } +static void hclge_misc_irq_uninit(struct hclge_dev *hdev) +{ + free_irq(hdev->misc_vector.vector_irq, hdev); + hclge_free_vector(hdev, 0); +} + static int hclge_notify_client(struct hclge_dev *hdev, enum hnae3_reset_notify_type type) { @@ -2471,12 +2535,6 @@ static int hclge_reset_wait(struct hclge_dev *hdev) cnt++; } - /* must clear reset status register to - * prevent driver detect reset interrupt again - */ - reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG); - hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, reg); - if (cnt >= HCLGE_RESET_WAIT_CNT) { dev_warn(&hdev->pdev->dev, "Wait for reset timeout: %d\n", hdev->reset_type); @@ -2534,22 +2592,6 @@ static void hclge_do_reset(struct hclge_dev *hdev, enum hnae3_reset_type type) } } -static enum hnae3_reset_type hclge_detected_reset_event(struct hclge_dev *hdev) -{ - enum hnae3_reset_type rst_level = HNAE3_NONE_RESET; - u32 rst_reg_val; - - rst_reg_val = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG); - if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_reg_val) - rst_level = HNAE3_GLOBAL_RESET; - else if (BIT(HCLGE_VECTOR0_CORERESET_INT_B) & rst_reg_val) - rst_level = HNAE3_CORE_RESET; - else if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & rst_reg_val) - rst_level = HNAE3_IMP_RESET; - - return rst_level; -} - static void hclge_reset_event(struct hnae3_handle *handle, enum hnae3_reset_type reset) { @@ -2584,9 +2626,6 @@ static void hclge_reset_subtask(struct hclge_dev *hdev) do_reset = hdev->reset_type != HNAE3_NONE_RESET; - /* Reset is detected by interrupt */ - if (hdev->reset_type == HNAE3_NONE_RESET) - hdev->reset_type = hclge_detected_reset_event(hdev); if (hdev->reset_type == HNAE3_NONE_RESET) return; @@ -2622,7 +2661,6 @@ static void hclge_reset_subtask(struct hclge_dev *hdev) static void hclge_misc_irq_service_task(struct hclge_dev *hdev) { hclge_reset_subtask(hdev); - hclge_enable_vector(&hdev->misc_vector, true); } static void hclge_service_task(struct work_struct *work) @@ -4661,6 +4699,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) hdev->pdev = pdev; hdev->ae_dev = ae_dev; hdev->reset_type = HNAE3_NONE_RESET; + hdev->reset_pending = 0; ae_dev->priv = hdev; ret = hclge_pci_init(hdev); @@ -4895,8 +4934,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) /* Disable MISC vector(vector0) */ hclge_enable_vector(&hdev->misc_vector, false); - hclge_free_vector(hdev, 0); hclge_destroy_cmd_queue(&hdev->hw); + hclge_misc_irq_uninit(hdev); hclge_pci_uninit(hdev); ae_dev->priv = NULL; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 7027814ea5d7..d4429496f4b5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -105,6 +105,12 @@ enum HCLGE_DEV_STATE { HCLGE_STATE_MAX }; +enum hclge_evt_cause { + HCLGE_VECTOR0_EVENT_RST, + HCLGE_VECTOR0_EVENT_MBX, + HCLGE_VECTOR0_EVENT_OTHER, +}; + #define HCLGE_MPF_ENBALE 1 struct hclge_caps { u16 num_tqp; @@ -420,6 +426,7 @@ struct hclge_dev { unsigned long state; enum hnae3_reset_type reset_type; + unsigned long reset_pending; /* client rst is pending to be served */ u32 fw_version; u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */ u16 num_tqps; /* Num task queue pairs of this PF */