DPDK patches and discussions
 help / color / mirror / Atom feed
From: Moti Haimovsky <motih@mellanox.com>
To: gaetan.rivet@6wind.com, ferruh.yigit@intel.com
Cc: dev@dpdk.org, Moti Haimovsky <motih@mellanox.com>
Subject: [dpdk-dev] [PATCH v6 2/3] net/failsafe: slaves Rx interrupts registration
Date: Wed, 24 Jan 2018 18:12:07 +0200	[thread overview]
Message-ID: <1516810328-39383-3-git-send-email-motih@mellanox.com> (raw)
In-Reply-To: <1516810328-39383-1-git-send-email-motih@mellanox.com>

This commit adds the following functionality to failsafe PMD:
* Register and unregister slaves Rx interrupts.
* Enable and Disable slaves Rx interrupts.
The interrupts events generated by the slaves are not handled in this
commit.

Signed-off-by: Moti Haimovsky <motih@mellanox.com>
---
V6:
Added a wrapper around epoll_create1 since it is not supported in FreeBSD.
See: 1516193643-130838-1-git-send-email-motih@mellanox.com

V5:
Initial version of this patch in accordance to inputs from Gaetan Rivet
in reply to
1516354344-13495-2-git-send-email-motih@mellanox.com
---
 drivers/net/failsafe/Makefile                  |   5 +
 drivers/net/failsafe/failsafe_epoll.h          |  10 ++
 drivers/net/failsafe/failsafe_epoll_bsdapp.c   |  19 +++
 drivers/net/failsafe/failsafe_epoll_linuxapp.c |  18 +++
 drivers/net/failsafe/failsafe_ether.c          |   1 +
 drivers/net/failsafe/failsafe_intr.c           | 198 +++++++++++++++++++++++++
 drivers/net/failsafe/failsafe_ops.c            |  36 ++++-
 drivers/net/failsafe/failsafe_private.h        |  16 ++
 8 files changed, 301 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/failsafe/failsafe_epoll.h
 create mode 100644 drivers/net/failsafe/failsafe_epoll_bsdapp.c
 create mode 100644 drivers/net/failsafe/failsafe_epoll_linuxapp.c

diff --git a/drivers/net/failsafe/Makefile b/drivers/net/failsafe/Makefile
index 91a734b..4e6a983 100644
--- a/drivers/net/failsafe/Makefile
+++ b/drivers/net/failsafe/Makefile
@@ -47,6 +47,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_ether.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_intr.c
+ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_epoll_linuxapp.c
+else
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_FAILSAFE) += failsafe_epoll_bsdapp.c
+endif
 
 # No exported include files
 
diff --git a/drivers/net/failsafe/failsafe_epoll.h b/drivers/net/failsafe/failsafe_epoll.h
new file mode 100644
index 0000000..8e6a1ec
--- /dev/null
+++ b/drivers/net/failsafe/failsafe_epoll.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Mellanox Technologies, Ltd.
+ */
+
+#ifndef _RTE_ETH_FAILSAFE_EPOLL_H_
+#define _RTE_ETH_FAILSAFE_EPOLL_H_
+
+int failsafe_epoll_create1(int flags);
+
+#endif /* _RTE_ETH_FAILSAFE_EPOLL_H_*/
diff --git a/drivers/net/failsafe/failsafe_epoll_bsdapp.c b/drivers/net/failsafe/failsafe_epoll_bsdapp.c
new file mode 100644
index 0000000..46c839b
--- /dev/null
+++ b/drivers/net/failsafe/failsafe_epoll_bsdapp.c
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Mellanox Technologies, Ltd.
+ */
+
+/**
+ * @file
+ * epoll wrapper for failsafe driver.
+ */
+
+#include <rte_common.h>
+
+#include "failsafe_epoll.h"
+
+int
+failsafe_epoll_create1(int flags)
+{
+	RTE_SET_USED(flags);
+	return -ENOTSUP;
+}
diff --git a/drivers/net/failsafe/failsafe_epoll_linuxapp.c b/drivers/net/failsafe/failsafe_epoll_linuxapp.c
new file mode 100644
index 0000000..d82ee0a
--- /dev/null
+++ b/drivers/net/failsafe/failsafe_epoll_linuxapp.c
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 Mellanox Technologies, Ltd.
+ */
+
+/**
+ * @file
+ * epoll wrapper for failsafe driver.
+ */
+
+#include <sys/epoll.h>
+
+#include "failsafe_epoll.h"
+
+int
+failsafe_epoll_create1(int flags)
+{
+	return epoll_create1(flags);
+}
diff --git a/drivers/net/failsafe/failsafe_ether.c b/drivers/net/failsafe/failsafe_ether.c
index 8a4cacf..0f1630e 100644
--- a/drivers/net/failsafe/failsafe_ether.c
+++ b/drivers/net/failsafe/failsafe_ether.c
@@ -283,6 +283,7 @@
 		return;
 	switch (sdev->state) {
 	case DEV_STARTED:
+		failsafe_rx_intr_uninstall_subdevice(sdev);
 		rte_eth_dev_stop(PORT_ID(sdev));
 		sdev->state = DEV_ACTIVE;
 		/* fallthrough */
diff --git a/drivers/net/failsafe/failsafe_intr.c b/drivers/net/failsafe/failsafe_intr.c
index 54ef2f4..512efc7 100644
--- a/drivers/net/failsafe/failsafe_intr.c
+++ b/drivers/net/failsafe/failsafe_intr.c
@@ -9,8 +9,198 @@
 
 #include <unistd.h>
 
+#include "failsafe_epoll.h"
 #include "failsafe_private.h"
 
+#define NUM_RX_PROXIES (FAILSAFE_MAX_ETHPORTS * RTE_MAX_RXTX_INTR_VEC_ID)
+
+/**
+ * Install failsafe Rx event proxy subsystem.
+ * This is the way the failsafe PMD generates Rx events on behalf of its
+ * subdevices.
+ *
+ * @param priv
+ *   Pointer to failsafe private structure.
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
+ */
+static int
+fs_rx_event_proxy_install(struct fs_priv *priv)
+{
+	int rc = 0;
+
+	/*
+	 * Create the epoll fd and event vector for the proxy service to
+	 * wait on for Rx events generated by the subdevices.
+	 */
+	priv->rxp.efd = failsafe_epoll_create1(0);
+	if (priv->rxp.efd < 0) {
+		rte_errno = errno;
+		ERROR("Failed to create epoll,"
+		      " Rx interrupts will not be supported");
+		return -rte_errno;
+	}
+	priv->rxp.evec = calloc(NUM_RX_PROXIES, sizeof(*priv->rxp.evec));
+	if (priv->rxp.evec == NULL) {
+		ERROR("Failed to allocate memory for event vectors,"
+		      " Rx interrupts will not be supported");
+		rc = -ENOMEM;
+		goto error;
+	}
+	return 0;
+error:
+	if (priv->rxp.efd >= 0) {
+		close(priv->rxp.efd);
+		priv->rxp.efd = -1;
+	}
+	if (priv->rxp.evec != NULL) {
+		free(priv->rxp.evec);
+		priv->rxp.evec = NULL;
+	}
+	rte_errno = -rc;
+	return rc;
+}
+
+/**
+ * RX Interrupt control per subdevice.
+ *
+ * @param sdev
+ *   Pointer to sub-device structure.
+ * @param op
+ *   The operation be performed for the vector.
+ *   Operation type of {RTE_INTR_EVENT_ADD, RTE_INTR_EVENT_DEL}.
+ * @return
+ *   - On success, zero.
+ *   - On failure, a negative value.
+ */
+static int
+failsafe_eth_rx_intr_ctl_subdevice(struct sub_device *sdev, int op)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev *fsdev;
+	int epfd;
+	uint16_t pid;
+	uint16_t qid;
+	struct rxq *fsrxq;
+	int rc;
+	int ret = 0;
+
+	if (sdev == NULL || (ETH(sdev) == NULL) ||
+	    sdev->fs_dev == NULL || (PRIV(sdev->fs_dev) == NULL)) {
+		ERROR("Called with invalid arguments");
+		return -EINVAL;
+	}
+	dev = ETH(sdev);
+	fsdev = sdev->fs_dev;
+	epfd = PRIV(sdev->fs_dev)->rxp.efd;
+	pid = PORT_ID(sdev);
+
+	if (epfd <= 0) {
+		if (op == RTE_INTR_EVENT_ADD) {
+			ERROR("Proxy events are not initialized");
+			return -EBADFD;
+		} else {
+			return 0;
+		}
+	}
+	if (dev->data->nb_rx_queues > fsdev->data->nb_rx_queues) {
+		ERROR("subdevice has too many queues,"
+		      " Interrupts will not be enabled");
+			return -E2BIG;
+	}
+	for (qid = 0; qid < dev->data->nb_rx_queues; qid++) {
+		fsrxq = fsdev->data->rx_queues[qid];
+		rc = rte_eth_dev_rx_intr_ctl_q(pid, qid, epfd,
+					       op, (void *)fsrxq);
+		if (rc) {
+			ERROR("rte_eth_dev_rx_intr_ctl_q failed for "
+			      "port %d  queue %d, epfd %d, error %d",
+			      pid, qid, epfd, rc);
+			ret = rc;
+		}
+	}
+	return ret;
+}
+
+/**
+ * Install Rx interrupts subsystem for a subdevice.
+ * This is a support for dynamically adding subdevices.
+ *
+ * @param sdev
+ *   Pointer to subdevice structure.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
+ */
+int failsafe_rx_intr_install_subdevice(struct sub_device *sdev)
+{
+	int rc;
+	int qid;
+	struct rte_eth_dev *fsdev;
+	struct rxq **rxq;
+	const struct rte_intr_conf *const intr_conf =
+				&ETH(sdev)->data->dev_conf.intr_conf;
+
+	fsdev = sdev->fs_dev;
+	rxq = (struct rxq **)fsdev->data->rx_queues;
+	if (intr_conf->rxq == 0)
+		return 0;
+	rc = failsafe_eth_rx_intr_ctl_subdevice(sdev, RTE_INTR_EVENT_ADD);
+	if (rc)
+		return rc;
+	/* enable interrupts on already-enabled queues */
+	for (qid = 0; qid < ETH(sdev)->data->nb_rx_queues; qid++) {
+		if (rxq[qid]->enable_events) {
+			int ret = rte_eth_dev_rx_intr_enable(PORT_ID(sdev),
+							     qid);
+			if (ret && (ret != -ENOTSUP)) {
+				ERROR("Failed to enable interrupts on "
+				      "port %d queue %d", PORT_ID(sdev), qid);
+				rc = ret;
+			}
+		}
+	}
+	return rc;
+}
+
+/**
+ * Uninstall Rx interrupts subsystem for a subdevice.
+ * This is a support for dynamically removing subdevices.
+ *
+ * @param sdev
+ *   Pointer to subdevice structure.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
+ */
+void failsafe_rx_intr_uninstall_subdevice(struct sub_device *sdev)
+{
+	int qid;
+
+	for (qid = 0; qid < ETH(sdev)->data->nb_rx_queues; qid++)
+		rte_eth_dev_rx_intr_disable(PORT_ID(sdev), qid);
+	failsafe_eth_rx_intr_ctl_subdevice(sdev, RTE_INTR_EVENT_DEL);
+}
+
+/**
+ * Uninstall failsafe Rx event proxy.
+ *
+ * @param priv
+ *   Pointer to failsafe private structure.
+ */
+static void
+fs_rx_event_proxy_uninstall(struct fs_priv *priv)
+{
+	if (priv->rxp.evec != NULL) {
+		free(priv->rxp.evec);
+		priv->rxp.evec = NULL;
+	}
+	if (priv->rxp.efd > 0) {
+		close(priv->rxp.efd);
+		priv->rxp.efd = -1;
+	}
+}
+
 /**
  * Uninstall failsafe interrupt vector.
  *
@@ -107,8 +297,12 @@
 failsafe_rx_intr_uninstall(struct rte_eth_dev *dev)
 {
 	struct fs_priv *priv;
+	struct rte_intr_handle *intr_handle;
 
 	priv = PRIV(dev);
+	intr_handle = &priv->intr_handle;
+	rte_intr_free_epoll_fd(intr_handle);
+	fs_rx_event_proxy_uninstall(priv);
 	fs_rx_intr_vec_uninstall(priv);
 	dev->intr_handle = NULL;
 }
@@ -133,6 +327,10 @@
 		return 0;
 	if (fs_rx_intr_vec_install(priv) < 0)
 		return -rte_errno;
+	if (fs_rx_event_proxy_install(priv) < 0) {
+		fs_rx_intr_vec_uninstall(priv);
+		return -rte_errno;
+	}
 	dev->intr_handle = &priv->intr_handle;
 	return 0;
 }
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index d6a82b3..2ea9cdd 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -214,6 +214,13 @@
 				continue;
 			return ret;
 		}
+		ret = failsafe_rx_intr_install_subdevice(sdev);
+		if (ret) {
+			if (!fs_err(sdev, ret))
+				continue;
+			rte_eth_dev_stop(PORT_ID(sdev));
+			return ret;
+		}
 		sdev->state = DEV_STARTED;
 	}
 	if (PRIV(dev)->state < DEV_STARTED)
@@ -231,6 +238,7 @@
 	PRIV(dev)->state = DEV_STARTED - 1;
 	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_STARTED) {
 		rte_eth_dev_stop(PORT_ID(sdev));
+		failsafe_rx_intr_uninstall_subdevice(sdev);
 		sdev->state = DEV_STARTED - 1;
 	}
 	failsafe_rx_intr_uninstall(dev);
@@ -413,6 +421,10 @@
 fs_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
 {
 	struct rxq *rxq;
+	struct sub_device *sdev;
+	uint8_t i;
+	int ret;
+	int rc = 0;
 
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EINVAL;
@@ -424,14 +436,26 @@
 		return -rte_errno;
 	}
 	rxq->enable_events = 1;
-	return 0;
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_rx_intr_enable(PORT_ID(sdev), idx);
+		ret = fs_err(sdev, ret);
+		if (ret)
+			rc = ret;
+	}
+	if (rc)
+		rte_errno = -rc;
+	return rc;
 }
 
 static int
 fs_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 {
 	struct rxq *rxq;
+	struct sub_device *sdev;
 	uint64_t u64;
+	uint8_t i;
+	int rc = 0;
+	int ret;
 
 	if (idx >= dev->data->nb_rx_queues) {
 		rte_errno = EINVAL;
@@ -443,10 +467,18 @@
 		return -rte_errno;
 	}
 	rxq->enable_events = 0;
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_rx_intr_disable(PORT_ID(sdev), idx);
+		ret = fs_err(sdev, ret);
+		if (ret)
+			rc = ret;
+	}
 	/* Clear pending events */
 	while (read(rxq->event_fd, &u64, sizeof(uint64_t)) >  0)
 		;
-	return 0;
+	if (rc)
+		rte_errno = -rc;
+	return rc;
 }
 
 static bool
diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h
index 419e5e7..ff78b9f 100644
--- a/drivers/net/failsafe/failsafe_private.h
+++ b/drivers/net/failsafe/failsafe_private.h
@@ -63,6 +63,13 @@
 
 /* TYPES */
 
+struct rx_proxy {
+	/* epoll file descriptor */
+	int efd;
+	/* event vector to be used by epoll */
+	struct rte_epoll_event *evec;
+};
+
 struct rxq {
 	struct fs_priv *priv;
 	uint16_t qid;
@@ -158,6 +165,13 @@ struct fs_priv {
 	 */
 	enum dev_state state;
 	struct rte_eth_stats stats_accumulator;
+	/*
+	 * Rx interrupts/events proxy.
+	 * The PMD issues Rx events to the EAL on behalf of its subdevices,
+	 * it does that by registering an event-fd for each of its queues with
+	 * the EAL.
+	 */
+	struct rx_proxy rxp;
 	unsigned int pending_alarm:1; /* An alarm is pending */
 	/* flow isolation state */
 	int flow_isolated:1;
@@ -167,6 +181,8 @@ struct fs_priv {
 
 int failsafe_rx_intr_install(struct rte_eth_dev *dev);
 void failsafe_rx_intr_uninstall(struct rte_eth_dev *dev);
+int failsafe_rx_intr_install_subdevice(struct sub_device *sdev);
+void failsafe_rx_intr_uninstall_subdevice(struct sub_device *sdev);
 
 /* MISC */
 
-- 
1.8.3.1

  parent reply	other threads:[~2018-01-24 16:12 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-11 12:41 [dpdk-dev] [PATCH] net/failsafe: add Rx interrupts Moti Haimovsky
2017-12-12  1:34 ` Stephen Hemminger
2017-12-13 13:12   ` Mordechay Haimovsky
2018-01-04 15:01 ` [dpdk-dev] [PATCH v2] " Moti Haimovsky
2018-01-17 12:54   ` [dpdk-dev] [PATCH V3] " Moti Haimovsky
2018-01-19  9:32     ` [dpdk-dev] [PATCH v4] " Moti Haimovsky
2018-01-19  9:32       ` Moti Haimovsky
2018-01-19 14:11         ` Gaëtan Rivet
2018-01-23 18:43         ` [dpdk-dev] [PATCH v5 0/3] net/failsafe: add Rx interrupts support Moti Haimovsky
2018-01-23 18:43           ` [dpdk-dev] [PATCH v5 1/3] net/failsafe: regiter as an Rx interrupt mode PMD Moti Haimovsky
2018-01-23 18:43           ` [dpdk-dev] [PATCH v5 2/3] net/failsafe: slaves Rx interrupts registration Moti Haimovsky
2018-01-24 16:12             ` [dpdk-dev] [PATCH v6 0/3] net/failsafe: add Rx interrupts support Moti Haimovsky
2018-01-24 16:12               ` [dpdk-dev] [PATCH v6 1/3] net/failsafe: register as an Rx interrupt mode PMD Moti Haimovsky
2018-01-24 16:12               ` Moti Haimovsky [this message]
2018-01-25  8:07                 ` [dpdk-dev] [PATCH v7 0/3] net/failsafe: add Rx interrupts support Moti Haimovsky
2018-01-25  8:07                   ` [dpdk-dev] [PATCH v7 1/3] net/failsafe: register as an Rx interrupt mode PMD Moti Haimovsky
2018-01-25 11:36                     ` Gaëtan Rivet
2018-01-25  8:07                   ` [dpdk-dev] [PATCH v7 2/3] net/failsafe: slaves Rx interrupts registration Moti Haimovsky
2018-01-25 11:49                     ` Gaëtan Rivet
2018-01-25  8:07                   ` [dpdk-dev] [PATCH v7 3/3] net/failsafe: add Rx interrupts Moti Haimovsky
2018-01-25 11:58                     ` Gaëtan Rivet
2018-01-25 16:19                     ` [dpdk-dev] [PATCH v8 0/3] net/failsafe: add Rx interrupts support Moti Haimovsky
2018-01-25 16:19                       ` [dpdk-dev] [PATCH v8 1/3] net/failsafe: register as an Rx interrupt mode PMD Moti Haimovsky
2018-01-25 16:19                       ` [dpdk-dev] [PATCH v8 2/3] net/failsafe: slaves Rx interrupts registration Moti Haimovsky
2018-01-25 16:19                       ` [dpdk-dev] [PATCH v8 3/3] net/failsafe: add Rx interrupts Moti Haimovsky
2018-01-25 16:53                       ` [dpdk-dev] [PATCH v8 0/3] net/failsafe: add Rx interrupts support Gaëtan Rivet
2018-01-26 18:22                         ` Ferruh Yigit
2018-01-24 16:12               ` [dpdk-dev] [PATCH v6 3/3] net/failsafe: add Rx interrupts Moti Haimovsky
2018-01-23 18:43           ` [dpdk-dev] [PATCH v5 " Moti Haimovsky

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=1516810328-39383-3-git-send-email-motih@mellanox.com \
    --to=motih@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=gaetan.rivet@6wind.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).