From f65fc668ed8c05ae52af53376e3aaf319a9acbab Mon Sep 17 00:00:00 2001 From: Shaozhengchao Date: Thu, 19 Dec 2019 15:58:42 +0800 Subject: [PATCH] net/hinic: optimize interrupt rush driver inclusion category:bugfix bugzilla:4472 CVE:NA ----------------------------------------------------------------------- optimize interrupt rush Signed-off-by: Shaozhengchao Reviewed-by: Luoshaokai Signed-off-by: Yang Yingliang --- .../net/ethernet/huawei/hinic/hinic_main.c | 46 +++++++++++++------ .../net/ethernet/huawei/hinic/hinic_nic_dev.h | 1 + 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index ddabee714c47..5960603cea21 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -438,7 +438,7 @@ static void hinic_destroy_num_qps(struct hinic_nic_dev *nic_dev) kfree(nic_dev->qps_irq_info); } -int hinic_poll(struct napi_struct *napi, int budget) +static int hinic_poll(struct napi_struct *napi, int budget) { int tx_pkts, rx_pkts; struct hinic_irq *irq_cfg = container_of(napi, struct hinic_irq, napi); @@ -451,6 +451,13 @@ int hinic_poll(struct napi_struct *napi, int budget) if (tx_pkts >= budget || rx_pkts >= budget) return budget; + set_bit(HINIC_RESEND_ON, &irq_cfg->intr_flag); + rx_pkts += hinic_rx_poll(irq_cfg->rxq, budget - rx_pkts); + if (rx_pkts >= budget) { + clear_bit(HINIC_RESEND_ON, &irq_cfg->intr_flag); + return budget; + } + napi_complete(napi); if (!test_and_set_bit(HINIC_INTR_ON, &irq_cfg->intr_flag)) { @@ -484,24 +491,33 @@ static irqreturn_t qp_irq(int irq, void *data) { struct hinic_irq *irq_cfg = (struct hinic_irq *)data; struct hinic_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev); + u16 msix_entry_idx = irq_cfg->msix_entry_idx; + + if (napi_schedule_prep(&irq_cfg->napi)) { + if (l2nic_interrupt_switch) { + /* Disable the interrupt until napi will be completed */ + if (!HINIC_FUNC_IS_VF(nic_dev->hwdev)) { + hinic_set_msix_state(nic_dev->hwdev, + msix_entry_idx, + HINIC_MSIX_DISABLE); + } else if (!nic_dev->in_vm) { + disable_irq_nosync(irq_cfg->irq_id); + } - if (l2nic_interrupt_switch) { - /* Disable the interrupt until napi will be completed */ - if (!HINIC_FUNC_IS_VF(nic_dev->hwdev)) - hinic_set_msix_state(nic_dev->hwdev, - irq_cfg->msix_entry_idx, - HINIC_MSIX_DISABLE); - else if (!nic_dev->in_vm) - disable_irq_nosync(irq_cfg->irq_id); + clear_bit(HINIC_INTR_ON, &irq_cfg->intr_flag); + } - clear_bit(HINIC_INTR_ON, &irq_cfg->intr_flag); - } + hinic_misx_intr_clear_resend_bit(nic_dev->hwdev, + msix_entry_idx, 1); + + clear_bit(HINIC_RESEND_ON, &irq_cfg->intr_flag); - /* 1 is resend_timer */ - hinic_misx_intr_clear_resend_bit(nic_dev->hwdev, - irq_cfg->msix_entry_idx, 1); + __napi_schedule(&irq_cfg->napi); + } else if (!test_bit(HINIC_RESEND_ON, &irq_cfg->intr_flag)) { + hinic_misx_intr_clear_resend_bit(nic_dev->hwdev, msix_entry_idx, + 1); + } - napi_schedule(&irq_cfg->napi); return IRQ_HANDLED; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h index 3697aa4a47d2..c6879c431ff2 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h @@ -104,6 +104,7 @@ struct hinic_dcb_config { enum hinic_intr_flags { HINIC_INTR_ON, + HINIC_RESEND_ON, }; struct hinic_irq { -- GitLab