From: Ciara Power Date: Fri, 25 Oct 2019 09:56:06 +0000 (+0100) Subject: examples/quota-watermark: remove example X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=46971b273ec7f469ca67a865453e1dd36274c5e1;p=dpdk.git examples/quota-watermark: remove example Original DPDK rings code had explicit support for a single watermark per-ring, but more recent releases of DPDK had a more general mechanism where each enqueue or dequeue call could return the remaining elements/free-slots in the ring. Therefore, this example is not as relevant as before and can be removed. Signed-off-by: Ciara Power Acked-by: Stephen Hemminger Acked-by: Hemant Agrawal --- diff --git a/MAINTAINERS b/MAINTAINERS index 3ed168e3aa..34743c4f67 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1511,9 +1511,6 @@ F: doc/guides/sample_app_ug/performance_thread.rst F: examples/ptpclient/ -F: examples/quota_watermark/ -F: doc/guides/sample_app_ug/quota_watermark.rst - M: Bruce Richardson M: John McNamara F: examples/rxtx_callbacks/ diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 76a49e8af4..148b635d2f 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -262,6 +262,7 @@ Removed Items * Exception Path * L3 Forwarding in a Virtualization Environment + * Quota and Watermark * vhost-scsi diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst index 1334a50076..dd03a748b1 100644 --- a/doc/guides/sample_app_ug/index.rst +++ b/doc/guides/sample_app_ug/index.rst @@ -36,7 +36,6 @@ Sample Applications User Guides multi_process qos_metering qos_scheduler - quota_watermark timer packet_ordering vmdq_dcb_forwarding diff --git a/doc/guides/sample_app_ug/quota_watermark.rst b/doc/guides/sample_app_ug/quota_watermark.rst deleted file mode 100644 index 125e6fb73a..0000000000 --- a/doc/guides/sample_app_ug/quota_watermark.rst +++ /dev/null @@ -1,465 +0,0 @@ -.. SPDX-License-Identifier: BSD-3-Clause - Copyright(c) 2010-2017 Intel Corporation. - -Quota and Watermark Sample Application -====================================== - -The Quota and Watermark sample application is a simple example of packet -processing using Data Plane Development Kit (DPDK) that showcases the use -of a quota as the maximum number of packets enqueue/dequeue at a time and -low and high thresholds, or watermarks, to signal low and high ring usage -respectively. - -Additionally, it shows how the thresholds can be used to feedback congestion notifications to data producers by -temporarily stopping processing overloaded rings and sending Ethernet flow control frames. - -This sample application is split in two parts: - -* qw - The core quota and watermark sample application - -* qwctl - A command line tool to alter quota and watermarks while qw is running - -Overview --------- - -The Quota and Watermark sample application performs forwarding for each packet that is received on a given port. -The destination port is the adjacent port from the enabled port mask, that is, -if the first four ports are enabled (port mask 0xf), ports 0 and 1 forward into each other, -and ports 2 and 3 forward into each other. -The MAC addresses of the forwarded Ethernet frames are not affected. - -Internally, packets are pulled from the ports by the master logical core and put on a variable length processing pipeline, -each stage of which being connected by rings, as shown in :numref:`figure_pipeline_overview`. - -.. _figure_pipeline_overview: - -.. figure:: img/pipeline_overview.* - - Pipeline Overview - - -An adjustable quota value controls how many packets are being moved through the pipeline per enqueue and dequeue. -Adjustable threshold values associated with the rings control a back-off mechanism that -tries to prevent the pipeline from being overloaded by: - -* Stopping enqueuing on rings for which the usage has crossed the high watermark threshold - -* Sending Ethernet pause frames - -* Only resuming enqueuing on a ring once its usage goes below a global low watermark threshold - -This mechanism allows congestion notifications to go up the ring pipeline and -eventually lead to an Ethernet flow control frame being send to the source. - -On top of serving as an example of quota and watermark usage, -this application can be used to benchmark ring based processing pipelines performance using a traffic- generator, -as shown in :numref:`figure_ring_pipeline_perf_setup`. - -.. _figure_ring_pipeline_perf_setup: - -.. figure:: img/ring_pipeline_perf_setup.* - - Ring-based Processing Pipeline Performance Setup - -Compiling the Application -------------------------- - -To compile the sample application see :doc:`compiling`. - -The application is located in the ``quota_watermark`` sub-directory. - -Running the Application ------------------------ - -The core application, qw, has to be started first. - -Once it is up and running, one can alter quota and watermarks while it runs using the control application, qwctl. - -Running the Core Application -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The application requires a single command line option: - -.. code-block:: console - - ./qw/build/qw [EAL options] -- -p PORTMASK - -where, - --p PORTMASK: A hexadecimal bitmask of the ports to configure - -To run the application in a linux environment with four logical cores and ports 0 and 2, -issue the following command: - -.. code-block:: console - - ./qw/build/qw -l 0-3 -n 4 -- -p 5 - -Refer to the *DPDK Getting Started Guide* for general information on running applications and -the Environment Abstraction Layer (EAL) options. - -Running the Control Application -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The control application requires a number of command line options: - -.. code-block:: console - - ./qwctl/build/qwctl [EAL options] --proc-type=secondary - -The --proc-type=secondary option is necessary for the EAL to properly initialize the control application to -use the same huge pages as the core application and thus be able to access its rings. - -To run the application in a linux environment on logical core 0, issue the following command: - -.. code-block:: console - - ./qwctl/build/qwctl -l 0 -n 4 --proc-type=secondary - -Refer to the *DPDK Getting Started* Guide for general information on running applications and -the Environment Abstraction Layer (EAL) options. - -qwctl is an interactive command line that let the user change variables in a running instance of qw. -The help command gives a list of available commands: - -.. code-block:: console - - $ qwctl > help - -Code Overview -------------- - -The following sections provide a quick guide to the application's source code. - -Core Application - qw -~~~~~~~~~~~~~~~~~~~~~ - -EAL and Drivers Setup -^^^^^^^^^^^^^^^^^^^^^ - -The EAL arguments are parsed at the beginning of the main() function: - -.. code-block:: c - - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot initialize EAL\n"); - - argc -= ret; - argv += ret; - -Then, a call to init_dpdk(), defined in init.c, is made to initialize the poll mode drivers: - -.. code-block:: c - - void - init_dpdk(void) - { - int ret; - - /* Bind the drivers to usable devices */ - - ret = rte_pci_probe(); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_pci_probe(): error %d\n", ret); - - if (rte_eth_dev_count_avail() < 2) - rte_exit(EXIT_FAILURE, "Not enough Ethernet port available\n"); - } - -To fully understand this code, it is recommended to study the chapters that relate to the *Poll Mode Driver* -in the *DPDK Getting Started Guide* and the *DPDK API Reference*. - -Shared Variables Setup -^^^^^^^^^^^^^^^^^^^^^^ - -The quota and high and low watermark shared variables are put into an rte_memzone using a call to setup_shared_variables(): - -.. code-block:: c - - void - setup_shared_variables(void) - { - const struct rte_memzone *qw_memzone; - - qw_memzone = rte_memzone_reserve(QUOTA_WATERMARK_MEMZONE_NAME, - 3 * sizeof(int), rte_socket_id(), 0); - if (qw_memzone == NULL) - rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); - - quota = qw_memzone->addr; - low_watermark = (unsigned int *) qw_memzone->addr + 1; - high_watermark = (unsigned int *) qw_memzone->addr + 2; - } - -These three variables are initialized to a default value in main() and -can be changed while qw is running using the qwctl control program. - -Application Arguments -^^^^^^^^^^^^^^^^^^^^^ - -The qw application only takes one argument: a port mask that specifies which ports should be used by the application. -At least two ports are needed to run the application and there should be an even number of ports given in the port mask. - -The port mask parsing is done in parse_qw_args(), defined in args.c. - -Mbuf Pool Initialization -^^^^^^^^^^^^^^^^^^^^^^^^ - -Once the application's arguments are parsed, an mbuf pool is created. -It contains a set of mbuf objects that are used by the driver and the application to store network packets: - -.. code-block:: c - - /* Create a pool of mbuf to store packets */ - mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0, - MBUF_DATA_SIZE, rte_socket_id()); - - if (mbuf_pool == NULL) - rte_panic("%s\n", rte_strerror(rte_errno)); - -The rte_mempool is a generic structure used to handle pools of objects. -In this case, it is necessary to create a pool that will be used by the driver. - -The number of allocated pkt mbufs is MBUF_PER_POOL, with a data room size -of MBUF_DATA_SIZE each. -A per-lcore cache of 32 mbufs is kept. -The memory is allocated in on the master lcore's socket, but it is possible to extend this code to allocate one mbuf pool per socket. - -The rte_pktmbuf_pool_create() function uses the default mbuf pool and mbuf -initializers, respectively rte_pktmbuf_pool_init() and rte_pktmbuf_init(). -An advanced application may want to use the mempool API to create the -mbuf pool with more control. - -Ports Configuration and Pairing -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Each port in the port mask is configured and a corresponding ring is created in the master lcore's array of rings. -This ring is the first in the pipeline and will hold the packets directly coming from the port. - -.. code-block:: c - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) - if (is_bit_set(port_id, portmask)) { - configure_eth_port(port_id); - init_ring(master_lcore_id, port_id); - } - - pair_ports(); - -The configure_eth_port() and init_ring() functions are used to configure a port and a ring respectively and are defined in init.c. -They make use of the DPDK APIs defined in rte_eth.h and rte_ring.h. - -pair_ports() builds the port_pairs[] array so that its key-value pairs are a mapping between reception and transmission ports. -It is defined in init.c. - -Logical Cores Assignment -^^^^^^^^^^^^^^^^^^^^^^^^ - -The application uses the master logical core to poll all the ports for new packets and enqueue them on a ring associated with the port. - -Each logical core except the last runs pipeline_stage() after a ring for each used port is initialized on that core. -pipeline_stage() on core X dequeues packets from core X-1's rings and enqueue them on its own rings. See :numref:`figure_threads_pipelines`. - -.. code-block:: c - - /* Start pipeline_stage() on all the available slave lcore but the last */ - - for (lcore_id = 0 ; lcore_id < last_lcore_id; lcore_id++) { - if (rte_lcore_is_enabled(lcore_id) && lcore_id != master_lcore_id) { - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) - if (is_bit_set(port_id, portmask)) - init_ring(lcore_id, port_id); - - rte_eal_remote_launch(pipeline_stage, NULL, lcore_id); - } - } - -The last available logical core runs send_stage(), -which is the last stage of the pipeline dequeuing packets from the last ring in the pipeline and -sending them out on the destination port setup by pair_ports(). - -.. code-block:: c - - /* Start send_stage() on the last slave core */ - - rte_eal_remote_launch(send_stage, NULL, last_lcore_id); - -Receive, Process and Transmit Packets -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. _figure_threads_pipelines: - -.. figure:: img/threads_pipelines.* - - Threads and Pipelines - - -In the receive_stage() function running on the master logical core, -the main task is to read ingress packets from the RX ports and enqueue them -on the port's corresponding first ring in the pipeline. -This is done using the following code: - -.. code-block:: c - - lcore_id = rte_lcore_id(); - - /* Process each port round robin style */ - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { - if (!is_bit_set(port_id, portmask)) - continue; - - ring = rings[lcore_id][port_id]; - - if (ring_state[port_id] != RING_READY) { - if (rte_ring_count(ring) > *low_watermark) - continue; - else - ring_state[port_id] = RING_READY; - } - - /* Enqueue received packets on the RX ring */ - nb_rx_pkts = rte_eth_rx_burst(port_id, 0, pkts, - (uint16_t) *quota); - ret = rte_ring_enqueue_bulk(ring, (void *) pkts, - nb_rx_pkts, &free); - if (RING_SIZE - free > *high_watermark) { - ring_state[port_id] = RING_OVERLOADED; - send_pause_frame(port_id, 1337); - } - - if (ret == 0) { - - /* - * Return mbufs to the pool, - * effectively dropping packets - */ - for (i = 0; i < nb_rx_pkts; i++) - rte_pktmbuf_free(pkts[i]); - } - } - -For each port in the port mask, the corresponding ring's pointer is fetched into ring and that ring's state is checked: - -* If it is in the RING_READY state, \*quota packets are grabbed from the port and put on the ring. - Should this operation make the ring's usage cross its high watermark, - the ring is marked as overloaded and an Ethernet flow control frame is sent to the source. - -* If it is not in the RING_READY state, this port is ignored until the ring's usage crosses the \*low_watermark value. - -The pipeline_stage() function's task is to process and move packets from the preceding pipeline stage. -This thread is running on most of the logical cores to create and arbitrarily long pipeline. - -.. code-block:: c - - lcore_id = rte_lcore_id(); - - previous_lcore_id = get_previous_lcore_id(lcore_id); - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { - if (!is_bit_set(port_id, portmask)) - continue; - - tx = rings[lcore_id][port_id]; - rx = rings[previous_lcore_id][port_id]; - - if (ring_state[port_id] != RING_READY) { - if (rte_ring_count(tx) > *low_watermark) - continue; - else - ring_state[port_id] = RING_READY; - } - - /* Dequeue up to quota mbuf from rx */ - nb_dq_pkts = rte_ring_dequeue_burst(rx, pkts, - *quota, NULL); - if (unlikely(nb_dq_pkts < 0)) - continue; - - /* Enqueue them on tx */ - ret = rte_ring_enqueue_bulk(tx, pkts, - nb_dq_pkts, &free); - if (RING_SIZE - free > *high_watermark) - ring_state[port_id] = RING_OVERLOADED; - - if (ret == 0) { - - /* - * Return mbufs to the pool, - * effectively dropping packets - */ - for (i = 0; i < nb_dq_pkts; i++) - rte_pktmbuf_free(pkts[i]); - } - } - -The thread's logic works mostly like receive_stage(), -except that packets are moved from ring to ring instead of port to ring. - -In this example, no actual processing is done on the packets, -but pipeline_stage() is an ideal place to perform any processing required by the application. - -Finally, the send_stage() function's task is to read packets from the last ring in a pipeline and -send them on the destination port defined in the port_pairs[] array. -It is running on the last available logical core only. - -.. code-block:: c - - lcore_id = rte_lcore_id(); - - previous_lcore_id = get_previous_lcore_id(lcore_id); - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { - if (!is_bit_set(port_id, portmask)) continue; - - dest_port_id = port_pairs[port_id]; - tx = rings[previous_lcore_id][port_id]; - - if (rte_ring_empty(tx)) continue; - - /* Dequeue packets from tx and send them */ - - nb_dq_pkts = rte_ring_dequeue_burst(tx, (void *) tx_pkts, *quota); - nb_tx_pkts = rte_eth_tx_burst(dest_port_id, 0, tx_pkts, nb_dq_pkts); - } - -For each port in the port mask, up to \*quota packets are pulled from the last ring in its pipeline and -sent on the destination port paired with the current port. - -Control Application - qwctl -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The qwctl application uses the rte_cmdline library to provide the user with an interactive command line that -can be used to modify and inspect parameters in a running qw application. -Those parameters are the global quota and low_watermark value as well as each ring's built-in high watermark. - -Command Definitions -^^^^^^^^^^^^^^^^^^^ - -The available commands are defined in commands.c. - -It is advised to use the cmdline sample application user guide as a reference for everything related to the rte_cmdline library. - -Accessing Shared Variables -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The setup_shared_variables() function retrieves the shared variables quota and -low_watermark from the rte_memzone previously created by qw. - -.. code-block:: c - - static void - setup_shared_variables(void) - { - const struct rte_memzone *qw_memzone; - - qw_memzone = rte_memzone_lookup(QUOTA_WATERMARK_MEMZONE_NAME); - if (qw_memzone == NULL) - rte_exit(EXIT_FAILURE, "Couldn't find memzone\n"); - - quota = qw_memzone->addr; - - low_watermark = (unsigned int *) qw_memzone->addr + 1; - high_watermark = (unsigned int *) qw_memzone->addr + 2; - } diff --git a/examples/Makefile b/examples/Makefile index 0940b4be16..e282bb798d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -59,7 +59,6 @@ endif DIRS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ptpclient DIRS-$(CONFIG_RTE_LIBRTE_METER) += qos_meter DIRS-$(CONFIG_RTE_LIBRTE_SCHED) += qos_sched -DIRS-y += quota_watermark DIRS-$(CONFIG_RTE_ETHDEV_RXTX_CALLBACKS) += rxtx_callbacks DIRS-y += service_cores DIRS-y += skeleton diff --git a/examples/meson.build b/examples/meson.build index 20b788a2c2..2f8d31f053 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -33,7 +33,7 @@ all_examples = [ 'netmap_compat', 'ntb', 'packet_ordering', 'performance-thread', 'ptpclient', 'qos_meter', 'qos_sched', - 'quota_watermark', 'rxtx_callbacks', + 'rxtx_callbacks', 'server_node_efd', 'service_cores', 'skeleton', 'tep_termination', 'timer', 'vdpa', diff --git a/examples/quota_watermark/Makefile b/examples/quota_watermark/Makefile deleted file mode 100644 index 8ef053198a..0000000000 --- a/examples/quota_watermark/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation - -ifeq ($(RTE_SDK),) -$(error "Please define RTE_SDK environment variable") -endif - -# Default target, detect a build directory, by looking for a path with a .config -RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) - -include $(RTE_SDK)/mk/rte.vars.mk - -DIRS-$(CONFIG_RTE_EXEC_ENV_LINUX) += qw -DIRS-$(CONFIG_RTE_EXEC_ENV_LINUX) += qwctl - -include $(RTE_SDK)/mk/rte.extsubdir.mk diff --git a/examples/quota_watermark/include/conf.h b/examples/quota_watermark/include/conf.h deleted file mode 100644 index 4f29aa64b6..0000000000 --- a/examples/quota_watermark/include/conf.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _CONF_H_ -#define _CONF_H_ - -#define RING_SIZE 1024 -#define MAX_PKT_QUOTA 64 - -#define RX_DESC_PER_QUEUE 1024 -#define TX_DESC_PER_QUEUE 1024 - -#define MBUF_DATA_SIZE RTE_MBUF_DEFAULT_BUF_SIZE -#define MBUF_PER_POOL 8192 - -#define QUOTA_WATERMARK_MEMZONE_NAME "qw_global_vars" - -#endif /* _CONF_H_ */ diff --git a/examples/quota_watermark/meson.build b/examples/quota_watermark/meson.build deleted file mode 100644 index c370d7476f..0000000000 --- a/examples/quota_watermark/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2018 Intel Corporation - -# meson file, for building this example as part of a main DPDK build. -# -# To build this example as a standalone application with an already-installed -# DPDK instance, use 'make' - -# Example app currently unsupported by meson build -build = false diff --git a/examples/quota_watermark/qw/Makefile b/examples/quota_watermark/qw/Makefile deleted file mode 100644 index 3f10f01c3b..0000000000 --- a/examples/quota_watermark/qw/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation - -ifeq ($(RTE_SDK),) -$(error "Please define RTE_SDK environment variable") -endif - -# Default target, detect a build directory, by looking for a path with a .config -RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) - -include $(RTE_SDK)/mk/rte.vars.mk - -# binary name -APP = qw - -# all source are stored in SRCS-y -SRCS-y := args.c init.c main.c - -CFLAGS += -O3 -DQW_SOFTWARE_FC -CFLAGS += $(WERROR_FLAGS) - -include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/examples/quota_watermark/qw/args.c b/examples/quota_watermark/qw/args.c deleted file mode 100644 index a750ec258d..0000000000 --- a/examples/quota_watermark/qw/args.c +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include - -#include -#include - -#include "args.h" - - -unsigned int portmask = 0; - - -static void -usage(const char *prgname) -{ - fprintf(stderr, "Usage: %s [EAL args] -- -p \n" - "-p PORTMASK: hexadecimal bitmask of NIC ports to configure\n", - prgname); -} - -static unsigned long -parse_portmask(const char *portmask_str) -{ - return strtoul(portmask_str, NULL, 16); -} - -static void -check_core_count(void) -{ - if (rte_lcore_count() < 3) - rte_exit(EXIT_FAILURE, - "At least 3 cores need to be passed in the coremask\n"); -} - -static void -check_portmask_value(unsigned int portmask) -{ - unsigned int port_nb = 0; - - port_nb = __builtin_popcount(portmask); - - if (port_nb == 0) - rte_exit(EXIT_FAILURE, - "At least 2 ports need to be passed in the portmask\n"); - - if (port_nb % 2 != 0) - rte_exit(EXIT_FAILURE, - "An even number of ports is required in the portmask\n"); -} - -int -parse_qw_args(int argc, char **argv) -{ - int opt; - - while ((opt = getopt(argc, argv, "h:p:")) != -1) { - switch (opt) { - case 'h': - usage(argv[0]); - break; - case 'p': - portmask = parse_portmask(optarg); - break; - default: - usage(argv[0]); - } - } - - check_core_count(); - check_portmask_value(portmask); - - return 0; -} diff --git a/examples/quota_watermark/qw/args.h b/examples/quota_watermark/qw/args.h deleted file mode 100644 index ab777db01c..0000000000 --- a/examples/quota_watermark/qw/args.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _ARGS_H_ -#define _ARGS_H_ - -extern unsigned int portmask; - -int parse_qw_args(int argc, char **argv); - -#endif /* _ARGS_H_ */ diff --git a/examples/quota_watermark/qw/init.c b/examples/quota_watermark/qw/init.c deleted file mode 100644 index 5ebcc83ac3..0000000000 --- a/examples/quota_watermark/qw/init.c +++ /dev/null @@ -1,168 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "args.h" -#include "init.h" -#include "main.h" -#include "../include/conf.h" - - -static struct rte_eth_conf port_conf = { - .rxmode = { - .split_hdr_size = 0, - }, - .txmode = { - .mq_mode = ETH_DCB_NONE, - }, -}; - -static struct rte_eth_fc_conf fc_conf = { - .mode = RTE_FC_TX_PAUSE, - .high_water = 80 * 510 / 100, - .low_water = 60 * 510 / 100, - .pause_time = 1337, - .send_xon = 0, -}; - - -void configure_eth_port(uint16_t port_id) -{ - int ret; - uint16_t nb_rxd = RX_DESC_PER_QUEUE; - uint16_t nb_txd = TX_DESC_PER_QUEUE; - struct rte_eth_rxconf rxq_conf; - struct rte_eth_txconf txq_conf; - struct rte_eth_dev_info dev_info; - struct rte_eth_conf local_port_conf = port_conf; - - rte_eth_dev_stop(port_id); - - rte_eth_dev_info_get(port_id, &dev_info); - if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) - local_port_conf.txmode.offloads |= - DEV_TX_OFFLOAD_MBUF_FAST_FREE; - ret = rte_eth_dev_configure(port_id, 1, 1, &local_port_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot configure port %u (error %d)\n", - (unsigned int) port_id, ret); - - ret = rte_eth_dev_adjust_nb_rx_tx_desc(port_id, &nb_rxd, &nb_txd); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Cannot adjust number of descriptors for port %u (error %d)\n", - (unsigned int) port_id, ret); - - /* Initialize the port's RX queue */ - rxq_conf = dev_info.default_rxconf; - rxq_conf.offloads = local_port_conf.rxmode.offloads; - ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, - rte_eth_dev_socket_id(port_id), - &rxq_conf, - mbuf_pool); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Failed to setup RX queue on port %u (error %d)\n", - (unsigned int) port_id, ret); - - /* Initialize the port's TX queue */ - txq_conf = dev_info.default_txconf; - txq_conf.offloads = local_port_conf.txmode.offloads; - ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, - rte_eth_dev_socket_id(port_id), - &txq_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Failed to setup TX queue on port %u (error %d)\n", - (unsigned int) port_id, ret); - - /* Initialize the port's flow control */ - ret = rte_eth_dev_flow_ctrl_set(port_id, &fc_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Failed to setup hardware flow control on port %u (error %d)\n", - (unsigned int) port_id, ret); - - /* Start the port */ - ret = rte_eth_dev_start(port_id); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Failed to start port %u (error %d)\n", - (unsigned int) port_id, ret); - - /* Put it in promiscuous mode */ - ret = rte_eth_promiscuous_enable(port_id); - if (ret != 0) - rte_exit(EXIT_FAILURE, - "Failed to enable promiscuous mode for port %u: %s\n", - port_id, rte_strerror(-ret)); -} - -void -init_dpdk(void) -{ - if (rte_eth_dev_count_avail() < 2) - rte_exit(EXIT_FAILURE, "Not enough ethernet port available\n"); -} - -void init_ring(int lcore_id, uint16_t port_id) -{ - struct rte_ring *ring; - char ring_name[RTE_RING_NAMESIZE]; - - snprintf(ring_name, RTE_RING_NAMESIZE, - "core%d_port%d", lcore_id, port_id); - ring = rte_ring_create(ring_name, RING_SIZE, rte_socket_id(), - RING_F_SP_ENQ | RING_F_SC_DEQ); - - if (ring == NULL) - rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); - - *high_watermark = 80 * RING_SIZE / 100; - - rings[lcore_id][port_id] = ring; -} - -void -pair_ports(void) -{ - uint16_t i, j; - - /* Pair ports with their "closest neighbour" in the portmask */ - for (i = 0; i < RTE_MAX_ETHPORTS; i++) - if (is_bit_set(i, portmask)) - for (j = i + 1; j < RTE_MAX_ETHPORTS; j++) - if (is_bit_set(j, portmask)) { - port_pairs[i] = j; - port_pairs[j] = i; - i = j; - break; - } -} - -void -setup_shared_variables(void) -{ - const struct rte_memzone *qw_memzone; - - qw_memzone = rte_memzone_reserve(QUOTA_WATERMARK_MEMZONE_NAME, - 3 * sizeof(int), rte_socket_id(), 0); - if (qw_memzone == NULL) - rte_exit(EXIT_FAILURE, "%s\n", rte_strerror(rte_errno)); - - quota = qw_memzone->addr; - low_watermark = (unsigned int *) qw_memzone->addr + 1; - high_watermark = (unsigned int *) qw_memzone->addr + 2; -} diff --git a/examples/quota_watermark/qw/init.h b/examples/quota_watermark/qw/init.h deleted file mode 100644 index e0c90df72d..0000000000 --- a/examples/quota_watermark/qw/init.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _INIT_H_ -#define _INIT_H_ - -void configure_eth_port(uint16_t port_id); -void init_dpdk(void); -void init_ring(int lcore_id, uint16_t port_id); -void pair_ports(void); -void setup_shared_variables(void); - -#endif /* _INIT_H_ */ diff --git a/examples/quota_watermark/qw/main.c b/examples/quota_watermark/qw/main.c deleted file mode 100644 index c985eed243..0000000000 --- a/examples/quota_watermark/qw/main.c +++ /dev/null @@ -1,373 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "args.h" -#include "main.h" -#include "init.h" -#include "../include/conf.h" - - -#ifdef QW_SOFTWARE_FC -#define SEND_PAUSE_FRAME(port_id, duration) send_pause_frame(port_id, duration) -#else -#define SEND_PAUSE_FRAME(port_id, duration) do { } while(0) -#endif - -#define ETHER_TYPE_FLOW_CONTROL 0x8808 - -struct ether_fc_frame { - uint16_t opcode; - uint16_t param; -} __attribute__((__packed__)); - - -int *quota; -unsigned int *low_watermark; -unsigned int *high_watermark; - -uint16_t port_pairs[RTE_MAX_ETHPORTS]; - -struct rte_ring *rings[RTE_MAX_LCORE][RTE_MAX_ETHPORTS]; -struct rte_mempool *mbuf_pool; - - -static void send_pause_frame(uint16_t port_id, uint16_t duration) -{ - struct rte_mbuf *mbuf; - struct ether_fc_frame *pause_frame; - struct rte_ether_hdr *hdr; - struct rte_ether_addr mac_addr; - int ret; - - RTE_LOG_DP(DEBUG, USER1, - "Sending PAUSE frame (duration=%d) on port %d\n", - duration, port_id); - - ret = rte_eth_macaddr_get(port_id, &mac_addr); - if (ret != 0) { - RTE_LOG_DP(ERR, USER1, - "Failed to get MAC address (port %u): %s\n", - port_id, rte_strerror(-ret)); - return; - } - - /* Get a mbuf from the pool */ - mbuf = rte_pktmbuf_alloc(mbuf_pool); - if (unlikely(mbuf == NULL)) - return; - - /* Prepare a PAUSE frame */ - hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); - pause_frame = (struct ether_fc_frame *) &hdr[1]; - - rte_ether_addr_copy(&mac_addr, &hdr->s_addr); - - void *tmp = &hdr->d_addr.addr_bytes[0]; - *((uint64_t *)tmp) = 0x010000C28001ULL; - - hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_FLOW_CONTROL); - - pause_frame->opcode = rte_cpu_to_be_16(0x0001); - pause_frame->param = rte_cpu_to_be_16(duration); - - mbuf->pkt_len = 60; - mbuf->data_len = 60; - - rte_eth_tx_burst(port_id, 0, &mbuf, 1); -} - -/** - * Get the previous enabled lcore ID - * - * @param lcore_id - * The current lcore ID. - * @return - * The previous enabled lcore_id or -1 if not found. - */ -static unsigned int -get_previous_lcore_id(unsigned int lcore_id) -{ - int i; - - for (i = lcore_id - 1; i >= 0; i--) - if (rte_lcore_is_enabled(i)) - return i; - - return -1; -} - -/** - * Get the last enabled lcore ID - * - * @return - * The last enabled lcore_id. - */ -static unsigned int -get_last_lcore_id(void) -{ - int i; - - for (i = RTE_MAX_LCORE; i >= 0; i--) - if (rte_lcore_is_enabled(i)) - return i; - - return 0; -} - -static void -receive_stage(__attribute__((unused)) void *args) -{ - int i, ret; - - uint16_t port_id; - uint16_t nb_rx_pkts; - - unsigned int lcore_id; - unsigned int free; - - struct rte_mbuf *pkts[MAX_PKT_QUOTA]; - struct rte_ring *ring; - enum ring_state ring_state[RTE_MAX_ETHPORTS] = { RING_READY }; - - lcore_id = rte_lcore_id(); - - RTE_LOG(INFO, USER1, - "%s() started on core %u\n", __func__, lcore_id); - - while (1) { - - /* Process each port round robin style */ - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { - - if (!is_bit_set(port_id, portmask)) - continue; - - ring = rings[lcore_id][port_id]; - - if (ring_state[port_id] != RING_READY) { - if (rte_ring_count(ring) > *low_watermark) - continue; - else - ring_state[port_id] = RING_READY; - } - - /* Enqueue received packets on the RX ring */ - nb_rx_pkts = rte_eth_rx_burst(port_id, 0, pkts, - (uint16_t) *quota); - ret = rte_ring_enqueue_bulk(ring, (void *) pkts, - nb_rx_pkts, &free); - if (RING_SIZE - free > *high_watermark) { - ring_state[port_id] = RING_OVERLOADED; - send_pause_frame(port_id, 1337); - } - - if (ret == 0) { - - /* - * Return mbufs to the pool, - * effectively dropping packets - */ - for (i = 0; i < nb_rx_pkts; i++) - rte_pktmbuf_free(pkts[i]); - } - } - } -} - -static int -pipeline_stage(__attribute__((unused)) void *args) -{ - int i, ret; - int nb_dq_pkts; - - uint16_t port_id; - - unsigned int lcore_id, previous_lcore_id; - unsigned int free; - - void *pkts[MAX_PKT_QUOTA]; - struct rte_ring *rx, *tx; - enum ring_state ring_state[RTE_MAX_ETHPORTS] = { RING_READY }; - - lcore_id = rte_lcore_id(); - previous_lcore_id = get_previous_lcore_id(lcore_id); - - RTE_LOG(INFO, USER1, - "%s() started on core %u - processing packets from core %u\n", - __func__, lcore_id, previous_lcore_id); - - while (1) { - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { - - if (!is_bit_set(port_id, portmask)) - continue; - - tx = rings[lcore_id][port_id]; - rx = rings[previous_lcore_id][port_id]; - - if (ring_state[port_id] != RING_READY) { - if (rte_ring_count(tx) > *low_watermark) - continue; - else - ring_state[port_id] = RING_READY; - } - - /* Dequeue up to quota mbuf from rx */ - nb_dq_pkts = rte_ring_dequeue_burst(rx, pkts, - *quota, NULL); - if (unlikely(nb_dq_pkts < 0)) - continue; - - /* Enqueue them on tx */ - ret = rte_ring_enqueue_bulk(tx, pkts, - nb_dq_pkts, &free); - if (RING_SIZE - free > *high_watermark) - ring_state[port_id] = RING_OVERLOADED; - - if (ret == 0) { - - /* - * Return mbufs to the pool, - * effectively dropping packets - */ - for (i = 0; i < nb_dq_pkts; i++) - rte_pktmbuf_free(pkts[i]); - } - } - } - - return 0; -} - -static int -send_stage(__attribute__((unused)) void *args) -{ - uint16_t nb_dq_pkts; - - uint16_t port_id; - uint16_t dest_port_id; - - unsigned int lcore_id, previous_lcore_id; - - struct rte_ring *tx; - struct rte_mbuf *tx_pkts[MAX_PKT_QUOTA]; - - lcore_id = rte_lcore_id(); - previous_lcore_id = get_previous_lcore_id(lcore_id); - - RTE_LOG(INFO, USER1, - "%s() started on core %u - processing packets from core %u\n", - __func__, lcore_id, previous_lcore_id); - - while (1) { - - /* Process each ring round robin style */ - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { - - if (!is_bit_set(port_id, portmask)) - continue; - - dest_port_id = port_pairs[port_id]; - tx = rings[previous_lcore_id][port_id]; - - if (rte_ring_empty(tx)) - continue; - - /* Dequeue packets from tx and send them */ - nb_dq_pkts = (uint16_t) rte_ring_dequeue_burst(tx, - (void *) tx_pkts, *quota, NULL); - rte_eth_tx_burst(dest_port_id, 0, tx_pkts, nb_dq_pkts); - - /* TODO: Check if nb_dq_pkts == nb_tx_pkts? */ - } - } - - return 0; -} - -int -main(int argc, char **argv) -{ - int ret; - unsigned int lcore_id, master_lcore_id, last_lcore_id; - - uint16_t port_id; - - rte_log_set_global_level(RTE_LOG_INFO); - - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot initialize EAL\n"); - - argc -= ret; - argv += ret; - - init_dpdk(); - setup_shared_variables(); - - *quota = 32; - *low_watermark = 60 * RING_SIZE / 100; - - last_lcore_id = get_last_lcore_id(); - master_lcore_id = rte_get_master_lcore(); - - /* Parse the application's arguments */ - ret = parse_qw_args(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid quota/watermark argument(s)\n"); - - /* Create a pool of mbuf to store packets */ - mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", MBUF_PER_POOL, 32, 0, - MBUF_DATA_SIZE, rte_socket_id()); - if (mbuf_pool == NULL) - rte_panic("%s\n", rte_strerror(rte_errno)); - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) - if (is_bit_set(port_id, portmask)) { - configure_eth_port(port_id); - init_ring(master_lcore_id, port_id); - } - - pair_ports(); - - /* - * Start pipeline_connect() on all the available slave lcores - * but the last - */ - for (lcore_id = 0 ; lcore_id < last_lcore_id; lcore_id++) { - if (rte_lcore_is_enabled(lcore_id) && - lcore_id != master_lcore_id) { - - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) - if (is_bit_set(port_id, portmask)) - init_ring(lcore_id, port_id); - - rte_eal_remote_launch(pipeline_stage, - NULL, lcore_id); - } - } - - /* Start send_stage() on the last slave core */ - rte_eal_remote_launch(send_stage, NULL, last_lcore_id); - - /* Start receive_stage() on the master core */ - receive_stage(NULL); - - return 0; -} diff --git a/examples/quota_watermark/qw/main.h b/examples/quota_watermark/qw/main.h deleted file mode 100644 index 9903ddc8c6..0000000000 --- a/examples/quota_watermark/qw/main.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _MAIN_H_ -#define _MAIN_H_ - -#include "../include/conf.h" - -enum ring_state { - RING_READY, - RING_OVERLOADED, -}; - -extern int *quota; -extern unsigned int *low_watermark; -extern unsigned int *high_watermark; - -extern uint16_t port_pairs[RTE_MAX_ETHPORTS]; - -extern struct rte_ring *rings[RTE_MAX_LCORE][RTE_MAX_ETHPORTS]; -extern struct rte_mempool *mbuf_pool; - - -static inline int -is_bit_set(int i, unsigned int mask) -{ - return (1 << i) & mask; -} - -#endif /* _MAIN_H_ */ diff --git a/examples/quota_watermark/qwctl/Makefile b/examples/quota_watermark/qwctl/Makefile deleted file mode 100644 index a40f280250..0000000000 --- a/examples/quota_watermark/qwctl/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2014 Intel Corporation - -ifeq ($(RTE_SDK),) -$(error "Please define RTE_SDK environment variable") -endif - -# Default target, detect a build directory, by looking for a path with a .config -RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) - -include $(RTE_SDK)/mk/rte.vars.mk - -# binary name -APP = qwctl - -# all source are stored in SRCS-y -SRCS-y := commands.c qwctl.c - -CFLAGS += -O3 -CFLAGS += $(WERROR_FLAGS) - -include $(RTE_SDK)/mk/rte.extapp.mk diff --git a/examples/quota_watermark/qwctl/commands.c b/examples/quota_watermark/qwctl/commands.c deleted file mode 100644 index a1c646b9fb..0000000000 --- a/examples/quota_watermark/qwctl/commands.c +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "qwctl.h" -#include "../include/conf.h" - - -/** - * help command - */ - -struct cmd_help_tokens { - cmdline_fixed_string_t verb; -}; - -cmdline_parse_token_string_t cmd_help_verb = - TOKEN_STRING_INITIALIZER(struct cmd_help_tokens, verb, "help"); - -static void -cmd_help_handler(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - cmdline_printf(cl, "Available commands:\n" - "- help\n" - "- set [ring_name|variable] \n" - "- show [ring_name|variable]\n" - "\n" - "Available variables:\n" - "- low_watermark\n" - "- quota\n" - "- ring names follow the core%%u_port%%u format\n"); -} - -cmdline_parse_inst_t cmd_help = { - .f = cmd_help_handler, - .data = NULL, - .help_str = "show help", - .tokens = { - (void *) &cmd_help_verb, - NULL, - }, -}; - - -/** - * set command - */ - -struct cmd_set_tokens { - cmdline_fixed_string_t verb; - cmdline_fixed_string_t variable; - uint32_t value; -}; - -cmdline_parse_token_string_t cmd_set_verb = - TOKEN_STRING_INITIALIZER(struct cmd_set_tokens, verb, "set"); - -cmdline_parse_token_string_t cmd_set_variable = - TOKEN_STRING_INITIALIZER(struct cmd_set_tokens, variable, NULL); - -cmdline_parse_token_num_t cmd_set_value = - TOKEN_NUM_INITIALIZER(struct cmd_set_tokens, value, UINT32); - -static void -cmd_set_handler(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_set_tokens *tokens = parsed_result; - struct rte_ring *ring; - - if (!strcmp(tokens->variable, "quota")) { - - if (tokens->value > 0 && tokens->value <= MAX_PKT_QUOTA) - *quota = tokens->value; - else - cmdline_printf(cl, "quota must be between 1 and %u\n", - MAX_PKT_QUOTA); - } - - else if (!strcmp(tokens->variable, "low_watermark")) { - - if (tokens->value <= 100) - *low_watermark = tokens->value * RING_SIZE / 100; - else - cmdline_printf(cl, - "low_watermark must be between 0%% and 100%%\n"); - } - - else { - - ring = rte_ring_lookup(tokens->variable); - if (ring == NULL) - cmdline_printf(cl, "Cannot find ring \"%s\"\n", - tokens->variable); - else - if (tokens->value >= *low_watermark * 100 / RING_SIZE - && tokens->value <= 100) - *high_watermark = tokens->value * - RING_SIZE / 100; - else - cmdline_printf(cl, - "ring high watermark must be between %u%% and 100%%\n", - *low_watermark * 100 / RING_SIZE); - } -} - -cmdline_parse_inst_t cmd_set = { - .f = cmd_set_handler, - .data = NULL, - .help_str = "Set a variable value", - .tokens = { - (void *) &cmd_set_verb, - (void *) &cmd_set_variable, - (void *) &cmd_set_value, - NULL, - }, -}; - - -/** - * show command - */ - -struct cmd_show_tokens { - cmdline_fixed_string_t verb; - cmdline_fixed_string_t variable; -}; - -cmdline_parse_token_string_t cmd_show_verb = - TOKEN_STRING_INITIALIZER(struct cmd_show_tokens, verb, "show"); - -cmdline_parse_token_string_t cmd_show_variable = - TOKEN_STRING_INITIALIZER(struct cmd_show_tokens, - variable, NULL); - - -static void -cmd_show_handler(__attribute__((unused)) void *parsed_result, - struct cmdline *cl, - __attribute__((unused)) void *data) -{ - struct cmd_show_tokens *tokens = parsed_result; - struct rte_ring *ring; - - if (!strcmp(tokens->variable, "quota")) - cmdline_printf(cl, "Global quota: %d\n", *quota); - - else if (!strcmp(tokens->variable, "low_watermark")) - cmdline_printf(cl, "Global low_watermark: %u\n", - *low_watermark); - - else { - - ring = rte_ring_lookup(tokens->variable); - if (ring == NULL) - cmdline_printf(cl, "Cannot find ring \"%s\"\n", - tokens->variable); - else - rte_ring_dump(stdout, ring); - } -} - -cmdline_parse_inst_t cmd_show = { - .f = cmd_show_handler, - .data = NULL, - .help_str = "Show a variable value", - .tokens = { - (void *) &cmd_show_verb, - (void *) &cmd_show_variable, - NULL, - }, -}; - - -cmdline_parse_ctx_t qwctl_ctx[] = { - (cmdline_parse_inst_t *)&cmd_help, - (cmdline_parse_inst_t *)&cmd_set, - (cmdline_parse_inst_t *)&cmd_show, - NULL, -}; diff --git a/examples/quota_watermark/qwctl/commands.h b/examples/quota_watermark/qwctl/commands.h deleted file mode 100644 index 4a4e974755..0000000000 --- a/examples/quota_watermark/qwctl/commands.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _COMMANDS_H_ -#define _COMMANDS_H_ - -#include - -extern cmdline_parse_ctx_t qwctl_ctx[]; - -#endif /* _COMMANDS_H_ */ diff --git a/examples/quota_watermark/qwctl/qwctl.c b/examples/quota_watermark/qwctl/qwctl.c deleted file mode 100644 index 2f7914c803..0000000000 --- a/examples/quota_watermark/qwctl/qwctl.c +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include - - -#include "qwctl.h" -#include "commands.h" -#include "../include/conf.h" - - -int *quota; -unsigned int *low_watermark; -unsigned int *high_watermark; - - -static void -setup_shared_variables(void) -{ - const struct rte_memzone *qw_memzone; - - qw_memzone = rte_memzone_lookup(QUOTA_WATERMARK_MEMZONE_NAME); - if (qw_memzone == NULL) - rte_exit(EXIT_FAILURE, "Couldn't find memzone\n"); - - quota = qw_memzone->addr; - low_watermark = (unsigned int *) qw_memzone->addr + 1; - high_watermark = (unsigned int *) qw_memzone->addr + 2; -} - -int main(int argc, char **argv) -{ - int ret; - struct cmdline *cl; - - rte_log_set_global_level(RTE_LOG_INFO); - - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot initialize EAL\n"); - - setup_shared_variables(); - - cl = cmdline_stdin_new(qwctl_ctx, "qwctl> "); - if (cl == NULL) - rte_exit(EXIT_FAILURE, "Cannot create cmdline instance\n"); - - cmdline_interact(cl); - cmdline_stdin_exit(cl); - - return 0; -} diff --git a/examples/quota_watermark/qwctl/qwctl.h b/examples/quota_watermark/qwctl/qwctl.h deleted file mode 100644 index 2a4559388a..0000000000 --- a/examples/quota_watermark/qwctl/qwctl.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation - */ - -#ifndef _MAIN_H_ -#define _MAIN_H_ - -extern int *quota; -extern unsigned int *low_watermark; -extern unsigned int *high_watermark; - -#endif /* _MAIN_H_ */