From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [RFC-PATCH-v3 5/6] pktdev: adding app test
Date: Wed, 10 Jun 2015 14:07:20 +0100 [thread overview]
Message-ID: <1433941641-19405-6-git-send-email-bruce.richardson@intel.com> (raw)
In-Reply-To: <1433941641-19405-1-git-send-email-bruce.richardson@intel.com>
From: Marc Sune <marc.sune@bisdn.de>
Add a basic test for pktdev non-buffered API for pktdev types:
* ethdev
* ring
* kni
Signed-off-by: Marc Sune <marc.sune@bisdn.de>
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
app/test/Makefile | 4 +
app/test/test_pktdev.c | 440 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 444 insertions(+)
create mode 100644 app/test/test_pktdev.c
diff --git a/app/test/Makefile b/app/test/Makefile
index 3c777bf..77e48c1 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -58,6 +58,10 @@ SRCS-y += test_ring.c
SRCS-y += test_ring_perf.c
SRCS-y += test_pmd_perf.c
+ifeq ($(CONFIG_RTE_LIBRTE_PKTDEV),y)
+SRCS-y += test_pktdev.c
+endif
+
ifeq ($(CONFIG_RTE_LIBRTE_TABLE),y)
SRCS-y += test_table.c
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test_table_pipeline.c
diff --git a/app/test/test_pktdev.c b/app/test/test_pktdev.c
new file mode 100644
index 0000000..e24fd78
--- /dev/null
+++ b/app/test/test_pktdev.c
@@ -0,0 +1,440 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2014 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 <stdio.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <unistd.h>
+#include <rte_cycles.h>
+#include <rte_errno.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_kni.h>
+#include <rte_byteorder.h>
+#include <rte_atomic.h>
+#include <rte_malloc.h>
+#include <rte_pktdev.h>
+
+#include "packet_burst_generator.h"
+#include "test.h"
+
+/* General test constants */
+#define MAX_PKTDEVS 4
+#define NB_MBUF 8192
+#define SOCKET 0
+#define MAX_PACKET_SZ 2048
+#define MBUF_DATA_SZ (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
+#define PKT_BURST_SZ 32
+#define MEMPOOL_CACHE_SZ PKT_BURST_SZ
+#define RING_SIZE 128
+
+#define RING_NAME "test-pktdev"
+#define KNI_NAME "kni-pktdev"
+#define MEMPOOL_NAME "pkdev-mempool"
+
+/* Shared mempool */
+struct rte_mempool* mp;
+
+/* We use port_id 0 */
+static uint8_t port_id = 0;
+
+/* Device specific contexts*/
+static struct rte_ring* r = NULL;
+#ifdef RTE_LIBRTE_KNI
+static struct rte_kni* kni = NULL;
+#endif
+
+/* pktdev handles */
+static struct rte_pktdev* ring_dev = NULL;
+#ifdef RTE_LIBRTE_KNI
+static struct rte_pktdev* kni_dev = NULL;
+#endif
+static struct rte_pktdev* eth_dev = NULL;
+
+static int
+setup_mempool(void)
+{
+ mp = rte_mempool_lookup(MEMPOOL_NAME);
+ if (!mp)
+ mp = rte_pktmbuf_pool_create(MEMPOOL_NAME,
+ NB_MBUF,
+ MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ,
+ SOCKET);
+
+ if (!mp){
+ printf( "Could not create mempool!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+setup_ring(void)
+{
+ r = rte_ring_lookup(RING_NAME);
+
+ if (r == NULL)
+ r = rte_ring_create(RING_NAME, RING_SIZE, SOCKET_ID_ANY, 0);
+
+ if (r == NULL) {
+ printf( "ERROR: unable to create rte_ring '" RING_NAME "' required for the pktdev device!\n");
+ return -1;
+ }
+
+ /* Check NULL ring */
+ if (rte_pktdev_from_ring(NULL) != NULL) {
+ printf( "ERROR: invalid behaviour of rte_pktdev_from_ring() for NULL rings!\n");
+ return -1;
+ }
+
+ /* Create the pktdev device */
+ ring_dev = rte_pktdev_from_ring(r);
+
+ if (ring_dev == NULL) {
+ printf( "ERROR: could not create pktdev from rte_ring '" RING_NAME "'!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef RTE_LIBRTE_KNI
+static int
+setup_kni(void)
+{
+ struct rte_kni_conf conf;
+ struct rte_kni_ops ops;
+
+ memset(&conf, 0, sizeof(conf));
+ memset(&ops, 0, sizeof(ops));
+ sprintf(conf.name,"%s", KNI_NAME);
+ conf.mbuf_size = MAX_PACKET_SZ;
+
+ /* Initialize KNI subsystem */
+ rte_kni_init(1);
+
+ /* Allocate KNI interface */
+ kni = rte_kni_get(KNI_NAME);
+
+ if (kni == NULL)
+ kni = rte_kni_alloc(mp, &conf, &ops);
+
+ if (kni == NULL) {
+ printf( "ERROR: could not allocate KNI interface '" KNI_NAME "'!\n");
+ return -1;
+ }
+
+ /* Check NULL CTX */
+ if (rte_pktdev_from_kni(NULL) != NULL) {
+ printf( "ERROR: invalid behaviour of rte_pktdev_from_kni() for NULL KNI context!\n");
+ return -1;
+ }
+
+ kni_dev = rte_pktdev_from_kni(kni);
+
+ if (kni_dev == NULL) {
+ printf( "ERROR: could not create pktdev from KNI interface '" KNI_NAME "'\n");
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* RTE_LIBRTE_KNI */
+
+
+static struct rte_eth_conf port_conf = {
+ .rxmode = {
+ .mq_mode = ETH_MQ_RX_NONE,
+ .max_rx_pkt_len = MAX_PACKET_SZ,
+ .split_hdr_size = 0,
+ .header_split = 0, /**< Header Split disabled */
+ .hw_ip_checksum = 0, /**< IP checksum offload enabled */
+ .hw_vlan_filter = 0, /**< VLAN filtering disabled */
+ .hw_vlan_strip = 0, /**< VLAN strip enabled. */
+ .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
+ .jumbo_frame = 0, /**< Jumbo Frame Support disabled */
+ .hw_strip_crc = 0, /**< CRC stripped by hardware */
+ .enable_scatter = 0, /**< scatter rx disabled */
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+ .lpbk_mode = 1, /* enable loopback */
+};
+
+static int
+setup_ethdev(void)
+{
+ uint16_t nb_rx_queue = 1, nb_tx_queue = 1;
+ int ret;
+
+ if (rte_eth_dev_count() == 0 ) {
+ printf( "ERROR: pktdev test requires at least one ethdev!\n");
+ return -1;
+ }
+
+ /* Check NULL CTX */
+ if (rte_pktdev_from_ethport(255, 0, 0) != NULL) {
+ printf( "ERROR: invalid behaviour of rte_pktdev_from_ethport() for invalid port id!\n");
+ return -1;
+ }
+
+ /* port configure */
+ ret = rte_eth_dev_configure(port_id, nb_rx_queue, nb_tx_queue,
+ &port_conf);
+ if (ret < 0) {
+ printf( "ERROR: unable to configure port 0 '%s'.\n",
+ rte_strerror(ret));
+ return -1;
+ }
+
+ /* tx queue setup */
+ ret = rte_eth_tx_queue_setup(port_id, 0, PKT_BURST_SZ, 0, NULL);
+ if (ret < 0) {
+ printf( "ERROR: unable to setup TX queue '%s'.\n",
+ rte_strerror(ret));
+ return -1;
+ }
+
+ /* rx queue steup */
+ ret = rte_eth_rx_queue_setup(port_id, 0, PKT_BURST_SZ, 0, NULL, mp);
+ if (ret < 0) {
+ printf( "ERROR: unable to setup RX queue '%s'.\n",
+ rte_strerror(ret));
+ return -1;
+ }
+
+ /* Start device */
+ ret = rte_eth_dev_start(port_id);
+ if (ret < 0) {
+ printf( "ERROR: unable to start eth_dev '%s'.\n",
+ rte_strerror(ret));
+ return -1;
+ }
+
+ /* Enable promiscuous */
+ rte_eth_promiscuous_enable(port_id);
+
+ /* Create eth_dev */
+ eth_dev = rte_pktdev_from_ethport(0, 0, 0);
+ if (eth_dev == NULL) {
+ printf( "ERROR: could not create pktdev from ethdev'\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+stop_ethdev(void)
+{
+ rte_eth_dev_stop(port_id);
+}
+
+/* I/O loop stop flag */
+static bool keep_running = true;
+
+/* Intialize as an ARP pkt */
+static void
+init_pkt(struct rte_mbuf *mbuf)
+{
+ struct ether_hdr *eth;
+
+ /* Set length */
+ rte_pktmbuf_reset(mbuf);
+ rte_ctrlmbuf_len(mbuf) = ETHER_MIN_LEN;
+ eth = (struct ether_hdr*)rte_ctrlmbuf_data(mbuf);
+
+ /* Set mac addresses & ethtype */
+ memset(eth, 0, sizeof(*eth));
+ eth->d_addr.addr_bytes[0] = 0x2;
+ eth->d_addr.addr_bytes[0] = 0x1;
+ eth->ether_type = ETHER_TYPE_ARP;
+}
+
+/*
+ * Injects a pkt through the rte_ring pkt dev, and the packet
+ * has to travel back and forth through the chain (eth_dev in loopback)
+ */
+static int
+io_loop(void* not_used)
+{
+ (void)not_used;
+ unsigned int len;
+ struct rte_mbuf *burst[PKT_BURST_SZ];
+ struct rte_mbuf *mbuf = NULL;
+
+ /* Get an mbuf */
+ rte_mempool_get(mp, (void**)&mbuf);
+ if (mbuf == NULL) {
+ printf("Unable to allocate an mbuf\n");
+ return -1;
+ }
+
+ /* Prepare packet */
+ init_pkt(mbuf);
+
+ /* Test ring dev */
+ printf("Testing ring pktdev...\n");
+ burst[0] = mbuf;
+ len = rte_pkt_tx_burst(ring_dev, burst, 1);
+
+ if (len != 1) {
+ printf("TX through ring pktdev failed (len:%u)\n", len);
+ return -1;
+ }
+ if (ring_dev->tx_count != 1) {
+ printf("TX through ring pktdev stats check failed (len:%u)\n", len);
+ return -1;
+ }
+
+ len = rte_pkt_rx_burst(ring_dev, burst, PKT_BURST_SZ);
+ if (len != 1) {
+ printf("RX through ring pktdev failed (len:%u), ring count: %u\n",
+ len,
+ rte_ring_count(r));
+ return -1;
+ }
+ if (ring_dev->rx_count != 1) {
+ printf("TX through ring pktdev stats check failed (len:%u)\n", len);
+ return -1;
+ }
+
+
+
+#ifdef RTE_LIBRTE_KNI
+ /* Test KNI dev. TODO: check stats and RX */
+ printf("Testing KNI pktdev...\n");
+ rte_mempool_get(mp, (void**)&mbuf);
+ if (mbuf == NULL) {
+ printf("Unable to allocate an mbuf (len:%u)\n", len);
+ return -1;
+ }
+
+ init_pkt(mbuf);
+ burst[0] = mbuf;
+
+ len = rte_pkt_tx_burst(kni_dev, burst, 1);
+ if (len != 1) {
+ printf("TX through kni pktdev failed (len:%u)\n", len);
+ return -1;
+ }
+ if (kni_dev->tx_count != 1) {
+ printf("TX through KNI pktdev stats check failed (len:%u)\n", len);
+ return -1;
+ }
+#endif /* RTE_LIBRTE_KNI */
+
+ /* Test eth dev. TODO: check RX */
+ printf("Testing ethdev pktdev...\n");
+ rte_mempool_get(mp, (void**)&mbuf);
+ if (mbuf == NULL) {
+ printf("Unable to allocate an mbuf (len:%u)\n", len);
+ return -1;
+ }
+
+ init_pkt(mbuf);
+ burst[0] = mbuf;
+
+ len = rte_pkt_tx_burst(eth_dev, burst, 1);
+ if (len != 1) {
+ printf("TX through eth pktdev failed\n");
+ return -1;
+ }
+ if (eth_dev->tx_count != 1) {
+ printf("TX through eth pktdev stats check failed (len:%u)\n", len);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+test_pktdev(void)
+{
+ unsigned int lcore_id;
+
+ /* Get lcore id */
+ for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+ if (lcore_id == rte_get_master_lcore())
+ continue;
+ if ( rte_lcore_is_enabled(lcore_id) == 1)
+ break;
+ }
+
+ if (lcore_id == RTE_MAX_LCORE) {
+ printf("No available lcores to run I/O loop. This test requires at least 2 lcores\n");
+ return -1;
+ }
+
+ printf("Initializing devices...\n");
+
+ if(setup_mempool() < 0)
+ return -1;
+ if(setup_ring() < 0)
+ return -1;
+#ifdef RTE_LIBRTE_KNI
+ if(setup_kni() < 0)
+ return -1;
+#endif /* RTE_LIBRTE_KNI */
+
+ if(setup_ethdev() < 0)
+ return -1;
+
+ printf("Launching I/O core and testing devs...\n");
+ rte_eal_remote_launch(io_loop, NULL, lcore_id);
+
+ /* Wait */
+ sleep(1);
+
+ /* Stop lcore */
+ keep_running = false;
+ rte_eal_wait_lcore(lcore_id);
+
+ printf("Cleaning the house...\n");
+
+ stop_ethdev();
+
+ return 0;
+}
+
+
+static struct test_command pktdev_cmd = {
+ .command = "pktdev_autotest",
+ .callback = test_pktdev,
+};
+
+REGISTER_TEST_COMMAND(pktdev_cmd);
--
2.4.2
next prev parent reply other threads:[~2015-06-10 13:07 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-11 16:29 [dpdk-dev] [RFC PATCHv2 0/2] pktdev as wrapper type Bruce Richardson
2015-05-11 16:29 ` [dpdk-dev] [RFC PATCHv2 1/2] Add example pktdev implementation Bruce Richardson
2015-05-11 16:29 ` [dpdk-dev] [RFC PATCHv2 2/2] example app showing pktdevs used in a chain Bruce Richardson
2015-05-19 11:31 ` [dpdk-dev] [RFC PATCHv2 0/2] pktdev as wrapper type Bruce Richardson
2015-05-20 0:19 ` Wiles, Keith
2015-05-20 8:31 ` Thomas Monjalon
2015-05-20 10:05 ` Marc Sune
2015-05-20 10:28 ` Neil Horman
2015-05-20 17:01 ` Marc Sune
2015-05-20 18:47 ` Neil Horman
2015-05-21 12:12 ` Richardson, Bruce
2015-06-10 13:07 ` [dpdk-dev] [RFC-PATCH-v3 0/6] pktdev update Bruce Richardson
2015-06-10 13:07 ` [dpdk-dev] [RFC-PATCH-v3 1/6] kni: add function to query the name of a kni object Bruce Richardson
2015-06-10 13:07 ` [dpdk-dev] [RFC-PATCH-v3 2/6] pktdev: Add pktdev implementation library Bruce Richardson
2015-06-10 13:07 ` [dpdk-dev] [RFC-PATCH-v3 3/6] example app showing pktdevs used in a chain Bruce Richardson
2015-06-10 13:07 ` [dpdk-dev] [RFC-PATCH-v3 4/6] new pktdev l2fwd sample Bruce Richardson
2015-06-10 13:07 ` Bruce Richardson [this message]
2015-06-10 13:07 ` [dpdk-dev] [RFC-PATCH-v3 6/6] test: add pktdev performance tests Bruce Richardson
2015-06-10 13:26 ` [dpdk-dev] [RFC-PATCH-v3 0/6] pktdev update Thomas Monjalon
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=1433941641-19405-6-git-send-email-bruce.richardson@intel.com \
--to=bruce.richardson@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).