DPDK patches and discussions
 help / color / mirror / Atom feed
From: Beilei Xing <beilei.xing@intel.com>
To: qi.z.zhang@intel.com
Cc: dev@dpdk.org, dhanya.r.pillai@intel.com
Subject: [dpdk-dev] [PATCH v2] net/i40e: remove PF interrupt handler for multi-driver
Date: Fri, 27 Jul 2018 09:36:22 +0800	[thread overview]
Message-ID: <1532655382-4612-1-git-send-email-beilei.xing@intel.com> (raw)
In-Reply-To: <1532582051-78468-1-git-send-email-beilei.xing@intel.com>

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 <beilei.xing@intel.com>
---
 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;
 }
-- 
2.5.5

  reply	other threads:[~2018-07-27  1:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-26  5:14 [dpdk-dev] [PATCH] net/i40e: remove PF interrupt handler Beilei Xing
2018-07-27  1:36 ` Beilei Xing [this message]
2018-09-11  3:35   ` [dpdk-dev] [PATCH v3] net/i40e: add alarm handler Beilei Xing
2018-09-11 13:04     ` Zhang, Qi Z
2018-09-17 11:07     ` Ferruh Yigit
2018-09-18  2:52       ` Xing, Beilei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1532655382-4612-1-git-send-email-beilei.xing@intel.com \
    --to=beilei.xing@intel.com \
    --cc=dev@dpdk.org \
    --cc=dhanya.r.pillai@intel.com \
    --cc=qi.z.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).