[dpdk-dev] [RFC 1/7] eth: move ethdev 'burst' API into separate structure
Konstantin Ananyev
konstantin.ananyev at intel.com
Fri Aug 20 18:28:28 CEST 2021
Move public function pointers (rx_pkt_burst(), etc.) from rte_eth_dev
into a separate flat array. We can keep it public to still use inline
functions for 'fast' calls (like rte_eth_rx_burst(), etc.) to
avoid/minimize slowdown.
The intention is to make rte_eth_dev and related structures internal.
That should allow future possible changes to core eth_dev strcutures
to be transaprent to the user and help to avoid ABI/API breakages.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev at intel.com>
---
lib/ethdev/ethdev_private.c | 74 ++++++++++++++++++++++++++++++++++++
lib/ethdev/ethdev_private.h | 3 ++
lib/ethdev/rte_ethdev.c | 12 ++++++
lib/ethdev/rte_ethdev_core.h | 33 ++++++++++++++++
4 files changed, 122 insertions(+)
diff --git a/lib/ethdev/ethdev_private.c b/lib/ethdev/ethdev_private.c
index 012cf73ca2..1ab64d24cf 100644
--- a/lib/ethdev/ethdev_private.c
+++ b/lib/ethdev/ethdev_private.c
@@ -174,3 +174,77 @@ rte_eth_devargs_parse_representor_ports(char *str, void *data)
RTE_LOG(ERR, EAL, "wrong representor format: %s\n", str);
return str == NULL ? -1 : 0;
}
+
+static uint16_t
+dummy_eth_rx_burst(__rte_unused uint16_t port_id,
+ __rte_unused uint16_t queue_id,
+ __rte_unused struct rte_mbuf **rx_pkts,
+ __rte_unused uint16_t nb_pkts)
+{
+ RTE_LOG(ERR, EAL, "rx_pkt_burst for unconfigured port %u\n", port_id);
+ rte_errno = ENOTSUP;
+ return 0;
+}
+
+static uint16_t
+dummy_eth_tx_burst(__rte_unused uint16_t port_id,
+ __rte_unused uint16_t queue_id,
+ __rte_unused struct rte_mbuf **tx_pkts,
+ __rte_unused uint16_t nb_pkts)
+{
+ RTE_LOG(ERR, EAL, "tx_pkt_burst for unconfigured port %u\n", port_id);
+ rte_errno = ENOTSUP;
+ return 0;
+}
+
+static uint16_t
+dummy_eth_tx_prepare(__rte_unused uint16_t port_id,
+ __rte_unused uint16_t queue_id,
+ __rte_unused struct rte_mbuf **tx_pkts,
+ __rte_unused uint16_t nb_pkts)
+{
+ RTE_LOG(ERR, EAL, "tx_pkt_prepare for unconfigured port %u\n", port_id);
+ rte_errno = ENOTSUP;
+ return 0;
+}
+
+static int
+dummy_eth_rx_queue_count(__rte_unused uint16_t port_id,
+ __rte_unused uint16_t queue_id)
+{
+ RTE_LOG(ERR, EAL, "rx_queue_count for unconfigured port %u\n", port_id);
+ return -ENOTSUP;
+}
+
+static int
+dummy_eth_rx_descriptor_status(__rte_unused uint16_t port_id,
+ __rte_unused uint16_t queue_id, __rte_unused uint16_t offset)
+{
+ RTE_LOG(ERR, EAL, "rx_descriptor_status for unconfigured port %u\n",
+ port_id);
+ return -ENOTSUP;
+}
+
+static int
+dummy_eth_tx_descriptor_status(__rte_unused uint16_t port_id,
+ __rte_unused uint16_t queue_id, __rte_unused uint16_t offset)
+{
+ RTE_LOG(ERR, EAL, "tx_descriptor_status for unconfigured port %u\n",
+ port_id);
+ return -ENOTSUP;
+}
+
+void
+rte_eth_dev_burst_api_reset(struct rte_eth_burst_api *rba)
+{
+ static const struct rte_eth_burst_api dummy = {
+ .rx_pkt_burst = dummy_eth_rx_burst,
+ .tx_pkt_burst = dummy_eth_tx_burst,
+ .tx_pkt_prepare = dummy_eth_tx_prepare,
+ .rx_queue_count = dummy_eth_rx_queue_count,
+ .rx_descriptor_status = dummy_eth_rx_descriptor_status,
+ .tx_descriptor_status = dummy_eth_tx_descriptor_status,
+ };
+
+ *rba = dummy;
+}
diff --git a/lib/ethdev/ethdev_private.h b/lib/ethdev/ethdev_private.h
index 9bb0879538..b9b0e6755a 100644
--- a/lib/ethdev/ethdev_private.h
+++ b/lib/ethdev/ethdev_private.h
@@ -30,6 +30,9 @@ eth_find_device(const struct rte_eth_dev *_start, rte_eth_cmp_t cmp,
/* Parse devargs value for representor parameter. */
int rte_eth_devargs_parse_representor_ports(char *str, void *data);
+/* reset eth 'burst' API to dummy values */
+void rte_eth_dev_burst_api_reset(struct rte_eth_burst_api *rba);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 9d95cd11e1..949292a617 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -44,6 +44,9 @@
static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
+/* public 'fast/burst' API */
+struct rte_eth_burst_api rte_eth_burst_api[RTE_MAX_ETHPORTS];
+
/* spinlock for eth device callbacks */
static rte_spinlock_t eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
@@ -1336,6 +1339,7 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
int diag;
int ret;
uint16_t old_mtu;
+ struct rte_eth_burst_api rba;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
@@ -1363,6 +1367,9 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
*/
dev->data->dev_configured = 0;
+ rba = rte_eth_burst_api[port_id];
+ rte_eth_dev_burst_api_reset(&rte_eth_burst_api[port_id]);
+
/* Store original config, as rollback required on failure */
memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
@@ -1623,6 +1630,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
if (old_mtu != dev->data->mtu)
dev->data->mtu = old_mtu;
+ rte_eth_burst_api[port_id] = rba;
+
rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret);
return ret;
}
@@ -1871,6 +1880,7 @@ rte_eth_dev_close(uint16_t port_id)
dev = &rte_eth_devices[port_id];
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
+ rte_eth_dev_burst_api_reset(rte_eth_burst_api + port_id);
*lasterr = (*dev->dev_ops->dev_close)(dev);
if (*lasterr != 0)
lasterr = &binerr;
@@ -1892,6 +1902,8 @@ rte_eth_dev_reset(uint16_t port_id)
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);
+ rte_eth_dev_burst_api_reset(rte_eth_burst_api + port_id);
+
ret = rte_eth_dev_stop(port_id);
if (ret != 0) {
RTE_ETHDEV_LOG(ERR,
diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
index edf96de2dc..fb8526cb9f 100644
--- a/lib/ethdev/rte_ethdev_core.h
+++ b/lib/ethdev/rte_ethdev_core.h
@@ -25,21 +25,31 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
struct rte_eth_dev;
+typedef uint16_t (*rte_eth_rx_burst_t)(uint16_t port_id, uint16_t queue_id,
+ struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
+
typedef uint16_t (*eth_rx_burst_t)(void *rxq,
struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
/**< @internal Retrieve input packets from a receive queue of an Ethernet device. */
+typedef uint16_t (*rte_eth_tx_burst_t)(uint16_t port_id, uint16_t queue_id,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+
typedef uint16_t (*eth_tx_burst_t)(void *txq,
struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
/**< @internal Send output packets on a transmit queue of an Ethernet device. */
+typedef uint16_t (*rte_eth_tx_prep_t)(uint16_t port_id, uint16_t queue_id,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+
typedef uint16_t (*eth_tx_prep_t)(void *txq,
struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
/**< @internal Prepare output packets on a transmit queue of an Ethernet device. */
+typedef int (*rte_eth_rx_queue_count_t)(uint16_t port_id, uint16_t queue_id);
typedef uint32_t (*eth_rx_queue_count_t)(struct rte_eth_dev *dev,
uint16_t rx_queue_id);
@@ -48,12 +58,35 @@ typedef uint32_t (*eth_rx_queue_count_t)(struct rte_eth_dev *dev,
typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset);
/**< @internal Check DD bit of specific RX descriptor */
+typedef int (*rte_eth_rx_descriptor_status_t)(uint16_t port_id,
+ uint16_t queue_id, uint16_t offset);
+
typedef int (*eth_rx_descriptor_status_t)(void *rxq, uint16_t offset);
/**< @internal Check the status of a Rx descriptor */
+typedef int (*rte_eth_tx_descriptor_status_t)(uint16_t port_id,
+ uint16_t queue_id, uint16_t offset);
+
typedef int (*eth_tx_descriptor_status_t)(void *txq, uint16_t offset);
/**< @internal Check the status of a Tx descriptor */
+struct rte_eth_burst_api {
+ rte_eth_rx_burst_t rx_pkt_burst;
+ /**< PMD receive function. */
+ rte_eth_tx_burst_t tx_pkt_burst;
+ /**< PMD transmit function. */
+ rte_eth_tx_prep_t tx_pkt_prepare;
+ /**< PMD transmit prepare function. */
+ rte_eth_rx_queue_count_t rx_queue_count;
+ /**< Get the number of used RX descriptors. */
+ rte_eth_rx_descriptor_status_t rx_descriptor_status;
+ /**< Check the status of a Rx descriptor. */
+ rte_eth_tx_descriptor_status_t tx_descriptor_status;
+ /**< Check the status of a Tx descriptor. */
+ uintptr_t reserved[2];
+} __rte_cache_min_aligned;
+
+extern struct rte_eth_burst_api rte_eth_burst_api[RTE_MAX_ETHPORTS];
/**
* @internal
--
2.26.3
More information about the dev
mailing list