All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Monjalon <thomas@monjalon.net>
To: dev@dpdk.org
Cc: ferruh.yigit@intel.com, Matan Azrad <matan@mellanox.com>
Subject: [PATCH v3 2/5] ethdev: allow event registration for all ports
Date: Fri, 29 Dec 2017 14:36:55 +0100	[thread overview]
Message-ID: <20171229133658.31258-3-thomas@monjalon.net> (raw)
In-Reply-To: <20171229133658.31258-1-thomas@monjalon.net>

From: Matan Azrad <matan@mellanox.com>

Add option to register event callback for all ports by one call to
rte_eth_dev_callback_register using port_id=RTE_ETH_ALL.

In this case the callback is also registered to invalid ports.

Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
---
v2:
	- moved callback lists constructor
	- changed ports variables from 32 to 16 bits
	- changed doxygen comment
v3: no change
---
 lib/librte_ether/rte_ethdev.c | 121 ++++++++++++++++++++++++++++--------------
 lib/librte_ether/rte_ethdev.h |   8 ++-
 2 files changed, 88 insertions(+), 41 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index c196c3692..5323d445d 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -204,7 +204,6 @@ eth_dev_get(uint16_t port_id)
 
 	eth_dev->data = &rte_eth_dev_data[port_id];
 	eth_dev->state = RTE_ETH_DEV_ATTACHED;
-	TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
 	eth_dev_last_created_port = port_id;
 
@@ -2820,6 +2819,14 @@ rte_eth_mirror_rule_reset(uint16_t port_id, uint8_t rule_id)
 	return (*dev->dev_ops->mirror_rule_reset)(dev, rule_id);
 }
 
+RTE_INIT(eth_dev_init_cb_lists)
+{
+	int i;
+
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+		TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs);
+}
+
 int
 rte_eth_dev_callback_register(uint16_t port_id,
 			enum rte_eth_event_type event,
@@ -2827,37 +2834,59 @@ rte_eth_dev_callback_register(uint16_t port_id,
 {
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_callback *user_cb;
+	uint16_t next_port;
+	uint16_t last_port;
 
 	if (!cb_fn)
 		return -EINVAL;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
+		RTE_LOG(ERR, EAL, "Invalid port_id=%d\n", port_id);
+		return -EINVAL;
+	}
+
+	if (port_id == RTE_ETH_ALL) {
+		next_port = 0;
+		last_port = RTE_MAX_ETHPORTS - 1;
+	} else {
+		next_port = last_port = port_id;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	rte_spinlock_lock(&rte_eth_dev_cb_lock);
 
-	TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
-		if (user_cb->cb_fn == cb_fn &&
-			user_cb->cb_arg == cb_arg &&
-			user_cb->event == event) {
-			break;
+	do {
+		dev = &rte_eth_devices[next_port];
+
+		TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
+			if (user_cb->cb_fn == cb_fn &&
+				user_cb->cb_arg == cb_arg &&
+				user_cb->event == event) {
+				break;
+			}
 		}
-	}
 
-	/* create a new callback. */
-	if (user_cb == NULL) {
-		user_cb = rte_zmalloc("INTR_USER_CALLBACK",
-					sizeof(struct rte_eth_dev_callback), 0);
-		if (user_cb != NULL) {
-			user_cb->cb_fn = cb_fn;
-			user_cb->cb_arg = cb_arg;
-			user_cb->event = event;
-			TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), user_cb, next);
+		/* create a new callback. */
+		if (user_cb == NULL) {
+			user_cb = rte_zmalloc("INTR_USER_CALLBACK",
+				sizeof(struct rte_eth_dev_callback), 0);
+			if (user_cb != NULL) {
+				user_cb->cb_fn = cb_fn;
+				user_cb->cb_arg = cb_arg;
+				user_cb->event = event;
+				TAILQ_INSERT_TAIL(&(dev->link_intr_cbs),
+						  user_cb, next);
+			} else {
+				rte_spinlock_unlock(&rte_eth_dev_cb_lock);
+				rte_eth_dev_callback_unregister(port_id, event,
+								cb_fn, cb_arg);
+				return -ENOMEM;
+			}
+
 		}
-	}
+	} while (++next_port <= last_port);
 
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
-	return (user_cb == NULL) ? -ENOMEM : 0;
+	return 0;
 }
 
 int
@@ -2868,36 +2897,50 @@ rte_eth_dev_callback_unregister(uint16_t port_id,
 	int ret;
 	struct rte_eth_dev *dev;
 	struct rte_eth_dev_callback *cb, *next;
+	uint16_t next_port;
+	uint16_t last_port;
 
 	if (!cb_fn)
 		return -EINVAL;
 
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+	if (!rte_eth_dev_is_valid_port(port_id) && port_id != RTE_ETH_ALL) {
+		RTE_LOG(ERR, EAL, "Invalid port_id=%d\n", port_id);
+		return -EINVAL;
+	}
+
+	if (port_id == RTE_ETH_ALL) {
+		next_port = 0;
+		last_port = RTE_MAX_ETHPORTS - 1;
+	} else {
+		next_port = last_port = port_id;
+	}
 
-	dev = &rte_eth_devices[port_id];
 	rte_spinlock_lock(&rte_eth_dev_cb_lock);
 
-	ret = 0;
-	for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; cb = next) {
+	do {
+		dev = &rte_eth_devices[next_port];
+		ret = 0;
+		for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL;
+		     cb = next) {
 
-		next = TAILQ_NEXT(cb, next);
+			next = TAILQ_NEXT(cb, next);
 
-		if (cb->cb_fn != cb_fn || cb->event != event ||
-				(cb->cb_arg != (void *)-1 &&
-				cb->cb_arg != cb_arg))
-			continue;
+			if (cb->cb_fn != cb_fn || cb->event != event ||
+			    (cb->cb_arg != (void *)-1 && cb->cb_arg != cb_arg))
+				continue;
 
-		/*
-		 * if this callback is not executing right now,
-		 * then remove it.
-		 */
-		if (cb->active == 0) {
-			TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
-			rte_free(cb);
-		} else {
-			ret = -EAGAIN;
+			/*
+			 * if this callback is not executing right now,
+			 * then remove it.
+			 */
+			if (cb->active == 0) {
+				TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
+				rte_free(cb);
+			} else {
+				ret = -EAGAIN;
+			}
 		}
-	}
+	} while (++next_port <= last_port);
 
 	rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 	return ret;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 15309aa7c..c92508cfd 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1137,6 +1137,8 @@ struct rte_eth_dcb_info {
 
 struct rte_eth_dev;
 
+#define RTE_ETH_ALL RTE_MAX_ETHPORTS
+
 struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
@@ -3536,10 +3538,11 @@ typedef int (*rte_eth_dev_cb_fn)(uint16_t port_id,
 
 
 /**
- * Register a callback function for specific port id.
+ * Register a callback function for port event.
  *
  * @param port_id
  *  Port id.
+ *  RTE_ETH_ALL means register the event for all port ids.
  * @param event
  *  Event interested.
  * @param cb_fn
@@ -3556,10 +3559,11 @@ int rte_eth_dev_callback_register(uint16_t port_id,
 		rte_eth_dev_cb_fn cb_fn, void *cb_arg);
 
 /**
- * Unregister a callback function for specific port id.
+ * Unregister a callback function for port event.
  *
  * @param port_id
  *  Port id.
+ *  RTE_ETH_ALL means unregister the event for all port ids.
  * @param event
  *  Event interested.
  * @param cb_fn
-- 
2.15.1

  parent reply	other threads:[~2017-12-29 13:37 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-28 22:13 [PATCH] ethdev: add notifications for probing and removal Thomas Monjalon
2017-12-22  3:17 ` Ferruh Yigit
2017-12-22  8:39   ` Thomas Monjalon
2017-12-29 13:12 ` [PATCH v2 0/3] ethdev port notifications Thomas Monjalon
2017-12-29 13:12   ` [PATCH v2 1/3] ethdev: allow event registration for all ports Thomas Monjalon
2017-12-29 13:12   ` [PATCH v2 2/3] ethdev: free detached port by the dedicated function Thomas Monjalon
2017-12-29 13:12   ` [PATCH v2 3/3] ethdev: add notifications for probing and removal Thomas Monjalon
2017-12-29 13:36 ` [PATCH v3 0/5] ethdev port notifications Thomas Monjalon
2017-12-29 13:36   ` [PATCH v3 1/5] ethdev: remove useless parameter in callback process Thomas Monjalon
2018-01-02 11:35     ` Iremonger, Bernard
2018-01-02 12:21       ` Neil Horman
2018-01-03  8:17         ` Thomas Monjalon
2017-12-29 13:36   ` Thomas Monjalon [this message]
2017-12-29 13:36   ` [PATCH v3 3/5] ethdev: free detached port by the dedicated function Thomas Monjalon
2017-12-29 13:36   ` [PATCH v3 4/5] ethdev: add notifications for probing and removal Thomas Monjalon
2017-12-29 13:36   ` [PATCH v3 5/5] app/testpmd: extend event printing Thomas Monjalon
2018-01-04 16:01 ` [PATCH v4 0/5] ethdev port notifications Thomas Monjalon
2018-01-04 16:01   ` [PATCH v4 1/5] ethdev: remove useless parameter in callback process Thomas Monjalon
2018-01-04 16:01   ` [PATCH v4 2/5] ethdev: allow event registration for all ports Thomas Monjalon
2018-01-04 16:01   ` [PATCH v4 3/5] ethdev: free detached port by the dedicated function Thomas Monjalon
2018-01-04 16:01   ` [PATCH v4 4/5] ethdev: add notifications for probing and removal Thomas Monjalon
2018-01-04 16:01   ` [PATCH v4 5/5] app/testpmd: extend event printing Thomas Monjalon
2018-01-04 16:03     ` Thomas Monjalon
2018-01-10 21:02     ` Ferruh Yigit
2018-01-10 21:19   ` [PATCH v4 0/5] ethdev port notifications Ferruh Yigit

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=20171229133658.31258-3-thomas@monjalon.net \
    --to=thomas@monjalon.net \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=matan@mellanox.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.