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 201A15AA0 for ; Wed, 10 Jun 2015 15:07:28 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) 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="708567597" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.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 t5AD7Phh010140; 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 t5AD7Pf4019504; Wed, 10 Jun 2015 14:07:25 +0100 Received: (from bricha3@localhost) by sivswdev01.ir.intel.com with id t5AD7Psg019497; Wed, 10 Jun 2015 14:07:25 +0100 From: Bruce Richardson To: dev@dpdk.org Date: Wed, 10 Jun 2015 14:07:20 +0100 Message-Id: <1433941641-19405-6-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 5/6] pktdev: adding app test 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:30 -0000 From: Marc Sune Add a basic test for pktdev non-buffered API for pktdev types: * ethdev * ring * kni Signed-off-by: Marc Sune Signed-off-by: Bruce Richardson --- 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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