From patchwork Fri Jul 27 01:36:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xing, Beilei" X-Patchwork-Id: 43413 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 35D7C2B95; Fri, 27 Jul 2018 03:36:29 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id F131225D9 for ; Fri, 27 Jul 2018 03:36:27 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Jul 2018 18:36:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,407,1526367600"; d="scan'208";a="58240925" Received: from unknown (HELO dpdk9.sh.intel.com) ([10.67.118.52]) by fmsmga008.fm.intel.com with ESMTP; 26 Jul 2018 18:35:46 -0700 From: Beilei Xing To: qi.z.zhang@intel.com Cc: dev@dpdk.org, dhanya.r.pillai@intel.com Date: Fri, 27 Jul 2018 09:36:22 +0800 Message-Id: <1532655382-4612-1-git-send-email-beilei.xing@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1532582051-78468-1-git-send-email-beilei.xing@intel.com> References: <1532582051-78468-1-git-send-email-beilei.xing@intel.com> Subject: [dpdk-dev] [PATCH v2] net/i40e: remove PF interrupt handler for multi-driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" When multi-dirver is enabled, internal Rx interrupt/LSC/adminq share the same source, that will cause lots of CPU cycles wasted during receiving packets. So remove the PF interrupt handler only when multi-driver is enabled. Signed-off-by: Beilei Xing --- drivers/net/i40e/i40e_ethdev.c | 130 +++++++++++++++++++++++++++++++---------- 1 file changed, 99 insertions(+), 31 deletions(-) v2 changes: - Remove PF interrupt handler only when multi-driver is enabled. diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index a340540..6c50c9f 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -290,6 +290,7 @@ static void i40e_stat_update_48(struct i40e_hw *hw, uint64_t *stat); static void i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue); static void i40e_dev_interrupt_handler(void *param); +static void i40e_dev_alarm_handler(void *param); static int i40e_res_pool_init(struct i40e_res_pool_info *pool, uint32_t base, uint32_t num); static void i40e_res_pool_destroy(struct i40e_res_pool_info *pool); @@ -1189,6 +1190,8 @@ i40e_aq_debug_write_global_register(struct i40e_hw *hw, return i40e_aq_debug_write_register(hw, reg_addr, reg_val, cmd_details); } +#define I40E_ALARM_INTERVAL 50000 /* us */ + static int eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) { @@ -1450,16 +1453,20 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) /* initialize pf host driver to setup SRIOV resource if applicable */ i40e_pf_host_init(dev); - /* register callback func to eal lib */ - rte_intr_callback_register(intr_handle, - i40e_dev_interrupt_handler, dev); - /* configure and enable device interrupt */ i40e_pf_config_irq0(hw, TRUE); i40e_pf_enable_irq0(hw); - /* enable uio intr after callback register */ - rte_intr_enable(intr_handle); + if (!pf->support_multi_driver) { + /* register callback func to eal lib */ + rte_intr_callback_register(intr_handle, + i40e_dev_interrupt_handler, dev); + /* enable uio intr after callback register */ + rte_intr_enable(intr_handle); + } else { + rte_eal_alarm_set(I40E_ALARM_INTERVAL, + i40e_dev_alarm_handler, dev); + } /* By default disable flexible payload in global configuration */ if (!pf->support_multi_driver) @@ -1654,23 +1661,27 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev) rte_free(dev->data->mac_addrs); dev->data->mac_addrs = NULL; - /* disable uio intr before callback unregister */ - rte_intr_disable(intr_handle); - - /* unregister callback func to eal lib */ - do { - ret = rte_intr_callback_unregister(intr_handle, - i40e_dev_interrupt_handler, dev); - if (ret >= 0) { - break; - } else if (ret != -EAGAIN) { - PMD_INIT_LOG(ERR, - "intr callback unregister failed: %d", - ret); - return ret; - } - i40e_msec_delay(500); - } while (retries++ < 5); + if (!pf->support_multi_driver) { + /* disable uio intr before callback unregister */ + rte_intr_disable(intr_handle); + + /* unregister callback func to eal lib */ + do { + ret = rte_intr_callback_unregister(intr_handle, + i40e_dev_interrupt_handler, dev); + if (ret >= 0) { + break; + } else if (ret != -EAGAIN) { + PMD_INIT_LOG(ERR, + "intr callback unregister failed: %d", + ret); + return ret; + } + i40e_msec_delay(500); + } while (retries++ < 5); + } else { + rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev); + } i40e_rm_ethtype_filter_list(pf); i40e_rm_tunnel_filter_list(pf); @@ -2161,7 +2172,8 @@ i40e_dev_start(struct rte_eth_dev *dev) return -EINVAL; } - rte_intr_disable(intr_handle); + if (!pf->support_multi_driver || dev->data->dev_conf.intr_conf.rxq != 0) + rte_intr_disable(intr_handle); if ((rte_intr_cap_multiple(intr_handle) || !RTE_ETH_DEV_SRIOV(dev).active) && @@ -2259,9 +2271,12 @@ i40e_dev_start(struct rte_eth_dev *dev) } if (!rte_intr_allow_others(intr_handle)) { - rte_intr_callback_unregister(intr_handle, - i40e_dev_interrupt_handler, - (void *)dev); + if (!pf->support_multi_driver) + rte_intr_callback_unregister(intr_handle, + i40e_dev_interrupt_handler, + (void *)dev); + else + rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev); /* configure and enable device interrupt */ i40e_pf_config_irq0(hw, FALSE); i40e_pf_enable_irq0(hw); @@ -2282,7 +2297,8 @@ i40e_dev_start(struct rte_eth_dev *dev) } /* enable uio intr after callback register */ - rte_intr_enable(intr_handle); + if (!pf->support_multi_driver || dev->data->dev_conf.intr_conf.rxq != 0) + rte_intr_enable(intr_handle); i40e_filter_restore(pf); @@ -2334,7 +2350,7 @@ i40e_dev_stop(struct rte_eth_dev *dev) /* Set link down */ i40e_dev_set_link_down(dev); - if (!rte_intr_allow_others(intr_handle)) + if (!pf->support_multi_driver && !rte_intr_allow_others(intr_handle)) /* resume to the default handler */ rte_intr_callback_register(intr_handle, i40e_dev_interrupt_handler, @@ -2392,7 +2408,8 @@ i40e_dev_close(struct rte_eth_dev *dev) /* Disable interrupt */ i40e_pf_disable_irq0(hw); - rte_intr_disable(intr_handle); + if (!pf->support_multi_driver || dev->data->dev_conf.intr_conf.rxq != 0) + rte_intr_disable(intr_handle); i40e_fdir_teardown(pf); @@ -6535,6 +6552,55 @@ i40e_dev_interrupt_handler(void *param) rte_intr_enable(dev->intr_handle); } +static void +i40e_dev_alarm_handler(void *param) +{ + struct rte_eth_dev *dev = (struct rte_eth_dev *)param; + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t icr0; + + /* Disable interrupt */ + i40e_pf_disable_irq0(hw); + + /* read out interrupt causes */ + icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0); + + /* No interrupt event indicated */ + if (!(icr0 & I40E_PFINT_ICR0_INTEVENT_MASK)) { + PMD_DRV_LOG(INFO, "No interrupt event"); + goto done; + } + if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK) + PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error"); + if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) + PMD_DRV_LOG(ERR, "ICR0: malicious programming detected"); + if (icr0 & I40E_PFINT_ICR0_GRST_MASK) + PMD_DRV_LOG(INFO, "ICR0: global reset requested"); + if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) + PMD_DRV_LOG(INFO, "ICR0: PCI exception activated"); + if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK) + PMD_DRV_LOG(INFO, "ICR0: a change in the storm control state"); + if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) + PMD_DRV_LOG(ERR, "ICR0: HMC error"); + if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK) + PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error"); + + if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { + PMD_DRV_LOG(INFO, "ICR0: VF reset detected"); + i40e_dev_handle_vfr_event(dev); + } + if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { + PMD_DRV_LOG(INFO, "ICR0: adminq event"); + i40e_dev_handle_aq_msg(dev); + } + +done: + /* Enable interrupt */ + i40e_pf_enable_irq0(hw); + rte_eal_alarm_set(I40E_ALARM_INTERVAL, + i40e_dev_alarm_handler, dev); +} + int i40e_add_macvlan_filters(struct i40e_vsi *vsi, struct i40e_macvlan_filter *filter, @@ -11402,6 +11468,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id) struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); uint16_t msix_intr; msix_intr = intr_handle->intr_vec[queue_id]; @@ -11419,7 +11486,8 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id) I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); I40E_WRITE_FLUSH(hw); - rte_intr_enable(&pci_dev->intr_handle); + if (!pf->support_multi_driver) + rte_intr_enable(&pci_dev->intr_handle); return 0; }