> From: dev [mailto:dev-boun...@dpdk.org] On Behalf Of Harry van Haaren > Sent: Friday, March 24, 2017 4:53 PM > To: dev@dpdk.org > Cc: jerin.ja...@caviumnetworks.com; Van Haaren, Harry > <harry.van.haa...@intel.com>; Richardson, Bruce > <bruce.richard...@intel.com>; Hunt, David <david.h...@intel.com> > Subject: [dpdk-dev] [PATCH v5 14/20] test/eventdev: add SW test > infrastructure > > Add the test infrastructure, create and destroy the test instance. > > Signed-off-by: Bruce Richardson <bruce.richard...@intel.com> > Signed-off-by: David Hunt <david.h...@intel.com> > Signed-off-by: Harry van Haaren <harry.van.haa...@intel.com> > --- > test/test/Makefile | 5 +- > test/test/autotest_data.py | 26 ++++ > test/test/test_eventdev_sw.c | 358 > +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 > test/test/test_eventdev_sw.c > > diff --git a/test/test/Makefile b/test/test/Makefile index a426548..dc92d9c > 100644 > --- a/test/test/Makefile > +++ b/test/test/Makefile > @@ -197,7 +197,10 @@ SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += > test_cryptodev_blockcipher.c > SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c > SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c > > -SRCS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += test_eventdev.c > +ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y) > +SRCS-y += test_eventdev.c > +SRCS-$(CONFIG_RTE_LIBRTE_PMD_SW_EVENTDEV) += > test_eventdev_sw.c endif > > SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c > > diff --git a/test/test/autotest_data.py b/test/test/autotest_data.py index > 0cd598b..165ed6c 100644 > --- a/test/test/autotest_data.py > +++ b/test/test/autotest_data.py > @@ -346,6 +346,32 @@ def per_sockets(num): > non_parallel_test_group_list = [ > > { > + "Prefix": "eventdev", > + "Memory": "512", > + "Tests": > + [ > + { > + "Name": "Eventdev common autotest", > + "Command": "eventdev_common_autotest", > + "Func": default_autotest, > + "Report": None, > + }, > + ] > + }, > + { > + "Prefix": "eventdev_sw", > + "Memory": "512", > + "Tests": > + [ > + { > + "Name": "Eventdev sw autotest", > + "Command": "eventdev_sw_autotest", > + "Func": default_autotest, > + "Report": None, > + }, > + ] > + }, > + { > "Prefix": "kni", > "Memory": "512", > "Tests": > diff --git a/test/test/test_eventdev_sw.c b/test/test/test_eventdev_sw.c > new file mode 100644 index 0000000..808b7b3 > --- /dev/null > +++ b/test/test/test_eventdev_sw.c > @@ -0,0 +1,358 @@ > +/*- > + * BSD LICENSE > + * > + * Copyright(c) 2016-2017 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 <string.h> > +#include <stdint.h> > +#include <errno.h> > +#include <unistd.h> > +#include <sys/queue.h> > + > +#include <rte_memory.h> > +#include <rte_memzone.h> > +#include <rte_launch.h> > +#include <rte_eal.h> > +#include <rte_per_lcore.h> > +#include <rte_lcore.h> > +#include <rte_debug.h> > +#include <rte_ethdev.h> > +#include <rte_cycles.h> > + > +#include <rte_eventdev.h> > +#include "test.h" > + > +#define MAX_PORTS 16 > +#define MAX_QIDS 16 > +#define NUM_PACKETS (1<<18) > + > +static int evdev; > + > +struct test { > + struct rte_mempool *mbuf_pool; > + uint8_t port[MAX_PORTS]; > + uint8_t qid[MAX_QIDS]; > + int nb_qids; > +}; > + > +static inline struct rte_mbuf * > +rte_gen_arp(int portid, struct rte_mempool *mp) { > + /* > + * len = 14 + 46 > + * ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 46 > + */ > + static const uint8_t arp_request[] = { > + /*0x0000:*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xa8, > + 0x6b, 0xfd, 0x02, 0x29, 0x08, 0x06, 0x00, 0x01, > + /*0x0010:*/ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xec, 0xa8, > + 0x6b, 0xfd, 0x02, 0x29, 0x0a, 0x00, 0x00, 0x01, > + /*0x0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, > + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + /*0x0030:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x00, 0x00, 0x00, 0x00 > + }; > + struct rte_mbuf *m; > + int pkt_len = sizeof(arp_request) - 1; > + > + m = rte_pktmbuf_alloc(mp); > + if (!m) > + return 0; > + > + memcpy((void *)((uintptr_t)m->buf_addr + m->data_off), > + arp_request, pkt_len); > + rte_pktmbuf_pkt_len(m) = pkt_len; > + rte_pktmbuf_data_len(m) = pkt_len; > + > + RTE_SET_USED(portid); > + > + return m; > +} > + > +/* initialization and config */ > +static inline int > +init(struct test *t, int nb_queues, int nb_ports) { > + struct rte_event_dev_config config = { > + .nb_event_queues = nb_queues, > + .nb_event_ports = nb_ports, > + .nb_event_queue_flows = 1024, > + .nb_events_limit = 4096, > + .nb_event_port_dequeue_depth = 128, > + .nb_event_port_enqueue_depth = 128, > + }; > + int ret; > + > + void *temp = t->mbuf_pool; /* save and restore mbuf pool */ > + > + memset(t, 0, sizeof(*t)); > + t->mbuf_pool = temp; > + > + ret = rte_event_dev_configure(evdev, &config); > + if (ret < 0) > + printf("%d: Error configuring device\n", __LINE__); > + return ret; > +}; > + > +static inline int > +create_ports(struct test *t, int num_ports) { > + int i; > + static const struct rte_event_port_conf conf = { > + .new_event_threshold = 1024, > + .dequeue_depth = 32, > + .enqueue_depth = 64, > + }; > + if (num_ports > MAX_PORTS) > + return -1; > + > + for (i = 0; i < num_ports; i++) { > + if (rte_event_port_setup(evdev, i, &conf) < 0) { > + printf("Error setting up port %d\n", i); > + return -1; > + } > + t->port[i] = i; > + } > + > + return 0; > +} > + > +static inline int > +create_lb_qids(struct test *t, int num_qids, uint32_t flags) { > + int i; > + > + /* Q creation */ > + const struct rte_event_queue_conf conf = { > + .event_queue_cfg = flags, > + .priority = RTE_EVENT_DEV_PRIORITY_NORMAL, > + .nb_atomic_flows = 1024, > + .nb_atomic_order_sequences = 1024, > + }; > + > + for (i = t->nb_qids; i < t->nb_qids + num_qids; i++) { > + if (rte_event_queue_setup(evdev, i, &conf) < 0) { > + printf("%d: error creating qid %d\n", __LINE__, i); > + return -1; > + } > + t->qid[i] = i; > + } > + t->nb_qids += num_qids; > + if (t->nb_qids > MAX_QIDS) > + return -1; > + > + return 0; > +} > + > +static inline int > +create_atomic_qids(struct test *t, int num_qids) { > + return create_lb_qids(t, num_qids, > RTE_EVENT_QUEUE_CFG_ATOMIC_ONLY); } > + > +static inline int > +create_ordered_qids(struct test *t, int num_qids) { > + return create_lb_qids(t, num_qids, > RTE_EVENT_QUEUE_CFG_ORDERED_ONLY); > +} > + > + > +static inline int > +create_unordered_qids(struct test *t, int num_qids) { > + return create_lb_qids(t, num_qids, > RTE_EVENT_QUEUE_CFG_PARALLEL_ONLY); > +} > + > +static inline int > +create_directed_qids(struct test *t, int num_qids, const uint8_t > +ports[]) { > + int i; > + > + /* Q creation */ > + static const struct rte_event_queue_conf conf = { > + .priority = RTE_EVENT_DEV_PRIORITY_NORMAL, > + .event_queue_cfg = > RTE_EVENT_QUEUE_CFG_SINGLE_LINK, > + .nb_atomic_flows = 1024, > + .nb_atomic_order_sequences = 1024, > + }; > + > + for (i = t->nb_qids; i < t->nb_qids + num_qids; i++) { > + if (rte_event_queue_setup(evdev, i, &conf) < 0) { > + printf("%d: error creating qid %d\n", __LINE__, i); > + return -1; > + } > + t->qid[i] = i; > + > + if (rte_event_port_link(evdev, ports[i - t->nb_qids], > + &t->qid[i], NULL, 1) != 1) { > + printf("%d: error creating link for qid %d\n", > + __LINE__, i); > + return -1; > + } > + } > + t->nb_qids += num_qids; > + if (t->nb_qids > MAX_QIDS) > + return -1; > + > + return 0; > +} > + > +/* destruction */ > +static inline int > +cleanup(struct test *t __rte_unused) > +{ > + rte_event_dev_stop(evdev); > + rte_event_dev_close(evdev); > + return 0; > +}; > + > +struct test_event_dev_stats { > + uint64_t rx_pkts; /**< Total packets received */ > + uint64_t rx_dropped; /**< Total packets dropped (Eg Invalid QID) > */ > + uint64_t tx_pkts; /**< Total packets transmitted */ > + > + /** Packets received on this port */ > + uint64_t port_rx_pkts[MAX_PORTS]; > + /** Packets dropped on this port */ > + uint64_t port_rx_dropped[MAX_PORTS]; > + /** Packets inflight on this port */ > + uint64_t port_inflight[MAX_PORTS]; > + /** Packets transmitted on this port */ > + uint64_t port_tx_pkts[MAX_PORTS]; > + /** Packets received on this qid */ > + uint64_t qid_rx_pkts[MAX_QIDS]; > + /** Packets dropped on this qid */ > + uint64_t qid_rx_dropped[MAX_QIDS]; > + /** Packets transmitted on this qid */ > + uint64_t qid_tx_pkts[MAX_QIDS]; > +}; > + > +static inline int > +test_event_dev_stats_get(int dev_id, struct test_event_dev_stats > +*stats) { > + static uint32_t i; > + static uint32_t total_ids[3]; /* rx, tx and drop */ > + static uint32_t port_rx_pkts_ids[MAX_PORTS]; > + static uint32_t port_rx_dropped_ids[MAX_PORTS]; > + static uint32_t port_inflight_ids[MAX_PORTS]; > + static uint32_t port_tx_pkts_ids[MAX_PORTS]; > + static uint32_t qid_rx_pkts_ids[MAX_QIDS]; > + static uint32_t qid_rx_dropped_ids[MAX_QIDS]; > + static uint32_t qid_tx_pkts_ids[MAX_QIDS]; > + > + > + stats->rx_pkts = rte_event_dev_xstats_by_name_get(dev_id, > + "dev_rx", &total_ids[0]); > + stats->rx_dropped = rte_event_dev_xstats_by_name_get(dev_id, > + "dev_drop", &total_ids[1]); > + stats->tx_pkts = rte_event_dev_xstats_by_name_get(dev_id, > + "dev_tx", &total_ids[2]); > + for (i = 0; i < MAX_PORTS; i++) { > + char name[32]; > + snprintf(name, sizeof(name), "port_%u_rx", i); > + stats->port_rx_pkts[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &port_rx_pkts_ids[i]); > + snprintf(name, sizeof(name), "port_%u_drop", i); > + stats->port_rx_dropped[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &port_rx_dropped_ids[i]); > + snprintf(name, sizeof(name), "port_%u_inflight", i); > + stats->port_inflight[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &port_inflight_ids[i]); > + snprintf(name, sizeof(name), "port_%u_tx", i); > + stats->port_tx_pkts[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &port_tx_pkts_ids[i]); > + } > + for (i = 0; i < MAX_QIDS; i++) { > + char name[32]; > + snprintf(name, sizeof(name), "qid_%u_rx", i); > + stats->qid_rx_pkts[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &qid_rx_pkts_ids[i]); > + snprintf(name, sizeof(name), "qid_%u_drop", i); > + stats->qid_rx_dropped[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &qid_rx_dropped_ids[i]); > + snprintf(name, sizeof(name), "qid_%u_tx", i); > + stats->qid_tx_pkts[i] = > rte_event_dev_xstats_by_name_get( > + dev_id, name, &qid_tx_pkts_ids[i]); > + } > + > + return 0; > +} > + > +static struct rte_mempool *eventdev_func_mempool; > + > +static int > +test_sw_eventdev(void) > +{ > + struct test *t = malloc(sizeof(struct test)); > + > + const char *eventdev_name = "event_sw0"; > + evdev = rte_event_dev_get_dev_id(eventdev_name); > + if (evdev < 0) { > + printf("%d: Eventdev %s not found - creating.\n", > + __LINE__, eventdev_name); > + if (rte_eal_vdev_init(eventdev_name, NULL) < 0) { > + printf("Error creating eventdev\n"); > + return -1; > + } > + evdev = rte_event_dev_get_dev_id(eventdev_name); > + if (evdev < 0) { > + printf("Error finding newly created eventdev\n"); > + return -1; > + } > + } > + > + /* Only create mbuf pool once, reuse for each test run */ > + if (!eventdev_func_mempool) { > + eventdev_func_mempool = rte_pktmbuf_pool_create( > + "EVENTDEV_SW_SA_MBUF_POOL", > + (1<<12), /* 4k buffers */ > + 32 /*MBUF_CACHE_SIZE*/, > + 0, > + 512, /* use very small mbufs */ > + rte_socket_id()); > + if (!eventdev_func_mempool) { > + printf("ERROR creating mempool\n"); > + return -1; > + } > + } > + t->mbuf_pool = eventdev_func_mempool; > + > + /* > + * Free test instance, leaving mempool initialized, and a pointer to it > + * in static eventdev_func_mempool, as it is re-used on re-runs > + */ > + free(t); > + > + return 0; > +} > + > +REGISTER_TEST_COMMAND(eventdev_sw_autotest, test_sw_eventdev); > -- > 2.7.4
Acked-by: Anatoly Burakov <anatoly.bura...@intel.com>