From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 6769B5A9D for ; Wed, 10 Jun 2015 15:07:30 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 10 Jun 2015 06:07:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,587,1427785200"; d="scan'208";a="740801162" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 10 Jun 2015 06:07:26 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t5AD7PkJ010127; Wed, 10 Jun 2015 14:07:25 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id t5AD7P1C019475; Wed, 10 Jun 2015 14:07:25 +0100 Received: (from bricha3@localhost) by sivswdev01.ir.intel.com with id t5AD7PgI019471; Wed, 10 Jun 2015 14:07:25 +0100 From: Bruce Richardson To: dev@dpdk.org Date: Wed, 10 Jun 2015 14:07:17 +0100 Message-Id: <1433941641-19405-3-git-send-email-bruce.richardson@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1433941641-19405-1-git-send-email-bruce.richardson@intel.com> References: <20150519113112.GA10700@bricha3-MOBL3> <1433941641-19405-1-git-send-email-bruce.richardson@intel.com> Subject: [dpdk-dev] [RFC-PATCH-v3 2/6] pktdev: Add pktdev implementation library X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2015 13:07:31 -0000 The pktdev API is a minimal API designed for runtime packet processing use. It works by providing a common API for RX and TX across a range of device and object types: namely SW rings, ethernet ports and KNI ports. By using the pktdev abstraction, packet data-path code can be written to accept packets from a source and pass them to a destination without having to be concerned about what the underlying types of those sources and destinations are. Pktdev does not provide any specific APIs for manipulating the underlying packet sources - that should be handled by the application initialization, or control code, not the data path code which uses the pktdev abstraction. Signed-off-by: Marc Sune Signed-off-by: Bruce Richardson --- config/common_bsdapp | 5 + config/common_linuxapp | 5 + lib/Makefile | 1 + lib/librte_pktdev/Makefile | 56 +++++ lib/librte_pktdev/rte_pktdev.c | 188 +++++++++++++++ lib/librte_pktdev/rte_pktdev.h | 400 +++++++++++++++++++++++++++++++ lib/librte_pktdev/rte_pktdev_version.map | 11 + mk/rte.app.mk | 1 + 8 files changed, 667 insertions(+) create mode 100644 lib/librte_pktdev/Makefile create mode 100644 lib/librte_pktdev/rte_pktdev.c create mode 100644 lib/librte_pktdev/rte_pktdev.h create mode 100644 lib/librte_pktdev/rte_pktdev_version.map diff --git a/config/common_bsdapp b/config/common_bsdapp index 0b169c8..ad073f2 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 5deb55a..ffffb58 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 5f480f9..c7980d4 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..e7c681c --- /dev/null +++ b/lib/librte_pktdev/Makefile @@ -0,0 +1,56 @@ +# 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 = librte_pktdev.a + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +EXPORT_MAP := rte_pktdev_version.map + +LIBABIVER := 1 + +# all source are stored in SRCS-y +SRCS-y := rte_pktdev.c + +# +# 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.c b/lib/librte_pktdev/rte_pktdev.c new file mode 100644 index 0000000..6e0c979 --- /dev/null +++ b/lib/librte_pktdev/rte_pktdev.c @@ -0,0 +1,188 @@ +/*- + * 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 +#include +#include +#include +#include +#include "rte_pktdev.h" + +struct rte_pktdev * +rte_pktdev_from_ring(struct rte_ring *r) +{ + struct rte_pktdev *d; + + if (r == NULL) + return NULL; + + d = rte_zmalloc(NULL, sizeof(*d), 0); + if (d == NULL) { + rte_errno = ENOMEM; + return d; + } + + d->type = RTE_PKT_DEV_TYPE_RING; + d->base_object = r; + 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; +} + +struct rte_pktdev * +rte_pktdev_from_kni(struct rte_kni *k) +{ + struct rte_pktdev *d; + + if (k == NULL) + return NULL; + + d = rte_zmalloc(NULL, sizeof(*d), 0); + if (d == NULL) { + rte_errno = ENOMEM; + return d; + } + + d->type = RTE_PKT_DEV_TYPE_KNI; + d->base_object = k; + 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 struct rte_pktdev * +rte_pktdev_from_ethdev(struct rte_eth_dev *e, uint16_t rxq, uint16_t txq) +{ + struct rte_pktdev *d; + + if (e == NULL) + return NULL; + + d = rte_zmalloc(NULL, sizeof(*d), 0); + if (d == NULL) { + rte_errno = ENOMEM; + return d; + } + + d->type = RTE_PKT_DEV_TYPE_ETHDEV; + d->base_object = e; + 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; +} + +struct rte_pktdev * +rte_pktdev_from_ethport(uint8_t port_id, uint16_t rxq, uint16_t txq) +{ + if(port_id >= rte_eth_dev_count()) + return NULL; + + return rte_pktdev_from_ethdev(&rte_eth_devices[port_id], rxq, txq); +} + +const char * +rte_pktdev_get_name(const struct rte_pktdev *dev, char *buffer, unsigned buf_len) +{ + if (buf_len == 0) + goto out; + + switch (dev->type) { + case RTE_PKT_DEV_TYPE_ETHDEV: { + const struct rte_eth_dev *e = dev->base_object; + snprintf(buffer, buf_len, "Port_%u", e->data->port_id); + break; + } + case RTE_PKT_DEV_TYPE_RING: { + const struct rte_ring *r = dev->base_object; + snprintf(buffer, buf_len, "%s", r->name); + break; + } + case RTE_PKT_DEV_TYPE_KNI: { + const struct rte_kni *k = dev->base_object; + snprintf(buffer, buf_len, "KNI_%s", rte_kni_get_name(k)); + break; + } + /* + * explicitly list all values, so compiler can detect missing values + * in future if new values are added to the enum. [Using "default", this + * error detection won't occur.] + */ + case RTE_PKT_DEV_TYPE_NONE: + case RTE_PKT_DEV_TYPE_MAX: + buffer[0] = '\0'; /* guarantee a valid null-terminated string */ + break; + } +out: + return buffer; +} + +void +rte_pktdev_set_tx_buf_err_callback(struct rte_pktdev *dev, + pkt_burst_error_t fn, void *param) +{ + dev->tx_error = fn; + dev->tx_error_param = param; +} + +uint64_t +rte_pktdev_get_rx_count(const struct rte_pktdev *dev) +{ + return dev->rx_count; +} + +uint64_t +rte_pktdev_get_tx_count(const struct rte_pktdev *dev) +{ + return dev->tx_count; +} + +uint64_t +rte_pktdev_get_tx_buffer_count(const struct rte_pktdev *dev) +{ + return dev->tx_buf_count; +} + +uint64_t +rte_pktdev_get_tx_drop_count(const struct rte_pktdev *dev) +{ + return dev->tx_drop_count; +} diff --git a/lib/librte_pktdev/rte_pktdev.h b/lib/librte_pktdev/rte_pktdev.h new file mode 100644 index 0000000..3acbc0d --- /dev/null +++ b/lib/librte_pktdev/rte_pktdev.h @@ -0,0 +1,400 @@ +/*- + * 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_ + +/** + * @file + * + * RTE Packet Processing Device API + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* Buffered TX works in bursts of 32 */ +#define TX_BUFFER_SIZE 32 + +/* + * forward definition of data structures. + * We don't need full mbuf/kni/ethdev headers here + */ +struct rte_mbuf; +struct rte_kni; +struct rte_eth_dev; + +/* forward declaration of structure declared here. Needed for function typedef */ +struct rte_pktdev; + +/** @internal Retrieve packets from a queue of a device. */ +typedef uint16_t (*pkt_rx_burst_t)(void *rx_handle, + struct rte_mbuf **rx_pkts, uint16_t nb_pkts); + +/** @internal Send packets on a queue of a device. */ +typedef uint16_t (*pkt_tx_burst_t)(void *tx_handle, + struct rte_mbuf **tx_pkts, uint16_t nb_pkts); + +/** + * Callback that applications can configure to be called when a burst of pkts + * fail to send on TX buffer flush. + */ +typedef void (*pkt_burst_error_t)(struct rte_pktdev *dev, + struct rte_mbuf **failed_pkts, uint16_t nb_failed, void *param); + +/** + * @internal Enum listing all the underlying types that pktdev can be built upon + */ +enum rte_pktdev_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 +}; + +/** + * @internal The pktdev structure + */ +struct rte_pktdev { + /* basic functionality support - type info, rx + tx */ + enum rte_pktdev_type type; /**< The type of object being used as a pktdev */ + void *base_object; /**< The underlying ethdev/ring/KNI object*/ + 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; /**< Handle passed to RX function */ + void *tx_handle; /**< Handle passed to TX function */ + + /* support for buffered TX */ + struct rte_mbuf *tx_buf[32]; /**< Store packets to allow buffered TX */ + uint16_t tx_buf_count; /**< Tracks tx_buffer occupation */ + pkt_burst_error_t tx_error; /**< callback for err sending buffered pkts */ + void *tx_error_param; /**< extra parameter passed to err callback */ + + /* basic stats tracking, packets in/out */ + uint64_t rx_count; /**< Received packets count */ + uint64_t tx_count; /**< Packets sent successfully, excluding + * any currently buffered packets */ + uint64_t tx_drop_count; /**< Packets dropped when flushing + * the tx_buffer **/ + +} __rte_cache_aligned; + +/** + * + * 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_pktdev *dev, struct rte_mbuf **rx_pkts, + uint16_t nb_pkts) +{ + uint16_t nb_rx; + /* special case ring, so that call gets inlined for performance */ + if (dev->type == RTE_PKT_DEV_TYPE_RING) + nb_rx = rte_ring_dequeue_burst(dev->rx_handle, (void *)rx_pkts, + nb_pkts); + else + nb_rx = (*dev->rx_pkt_burst)(dev->rx_handle, rx_pkts, nb_pkts); + dev->rx_count += nb_rx; + return nb_rx; +} + +/** + * 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_pktdev *dev, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts) +{ + uint16_t nb_tx; + /* special case ring, so that call gets inlined for performance */ + if (dev->type == RTE_PKT_DEV_TYPE_RING) + nb_tx = rte_ring_enqueue_burst(dev->tx_handle, (void *)tx_pkts, + nb_pkts); + else + nb_tx = (*dev->tx_pkt_burst)(dev->tx_handle, tx_pkts, nb_pkts); + dev->tx_count += nb_tx; + return nb_tx; +} + +/** + * @internal Unconditionally flush the tx buffer + */ +static inline void +_pktdev_tx_buffer_flush(struct rte_pktdev *dev) +{ + const uint16_t burst_size = dev->tx_buf_count; + const uint16_t nb_tx = rte_pkt_tx_burst(dev, dev->tx_buf, burst_size); + dev->tx_buf_count = 0; + if (likely(nb_tx == burst_size)) + return; + + dev->tx_drop_count += (burst_size - nb_tx); + if (dev->tx_error) + dev->tx_error(dev, &dev->tx_buf[nb_tx], burst_size - nb_tx, + dev->tx_error_param); + else { + uint16_t i; + for (i = nb_tx; i < burst_size; i++) + rte_pktmbuf_free(dev->tx_buf[i]); + } +} + +/** + * Flush any buffered packets on a pktdev port + * + * Transmits any currently buffered packets on the pktdev port. Does nothing if + * no packets are buffered. If not all packets are sent, + * - the dev drop-count is updated appropriately + * - any configured error callbacks are called, with the failing packets passed + * in as parameter. + * NOTE: The callback is responsible for freeing any unsent packets to ensure + * that memory is not leaked. + * - if no callback is configured, the packets are just dropped + * + * @param dev + * The pktdev which has TX buffers to be flushed + */ +static inline void +rte_pkt_tx_buffer_flush(struct rte_pktdev *dev) +{ + if (dev->tx_buf_count != 0) + _pktdev_tx_buffer_flush(dev); +} + + +/** + * Buffer a packet for future transmission + * + * This function takes a single packet and queues it up on a pktdev instance for + * sending at some point in the future. The packet is actually sent once one of + * two conditions are encountered: + * - The number of buffered packets hits TX_BUFFER_SIZE + * - The application calls "rte_pkt_dev_tx_buffer_flush" API to force a manual + * flush. + * + * @param dev + * The device on which the packet is to be sent + * @param buf + * The packet to be sent on the device. + */ +static inline void +rte_pkt_tx_buffer(struct rte_pktdev *dev, struct rte_mbuf *buf) +{ + dev->tx_buf[dev->tx_buf_count++] = buf; + + if (dev->tx_buf_count == TX_BUFFER_SIZE) + _pktdev_tx_buffer_flush(dev); +} + +/** + * Set the callback to be called when the tx buffer flushing fails + * + * @param dev + * The pktdev device + * @param fn + * Callback function to be called when the flushing of the tx buffer does not + * send all packets. The function should be of "void" type and take as + * parameters: + * - struct rte_pktdev *dev --> the dev parameter as passed in here + * - struct rte_mbuf **failed_pkts --> the array of failed packets (only) + * - uint16_t nb_failed --> the number of failed packets in the array + * - void *param --> user supplied extra parameter, as passed in here + * @param param + * The user-supplied extra parameter to be passed to the callback function + */ +void +rte_pktdev_set_tx_buf_err_callback(struct rte_pktdev *dev, + pkt_burst_error_t fn, void *param); + +/** + * Returns a printable string to use to identify a pktdev, for example, in logs. + * + * The name returned is based off the underlying object for the pktdev. For + * example, for a ring, it would be the name parameter of the ring object, for + * an ethernet port, the port number and RX/TX queue values. Example outputs: + * + * - RG_my_ring_name = a pktdev based on ring "RG_my_ring_name" + * - Port_1 = a pktdev based on port 1 + * + * @param d + * The pktdev device, for which the name is to be got + * @param buffer + * The output buffer in which the name is to be stored. + * @param buf_len + * The length of the output buffer. + * @return + * The pointer to the buffer. If buf_len > 0, the output buffer will + * always be null-terminated. + */ +const char * +rte_pktdev_get_name(const struct rte_pktdev *dev, char *buffer, unsigned buf_len); + +/** + * Returns the number of packets received by this pktdev + * + * @param dev + * The pktdev device to be queried + */ +uint64_t +rte_pktdev_get_rx_count(const struct rte_pktdev *dev); + +/** + * Returns the number of packets transmitted by this pktdev. + * + * The transmission count only includes packets actually sent, not any packets + * currently buffered for transmission + * + * @param dev + * The pktdev device to be queried + */ +uint64_t +rte_pktdev_get_tx_count(const struct rte_pktdev *dev); + +/** + * Returns the number of packets currently buffered for transmission + * + * @param dev + * The pktdev device to be queried + */ +uint64_t +rte_pktdev_get_tx_buffer_count(const struct rte_pktdev *dev); + +/** + * Returns the number of packets buffered for transmission, but for which sending + * failed. + * + * This does not count failures from calls to rte_pkt_tx_burst directly, only + * for buffered packets + * This does not count any packets currently buffered for which transmission + * has not yet been attempted. + * If a user-callback is provided for the handling of tx errors, this counter + * is updated before that callback is called, so it will always count failures + * even if the callback attempts a retransmission. + * + * @param dev + * The pktdev device to be queried + */ +uint64_t +rte_pktdev_get_tx_drop_count(const struct rte_pktdev *dev); + +/** + * Take an rte_ring and return it as a pktdev object + * + * @param r + * The rte_ring to be used. If a single-producer, single-consumer ring is used + * this parameter should be used only by a single pktdev. A multi-producer, + * multi-consumer ring can be shared between multiple pktdev instances. + * @return + * The pktdev object created. + * NULL on error, with rte_errno set appropriately: + * ENOMEM = memory allocation failed for pktdev structure + */ +struct rte_pktdev * +rte_pktdev_from_ring(struct rte_ring *r); + +/** + * Take a kni instance and return it as a pktdev object + * + * @param k + * The kni object to be used + * @return + * The pktdev object created. + * NULL on error, with rte_errno set appropriately: + * ENOMEM = memory allocation failed for pktdev structure + */ +struct rte_pktdev * +rte_pktdev_from_kni(struct rte_kni *k); + +/** + * Take an ethdev port RX and TX queue and return it as a pktdev object + * + * @param port_id + * The port number of the ethdev port to be used. + * @param rxq + * The receive queue on the ethdev port to be used for packet reception. Each + * queue should only be used by a single pktdev object, as the ethdev queues + * are not multi-thread safe. + * @param txq + * The transmit queue on the ethdev port to be used for packet transmission. Each + * queue should only be used by a single pktdev object, as the ethdev queues + * are not multi-thread safe. + * @return + * The pktdev object created + * NULL on error, with rte_errno set appropriately: + * ENOMEM = memory allocation failed for pktdev structure + */ +struct rte_pktdev * +rte_pktdev_from_ethport(uint8_t port_id, uint16_t rxq, uint16_t txq); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_PKTDEV_H_ */ diff --git a/lib/librte_pktdev/rte_pktdev_version.map b/lib/librte_pktdev/rte_pktdev_version.map new file mode 100644 index 0000000..8c8671a --- /dev/null +++ b/lib/librte_pktdev/rte_pktdev_version.map @@ -0,0 +1,11 @@ +DPDK_2.1 { + global: + + rte_pkt_rx_burst; + rte_pkt_tx_burst; + rte_pkt_dev_from_ring; + rte_pkt_dev_from_kni; + rte_pkt_dev_from_eth_port; + + local: *; +}; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 1a2043a..85d8732 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -112,6 +112,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile +_LDLIBS-$(CONFIG_RTE_LIBRTE_PKTDEV) += -lrte_pktdev _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt -- 2.4.2