[dpdk-dev] [RFC PATCHv2 1/2] Add example pktdev implementation

Bruce Richardson bruce.richardson at intel.com
Mon May 11 18:29:40 CEST 2015


This commit demonstrates what a minimal API for all packet handling
might look like. It provides common APIs for RX and TX, by wrapping
the types as appropriate. Implementations provided for ring, ethdev and
kni.

Signed-off-by: Bruce Richardson <bruce.richardson at intel.com>
---
 config/common_bsdapp           |   5 ++
 config/common_linuxapp         |   5 ++
 lib/Makefile                   |   1 +
 lib/librte_pktdev/Makefile     |  53 +++++++++++
 lib/librte_pktdev/rte_pktdev.h | 200 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 264 insertions(+)
 create mode 100644 lib/librte_pktdev/Makefile
 create mode 100644 lib/librte_pktdev/rte_pktdev.h

diff --git a/config/common_bsdapp b/config/common_bsdapp
index c2374c0..64fcdc8 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -132,6 +132,11 @@ CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 CONFIG_RTE_LIBRTE_KVARGS=y
 
 #
+# Compile generic packet handling device library
+#
+CONFIG_RTE_LIBRTE_PKTDEV=y
+
+#
 # Compile generic ethernet library
 #
 CONFIG_RTE_LIBRTE_ETHER=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 0078dc9..399f15d 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -129,6 +129,11 @@ CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 CONFIG_RTE_LIBRTE_KVARGS=y
 
 #
+# Compile generic packet handling device library
+#
+CONFIG_RTE_LIBRTE_PKTDEV=y
+
+#
 # Compile generic ethernet library
 #
 CONFIG_RTE_LIBRTE_ETHER=y
diff --git a/lib/Makefile b/lib/Makefile
index d94355d..4db5ee0 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -32,6 +32,7 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
+DIRS-$(CONFIG_RTE_LIBRTE_PKTDEV) += librte_pktdev
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MALLOC) += librte_malloc
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
diff --git a/lib/librte_pktdev/Makefile b/lib/librte_pktdev/Makefile
new file mode 100644
index 0000000..858d3e3
--- /dev/null
+++ b/lib/librte_pktdev/Makefile
@@ -0,0 +1,53 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2015 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = libpktdev.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_pktdev_version.map
+
+LIBABIVER := 1
+
+#
+# Export include files
+#
+SYMLINK-y-include += rte_pktdev.h
+
+DEPDIRS-y += lib/librte_ring lib/librte_kni lib/librte_ether
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pktdev/rte_pktdev.h b/lib/librte_pktdev/rte_pktdev.h
new file mode 100644
index 0000000..eba7989
--- /dev/null
+++ b/lib/librte_pktdev/rte_pktdev.h
@@ -0,0 +1,200 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PKTDEV_H_
+#define _RTE_PKTDEV_H_
+
+#include <stdint.h>
+
+/**
+ * @file
+ *
+ * RTE Packet Processing Device API
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_malloc.h>
+
+#include <rte_ring.h>
+#include <rte_ethdev.h>
+#include <rte_kni.h>
+
+/* forward definition of mbuf structure. We don't need full mbuf header here */
+struct rte_mbuf;
+
+typedef uint16_t (*pkt_rx_burst_t)(void *rx_handle,
+		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
+/**< @internal Retrieve packets from a queue of a device. */
+
+typedef uint16_t (*pkt_tx_burst_t)(void *tx_handle,
+		struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+/**< @internal Send packets on a queue of a device. */
+
+enum rte_pkt_dev_type {
+	RTE_PKT_DEV_TYPE_NONE = 0,
+	RTE_PKT_DEV_TYPE_ETHDEV,
+	RTE_PKT_DEV_TYPE_RING,
+	RTE_PKT_DEV_TYPE_KNI,
+
+	RTE_PKT_DEV_TYPE_MAX
+};
+
+struct rte_pkt_dev {
+	enum rte_pkt_dev_type type;
+	pkt_rx_burst_t rx_pkt_burst; /**< Pointer to receive function. */
+	pkt_tx_burst_t tx_pkt_burst; /**< Pointer to transmit function. */
+	void *rx_handle;
+	void *tx_handle;
+};
+
+/**
+ *
+ * Retrieve a burst of input packets from a receive queue of a
+ * device. The retrieved packets are stored in *rte_mbuf* structures whose
+ * pointers are supplied in the *rx_pkts* array.
+ *
+ * @param dev
+ *   The device to be polled for packets
+ * @param queue_id
+ *   The index of the receive queue from which to retrieve input packets.
+ * @param rx_pkts
+ *   The address of an array of pointers to *rte_mbuf* structures that
+ *   must be large enough to store *nb_pkts* pointers in it.
+ * @param nb_pkts
+ *   The maximum number of packets to retrieve.
+ * @return
+ *   The number of packets actually retrieved, which is the number
+ *   of pointers to *rte_mbuf* structures effectively supplied to the
+ *   *rx_pkts* array.
+ */
+static inline uint16_t
+rte_pkt_rx_burst(struct rte_pkt_dev *dev, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts)
+{
+	/* special case ring, so that call gets inlined for performance */
+	if (dev->type == RTE_PKT_DEV_TYPE_RING)
+		return rte_ring_dequeue_burst(dev->rx_handle, (void *)rx_pkts,
+				nb_pkts);
+	return (*dev->rx_pkt_burst)(dev->rx_handle, rx_pkts, nb_pkts);
+}
+
+/**
+ * Send a burst of output packets on a transmit queue of a device.
+ *
+ * @param dev
+ *   The device to be given the packets.
+ * @param queue_id
+ *   The index of the queue through which output packets must be sent.
+ * @param tx_pkts
+ *   The address of an array of *nb_pkts* pointers to *rte_mbuf* structures
+ *   which contain the output packets.
+ * @param nb_pkts
+ *   The maximum number of packets to transmit.
+ * @return
+ *   The number of output packets actually stored in transmit descriptors of
+ *   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
+rte_pkt_tx_burst(struct rte_pkt_dev *dev, struct rte_mbuf **tx_pkts,
+		uint16_t nb_pkts)
+{
+	/* special case ring, so that call gets inlined for performance */
+	if (dev->type == RTE_PKT_DEV_TYPE_RING)
+		return rte_ring_enqueue_burst(dev->tx_handle, (void *)tx_pkts,
+				nb_pkts);
+	return (*dev->tx_pkt_burst)(dev->tx_handle, tx_pkts, nb_pkts);
+}
+
+static inline struct rte_pkt_dev *
+rte_pkt_dev_from_ring(struct rte_ring *r)
+{
+	struct rte_pkt_dev *d = rte_zmalloc(NULL, sizeof(*d), 0);
+	if (d == NULL)
+		return d;
+
+	d->type = RTE_PKT_DEV_TYPE_RING;
+	d->rx_pkt_burst = (pkt_rx_burst_t)rte_ring_dequeue_burst;
+	d->tx_pkt_burst = (pkt_rx_burst_t)rte_ring_enqueue_burst;
+	d->rx_handle = r;
+	d->tx_handle = r;
+
+	return d;
+}
+
+static inline struct rte_pkt_dev *
+rte_pkt_dev_from_kni(struct rte_kni *k)
+{
+	struct rte_pkt_dev *d = rte_zmalloc(NULL, sizeof(*d), 0);
+	if (d == NULL)
+		return d;
+
+	d->type = RTE_PKT_DEV_TYPE_KNI;
+	d->rx_pkt_burst = (pkt_rx_burst_t)rte_kni_rx_burst;
+	d->tx_pkt_burst = (pkt_rx_burst_t)rte_kni_tx_burst;
+	d->rx_handle = k;
+	d->tx_handle = k;
+
+	return d;
+}
+
+static inline struct rte_pkt_dev *
+rte_pkt_dev_from_ethdev(struct rte_eth_dev *e, uint16_t rxq, uint16_t txq)
+{
+	struct rte_pkt_dev *d = rte_zmalloc(NULL, sizeof(*d), 0);
+	if (d == NULL)
+		return d;
+
+	d->type = RTE_PKT_DEV_TYPE_ETHDEV;
+	d->rx_pkt_burst = e->rx_pkt_burst;
+	d->tx_pkt_burst = e->tx_pkt_burst;
+	d->rx_handle = e->data->rx_queues[rxq];
+	d->tx_handle = e->data->tx_queues[txq];
+
+	return d;
+}
+
+static inline struct rte_pkt_dev *
+rte_pkt_dev_from_ethport(uint8_t port_id, uint16_t rxq, uint16_t txq)
+{
+	return rte_pkt_dev_from_ethdev(&rte_eth_devices[port_id], rxq, txq);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PKTDEV_H_ */
-- 
2.1.0



More information about the dev mailing list