From: Neil Horman <nhorman@tuxdriver.com>
To: Bruce Richardson <bruce.richardson@intel.com>
Cc: dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH] skeleton app: Very simple code for l2fwding
Date: Thu, 26 Jun 2014 16:38:44 -0400 [thread overview]
Message-ID: <20140626203844.GA639@localhost.localdomain> (raw)
In-Reply-To: <1403814160-19613-1-git-send-email-bruce.richardson@intel.com>
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 <bruce.richardson@intel.com>
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 <stdint.h>
> +#include <inttypes.h>
> +#include <rte_eal.h>
> +#include <rte_ethdev.h>
> +#include <rte_cycles.h>
> +#include <rte_lcore.h>
> +#include <rte_mbuf.h>
> +#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
>
>
next prev parent reply other threads:[~2014-06-26 20:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-26 20:22 Bruce Richardson
2014-06-26 20:38 ` Neil Horman [this message]
2014-06-26 20:56 ` Vincent JARDIN
2014-06-26 21:00 ` Richardson, Bruce
2014-11-13 12:20 ` Thomas Monjalon
2014-11-13 13:06 ` Bruce Richardson
2014-11-14 14:31 ` [dpdk-dev] [PATCH v2] " Bruce Richardson
2014-11-26 14:38 ` [dpdk-dev] [PATCH v3] examples/skeleton: very simple code for packet forwarding Thomas Monjalon
2014-11-26 15:42 ` Thomas Monjalon
2014-11-26 15:49 ` Bruce Richardson
2014-11-26 16:26 ` Thomas Monjalon
2014-11-26 16:29 ` 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=20140626203844.GA639@localhost.localdomain \
--to=nhorman@tuxdriver.com \
--cc=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).