From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.tuxdriver.com (charlotte.tuxdriver.com [70.61.120.58]) by dpdk.org (Postfix) with ESMTP id 6DDD4B0AA for ; Thu, 26 Jun 2014 22:38:40 +0200 (CEST) Received: from nat-pool-rdu-u.redhat.com ([66.187.233.203] helo=localhost) by smtp.tuxdriver.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.63) (envelope-from ) id 1X0GRW-0003Q1-PK; Thu, 26 Jun 2014 16:38:57 -0400 Date: Thu, 26 Jun 2014 16:38:44 -0400 From: Neil Horman To: Bruce Richardson Message-ID: <20140626203844.GA639@localhost.localdomain> References: <1403814160-19613-1-git-send-email-bruce.richardson@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1403814160-19613-1-git-send-email-bruce.richardson@intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Score: -2.9 (--) X-Spam-Status: No Cc: dev@dpdk.org Subject: Re: [dpdk-dev] [PATCH] skeleton app: Very simple code for l2fwding 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: Thu, 26 Jun 2014 20:38:41 -0000 On Thu, Jun 26, 2014 at 09:22:40PM +0100, Bruce Richardson wrote: > This is a very simple example app for doing packet forwarding with the > Intel DPDK. It's designed to serve as a start point for people new to > the Intel DPDK and who want to develop a new app. > > Therefore it's meant to: > * have as good a performance out-of-the-box as possible, using the > best-known settings for configuring the PMDs, so that any new apps can > be based off it. > * be kept as short as possible to make it easy to understand it and get > started with it. > > Signed-off-by: Bruce Richardson Isn't there already an l2fwd example app? Neil > --- > examples/Makefile | 1 + > examples/skeleton_app/Makefile | 57 ++++++++++ > examples/skeleton_app/basicfwd.c | 236 +++++++++++++++++++++++++++++++++++++++ > examples/skeleton_app/basicfwd.h | 46 ++++++++ > 4 files changed, 340 insertions(+) > create mode 100644 examples/skeleton_app/Makefile > create mode 100644 examples/skeleton_app/basicfwd.c > create mode 100644 examples/skeleton_app/basicfwd.h > > diff --git a/examples/Makefile b/examples/Makefile > index 4353b84..2605d1d 100644 > --- a/examples/Makefile > +++ b/examples/Makefile > @@ -60,6 +60,7 @@ DIRS-y += netmap_compat/bridge > DIRS-$(CONFIG_RTE_LIBRTE_METER) += qos_meter > DIRS-$(CONFIG_RTE_LIBRTE_SCHED) += qos_sched > DIRS-y += quota_watermark > +DIRS-y += skeleton_app > DIRS-y += timer > DIRS-y += vhost > DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += vhost_xen > diff --git a/examples/skeleton_app/Makefile b/examples/skeleton_app/Makefile > new file mode 100644 > index 0000000..244f4ef > --- /dev/null > +++ b/examples/skeleton_app/Makefile > @@ -0,0 +1,57 @@ > +# 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. > + > +ifeq ($(RTE_SDK),) > +$(error "Please define RTE_SDK environment variable") > +endif > + > +# Default target, can be overriden by command line or environment > +RTE_TARGET ?= x86_64-default-linuxapp-gcc > + > +include $(RTE_SDK)/mk/rte.vars.mk > + > +# binary name > +APP = basicfwd > + > +# all source are stored in SRCS-y > +SRCS-y := basicfwd.c > + > +CFLAGS += $(WERROR_FLAGS) > + > +# workaround for a gcc bug with noreturn attribute > +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603 > +ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) > +CFLAGS_main.o += -Wno-return-type > +endif > + > +EXTRA_CFLAGS += -O3 -g -Wfatal-errors > + > +include $(RTE_SDK)/mk/rte.extapp.mk > diff --git a/examples/skeleton_app/basicfwd.c b/examples/skeleton_app/basicfwd.c > new file mode 100644 > index 0000000..bf51a9d > --- /dev/null > +++ b/examples/skeleton_app/basicfwd.c > @@ -0,0 +1,236 @@ > +/*- > + * 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 "basicfwd.h" > + > +#define RX_RING_SIZE 128 > +#define RX_FREE_THRESH 32 > +#define RX_PTHRESH 8 > +#define RX_HTHRESH 8 > +#define RX_WTHRESH 0 > + > +#define TX_RING_SIZE 512 > +#define TX_FREE_THRESH 32 > +#define TX_PTHRESH 32 > +#define TX_HTHRESH 0 > +#define TX_WTHRESH 0 > +#define TX_RSBIT_THRESH 32 > +#define TX_Q_FLAGS (ETH_TXQ_FLAGS_NOMULTSEGS | ETH_TXQ_FLAGS_NOVLANOFFL |\ > + ETH_TXQ_FLAGS_NOXSUMSCTP | ETH_TXQ_FLAGS_NOXSUMUDP | \ > + ETH_TXQ_FLAGS_NOXSUMTCP) > + > +#define NUM_MBUFS 8191 > +#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) > +#define MBUF_CACHE_SIZE 250 > +#define BURST_SIZE 32 > + > +static struct rte_eth_conf port_conf_default = { > + .rxmode = { > + .mq_mode = ETH_MQ_RX_NONE, > + .max_rx_pkt_len = ETHER_MAX_LEN, > + .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 */ > + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ > + .hw_strip_crc = 0, /**< CRC stripped by hardware */ > + }, > + .txmode = { > + .mq_mode = ETH_MQ_TX_NONE, > + }, > + .lpbk_mode = 0, > +}; > + > +static const struct rte_eth_rxconf rx_conf_default = { > + .rx_thresh = { > + .pthresh = RX_PTHRESH, > + .hthresh = RX_HTHRESH, > + .wthresh = RX_WTHRESH, > + }, > + .rx_free_thresh = RX_FREE_THRESH, > + .rx_drop_en = 0, > +}; > + > +static struct rte_eth_txconf tx_conf_default = { > + .tx_thresh = { > + .pthresh = TX_PTHRESH, > + .hthresh = TX_HTHRESH, > + .wthresh = TX_WTHRESH, > + }, > + .tx_free_thresh = TX_FREE_THRESH, > + .tx_rs_thresh = TX_RSBIT_THRESH, > + .txq_flags = TX_Q_FLAGS > + > +}; > + > + > +/* > + * Initialises a given port using global settings and with the rx buffers > + * coming from the mbuf_pool passed as parameter > + */ > +static inline int > +port_init(uint8_t port, struct rte_mempool *mbuf_pool) > +{ > + struct rte_eth_conf port_conf = port_conf_default; > + const uint16_t rxRings = 1, txRings = 1; > + int retval; > + uint16_t q; > + > + if (port >= rte_eth_dev_count()) > + return -1; > + > + retval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf); > + if (retval != 0) > + return retval; > + > + for (q = 0; q < rxRings; q++) { > + retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, > + rte_eth_dev_socket_id(port), &rx_conf_default, > + mbuf_pool); > + if (retval < 0) > + return retval; > + } > + > + for (q = 0; q < txRings; q++) { > + retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, > + rte_eth_dev_socket_id(port), &tx_conf_default); > + if (retval < 0) > + return retval; > + } > + > + retval = rte_eth_dev_start(port); > + if (retval < 0) > + return retval; > + > + struct ether_addr addr; > + rte_eth_macaddr_get(port, &addr); > + printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 > + " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", > + (unsigned)port, > + addr.addr_bytes[0], addr.addr_bytes[1], > + addr.addr_bytes[2], addr.addr_bytes[3], > + addr.addr_bytes[4], addr.addr_bytes[5]); > + > + rte_eth_promiscuous_enable(port); > + > + return 0; > +} > + > +/* > + * Main thread that does the work, reading from INPUT_PORT > + * and writing to OUTPUT_PORT > + */ > +static __attribute__((noreturn)) void > +lcore_main(void) > +{ > + const uint8_t nb_ports = rte_eth_dev_count(); > + uint8_t port; > + for (port = 0; port < nb_ports; port++) > + if (rte_eth_dev_socket_id(port) > 0 && > + rte_eth_dev_socket_id(port) != > + (int)rte_socket_id()) > + printf("WARNING, port %u is on remote NUMA node to " > + "polling thread.\n\tPerformance will " > + "not be optimal.\n", port); > + > + printf("\nCore %u forwarding packets. [Ctrl+C to quit]\n", > + rte_lcore_id()); > + for (;;) { > + for (port = 0; port < nb_ports; port++) { > + struct rte_mbuf *bufs[BURST_SIZE]; > + const uint16_t nb_rx = rte_eth_rx_burst(port, 0, > + bufs, BURST_SIZE); > + if (unlikely(nb_rx == 0)) > + continue; > + const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, > + bufs, nb_rx); > + if (unlikely(nb_tx < nb_rx)) { > + uint16_t buf; > + for (buf = nb_tx; buf < nb_rx; buf++) > + rte_pktmbuf_free(bufs[buf]); > + } > + } > + } > +} > + > +/* Main function, does initialisation and calls the per-lcore functions */ > +int > +MAIN(int argc, char *argv[]) > +{ > + struct rte_mempool *mbuf_pool; > + unsigned nb_ports; > + uint8_t portid; > + > + /* init EAL */ > + int ret = rte_eal_init(argc, argv); > + if (ret < 0) > + rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); > + argc -= ret; > + argv += ret; > + > + if (rte_eal_pci_probe() != 0) > + rte_exit(EXIT_FAILURE, "Error with PCI probing\n"); > + > + nb_ports = rte_eth_dev_count(); > + if (nb_ports < 2 || (nb_ports & 1)) > + rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n"); > + > + mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports, > + MBUF_SIZE, MBUF_CACHE_SIZE, > + sizeof(struct rte_pktmbuf_pool_private), > + rte_pktmbuf_pool_init, NULL, > + rte_pktmbuf_init, NULL, > + rte_socket_id(), 0); > + if (mbuf_pool == NULL) > + rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); > + > + /* initialize all ports */ > + for (portid = 0; portid < nb_ports; portid++) > + if (port_init(portid, mbuf_pool) != 0) > + rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8"\n", > + portid); > + > + if (rte_lcore_count() > 1) > + printf("\nWARNING: Coremask too big - App uses only 1 lcore\n"); > + > + /* call lcore_main on master core only */ > + lcore_main(); > + return 0; > +} > diff --git a/examples/skeleton_app/basicfwd.h b/examples/skeleton_app/basicfwd.h > new file mode 100644 > index 0000000..2682d15 > --- /dev/null > +++ b/examples/skeleton_app/basicfwd.h > @@ -0,0 +1,46 @@ > +/*- > + * 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. > + */ > + > +#ifndef _MAIN_H_ > +#define _MAIN_H_ > + > + > +#ifdef RTE_EXEC_ENV_BAREMETAL > +#define MAIN _main > +#else > +#define MAIN main > +#endif > + > +int MAIN(int argc, char *argv[]); > + > +#endif /* ifndef _MAIN_H_ */ > -- > 1.9.3 > >