All of lore.kernel.org
 help / color / mirror / Atom feed
From: <pbhagavatula@marvell.com>
To: <jerinj@marvell.com>, <bruce.richardson@intel.com>,
	<hemant.agrawal@nxp.com>, Thomas Monjalon <thomas@monjalon.net>,
	"Marko Kovacevic" <marko.kovacevic@intel.com>,
	Ori Kam <orika@mellanox.com>,
	"Radu Nicolau" <radu.nicolau@intel.com>,
	Akhil Goyal <akhil.goyal@nxp.com>,
	"Tomasz Kantecki" <tomasz.kantecki@intel.com>,
	Sunil Kumar Kori <skori@marvell.com>,
	Pavan Nikhilesh <pbhagavatula@marvell.com>
Cc: <dev@dpdk.org>
Subject: [dpdk-dev] [PATCH v6 01/10] examples/l2fwd-event: add default poll mode routines
Date: Mon, 14 Oct 2019 23:52:38 +0530	[thread overview]
Message-ID: <20191014182247.961-2-pbhagavatula@marvell.com> (raw)
In-Reply-To: <20191014182247.961-1-pbhagavatula@marvell.com>

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Add the default l2fwd poll mode routines similar to examples/l2fwd.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 MAINTAINERS                         |   5 +
 examples/Makefile                   |   1 +
 examples/l2fwd-event/Makefile       |  59 +++++
 examples/l2fwd-event/l2fwd_common.c | 138 +++++++++++
 examples/l2fwd-event/l2fwd_common.h | 128 ++++++++++
 examples/l2fwd-event/l2fwd_poll.c   | 193 +++++++++++++++
 examples/l2fwd-event/l2fwd_poll.h   |  25 ++
 examples/l2fwd-event/main.c         | 371 ++++++++++++++++++++++++++++
 examples/l2fwd-event/meson.build    |  15 ++
 examples/meson.build                |   2 +-
 10 files changed, 936 insertions(+), 1 deletion(-)
 create mode 100644 examples/l2fwd-event/Makefile
 create mode 100644 examples/l2fwd-event/l2fwd_common.c
 create mode 100644 examples/l2fwd-event/l2fwd_common.h
 create mode 100644 examples/l2fwd-event/l2fwd_poll.c
 create mode 100644 examples/l2fwd-event/l2fwd_poll.h
 create mode 100644 examples/l2fwd-event/main.c
 create mode 100644 examples/l2fwd-event/meson.build

diff --git a/MAINTAINERS b/MAINTAINERS
index f8a56e2e2..6957b2a24 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1475,6 +1475,11 @@ M: Tomasz Kantecki <tomasz.kantecki@intel.com>
 F: doc/guides/sample_app_ug/l2_forward_cat.rst
 F: examples/l2fwd-cat/
 
+M: Sunil Kumar Kori <skori@marvell.com>
+M: Pavan Nikhilesh <pbhagavatula@marvell.com>
+F: examples/l2fwd-event/
+T: git://dpdk.org/next/dpdk-next-eventdev
+
 F: examples/l3fwd/
 F: doc/guides/sample_app_ug/l3_forward.rst
 
diff --git a/examples/Makefile b/examples/Makefile
index de11dd487..d18504bd2 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -34,6 +34,7 @@ endif
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += ipv4_multicast
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += kni
 DIRS-y += l2fwd
+DIRS-y += l2fwd-event
 ifneq ($(PQOS_INSTALL_PATH),)
 DIRS-y += l2fwd-cat
 endif
diff --git a/examples/l2fwd-event/Makefile b/examples/l2fwd-event/Makefile
new file mode 100644
index 000000000..73f02dd3b
--- /dev/null
+++ b/examples/l2fwd-event/Makefile
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2019 Marvell International Ltd.
+#
+
+# binary name
+APP = l2fwd-event
+
+# all source are stored in SRCS-y
+SRCS-y := main.c
+SRCS-y += l2fwd_poll.c
+SRCS-y += l2fwd_common.c
+
+# Build using pkg-config variables if possible
+ifeq ($(shell pkg-config --exists libdpdk && echo 0),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+	ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+	ln -sf $(APP)-static build/$(APP)
+
+PKGCONF=pkg-config --define-prefix
+
+PC_FILE := $(shell $(PKGCONF) --path libdpdk)
+CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)
+LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+	$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+	$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+	@mkdir -p $@
+
+.PHONY: clean
+clean:
+	rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+	test -d build && rmdir -p build || true
+
+else # Build using legacy build system
+
+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
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+endif
diff --git a/examples/l2fwd-event/l2fwd_common.c b/examples/l2fwd-event/l2fwd_common.c
new file mode 100644
index 000000000..8edbe1ba5
--- /dev/null
+++ b/examples/l2fwd-event/l2fwd_common.c
@@ -0,0 +1,138 @@
+#include "l2fwd_common.h"
+
+/* Print out statistics on packets dropped */
+void
+print_stats(struct l2fwd_resources *rsrc)
+{
+	uint64_t total_packets_dropped, total_packets_tx, total_packets_rx;
+	uint32_t port_id;
+
+	total_packets_dropped = 0;
+	total_packets_tx = 0;
+	total_packets_rx = 0;
+
+	const char clr[] = {27, '[', '2', 'J', '\0' };
+	const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0' };
+
+		/* Clear screen and move to top left */
+	printf("%s%s", clr, topLeft);
+
+	printf("\nPort statistics ====================================");
+
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
+		/* skip disabled ports */
+		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+			continue;
+		printf("\nStatistics for port %u ------------------------------"
+			   "\nPackets sent: %24"PRIu64
+			   "\nPackets received: %20"PRIu64
+			   "\nPackets dropped: %21"PRIu64,
+			   port_id,
+			   rsrc->port_stats[port_id].tx,
+			   rsrc->port_stats[port_id].rx,
+			   rsrc->port_stats[port_id].dropped);
+
+		total_packets_dropped +=
+					rsrc->port_stats[port_id].dropped;
+		total_packets_tx += rsrc->port_stats[port_id].tx;
+		total_packets_rx += rsrc->port_stats[port_id].rx;
+	}
+	printf("\nAggregate statistics ==============================="
+		   "\nTotal packets sent: %18"PRIu64
+		   "\nTotal packets received: %14"PRIu64
+		   "\nTotal packets dropped: %15"PRIu64,
+		   total_packets_tx,
+		   total_packets_rx,
+		   total_packets_dropped);
+	printf("\n====================================================\n");
+}
+
+int
+l2fwd_event_init_ports(struct l2fwd_resources *rsrc)
+{
+	uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
+	uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
+	struct rte_eth_conf port_conf = {
+		.rxmode = {
+			.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
+			.split_hdr_size = 0,
+		},
+		.txmode = {
+			.mq_mode = ETH_MQ_TX_NONE,
+		},
+	};
+	uint16_t nb_ports_available = 0;
+	uint16_t port_id;
+	int ret;
+
+	/* Initialise each port */
+	RTE_ETH_FOREACH_DEV(port_id) {
+		struct rte_eth_conf local_port_conf = port_conf;
+		struct rte_eth_dev_info dev_info;
+		struct rte_eth_rxconf rxq_conf;
+		struct rte_eth_txconf txq_conf;
+
+		/* skip ports that are not enabled */
+		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0) {
+			printf("Skipping disabled port %u\n", port_id);
+			continue;
+		}
+		nb_ports_available++;
+
+		/* init port */
+		printf("Initializing port %u... ", port_id);
+		fflush(stdout);
+		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_panic("Cannot configure device: err=%d, port=%u\n",
+				  ret, port_id);
+
+		ret = rte_eth_dev_adjust_nb_rx_tx_desc(port_id, &nb_rxd,
+						       &nb_txd);
+		if (ret < 0)
+			rte_panic("Cannot adjust number of descriptors: err=%d, port=%u\n",
+				  ret, port_id);
+
+		rte_eth_macaddr_get(port_id, &rsrc->eth_addr[port_id]);
+
+		/* init one RX queue */
+		fflush(stdout);
+		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,
+					     rsrc->pktmbuf_pool);
+		if (ret < 0)
+			rte_panic("rte_eth_rx_queue_setup:err=%d, port=%u\n",
+				  ret, port_id);
+
+		/* init one TX queue on each port */
+		fflush(stdout);
+		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_panic("rte_eth_tx_queue_setup:err=%d, port=%u\n",
+				  ret, port_id);
+
+		rte_eth_promiscuous_enable(port_id);
+
+		printf("Port %u,MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
+			port_id,
+			rsrc->eth_addr[port_id].addr_bytes[0],
+			rsrc->eth_addr[port_id].addr_bytes[1],
+			rsrc->eth_addr[port_id].addr_bytes[2],
+			rsrc->eth_addr[port_id].addr_bytes[3],
+			rsrc->eth_addr[port_id].addr_bytes[4],
+			rsrc->eth_addr[port_id].addr_bytes[5]);
+	}
+
+	return nb_ports_available;
+}
diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
new file mode 100644
index 000000000..0f6101fa5
--- /dev/null
+++ b/examples/l2fwd-event/l2fwd_common.h
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#ifndef __L2FWD_COMMON_H__
+#define __L2FWD_COMMON_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+#include <setjmp.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdbool.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_eal.h>
+#include <rte_launch.h>
+#include <rte_atomic.h>
+#include <rte_cycles.h>
+#include <rte_prefetch.h>
+#include <rte_lcore.h>
+#include <rte_per_lcore.h>
+#include <rte_branch_prediction.h>
+#include <rte_interrupts.h>
+#include <rte_random.h>
+#include <rte_debug.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_eventdev.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_spinlock.h>
+
+#define MAX_PKT_BURST 32
+#define MAX_RX_QUEUE_PER_LCORE 16
+#define MAX_TX_QUEUE_PER_PORT 16
+
+#define RTE_TEST_RX_DESC_DEFAULT 1024
+#define RTE_TEST_TX_DESC_DEFAULT 1024
+
+#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
+#define MEMPOOL_CACHE_SIZE 256
+
+#define DEFAULT_TIMER_PERIOD	10 /* default period is 10 seconds */
+#define MAX_TIMER_PERIOD	86400 /* 1 day max */
+
+/* Per-port statistics struct */
+struct l2fwd_port_statistics {
+	uint64_t dropped;
+	uint64_t tx;
+	uint64_t rx;
+} __rte_cache_aligned;
+
+struct l2fwd_resources {
+	volatile uint8_t force_quit;
+	uint8_t mac_updating;
+	uint8_t rx_queue_per_lcore;
+	uint16_t nb_rxd;
+	uint16_t nb_txd;
+	uint32_t enabled_port_mask;
+	uint64_t timer_period;
+	struct rte_mempool *pktmbuf_pool;
+	uint32_t dst_ports[RTE_MAX_ETHPORTS];
+	struct rte_ether_addr eth_addr[RTE_MAX_ETHPORTS];
+	struct l2fwd_port_statistics port_stats[RTE_MAX_ETHPORTS];
+	void *poll_rsrc;
+} __rte_cache_aligned;
+
+static __rte_always_inline void
+l2fwd_mac_updating(struct rte_mbuf *m, uint32_t dest_port_id,
+		   struct rte_ether_addr *addr)
+{
+	struct rte_ether_hdr *eth;
+	void *tmp;
+
+	eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
+
+	/* 02:00:00:00:00:xx */
+	tmp = &eth->d_addr.addr_bytes[0];
+	*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_port_id << 40);
+
+	/* src addr */
+	rte_ether_addr_copy(addr, &eth->s_addr);
+}
+
+static __rte_always_inline struct l2fwd_resources *
+l2fwd_get_rsrc(void)
+{
+	static const char name[RTE_MEMZONE_NAMESIZE] = "rsrc";
+	const struct rte_memzone *mz;
+
+	mz = rte_memzone_lookup(name);
+	if (mz != NULL)
+		return mz->addr;
+
+	mz = rte_memzone_reserve(name, sizeof(struct l2fwd_resources), 0, 0);
+	if (mz != NULL) {
+		struct l2fwd_resources *rsrc = mz->addr;
+
+		memset(rsrc, 0, sizeof(struct l2fwd_resources));
+		rsrc->mac_updating = true;
+		rsrc->rx_queue_per_lcore = 1;
+		rsrc->timer_period = 10 * rte_get_timer_hz();
+
+		return mz->addr;
+	}
+
+	rte_panic("Unable to allocate memory for l2fwd resources\n");
+
+	return NULL;
+}
+
+void print_stats(struct l2fwd_resources *rsrc);
+int l2fwd_event_init_ports(struct l2fwd_resources *rsrc);
+
+#endif /* __L2FWD_COMMON_H__ */
diff --git a/examples/l2fwd-event/l2fwd_poll.c b/examples/l2fwd-event/l2fwd_poll.c
new file mode 100644
index 000000000..b4eb39be2
--- /dev/null
+++ b/examples/l2fwd-event/l2fwd_poll.c
@@ -0,0 +1,193 @@
+#include "l2fwd_poll.h"
+
+static inline void
+l2fwd_poll_simple_forward(struct l2fwd_resources *rsrc, struct rte_mbuf *m,
+			  uint32_t portid)
+{
+	struct rte_eth_dev_tx_buffer *buffer;
+	uint32_t dst_port;
+	int sent;
+
+	dst_port = rsrc->dst_ports[portid];
+
+	if (rsrc->mac_updating)
+		l2fwd_mac_updating(m, dst_port, &rsrc->eth_addr[dst_port]);
+
+	buffer = ((struct l2fwd_poll_resources *)rsrc->poll_rsrc)->tx_buffer[
+								dst_port];
+	sent = rte_eth_tx_buffer(dst_port, 0, buffer, m);
+	if (sent)
+		rsrc->port_stats[dst_port].tx += sent;
+}
+
+/* main poll mode processing loop */
+static void
+l2fwd_poll_main_loop(struct l2fwd_resources *rsrc)
+{
+	uint8_t is_master = rte_lcore_id() == rte_get_master_lcore();
+	uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc, drain_tsc;
+	struct l2fwd_poll_resources *poll_rsrc = rsrc->poll_rsrc;
+	uint64_t timer_period = rsrc->timer_period;
+	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+	struct rte_eth_dev_tx_buffer *buf;
+	struct lcore_queue_conf *qconf;
+	uint32_t i, j, port_id, nb_rx;
+	struct rte_mbuf *m;
+	uint32_t lcore_id;
+	int32_t sent;
+
+	drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S *
+			BURST_TX_DRAIN_US;
+	prev_tsc = 0;
+	timer_tsc = 0;
+
+	lcore_id = rte_lcore_id();
+	qconf = &poll_rsrc->lcore_queue_conf[lcore_id];
+
+	if (qconf->n_rx_port == 0) {
+		printf("lcore %u has nothing to do\n", lcore_id);
+		return;
+	}
+
+	printf("entering main loop on lcore %u\n", lcore_id);
+
+	for (i = 0; i < qconf->n_rx_port; i++) {
+
+		port_id = qconf->rx_port_list[i];
+		printf(" -- lcoreid=%u port_id=%u\n", lcore_id, port_id);
+
+	}
+
+	while (!rsrc->force_quit) {
+
+		cur_tsc = rte_rdtsc();
+
+		/*
+		 * TX burst queue drain
+		 */
+		diff_tsc = cur_tsc - prev_tsc;
+		if (unlikely(diff_tsc > drain_tsc)) {
+			for (i = 0; i < qconf->n_rx_port; i++) {
+				port_id =
+					rsrc->dst_ports[qconf->rx_port_list[i]];
+				buf = poll_rsrc->tx_buffer[port_id];
+				sent = rte_eth_tx_buffer_flush(port_id, 0, buf);
+				if (sent)
+					rsrc->port_stats[port_id].tx += sent;
+			}
+
+			/* if timer is enabled */
+			if (is_master && timer_period > 0) {
+				/* advance the timer */
+				timer_tsc += diff_tsc;
+
+				/* if timer has reached its timeout */
+				if (unlikely(timer_tsc >= timer_period)) {
+					print_stats(rsrc);
+					/* reset the timer */
+					timer_tsc = 0;
+				}
+			}
+
+			prev_tsc = cur_tsc;
+		}
+
+		/*
+		 * Read packet from RX queues
+		 */
+		for (i = 0; i < qconf->n_rx_port; i++) {
+
+			port_id = qconf->rx_port_list[i];
+			nb_rx = rte_eth_rx_burst(port_id, 0, pkts_burst,
+						 MAX_PKT_BURST);
+
+			rsrc->port_stats[port_id].rx += nb_rx;
+
+			for (j = 0; j < nb_rx; j++) {
+				m = pkts_burst[j];
+				rte_prefetch0(rte_pktmbuf_mtod(m, void *));
+				l2fwd_poll_simple_forward(rsrc, m, port_id);
+			}
+		}
+	}
+}
+
+static void
+l2fwd_poll_lcore_config(struct l2fwd_resources *rsrc)
+{
+	struct l2fwd_poll_resources *poll_rsrc = rsrc->poll_rsrc;
+	struct lcore_queue_conf *qconf = NULL;
+	uint32_t rx_lcore_id = 0;
+	uint16_t port_id;
+
+	/* Initialize the port/queue configuration of each logical core */
+	RTE_ETH_FOREACH_DEV(port_id) {
+		/* skip ports that are not enabled */
+		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+			continue;
+
+		/* get the lcore_id for this port */
+		while (rte_lcore_is_enabled(rx_lcore_id) == 0 ||
+		       poll_rsrc->lcore_queue_conf[rx_lcore_id].n_rx_port ==
+		       rsrc->rx_queue_per_lcore) {
+			rx_lcore_id++;
+			if (rx_lcore_id >= RTE_MAX_LCORE)
+				rte_panic("Not enough cores\n");
+		}
+
+		if (qconf != &poll_rsrc->lcore_queue_conf[rx_lcore_id]) {
+			/* Assigned a new logical core in the loop above. */
+			qconf = &poll_rsrc->lcore_queue_conf[rx_lcore_id];
+		}
+
+		qconf->rx_port_list[qconf->n_rx_port] = port_id;
+		qconf->n_rx_port++;
+		printf("Lcore %u: RX port %u\n", rx_lcore_id, port_id);
+	}
+}
+
+static void
+l2fwd_poll_init_tx_buffers(struct l2fwd_resources *rsrc)
+{
+	struct l2fwd_poll_resources *poll_rsrc = rsrc->poll_rsrc;
+	uint16_t port_id;
+	int ret;
+
+	RTE_ETH_FOREACH_DEV(port_id) {
+		/* Initialize TX buffers */
+		poll_rsrc->tx_buffer[port_id] = rte_zmalloc_socket("tx_buffer",
+				RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0,
+				rte_eth_dev_socket_id(port_id));
+		if (poll_rsrc->tx_buffer[port_id] == NULL)
+			rte_panic("Cannot allocate buffer for tx on port %u\n",
+				  port_id);
+
+		rte_eth_tx_buffer_init(poll_rsrc->tx_buffer[port_id],
+				       MAX_PKT_BURST);
+
+		ret = rte_eth_tx_buffer_set_err_callback(
+				poll_rsrc->tx_buffer[port_id],
+				rte_eth_tx_buffer_count_callback,
+				&rsrc->port_stats[port_id].dropped);
+		if (ret < 0)
+			rte_panic("Cannot set error callback for tx buffer on port %u\n",
+				  port_id);
+	}
+}
+
+void
+l2fwd_poll_resource_setup(struct l2fwd_resources *rsrc)
+{
+	struct l2fwd_poll_resources *poll_rsrc;
+
+	poll_rsrc = rte_zmalloc("l2fwd_poll_rsrc",
+				sizeof(struct l2fwd_poll_resources), 0);
+	if (poll_rsrc == NULL)
+		rte_panic("Failed to allocate resources for l2fwd poll mode\n");
+
+	rsrc->poll_rsrc = poll_rsrc;
+	l2fwd_poll_lcore_config(rsrc);
+	l2fwd_poll_init_tx_buffers(rsrc);
+
+	poll_rsrc->poll_main_loop = l2fwd_poll_main_loop;
+}
diff --git a/examples/l2fwd-event/l2fwd_poll.h b/examples/l2fwd-event/l2fwd_poll.h
new file mode 100644
index 000000000..d59b0c844
--- /dev/null
+++ b/examples/l2fwd-event/l2fwd_poll.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#ifndef __L2FWD_POLL_H__
+#define __L2FWD_POLL_H__
+
+#include "l2fwd_common.h"
+
+typedef void (*poll_main_loop_cb)(struct l2fwd_resources *rsrc);
+
+struct lcore_queue_conf {
+	uint32_t rx_port_list[MAX_RX_QUEUE_PER_LCORE];
+	uint32_t n_rx_port;
+} __rte_cache_aligned;
+
+struct l2fwd_poll_resources {
+	poll_main_loop_cb poll_main_loop;
+	struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS];
+	struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];
+};
+
+void l2fwd_poll_resource_setup(struct l2fwd_resources *rsrc);
+
+#endif
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
new file mode 100644
index 000000000..11092b0d6
--- /dev/null
+++ b/examples/l2fwd-event/main.c
@@ -0,0 +1,371 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#include "l2fwd_poll.h"
+
+/* display usage */
+static void
+l2fwd_event_usage(const char *prgname)
+{
+	printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
+	       "  -p PORTMASK: hexadecimal bitmask of ports to configure\n"
+	       "  -q NQ: number of queue (=ports) per lcore (default is 1)\n"
+	       "  -T PERIOD: statistics will be refreshed each PERIOD seconds "
+	       "		(0 to disable, 10 default, 86400 maximum)\n"
+	       "  --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n"
+	       "      When enabled:\n"
+	       "       - The source MAC address is replaced by the TX port MAC address\n"
+	       "       - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n",
+	       prgname);
+}
+
+static int
+l2fwd_event_parse_portmask(const char *portmask)
+{
+	char *end = NULL;
+	unsigned long pm;
+
+	/* parse hexadecimal string */
+	pm = strtoul(portmask, &end, 16);
+	if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
+		return -1;
+
+	if (pm == 0)
+		return -1;
+
+	return pm;
+}
+
+static unsigned int
+l2fwd_event_parse_nqueue(const char *q_arg)
+{
+	char *end = NULL;
+	unsigned long n;
+
+	/* parse hexadecimal string */
+	n = strtoul(q_arg, &end, 10);
+	if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
+		return 0;
+	if (n == 0)
+		return 0;
+	if (n >= MAX_RX_QUEUE_PER_LCORE)
+		return 0;
+
+	return n;
+}
+
+static int
+l2fwd_event_parse_timer_period(const char *q_arg)
+{
+	char *end = NULL;
+	int n;
+
+	/* parse number string */
+	n = strtol(q_arg, &end, 10);
+	if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
+		return -1;
+	if (n >= MAX_TIMER_PERIOD)
+		return -1;
+
+	return n;
+}
+
+static const char short_options[] =
+	"p:"  /* portmask */
+	"q:"  /* number of queues */
+	"T:"  /* timer period */
+	;
+
+#define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
+#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
+
+enum {
+	/* long options mapped to a short option */
+
+	/* first long only option value must be >= 256, so that we won't
+	 * conflict with short options
+	 */
+	CMD_LINE_OPT_MIN_NUM = 256,
+};
+
+/* Parse the argument given in the command line of the application */
+static int
+l2fwd_event_parse_args(int argc, char **argv,
+		struct l2fwd_resources *rsrc)
+{
+	int mac_updating = 1;
+	struct option lgopts[] = {
+		{ CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1},
+		{ CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0},
+		{NULL, 0, 0, 0}
+	};
+	int opt, ret, timer_secs;
+	char *prgname = argv[0];
+	char **argvopt;
+	int option_index;
+
+	argvopt = argv;
+	while ((opt = getopt_long(argc, argvopt, short_options,
+				  lgopts, &option_index)) != EOF) {
+
+		switch (opt) {
+		/* portmask */
+		case 'p':
+			rsrc->enabled_port_mask =
+					l2fwd_event_parse_portmask(optarg);
+			if (rsrc->enabled_port_mask == 0) {
+				printf("invalid portmask\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			break;
+
+		/* nqueue */
+		case 'q':
+			rsrc->rx_queue_per_lcore =
+					l2fwd_event_parse_nqueue(optarg);
+			if (rsrc->rx_queue_per_lcore == 0) {
+				printf("invalid queue number\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			break;
+
+		/* timer period */
+		case 'T':
+			timer_secs = l2fwd_event_parse_timer_period(optarg);
+			if (timer_secs < 0) {
+				printf("invalid timer period\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			rsrc->timer_period = timer_secs;
+			/* convert to number of cycles */
+			rsrc->timer_period *= rte_get_timer_hz();
+			break;
+
+		/* long options */
+		case 0:
+			break;
+
+		default:
+			l2fwd_event_usage(prgname);
+			return -1;
+		}
+	}
+
+	rsrc->mac_updating = mac_updating;
+
+	if (optind >= 0)
+		argv[optind-1] = prgname;
+
+	ret = optind-1;
+	optind = 1; /* reset getopt lib */
+	return ret;
+}
+
+static int
+l2fwd_launch_one_lcore(void *args)
+{
+	struct l2fwd_resources *rsrc = args;
+	struct l2fwd_poll_resources *poll_rsrc = rsrc->poll_rsrc;
+
+	poll_rsrc->poll_main_loop(rsrc);
+
+	return 0;
+}
+
+/* Check the link status of all ports in up to 9s, and print them finally */
+static void
+check_all_ports_link_status(struct l2fwd_resources *rsrc,
+			    uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+	uint16_t port_id;
+	uint8_t count, all_ports_up, print_flag = 0;
+	struct rte_eth_link link;
+
+	printf("\nChecking link status...");
+	fflush(stdout);
+	for (count = 0; count <= MAX_CHECK_TIME; count++) {
+		if (rsrc->force_quit)
+			return;
+		all_ports_up = 1;
+		RTE_ETH_FOREACH_DEV(port_id) {
+			if (rsrc->force_quit)
+				return;
+			if ((port_mask & (1 << port_id)) == 0)
+				continue;
+			memset(&link, 0, sizeof(link));
+			rte_eth_link_get_nowait(port_id, &link);
+			/* print link status if flag set */
+			if (print_flag == 1) {
+				if (link.link_status)
+					printf(
+					"Port%d Link Up. Speed %u Mbps - %s\n",
+						port_id, link.link_speed,
+				(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+					("full-duplex") : ("half-duplex\n"));
+				else
+					printf("Port %d Link Down\n", port_id);
+				continue;
+			}
+			/* clear all_ports_up flag if any link down */
+			if (link.link_status == ETH_LINK_DOWN) {
+				all_ports_up = 0;
+				break;
+			}
+		}
+		/* after finally printing all link status, get out */
+		if (print_flag == 1)
+			break;
+
+		if (all_ports_up == 0) {
+			printf(".");
+			fflush(stdout);
+			rte_delay_ms(CHECK_INTERVAL);
+		}
+
+		/* set the print_flag if all ports up or timeout */
+		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+			print_flag = 1;
+			printf("done\n");
+		}
+	}
+}
+
+static void
+signal_handler(int signum)
+{
+	struct l2fwd_resources *rsrc = l2fwd_get_rsrc();
+	if (signum == SIGINT || signum == SIGTERM) {
+		printf("\n\nSignal %d received, preparing to exit...\n",
+				signum);
+		rsrc->force_quit = true;
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	struct l2fwd_resources *rsrc;
+	uint16_t nb_ports_available = 0;
+	uint32_t nb_ports_in_mask = 0;
+	uint16_t port_id, last_port;
+	uint32_t nb_mbufs;
+	uint16_t nb_ports;
+	int ret;
+
+	/* init EAL */
+	ret = rte_eal_init(argc, argv);
+	if (ret < 0)
+		rte_panic("Invalid EAL arguments\n");
+	argc -= ret;
+	argv += ret;
+
+	rsrc = l2fwd_get_rsrc();
+
+	signal(SIGINT, signal_handler);
+	signal(SIGTERM, signal_handler);
+
+	/* parse application arguments (after the EAL ones) */
+	ret = l2fwd_event_parse_args(argc, argv, rsrc);
+	if (ret < 0)
+		rte_panic("Invalid L2FWD arguments\n");
+
+	printf("MAC updating %s\n", rsrc->mac_updating ? "enabled" :
+			"disabled");
+
+	nb_ports = rte_eth_dev_count_avail();
+	if (nb_ports == 0)
+		rte_panic("No Ethernet ports - bye\n");
+
+	/* check port mask to possible port mask */
+	if (rsrc->enabled_port_mask & ~((1 << nb_ports) - 1))
+		rte_panic("Invalid portmask; possible (0x%x)\n",
+			(1 << nb_ports) - 1);
+
+	/* reset l2fwd_dst_ports */
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+		rsrc->dst_ports[port_id] = 0;
+	last_port = 0;
+
+	/*
+	 * Each logical core is assigned a dedicated TX queue on each port.
+	 */
+	RTE_ETH_FOREACH_DEV(port_id) {
+		/* skip ports that are not enabled */
+		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+			continue;
+
+		if (nb_ports_in_mask % 2) {
+			rsrc->dst_ports[port_id] = last_port;
+			rsrc->dst_ports[last_port] = port_id;
+		} else {
+			last_port = port_id;
+		}
+
+		nb_ports_in_mask++;
+	}
+	if (nb_ports_in_mask % 2) {
+		printf("Notice: odd number of ports in portmask.\n");
+		rsrc->dst_ports[last_port] = last_port;
+	}
+
+	nb_mbufs = RTE_MAX(nb_ports * (RTE_TEST_RX_DESC_DEFAULT +
+				       RTE_TEST_TX_DESC_DEFAULT +
+				       MAX_PKT_BURST + rte_lcore_count() *
+				       MEMPOOL_CACHE_SIZE), 8192U);
+
+	/* create the mbuf pool */
+	rsrc->pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool",
+			nb_mbufs, MEMPOOL_CACHE_SIZE, 0,
+			RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+	if (rsrc->pktmbuf_pool == NULL)
+		rte_panic("Cannot init mbuf pool\n");
+
+	nb_ports_available = l2fwd_event_init_ports(rsrc);
+	if (!nb_ports_available)
+		rte_panic("All available ports are disabled. Please set portmask.\n");
+
+	l2fwd_poll_resource_setup(rsrc);
+
+	/* initialize port stats */
+	memset(&rsrc->port_stats, 0,
+					sizeof(struct l2fwd_port_statistics));
+
+	/* All settings are done. Now enable eth devices */
+	RTE_ETH_FOREACH_DEV(port_id) {
+		/* skip ports that are not enabled */
+		if ((rsrc->enabled_port_mask &
+					(1 << port_id)) == 0)
+			continue;
+
+		ret = rte_eth_dev_start(port_id);
+		if (ret < 0)
+			rte_panic("rte_eth_dev_start:err=%d, port=%u\n", ret,
+				  port_id);
+	}
+
+	check_all_ports_link_status(rsrc, rsrc->enabled_port_mask);
+
+	/* launch per-lcore init on every lcore */
+	rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, rsrc,
+				 CALL_MASTER);
+	rte_eal_mp_wait_lcore();
+
+	RTE_ETH_FOREACH_DEV(port_id) {
+		if ((rsrc->enabled_port_mask &
+						(1 << port_id)) == 0)
+			continue;
+		printf("Closing port %d...", port_id);
+		rte_eth_dev_stop(port_id);
+		rte_eth_dev_close(port_id);
+		printf(" Done\n");
+	}
+	printf("Bye...\n");
+
+	return 0;
+}
diff --git a/examples/l2fwd-event/meson.build b/examples/l2fwd-event/meson.build
new file mode 100644
index 000000000..c936aa72e
--- /dev/null
+++ b/examples/l2fwd-event/meson.build
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2019 Marvell International Ltd.
+#
+
+# 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'
+
+deps += 'eventdev'
+sources = files(
+	'main.c',
+	'l2fwd_poll.c',
+	'l2fwd_common.c',
+)
diff --git a/examples/meson.build b/examples/meson.build
index a046b74ad..0b02640bf 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -19,7 +19,7 @@ all_examples = [
 	'ip_fragmentation', 'ip_pipeline',
 	'ip_reassembly', 'ipsec-secgw',
 	'ipv4_multicast', 'kni',
-	'l2fwd', 'l2fwd-cat',
+	'l2fwd', 'l2fwd-cat', 'l2fwd-event',
 	'l2fwd-crypto', 'l2fwd-jobstats',
 	'l2fwd-keepalive', 'l3fwd',
 	'l3fwd-acl', 'l3fwd-power',
-- 
2.17.1


  reply	other threads:[~2019-10-14 18:23 UTC|newest]

Thread overview: 108+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-19  9:25 [dpdk-dev] [PATCH v2 00/10] example/l2fwd-event: introduce l2fwd-event example pbhagavatula
2019-09-19  9:25 ` [dpdk-dev] [PATCH v2 01/10] examples/l2fwd-event: add default poll mode routines pbhagavatula
2019-09-19  9:43   ` Sunil Kumar Kori
2019-09-19 10:13   ` [dpdk-dev] [PATCH v3 00/10] example/l2fwd-event: introduce l2fwd-event example pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 01/10] examples/l2fwd-event: add default poll mode routines pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 02/10] examples/l2fwd-event: add infra for eventdev pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 03/10] examples/l2fwd-event: add infra to split eventdev framework pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 04/10] examples/l2fwd-event: add eth port setup for eventdev pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 05/10] examples/l2fwd-event: add eventdev queue and port setup pbhagavatula
2019-09-19 10:35       ` Sunil Kumar Kori
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 06/10] examples/l2fwd-event: add event Rx/Tx adapter setup pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 07/10] examples/l2fwd-event: add service core setup pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 08/10] examples/l2fwd-event: add eventdev main loop pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 09/10] examples/l2fwd-event: add graceful teardown pbhagavatula
2019-09-19 10:13     ` [dpdk-dev] [PATCH v3 10/10] doc: add application usage guide for l2fwd-event pbhagavatula
2019-09-24  9:41     ` [dpdk-dev] [PATCH v4 00/10] example/l2fwd-event: introduce l2fwd-event example pbhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 01/10] examples/l2fwd-event: add default poll mode routines pbhagavatula
2019-09-26 17:28         ` Jerin Jacob
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 02/10] examples/l2fwd-event: add infra for eventdev pbhagavatula
2019-09-26 17:33         ` Jerin Jacob
2019-09-27 13:08         ` Nipun Gupta
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 03/10] examples/l2fwd-event: add infra to split eventdev framework pbhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 04/10] examples/l2fwd-event: add eth port setup for eventdev pbhagavatula
2019-09-27 13:15         ` Nipun Gupta
2019-09-27 14:45           ` Pavan Nikhilesh Bhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 05/10] examples/l2fwd-event: add eventdev queue and port setup pbhagavatula
2019-09-27 13:22         ` Nipun Gupta
2019-09-27 14:43           ` Pavan Nikhilesh Bhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 06/10] examples/l2fwd-event: add event Rx/Tx adapter setup pbhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 07/10] examples/l2fwd-event: add service core setup pbhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 08/10] examples/l2fwd-event: add eventdev main loop pbhagavatula
2019-09-27 13:28         ` Nipun Gupta
2019-09-27 14:35           ` Pavan Nikhilesh Bhagavatula
2019-09-30  5:38             ` Nipun Gupta
2019-09-30  6:38               ` Jerin Jacob
2019-09-30  7:46                 ` Nipun Gupta
2019-09-30  8:09                   ` Pavan Nikhilesh Bhagavatula
2019-09-30 17:50                     ` Nipun Gupta
2019-10-01  5:59                       ` Pavan Nikhilesh Bhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 09/10] examples/l2fwd-event: add graceful teardown pbhagavatula
2019-09-24  9:42       ` [dpdk-dev] [PATCH v4 10/10] doc: add application usage guide for l2fwd-event pbhagavatula
2019-09-26 17:42         ` Jerin Jacob
2019-10-02 20:57       ` [dpdk-dev] [PATCH v5 00/10] example/l2fwd-event: introduce l2fwd-event example pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 01/10] examples/l2fwd-event: add default poll mode routines pbhagavatula
2019-10-11 14:41           ` Jerin Jacob
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 02/10] examples/l2fwd-event: add infra for eventdev pbhagavatula
2019-10-04 12:30           ` Nipun Gupta
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 03/10] examples/l2fwd-event: add infra to split eventdev framework pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 04/10] examples/l2fwd-event: add event device setup pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 05/10] examples/l2fwd-event: add eventdev queue and port setup pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 06/10] examples/l2fwd-event: add event Rx/Tx adapter setup pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 07/10] examples/l2fwd-event: add service core setup pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 08/10] examples/l2fwd-event: add eventdev main loop pbhagavatula
2019-10-11 14:52           ` Jerin Jacob
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 09/10] examples/l2fwd-event: add graceful teardown pbhagavatula
2019-10-02 20:57         ` [dpdk-dev] [PATCH v5 10/10] doc: add application usage guide for l2fwd-event pbhagavatula
2019-10-11 14:11           ` Jerin Jacob
2019-10-03 10:33         ` [dpdk-dev] [PATCH v5 00/10] example/l2fwd-event: introduce l2fwd-event example Jerin Jacob
2019-10-03 12:40           ` Hemant Agrawal
2019-10-03 12:47             ` Jerin Jacob
2019-10-09  7:50         ` Nipun Gupta
2019-10-14 18:22         ` [dpdk-dev] [PATCH v6 " pbhagavatula
2019-10-14 18:22           ` pbhagavatula [this message]
2019-10-16 19:07             ` [dpdk-dev] [PATCH v6 01/10] examples/l2fwd-event: add default poll mode routines Stephen Hemminger
2019-10-21  3:29             ` Varghese, Vipin
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 02/10] examples/l2fwd-event: add infra for eventdev pbhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 03/10] examples/l2fwd-event: add infra to split eventdev framework pbhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 04/10] examples/l2fwd-event: add event device setup pbhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 05/10] examples/l2fwd-event: add eventdev queue and port setup pbhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 06/10] examples/l2fwd-event: add event Rx/Tx adapter setup pbhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 07/10] examples/l2fwd-event: add service core setup pbhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 08/10] examples/l2fwd-event: add eventdev main loop pbhagavatula
2019-10-21  3:19             ` Varghese, Vipin
2019-10-21 16:53               ` Pavan Nikhilesh Bhagavatula
2019-10-22  3:13                 ` Varghese, Vipin
2019-10-22 17:02                   ` Pavan Nikhilesh Bhagavatula
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 09/10] examples/l2fwd-event: add graceful teardown pbhagavatula
2019-10-21  3:12             ` Varghese, Vipin
2019-10-21 16:56               ` Pavan Nikhilesh Bhagavatula
2019-10-22  2:48                 ` Varghese, Vipin
2019-10-14 18:22           ` [dpdk-dev] [PATCH v6 10/10] doc: add application usage guide for l2fwd-event pbhagavatula
2019-10-16 12:38           ` [dpdk-dev] [PATCH v6 00/10] example/l2fwd-event: introduce l2fwd-event example Jerin Jacob
2019-10-21  3:25           ` Varghese, Vipin
2019-10-21 17:02             ` Pavan Nikhilesh Bhagavatula
2019-10-22  2:57               ` Varghese, Vipin
2019-10-22 15:55                 ` Pavan Nikhilesh Bhagavatula
2019-10-26 11:10           ` [dpdk-dev] [PATCH v7 " pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 01/10] examples/l2fwd-event: add default poll mode routines pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 02/10] examples/l2fwd-event: add infra for eventdev pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 03/10] examples/l2fwd-event: add infra to split eventdev framework pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 04/10] examples/l2fwd-event: add event device setup pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 05/10] examples/l2fwd-event: add eventdev queue and port setup pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 06/10] examples/l2fwd-event: add event Rx/Tx adapter setup pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 07/10] examples/l2fwd-event: add service core setup pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 08/10] examples/l2fwd-event: add eventdev main loop pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 09/10] examples/l2fwd-event: add graceful teardown pbhagavatula
2019-10-26 11:10             ` [dpdk-dev] [PATCH v7 10/10] doc: add application usage guide for l2fwd-event pbhagavatula
2019-10-30 13:19               ` Jerin Jacob
2019-10-30 12:58             ` [dpdk-dev] [PATCH v7 00/10] example/l2fwd-event: introduce l2fwd-event example Jerin Jacob
2019-09-19  9:25 ` [dpdk-dev] [PATCH v2 02/10] examples/l2fwd-event: add infra for eventdev pbhagavatula
2019-09-19  9:25 ` [dpdk-dev] [PATCH v2 03/10] examples/l2fwd-event: add infra to split eventdev framework pbhagavatula
2019-09-19  9:25 ` [dpdk-dev] [PATCH v2 04/10] examples/l2fwd-event: add eth port setup for eventdev pbhagavatula
2019-09-19  9:25 ` [dpdk-dev] [PATCH v2 05/10] examples/l2fwd-event: add eventdev queue and port setup pbhagavatula
2019-09-19  9:26 ` [dpdk-dev] [PATCH v2 06/10] examples/l2fwd-event: add event Rx/Tx adapter setup pbhagavatula
2019-09-19  9:26 ` [dpdk-dev] [PATCH v2 07/10] examples/l2fwd-event: add service core setup pbhagavatula
2019-09-19  9:26 ` [dpdk-dev] [PATCH v2 08/10] examples/l2fwd-event: add eventdev main loop pbhagavatula
2019-09-19  9:26 ` [dpdk-dev] [PATCH v2 09/10] examples/l2fwd-event: add graceful teardown pbhagavatula
2019-10-17  4:08 [dpdk-dev] [PATCH v6 01/10] examples/l2fwd-event: add default poll mode routines Pavan Nikhilesh Bhagavatula

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=20191014182247.961-2-pbhagavatula@marvell.com \
    --to=pbhagavatula@marvell.com \
    --cc=akhil.goyal@nxp.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=hemant.agrawal@nxp.com \
    --cc=jerinj@marvell.com \
    --cc=marko.kovacevic@intel.com \
    --cc=orika@mellanox.com \
    --cc=radu.nicolau@intel.com \
    --cc=skori@marvell.com \
    --cc=thomas@monjalon.net \
    --cc=tomasz.kantecki@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.