DPDK patches and discussions
 help / color / mirror / Atom feed
From: Marcin Zapolski <marcinx.a.zapolski@intel.com>
To: dev@dpdk.org
Cc: Marcin Zapolski <marcinx.a.zapolski@intel.com>
Subject: [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline
Date: Tue, 30 Jul 2019 14:49:49 +0200	[thread overview]
Message-ID: <20190730124950.1293-2-marcinx.a.zapolski@intel.com> (raw)
In-Reply-To: <20190730124950.1293-1-marcinx.a.zapolski@intel.com>

Make rte_eth_rx_burst, rte_eth_tx_burst and other static inline ethdev
functions not inline. They are referencing DPDK internal structures and
inlining forces those structures to be exposed to user applications.

In internal testing with i40e NICs a performance drop of about 2% was
observed with testpmd.

Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
---
 lib/librte_ethdev/rte_ethdev.c           | 168 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h           | 166 ++--------------------
 lib/librte_ethdev/rte_ethdev_version.map |  12 ++
 3 files changed, 195 insertions(+), 151 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f..31432a956 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -749,6 +749,174 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id)
 	return rte_eth_devices[port_id].security_ctx;
 }
 
+uint16_t
+rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
+		 struct rte_mbuf **rx_pkts, const uint16_t nb_pkts)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	uint16_t nb_rx;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->rx_pkt_burst, 0);
+
+	if (queue_id >= dev->data->nb_rx_queues) {
+		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
+		return 0;
+	}
+#endif
+	nb_rx = (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id],
+				     rx_pkts, nb_pkts);
+
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+	if (unlikely(dev->post_rx_burst_cbs[queue_id] != NULL)) {
+		struct rte_eth_rxtx_callback *cb =
+				dev->post_rx_burst_cbs[queue_id];
+
+		do {
+			nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
+						nb_pkts, cb->param);
+			cb = cb->next;
+		} while (cb != NULL);
+	}
+#endif
+
+	return nb_rx;
+}
+
+int
+rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_count, -ENOTSUP);
+	if (queue_id >= dev->data->nb_rx_queues)
+		return -EINVAL;
+
+	return (int)(*dev->dev_ops->rx_queue_count)(dev, queue_id);
+}
+
+int
+rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_done, -ENOTSUP);
+	return (*dev->dev_ops->rx_descriptor_done)(
+		dev->data->rx_queues[queue_id], offset);
+}
+
+int
+rte_eth_rx_descriptor_status(uint16_t port_id, uint16_t queue_id,
+	uint16_t offset)
+{
+	struct rte_eth_dev *dev;
+	void *rxq;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+#endif
+	dev = &rte_eth_devices[port_id];
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	if (queue_id >= dev->data->nb_rx_queues)
+		return -ENODEV;
+#endif
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_status, -ENOTSUP);
+	rxq = dev->data->rx_queues[queue_id];
+
+	return (*dev->dev_ops->rx_descriptor_status)(rxq, offset);
+}
+
+int
+rte_eth_tx_descriptor_status(uint16_t port_id,
+	uint16_t queue_id, uint16_t offset)
+{
+	struct rte_eth_dev *dev;
+	void *txq;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+#endif
+	dev = &rte_eth_devices[port_id];
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	if (queue_id >= dev->data->nb_tx_queues)
+		return -ENODEV;
+#endif
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_descriptor_status, -ENOTSUP);
+	txq = dev->data->tx_queues[queue_id];
+
+	return (*dev->dev_ops->tx_descriptor_status)(txq, offset);
+}
+
+uint16_t
+rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
+		 struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->tx_pkt_burst, 0);
+
+	if (queue_id >= dev->data->nb_tx_queues) {
+		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
+		return 0;
+	}
+#endif
+
+#ifdef RTE_ETHDEV_RXTX_CALLBACKS
+	struct rte_eth_rxtx_callback *cb = dev->pre_tx_burst_cbs[queue_id];
+
+	if (unlikely(cb != NULL)) {
+		do {
+			nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts, nb_pkts,
+					cb->param);
+			cb = cb->next;
+		} while (cb != NULL);
+	}
+#endif
+
+	return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id],
+		tx_pkts, nb_pkts);
+}
+
+#ifndef RTE_ETHDEV_TX_PREPARE_NOOP
+
+uint16_t
+rte_eth_tx_prepare(uint16_t port_id, uint16_t queue_id,
+		struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+	struct rte_eth_dev *dev;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	if (!rte_eth_dev_is_valid_port(port_id)) {
+		RTE_ETHDEV_LOG(ERR, "Invalid TX port_id=%u\n", port_id);
+		rte_errno = EINVAL;
+		return 0;
+	}
+#endif
+
+	dev = &rte_eth_devices[port_id];
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	if (queue_id >= dev->data->nb_tx_queues) {
+		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
+		rte_errno = EINVAL;
+		return 0;
+	}
+#endif
+
+	if (!dev->tx_pkt_prepare)
+		return nb_pkts;
+
+	return (*dev->tx_pkt_prepare)(dev->data->tx_queues[queue_id],
+			tx_pkts, nb_pkts);
+}
+
+#endif
+
 uint16_t
 rte_eth_dev_count(void)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index dc6596bc9..3438cb681 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -4078,40 +4078,9 @@ rte_eth_dev_get_sec_ctx(uint16_t port_id);
  *   of pointers to *rte_mbuf* structures effectively supplied to the
  *   *rx_pkts* array.
  */
-static inline uint16_t
+uint16_t
 rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
-		 struct rte_mbuf **rx_pkts, const uint16_t nb_pkts)
-{
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	uint16_t nb_rx;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->rx_pkt_burst, 0);
-
-	if (queue_id >= dev->data->nb_rx_queues) {
-		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
-		return 0;
-	}
-#endif
-	nb_rx = (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id],
-				     rx_pkts, nb_pkts);
-
-#ifdef RTE_ETHDEV_RXTX_CALLBACKS
-	if (unlikely(dev->post_rx_burst_cbs[queue_id] != NULL)) {
-		struct rte_eth_rxtx_callback *cb =
-				dev->post_rx_burst_cbs[queue_id];
-
-		do {
-			nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
-						nb_pkts, cb->param);
-			cb = cb->next;
-		} while (cb != NULL);
-	}
-#endif
-
-	return nb_rx;
-}
+		 struct rte_mbuf **rx_pkts, const uint16_t nb_pkts);
 
 /**
  * Get the number of used descriptors of a rx queue
@@ -4125,19 +4094,8 @@ rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
  *     (-EINVAL) if *port_id* or *queue_id* is invalid
  *     (-ENOTSUP) if the device does not support this function
  */
-static inline int
-rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
-	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_count, -ENOTSUP);
-	if (queue_id >= dev->data->nb_rx_queues)
-		return -EINVAL;
-
-	return (int)(*dev->dev_ops->rx_queue_count)(dev, queue_id);
-}
+int
+rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id);
 
 /**
  * Check if the DD bit of the specific RX descriptor in the queue has been set
@@ -4154,15 +4112,9 @@ rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id)
  *  - (-ENODEV) if *port_id* invalid.
  *  - (-ENOTSUP) if the device does not support this function
  */
-static inline int
-rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset)
-{
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_done, -ENOTSUP);
-	return (*dev->dev_ops->rx_descriptor_done)( \
-		dev->data->rx_queues[queue_id], offset);
-}
+int
+rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id,
+	uint16_t offset);
 
 #define RTE_ETH_RX_DESC_AVAIL    0 /**< Desc available for hw. */
 #define RTE_ETH_RX_DESC_DONE     1 /**< Desc done, filled by hw. */
@@ -4201,26 +4153,9 @@ rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset)
  *  - (-ENOTSUP) if the device does not support this function.
  *  - (-ENODEV) bad port or queue (only if compiled with debug).
  */
-static inline int
+int
 rte_eth_rx_descriptor_status(uint16_t port_id, uint16_t queue_id,
-	uint16_t offset)
-{
-	struct rte_eth_dev *dev;
-	void *rxq;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-#endif
-	dev = &rte_eth_devices[port_id];
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (queue_id >= dev->data->nb_rx_queues)
-		return -ENODEV;
-#endif
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_status, -ENOTSUP);
-	rxq = dev->data->rx_queues[queue_id];
-
-	return (*dev->dev_ops->rx_descriptor_status)(rxq, offset);
-}
+	uint16_t offset);
 
 #define RTE_ETH_TX_DESC_FULL    0 /**< Desc filled for hw, waiting xmit. */
 #define RTE_ETH_TX_DESC_DONE    1 /**< Desc done, packet is transmitted. */
@@ -4259,25 +4194,8 @@ rte_eth_rx_descriptor_status(uint16_t port_id, uint16_t queue_id,
  *  - (-ENOTSUP) if the device does not support this function.
  *  - (-ENODEV) bad port or queue (only if compiled with debug).
  */
-static inline int rte_eth_tx_descriptor_status(uint16_t port_id,
-	uint16_t queue_id, uint16_t offset)
-{
-	struct rte_eth_dev *dev;
-	void *txq;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-#endif
-	dev = &rte_eth_devices[port_id];
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (queue_id >= dev->data->nb_tx_queues)
-		return -ENODEV;
-#endif
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_descriptor_status, -ENOTSUP);
-	txq = dev->data->tx_queues[queue_id];
-
-	return (*dev->dev_ops->tx_descriptor_status)(txq, offset);
-}
+int rte_eth_tx_descriptor_status(uint16_t port_id,
+	uint16_t queue_id, uint16_t offset);
 
 /**
  * Send a burst of output packets on a transmit queue of an Ethernet device.
@@ -4345,36 +4263,9 @@ static inline int rte_eth_tx_descriptor_status(uint16_t port_id,
  *   the transmit ring. The return value can be less than the value of the
  *   *tx_pkts* parameter when the transmit ring is full or has been filled up.
  */
-static inline uint16_t
+uint16_t
 rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
-		 struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->tx_pkt_burst, 0);
-
-	if (queue_id >= dev->data->nb_tx_queues) {
-		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
-		return 0;
-	}
-#endif
-
-#ifdef RTE_ETHDEV_RXTX_CALLBACKS
-	struct rte_eth_rxtx_callback *cb = dev->pre_tx_burst_cbs[queue_id];
-
-	if (unlikely(cb != NULL)) {
-		do {
-			nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts, nb_pkts,
-					cb->param);
-			cb = cb->next;
-		} while (cb != NULL);
-	}
-#endif
-
-	return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
-}
+		 struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
 
 /**
  * Process a burst of output packets on a transmit queue of an Ethernet device.
@@ -4431,36 +4322,9 @@ rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
 
 #ifndef RTE_ETHDEV_TX_PREPARE_NOOP
 
-static inline uint16_t
+uint16_t
 rte_eth_tx_prepare(uint16_t port_id, uint16_t queue_id,
-		struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-	struct rte_eth_dev *dev;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (!rte_eth_dev_is_valid_port(port_id)) {
-		RTE_ETHDEV_LOG(ERR, "Invalid TX port_id=%u\n", port_id);
-		rte_errno = EINVAL;
-		return 0;
-	}
-#endif
-
-	dev = &rte_eth_devices[port_id];
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (queue_id >= dev->data->nb_tx_queues) {
-		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
-		rte_errno = EINVAL;
-		return 0;
-	}
-#endif
-
-	if (!dev->tx_pkt_prepare)
-		return nb_pkts;
-
-	return (*dev->tx_pkt_prepare)(dev->data->tx_queues[queue_id],
-			tx_pkts, nb_pkts);
-}
+		struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
 
 #else
 
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index df9141825..ab590bb71 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -236,6 +236,18 @@ DPDK_19.05 {
 
 } DPDK_18.11;
 
+DPDK_19.11 {
+	global:
+
+	rte_eth_rx_burst;
+	rte_eth_rx_descriptor_done;
+	rte_eth_rx_descriptor_status;
+	rte_eth_rx_queue_count;
+	rte_eth_tx_burst;
+	rte_eth_tx_descriptor_status;
+	rte_eth_tx_prepare;
+} DPDK_19.05;
+
 EXPERIMENTAL {
 	global:
 
-- 
2.17.1


  reply	other threads:[~2019-07-30 13:09 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-30 12:49 [dpdk-dev] [RFC 19.11 0/2] Hide DPDK internal struct from public API Marcin Zapolski
2019-07-30 12:49 ` Marcin Zapolski [this message]
2019-07-30 15:01   ` [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline Jerin Jacob Kollanukkaran
2019-07-30 15:32     ` Bruce Richardson
2019-07-30 15:25   ` Stephen Hemminger
2019-07-30 15:33     ` Bruce Richardson
2019-07-30 15:54       ` Stephen Hemminger
2019-07-30 16:04         ` Wiles, Keith
2019-07-30 16:11         ` Bruce Richardson
2019-07-30 16:23           ` Stephen Hemminger
2019-07-30 12:49 ` [dpdk-dev] [RFC 19.11 2/2] ethdev: hide DPDK internal struct from public API Marcin Zapolski
2019-07-30 14:53   ` Ferruh Yigit
2019-09-06 13:18 ` [dpdk-dev] [RFC 19.11 v2 0/3] Hide " Marcin Zapolski
2019-09-06 14:00   ` Bruce Richardson
2019-09-06 13:18 ` [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev structures " Marcin Zapolski
2019-09-06 14:37   ` Ferruh Yigit
2019-09-09  8:07     ` Zapolski, MarcinX A
2019-09-09  9:59       ` Ferruh Yigit
2019-09-09 10:02         ` Zapolski, MarcinX A
2019-09-09 10:24           ` Ferruh Yigit
2019-09-09 11:41             ` Zapolski, MarcinX A
2019-09-14 10:34             ` Jerin Jacob
2019-09-06 17:24   ` Stephen Hemminger
2019-09-09  9:01     ` Zapolski, MarcinX A
2019-09-10  9:59   ` Zapolski, MarcinX A
2019-09-10 10:06     ` Bruce Richardson
2019-09-10 10:13       ` Zapolski, MarcinX A
2019-09-10 12:19         ` Bruce Richardson
2019-09-10 12:22           ` Zapolski, MarcinX A
2019-09-06 13:18 ` [dpdk-dev] [RFC 19.11 v2 2/3] i40e: make driver compatible with changes in ethdev Marcin Zapolski
2019-09-06 13:18 ` [dpdk-dev] [RFC 19.11 v2 3/3] ixgbe: " Marcin Zapolski
2019-07-30 15:45 [dpdk-dev] [RFC 19.11 1/2] ethdev: make DPDK core functions non-inline Jerin Jacob Kollanukkaran
2019-07-30 16:05 ` Bruce Richardson

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=20190730124950.1293-2-marcinx.a.zapolski@intel.com \
    --to=marcinx.a.zapolski@intel.com \
    --cc=dev@dpdk.org \
    /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).