All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jingjing Wu <jingjing.wu@intel.com>
To: dev@dpdk.org
Cc: jingjing.wu@intel.com, beilei.xing@intel.com,
	chenbo.xia@intel.com, xiuchun.lu@intel.com
Subject: [dpdk-dev] [PATCH v3 3/5] net/iavf_client: enable interrupt on control queue
Date: Thu,  7 Jan 2021 16:27:16 +0800	[thread overview]
Message-ID: <20210107082718.33748-4-jingjing.wu@intel.com> (raw)
In-Reply-To: <20210107082718.33748-1-jingjing.wu@intel.com>

New devarg "intr": if intr=1, use interrupt mode on control queue

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/iavf/iavf.h               |  19 ++++
 drivers/net/iavf/iavf_client_ethdev.c | 131 ++++++++++++++++++++++----
 drivers/net/iavf/iavf_ethdev.c        |  18 +---
 3 files changed, 134 insertions(+), 34 deletions(-)

diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index c34f971721..5516ecf021 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -198,6 +198,7 @@ struct iavf_adapter {
 #ifdef RTE_LIBRTE_IAVF_CLIENT
 	/* used for avf_client driver */
 	struct vfio_device *user_dev;
+	int intr_mode; /* interrupt mode if true */
 #endif
 	bool rx_bulk_alloc_allowed;
 	/* For vector PMD */
@@ -234,6 +235,22 @@ iavf_init_adminq_parameter(struct iavf_hw *hw)
 	hw->aq.asq_buf_size = IAVF_AQ_BUF_SZ;
 }
 
+/* Enable default admin queue interrupt setting */
+static inline void
+iavf_enable_irq0(struct iavf_hw *hw)
+{
+	/* Enable admin queue interrupt trigger */
+	IAVF_WRITE_REG(hw, IAVF_VFINT_ICR0_ENA1,
+		       IAVF_VFINT_ICR0_ENA1_ADMINQ_MASK);
+
+	IAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,
+		       IAVF_VFINT_DYN_CTL01_INTENA_MASK |
+		       IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
+		       IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
+
+	IAVF_WRITE_FLUSH(hw);
+}
+
 static inline void
 iavf_disable_irq0(struct iavf_hw *hw)
 {
@@ -342,4 +359,6 @@ int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
 			uint32_t mc_addrs_num, bool add);
 int iavf_request_queues(struct iavf_adapter *adapter, uint16_t num);
 int iavf_get_max_rss_queue_region(struct iavf_adapter *adapter);
+void iavf_dev_interrupt_handler(void *param);
+
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_client_ethdev.c b/drivers/net/iavf/iavf_client_ethdev.c
index 989f9d6062..770a7a8200 100644
--- a/drivers/net/iavf/iavf_client_ethdev.c
+++ b/drivers/net/iavf/iavf_client_ethdev.c
@@ -6,6 +6,8 @@
 #include <stdint.h>
 #include <string.h>
 
+#include <sys/eventfd.h>
+
 #include <rte_common.h>
 #include <rte_ether.h>
 #include <rte_ethdev_driver.h>
@@ -18,6 +20,9 @@
 #include "iavf.h"
 #include "iavf_rxtx.h"
 
+#define AVF_CLIENT_ARG_PATH           "path"
+#define AVF_CLIENT_ARG_INTR           "intr"
+
 static int iavf_client_dev_close(struct rte_eth_dev *dev);
 static int iavf_client_dev_reset(struct rte_eth_dev *dev);
 
@@ -25,11 +30,27 @@ static int iavf_client_dev_reset(struct rte_eth_dev *dev);
 static struct eth_dev_ops iavf_client_eth_dev_ops;
 
 static const char *valid_args[] = {
-#define AVF_CLIENT_ARG_PATH           "path"
 	AVF_CLIENT_ARG_PATH,
+	AVF_CLIENT_ARG_INTR,
 	NULL
 };
 
+static void
+iavf_client_event_handler(void *param)
+{
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	eventfd_t buf;
+
+	eventfd_read(dev->intr_handle->fd, &buf);
+
+	iavf_disable_irq0(hw);
+
+	iavf_handle_virtchnl_msg(dev);
+
+	iavf_enable_irq0(hw);
+}
+
 /* set up vfio_device for iavf_client*/
 static int
 iavf_client_vfio_user_setup(struct rte_eth_dev *dev, const char *path)
@@ -51,6 +72,11 @@ iavf_client_vfio_user_setup(struct rte_eth_dev *dev, const char *path)
 
 	hw->back = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
+	if (!vfio_dev->nb_irqs && adapter->intr_mode) {
+		PMD_INIT_LOG(ERR, "No irq support on device");
+		return -1;
+	}
+
 	if (!dev->intr_handle) {
 		dev->intr_handle = rte_zmalloc_socket("iavf_client_intr",
 				sizeof(*dev->intr_handle),
@@ -62,7 +88,7 @@ iavf_client_vfio_user_setup(struct rte_eth_dev *dev, const char *path)
 
 	}
 
-	dev->intr_handle->fd = -1;
+	dev->intr_handle->fd = vfio_dev->irqfds[0];
 	dev->intr_handle->type = RTE_INTR_HANDLE_VDEV;
 	dev->intr_handle->max_intr = 1;
 
@@ -145,26 +171,52 @@ iavf_client_eth_init(struct rte_eth_dev *eth_dev)
 	rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
 			&eth_dev->data->mac_addrs[0]);
 
-	rte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,
-			  iavf_client_dev_alarm_handler, eth_dev);
+	if (adapter->intr_mode) {
+		/* register callback func to eal lib */
+		rte_intr_callback_register(eth_dev->intr_handle,
+					   iavf_client_event_handler,
+					   (void *)eth_dev);
+		iavf_enable_irq0(hw);
+	} else {
+		rte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,
+				  iavf_client_dev_alarm_handler, eth_dev);
+	}
 	return 0;
 }
 
 static int
 iavf_client_dev_reset(struct rte_eth_dev *dev)
 {
+	struct iavf_adapter *adapter =
+		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_intr_handle *intr_handle = dev->intr_handle;
 	int ret;
 
-	rte_eal_alarm_cancel(iavf_client_dev_alarm_handler, dev);
+	if (adapter->intr_mode) {
+		iavf_disable_irq0(hw);
+		/* unregister callback func from eal lib */
+		rte_intr_callback_unregister(intr_handle,
+					     iavf_client_event_handler, dev);
+	} else {
+		rte_eal_alarm_cancel(iavf_client_dev_alarm_handler, dev);
+	}
 
 	iavf_shutdown_adminq(hw);
 	ret = iavf_init_vf(dev);
 
 	/* send reset msg to PF */
 	iavf_vf_reset(hw);
-	rte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,
-			  iavf_client_dev_alarm_handler, dev);
+	if (adapter->intr_mode) {
+		/* register callback func to eal lib */
+		rte_intr_callback_register(dev->intr_handle,
+					   iavf_client_event_handler,
+					   (void *)dev);
+		iavf_enable_irq0(hw);
+	} else {
+		rte_eal_alarm_set(IAVF_CLIENT_ALARM_INTERVAL,
+				  iavf_client_dev_alarm_handler, dev);
+	}
 
 	return ret;
 }
@@ -176,6 +228,15 @@ iavf_client_dev_close(struct rte_eth_dev *dev)
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+	if (adapter->intr_mode) {
+		iavf_disable_irq0(hw);
+		/* unregister callback func from eal lib */
+		rte_intr_callback_unregister(dev->intr_handle,
+					     iavf_client_event_handler, dev);
+	} else {
+		rte_eal_alarm_cancel(iavf_client_dev_alarm_handler, dev);
+	}
+
 	if (!adapter->stopped) {
 		iavf_stop_queues(dev);
 
@@ -188,10 +249,10 @@ iavf_client_dev_close(struct rte_eth_dev *dev)
 		iavf_add_del_all_mac_addr(adapter, false);
 		adapter->stopped = 1;
 	}
+
 	iavf_shutdown_adminq(hw);
-	iavf_disable_irq0(hw);
-	rte_eal_alarm_cancel(iavf_client_dev_alarm_handler, dev);
 	client_vfio_user_release((struct vfio_device *)hw->hw_addr);
+
 	return 0;
 }
 
@@ -210,6 +271,23 @@ iavf_client_get_string_arg(const char *key __rte_unused,
 	return 0;
 }
 
+static int
+iavf_client_intr_check(__rte_unused const char *key,
+			const char *value, void *opaque)
+{
+	int *intr = (int *)opaque;
+	int ret = 0;
+
+	if (!strcmp(value, "1"))
+		*intr  = 1;
+	else if (!strcmp(value, "0"))
+		*intr = 0;
+	else
+		ret = -1;
+
+	return ret;
+}
+
 static int
 iavf_client_pmd_probe(struct rte_vdev_device *vdev)
 {
@@ -217,6 +295,7 @@ iavf_client_pmd_probe(struct rte_vdev_device *vdev)
 	struct rte_eth_dev *eth_dev;
 	struct iavf_adapter *adapter;
 	char *path = NULL;
+	int intr_mode = 0;
 	int ret;
 
 	kvlist = rte_kvargs_parse(rte_vdev_device_args(vdev), valid_args);
@@ -227,35 +306,52 @@ iavf_client_pmd_probe(struct rte_vdev_device *vdev)
 
 	if (rte_kvargs_count(kvlist, AVF_CLIENT_ARG_PATH) == 1) {
 		if (rte_kvargs_process(kvlist, AVF_CLIENT_ARG_PATH,
-				       &iavf_client_get_string_arg, &path) < 0) {
+					&iavf_client_get_string_arg,
+					&path) < 0) {
 			PMD_INIT_LOG(ERR, "error to parse %s",
 				     AVF_CLIENT_ARG_PATH);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto free_kvlist;
 		}
 	} else {
 		PMD_INIT_LOG(ERR, "arg %s is mandatory for iavf_client",
 			     AVF_CLIENT_ARG_PATH);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto free_kvlist;
+	}
+
+	if (rte_kvargs_count(kvlist, AVF_CLIENT_ARG_INTR) == 1) {
+		if (rte_kvargs_process(kvlist, AVF_CLIENT_ARG_INTR,
+					iavf_client_intr_check,
+					&intr_mode) < 0) {
+			PMD_INIT_LOG(ERR, "arg %s must be 1 or 0",
+				     AVF_CLIENT_ARG_INTR);
+			ret = -EINVAL;
+			goto free_kvlist;
+		}
 	}
 
 	eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*adapter));
 
 	ret = iavf_client_vfio_user_setup(eth_dev, path);
-	if (ret) {
+	if (ret)
 		goto err;
-	}
+
+	adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);
+	adapter->intr_mode = intr_mode;
 
 	ret = iavf_client_eth_init(eth_dev);
-	if (ret) {
+	if (ret)
 		goto err;
-	}
 
 	rte_eth_dev_probing_finish(eth_dev);
+
 	rte_kvargs_free(kvlist);
 
 	return 0;
 err:
 	rte_eth_dev_release_port(eth_dev);
+free_kvlist:
 	rte_kvargs_free(kvlist);
 	return ret;
 }
@@ -287,4 +383,5 @@ static struct rte_vdev_driver iavf_client_driver = {
 RTE_PMD_REGISTER_VDEV(net_iavf_client, iavf_client_driver);
 RTE_PMD_REGISTER_ALIAS(net_iavf_client, iavf_client);
 RTE_PMD_REGISTER_PARAM_STRING(net_iavf_client,
-	"path=<path>");
+	"path=<path>"
+	"intr=[0|1]");
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 6b5e47adf2..bc07ecbed7 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -1869,23 +1869,7 @@ iavf_init_vf(struct rte_eth_dev *dev)
 	return -1;
 }
 
-/* Enable default admin queue interrupt setting */
-static inline void
-iavf_enable_irq0(struct iavf_hw *hw)
-{
-	/* Enable admin queue interrupt trigger */
-	IAVF_WRITE_REG(hw, IAVF_VFINT_ICR0_ENA1,
-		       IAVF_VFINT_ICR0_ENA1_ADMINQ_MASK);
-
-	IAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,
-		       IAVF_VFINT_DYN_CTL01_INTENA_MASK |
-		       IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
-		       IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
-
-	IAVF_WRITE_FLUSH(hw);
-}
-
-static void
+void
 iavf_dev_interrupt_handler(void *param)
 {
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
-- 
2.21.1


  parent reply	other threads:[~2021-01-07  8:41 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-19 14:38 [dpdk-dev] [PATCH v1 0/2] introduce new iavf driver on vfio-user client Jingjing Wu
2020-12-19 14:38 ` [dpdk-dev] [PATCH v1 1/2] common/iavf: emulated pci interfaces " Jingjing Wu
2020-12-19 14:38 ` [dpdk-dev] [PATCH v1 2/2] net/iavf: introduce iavf driver " Jingjing Wu
2020-12-22  8:14   ` Xia, Chenbo
2021-01-07  7:45 ` [dpdk-dev] [PATCH v2 0/4] introduce new " Jingjing Wu
2021-01-07  7:45   ` [dpdk-dev] [PATCH v2 1/4] net/iavf_client: introduce " Jingjing Wu
2021-01-07  7:45   ` [dpdk-dev] [PATCH v2 2/4] net/iavf_client: enable interrupt on control queue Jingjing Wu
2021-01-07  7:45   ` [dpdk-dev] [PATCH v2 3/4] net/iavf_client: enable interrupt of " Jingjing Wu
2021-01-07  7:45   ` [dpdk-dev] [PATCH v2 4/4] net/iavf: fix vector mapping with queue Jingjing Wu
2021-01-07  8:27   ` [dpdk-dev] [PATCH v3 0/5] introduce new iavf driver on vfio-user client Jingjing Wu
2021-01-07  8:27     ` [dpdk-dev] [PATCH v3 1/5] common/iavf: emulated pci interfaces " Jingjing Wu
2021-01-07  8:27     ` [dpdk-dev] [PATCH v3 2/5] net/iavf_client: introduce iavf driver " Jingjing Wu
2021-01-07  8:27     ` Jingjing Wu [this message]
2021-01-07  8:27     ` [dpdk-dev] [PATCH v3 4/5] net/iavf_client: enable interrupt of Rx queue Jingjing Wu
2021-01-07  8:27     ` [dpdk-dev] [PATCH v3 5/5] net/iavf: fix vector mapping with queue Jingjing Wu
2021-01-12  6:10       ` Xing, Beilei
2021-01-12  6:45         ` Wu, Jingjing
2021-01-14 10:24       ` Xie, WeiX

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=20210107082718.33748-4-jingjing.wu@intel.com \
    --to=jingjing.wu@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=chenbo.xia@intel.com \
    --cc=dev@dpdk.org \
    --cc=xiuchun.lu@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.