[v5,08/10] examples/l2fwd-event: add eventdev main loop

Message ID 20191002205754.11746-9-pbhagavatula@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Jerin Jacob
Headers
Series example/l2fwd-event: introduce l2fwd-event example |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Pavan Nikhilesh Bhagavatula Oct. 2, 2019, 8:57 p.m. UTC
  From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Add event dev main loop based on enabled l2fwd options and eventdev
capabilities.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 examples/l2fwd-event/l2fwd_common.c |   6 +
 examples/l2fwd-event/l2fwd_common.h |   2 +
 examples/l2fwd-event/l2fwd_event.c  | 294 ++++++++++++++++++++++++++++
 examples/l2fwd-event/l2fwd_event.h  |   2 +
 examples/l2fwd-event/main.c         |   6 +-
 5 files changed, 309 insertions(+), 1 deletion(-)
  

Comments

Jerin Jacob Oct. 11, 2019, 2:52 p.m. UTC | #1
On Thu, Oct 3, 2019 at 2:29 AM <pbhagavatula@marvell.com> wrote:
>
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
> Add event dev main loop based on enabled l2fwd options and eventdev
> capabilities.
>
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
>  examples/l2fwd-event/l2fwd_common.c |   6 +
>  examples/l2fwd-event/l2fwd_common.h |   2 +
>  examples/l2fwd-event/l2fwd_event.c  | 294 ++++++++++++++++++++++++++++
>  examples/l2fwd-event/l2fwd_event.h  |   2 +
>  examples/l2fwd-event/main.c         |   6 +-
>  5 files changed, 309 insertions(+), 1 deletion(-)
>
> diff --git a/examples/l2fwd-event/l2fwd_common.c b/examples/l2fwd-event/l2fwd_common.c
> index 213652d72..40e933c91 100644
> --- a/examples/l2fwd-event/l2fwd_common.c
> +++ b/examples/l2fwd-event/l2fwd_common.c
> @@ -65,6 +65,12 @@ l2fwd_event_init_ports(struct l2fwd_resources *l2fwd_rsrc)
>         uint16_t port_id;
>         int ret;
>
> +       if (l2fwd_rsrc->event_mode) {
> +               port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
> +               port_conf.rx_adv_conf.rss_conf.rss_key = NULL;
> +               port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP;
> +       }
> +
>         /* Initialise each port */
>         RTE_ETH_FOREACH_DEV(port_id) {
>                 struct rte_eth_conf local_port_conf = port_conf;
> diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
> index cdafa52c7..852c6d321 100644
> --- a/examples/l2fwd-event/l2fwd_common.h
> +++ b/examples/l2fwd-event/l2fwd_common.h
> @@ -114,7 +114,9 @@ l2fwd_get_rsrc(void)
>
>                 memset(l2fwd_rsrc, 0, sizeof(struct l2fwd_resources));
>                 l2fwd_rsrc->mac_updating = true;
> +               l2fwd_rsrc->event_mode = true;
>                 l2fwd_rsrc->rx_queue_per_lcore = 1;
> +               l2fwd_rsrc->sched_type = RTE_SCHED_TYPE_ATOMIC;
>                 l2fwd_rsrc->timer_period = 10 * rte_get_timer_hz();
>
>                 return mz->addr;
> diff --git a/examples/l2fwd-event/l2fwd_event.c b/examples/l2fwd-event/l2fwd_event.c
> index adba40069..df0b56773 100644
> --- a/examples/l2fwd-event/l2fwd_event.c
> +++ b/examples/l2fwd-event/l2fwd_event.c
> @@ -17,6 +17,12 @@
>
>  #include "l2fwd_event.h"
>
> +#define L2FWD_EVENT_SINGLE     0x1
> +#define L2FWD_EVENT_BURST      0x2
> +#define L2FWD_EVENT_TX_DIRECT  0x4
> +#define L2FWD_EVENT_TX_ENQ     0x8
> +#define L2FWD_EVENT_UPDT_MAC   0x10
> +
>  static inline int
>  l2fwd_event_service_enable(uint32_t service_id)
>  {
> @@ -128,11 +134,289 @@ l2fwd_event_capability_setup(struct l2fwd_event_resources *event_rsrc)
>                 l2fwd_event_set_internal_port_ops(&event_rsrc->ops);
>  }
>
> +static __rte_noinline int
> +l2fwd_get_free_event_port(struct l2fwd_event_resources *event_rsrc)
> +{
> +       static int index;
> +       int port_id;
> +
> +       rte_spinlock_lock(&event_rsrc->evp.lock);
> +       if (index >= event_rsrc->evp.nb_ports) {
> +               printf("No free event port is available\n");
> +               return -1;
> +       }
> +
> +       port_id = event_rsrc->evp.event_p_id[index];
> +       index++;
> +       rte_spinlock_unlock(&event_rsrc->evp.lock);
> +
> +       return port_id;
> +}
> +
> +static __rte_always_inline void
> +l2fwd_event_loop_single(struct l2fwd_resources *l2fwd_rsrc,
> +                       const uint32_t flags)
> +{
> +       const uint8_t is_master = rte_get_master_lcore() == rte_lcore_id();
> +       struct l2fwd_event_resources *event_rsrc = l2fwd_rsrc->event_rsrc;
> +       const int port_id = l2fwd_get_free_event_port(event_rsrc);
> +       uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
> +       const uint64_t timer_period = l2fwd_rsrc->timer_period;
> +       const uint8_t tx_q_id = event_rsrc->evq.event_q_id[
> +                                       event_rsrc->evq.nb_queues - 1];

See below

> +       const uint8_t event_d_id = event_rsrc->event_d_id;
> +       struct rte_mbuf *mbuf;
> +       uint16_t dst_port;
> +       struct rte_event ev;
> +
> +       if (port_id < 0)
> +               return;
> +
> +       printf("%s(): entering eventdev main loop on lcore %u\n", __func__,
> +               rte_lcore_id());
> +
> +       while (!l2fwd_rsrc->force_quit) {
> +               /* if timer is enabled */
> +               if (is_master && timer_period > 0) {
> +                       cur_tsc = rte_rdtsc();
> +                       diff_tsc = cur_tsc - prev_tsc;
> +
> +                       /* advance the timer */
> +                       timer_tsc += diff_tsc;
> +
> +                       /* if timer has reached its timeout */
> +                       if (unlikely(timer_tsc >= timer_period)) {
> +                               print_stats(l2fwd_rsrc);
> +                               /* reset the timer */
> +                               timer_tsc = 0;
> +                       }
> +                       prev_tsc = cur_tsc;
> +               }
> +
> +               /* Read packet from eventdev */
> +               if (!rte_event_dequeue_burst(event_d_id, port_id, &ev, 1, 0))
> +                       continue;
> +
> +
> +               mbuf = ev.mbuf;
> +               dst_port = l2fwd_rsrc->dst_ports[mbuf->port];
> +               rte_prefetch0(rte_pktmbuf_mtod(mbuf, void *));
> +
> +               if (timer_period > 0)
> +                       __atomic_fetch_add(
> +                                       &l2fwd_rsrc->port_stats[mbuf->port].rx,
> +                                       1, __ATOMIC_RELAXED);
> +
> +               mbuf->port = dst_port;
> +               if (flags & L2FWD_EVENT_UPDT_MAC)
> +                       l2fwd_mac_updating(mbuf, dst_port,
> +                                          &l2fwd_rsrc->eth_addr[dst_port]);

See below

> +
> +               if (flags & L2FWD_EVENT_TX_ENQ) {
> +                       ev.queue_id = tx_q_id;
> +                       ev.op = RTE_EVENT_OP_FORWARD;
> +                       while (rte_event_enqueue_burst(event_d_id, port_id,
> +                                                      &ev, 1) &&
> +                                       !l2fwd_rsrc->force_quit)
> +                               ;
> +               }
> +
> +               if (flags & L2FWD_EVENT_TX_DIRECT) {
> +                       rte_event_eth_tx_adapter_txq_set(mbuf, 0);
> +                       while (!rte_event_eth_tx_adapter_enqueue(event_d_id,
> +                                                               port_id,
> +                                                               &ev, 1) &&

See below

> +                                       !l2fwd_rsrc->force_quit)
> +                               ;
> +               }
> +
> +               if (timer_period > 0)
> +                       __atomic_fetch_add(
> +                                       &l2fwd_rsrc->port_stats[mbuf->port].tx,
> +                                       1, __ATOMIC_RELAXED);

As style comment:

# There is a lot of multiline statements in the code, which reduce the
readability of the code. Please find below some options to reduce it.
Could you please check options to reduce it

1) shorten the structure name like
 s/event_rsrc/evt_rsrc
 s/l2fwd_rsrc/ rsrc

2) I think, rte_exit(EXIT_FAILURE can be replaced to rte_panic in the
application case

3) Adjusting the newline code starts
diff --git a/examples/l2fwd-event/l2fwd_event.c
b/examples/l2fwd-event/l2fwd_event.c
index df0b56773..49665a102 100644
--- a/examples/l2fwd-event/l2fwd_event.c
+++ b/examples/l2fwd-event/l2fwd_event.c
@@ -87,8 +87,8 @@ l2fwd_event_service_setup(struct l2fwd_resources *l2fwd_rsrc)
                                &service_id);
                if (ret != -ESRCH && ret != 0)
                        rte_exit(EXIT_FAILURE,
-                                       "Error in starting Rx
adapter[%d] service\n",
-                                       event_rsrc->rx_adptr.rx_adptr[i]);
+                                "Error in starting Rx adapter[%d] service\n",
+                                event_rsrc->rx_adptr.rx_adptr[i]);
                l2fwd_event_service_enable(service_id);
        }

4) Replace code in the nested loop with static inline function so that code gets
enough space in new function.
  

Patch

diff --git a/examples/l2fwd-event/l2fwd_common.c b/examples/l2fwd-event/l2fwd_common.c
index 213652d72..40e933c91 100644
--- a/examples/l2fwd-event/l2fwd_common.c
+++ b/examples/l2fwd-event/l2fwd_common.c
@@ -65,6 +65,12 @@  l2fwd_event_init_ports(struct l2fwd_resources *l2fwd_rsrc)
 	uint16_t port_id;
 	int ret;
 
+	if (l2fwd_rsrc->event_mode) {
+		port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
+		port_conf.rx_adv_conf.rss_conf.rss_key = NULL;
+		port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP;
+	}
+
 	/* Initialise each port */
 	RTE_ETH_FOREACH_DEV(port_id) {
 		struct rte_eth_conf local_port_conf = port_conf;
diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
index cdafa52c7..852c6d321 100644
--- a/examples/l2fwd-event/l2fwd_common.h
+++ b/examples/l2fwd-event/l2fwd_common.h
@@ -114,7 +114,9 @@  l2fwd_get_rsrc(void)
 
 		memset(l2fwd_rsrc, 0, sizeof(struct l2fwd_resources));
 		l2fwd_rsrc->mac_updating = true;
+		l2fwd_rsrc->event_mode = true;
 		l2fwd_rsrc->rx_queue_per_lcore = 1;
+		l2fwd_rsrc->sched_type = RTE_SCHED_TYPE_ATOMIC;
 		l2fwd_rsrc->timer_period = 10 * rte_get_timer_hz();
 
 		return mz->addr;
diff --git a/examples/l2fwd-event/l2fwd_event.c b/examples/l2fwd-event/l2fwd_event.c
index adba40069..df0b56773 100644
--- a/examples/l2fwd-event/l2fwd_event.c
+++ b/examples/l2fwd-event/l2fwd_event.c
@@ -17,6 +17,12 @@ 
 
 #include "l2fwd_event.h"
 
+#define L2FWD_EVENT_SINGLE	0x1
+#define L2FWD_EVENT_BURST	0x2
+#define L2FWD_EVENT_TX_DIRECT	0x4
+#define L2FWD_EVENT_TX_ENQ	0x8
+#define L2FWD_EVENT_UPDT_MAC	0x10
+
 static inline int
 l2fwd_event_service_enable(uint32_t service_id)
 {
@@ -128,11 +134,289 @@  l2fwd_event_capability_setup(struct l2fwd_event_resources *event_rsrc)
 		l2fwd_event_set_internal_port_ops(&event_rsrc->ops);
 }
 
+static __rte_noinline int
+l2fwd_get_free_event_port(struct l2fwd_event_resources *event_rsrc)
+{
+	static int index;
+	int port_id;
+
+	rte_spinlock_lock(&event_rsrc->evp.lock);
+	if (index >= event_rsrc->evp.nb_ports) {
+		printf("No free event port is available\n");
+		return -1;
+	}
+
+	port_id = event_rsrc->evp.event_p_id[index];
+	index++;
+	rte_spinlock_unlock(&event_rsrc->evp.lock);
+
+	return port_id;
+}
+
+static __rte_always_inline void
+l2fwd_event_loop_single(struct l2fwd_resources *l2fwd_rsrc,
+			const uint32_t flags)
+{
+	const uint8_t is_master = rte_get_master_lcore() == rte_lcore_id();
+	struct l2fwd_event_resources *event_rsrc = l2fwd_rsrc->event_rsrc;
+	const int port_id = l2fwd_get_free_event_port(event_rsrc);
+	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
+	const uint64_t timer_period = l2fwd_rsrc->timer_period;
+	const uint8_t tx_q_id = event_rsrc->evq.event_q_id[
+					event_rsrc->evq.nb_queues - 1];
+	const uint8_t event_d_id = event_rsrc->event_d_id;
+	struct rte_mbuf *mbuf;
+	uint16_t dst_port;
+	struct rte_event ev;
+
+	if (port_id < 0)
+		return;
+
+	printf("%s(): entering eventdev main loop on lcore %u\n", __func__,
+		rte_lcore_id());
+
+	while (!l2fwd_rsrc->force_quit) {
+		/* if timer is enabled */
+		if (is_master && timer_period > 0) {
+			cur_tsc = rte_rdtsc();
+			diff_tsc = cur_tsc - prev_tsc;
+
+			/* advance the timer */
+			timer_tsc += diff_tsc;
+
+			/* if timer has reached its timeout */
+			if (unlikely(timer_tsc >= timer_period)) {
+				print_stats(l2fwd_rsrc);
+				/* reset the timer */
+				timer_tsc = 0;
+			}
+			prev_tsc = cur_tsc;
+		}
+
+		/* Read packet from eventdev */
+		if (!rte_event_dequeue_burst(event_d_id, port_id, &ev, 1, 0))
+			continue;
+
+
+		mbuf = ev.mbuf;
+		dst_port = l2fwd_rsrc->dst_ports[mbuf->port];
+		rte_prefetch0(rte_pktmbuf_mtod(mbuf, void *));
+
+		if (timer_period > 0)
+			__atomic_fetch_add(
+					&l2fwd_rsrc->port_stats[mbuf->port].rx,
+					1, __ATOMIC_RELAXED);
+
+		mbuf->port = dst_port;
+		if (flags & L2FWD_EVENT_UPDT_MAC)
+			l2fwd_mac_updating(mbuf, dst_port,
+					   &l2fwd_rsrc->eth_addr[dst_port]);
+
+		if (flags & L2FWD_EVENT_TX_ENQ) {
+			ev.queue_id = tx_q_id;
+			ev.op = RTE_EVENT_OP_FORWARD;
+			while (rte_event_enqueue_burst(event_d_id, port_id,
+						       &ev, 1) &&
+					!l2fwd_rsrc->force_quit)
+				;
+		}
+
+		if (flags & L2FWD_EVENT_TX_DIRECT) {
+			rte_event_eth_tx_adapter_txq_set(mbuf, 0);
+			while (!rte_event_eth_tx_adapter_enqueue(event_d_id,
+								port_id,
+								&ev, 1) &&
+					!l2fwd_rsrc->force_quit)
+				;
+		}
+
+		if (timer_period > 0)
+			__atomic_fetch_add(
+					&l2fwd_rsrc->port_stats[mbuf->port].tx,
+					1, __ATOMIC_RELAXED);
+	}
+}
+
+static __rte_always_inline void
+l2fwd_event_loop_burst(struct l2fwd_resources *l2fwd_rsrc,
+		       const uint32_t flags)
+{
+	const uint8_t is_master = rte_get_master_lcore() == rte_lcore_id();
+	struct l2fwd_event_resources *event_rsrc = l2fwd_rsrc->event_rsrc;
+	const int port_id = l2fwd_get_free_event_port(event_rsrc);
+	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
+	const uint64_t timer_period = l2fwd_rsrc->timer_period;
+	const uint8_t tx_q_id = event_rsrc->evq.event_q_id[
+					event_rsrc->evq.nb_queues - 1];
+	const uint8_t event_d_id = event_rsrc->event_d_id;
+	const uint8_t deq_len = event_rsrc->deq_depth;
+	struct rte_event ev[MAX_PKT_BURST];
+	struct rte_mbuf *mbuf;
+	uint16_t nb_rx, nb_tx;
+	uint16_t dst_port;
+	uint8_t i;
+
+	if (port_id < 0)
+		return;
+
+	printf("%s(): entering eventdev main loop on lcore %u\n", __func__,
+		rte_lcore_id());
+
+	while (!l2fwd_rsrc->force_quit) {
+		/* if timer is enabled */
+		if (is_master && timer_period > 0) {
+			cur_tsc = rte_rdtsc();
+			diff_tsc = cur_tsc - prev_tsc;
+
+			/* advance the timer */
+			timer_tsc += diff_tsc;
+
+			/* if timer has reached its timeout */
+			if (unlikely(timer_tsc >= timer_period)) {
+				print_stats(l2fwd_rsrc);
+				/* reset the timer */
+				timer_tsc = 0;
+			}
+			prev_tsc = cur_tsc;
+		}
+
+		/* Read packet from eventdev */
+		nb_rx = rte_event_dequeue_burst(event_d_id, port_id, ev,
+						deq_len, 0);
+		if (nb_rx == 0)
+			continue;
+
+
+		for (i = 0; i < nb_rx; i++) {
+			mbuf = ev[i].mbuf;
+			dst_port = l2fwd_rsrc->dst_ports[mbuf->port];
+			rte_prefetch0(rte_pktmbuf_mtod(mbuf, void *));
+
+			if (timer_period > 0) {
+				__atomic_fetch_add(
+					&l2fwd_rsrc->port_stats[mbuf->port].rx,
+					1, __ATOMIC_RELAXED);
+				__atomic_fetch_add(
+					&l2fwd_rsrc->port_stats[mbuf->port].tx,
+					1, __ATOMIC_RELAXED);
+			}
+			mbuf->port = dst_port;
+			if (flags & L2FWD_EVENT_UPDT_MAC)
+				l2fwd_mac_updating(mbuf, dst_port,
+						   &l2fwd_rsrc->eth_addr[
+								dst_port]);
+
+			if (flags & L2FWD_EVENT_TX_ENQ) {
+				ev[i].queue_id = tx_q_id;
+				ev[i].op = RTE_EVENT_OP_FORWARD;
+			}
+
+			if (flags & L2FWD_EVENT_TX_DIRECT)
+				rte_event_eth_tx_adapter_txq_set(mbuf, 0);
+
+		}
+
+		if (flags & L2FWD_EVENT_TX_ENQ) {
+			nb_tx = rte_event_enqueue_burst(event_d_id, port_id,
+							ev, nb_rx);
+			while (nb_tx < nb_rx && !l2fwd_rsrc->force_quit)
+				nb_tx += rte_event_enqueue_burst(event_d_id,
+						port_id, ev + nb_tx,
+						nb_rx - nb_tx);
+		}
+
+		if (flags & L2FWD_EVENT_TX_DIRECT) {
+			nb_tx = rte_event_eth_tx_adapter_enqueue(event_d_id,
+								 port_id, ev,
+								 nb_rx);
+			while (nb_tx < nb_rx && !l2fwd_rsrc->force_quit)
+				nb_tx += rte_event_eth_tx_adapter_enqueue(
+						event_d_id, port_id,
+						ev + nb_tx, nb_rx - nb_tx);
+		}
+	}
+}
+
+static __rte_always_inline void
+l2fwd_event_loop(struct l2fwd_resources *l2fwd_rsrc,
+			const uint32_t flags)
+{
+	if (flags & L2FWD_EVENT_SINGLE)
+		l2fwd_event_loop_single(l2fwd_rsrc, flags);
+	if (flags & L2FWD_EVENT_BURST)
+		l2fwd_event_loop_burst(l2fwd_rsrc, flags);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_d(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc,
+			 L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_SINGLE);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_d_brst(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_BURST);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_q(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_SINGLE);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_q_brst(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_BURST);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_d_mac(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_UPDT_MAC |
+			L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_SINGLE);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_d_brst_mac(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_UPDT_MAC |
+			L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_BURST);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_q_mac(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_UPDT_MAC |
+			L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_SINGLE);
+}
+
+static void __rte_noinline
+l2fwd_event_main_loop_tx_q_brst_mac(struct l2fwd_resources *l2fwd_rsrc)
+{
+	l2fwd_event_loop(l2fwd_rsrc, L2FWD_EVENT_UPDT_MAC |
+			L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_BURST);
+}
+
 void
 l2fwd_event_resource_setup(struct l2fwd_resources *l2fwd_rsrc)
 {
+	/* [MAC_UPDT][TX_MODE][BURST] */
+	const event_loop_cb event_loop[2][2][2] = {
+		[0][0][0] = l2fwd_event_main_loop_tx_d,
+		[0][0][1] = l2fwd_event_main_loop_tx_d_brst,
+		[0][1][0] = l2fwd_event_main_loop_tx_q,
+		[0][1][1] = l2fwd_event_main_loop_tx_q_brst,
+		[1][0][0] = l2fwd_event_main_loop_tx_d_mac,
+		[1][0][1] = l2fwd_event_main_loop_tx_d_brst_mac,
+		[1][1][0] = l2fwd_event_main_loop_tx_q_mac,
+		[1][1][1] = l2fwd_event_main_loop_tx_q_brst_mac,
+	};
 	struct l2fwd_event_resources *event_rsrc;
 	uint32_t event_queue_cfg;
+	int ret;
 
 	if (!rte_event_dev_count())
 		rte_exit(EXIT_FAILURE, "No Eventdev found\n");
@@ -158,4 +442,14 @@  l2fwd_event_resource_setup(struct l2fwd_resources *l2fwd_rsrc)
 
 	/* Rx/Tx adapters configuration */
 	event_rsrc->ops.adapter_setup(l2fwd_rsrc);
+
+	/* Start event device */
+	ret = rte_event_dev_start(event_rsrc->event_d_id);
+	if (ret < 0)
+		rte_exit(EXIT_FAILURE, "Error in starting eventdev");
+
+	event_rsrc->ops.l2fwd_event_loop = event_loop
+					[l2fwd_rsrc->mac_updating]
+					[event_rsrc->tx_mode_q]
+					[event_rsrc->has_burst];
 }
diff --git a/examples/l2fwd-event/l2fwd_event.h b/examples/l2fwd-event/l2fwd_event.h
index e0c589f93..cef7b5d1a 100644
--- a/examples/l2fwd-event/l2fwd_event.h
+++ b/examples/l2fwd-event/l2fwd_event.h
@@ -18,6 +18,7 @@  typedef void (*event_port_setup_cb)(struct l2fwd_resources *l2fwd_rsrc);
 typedef void (*event_queue_setup_cb)(struct l2fwd_resources *l2fwd_rsrc,
 				     uint32_t event_queue_cfg);
 typedef void (*adapter_setup_cb)(struct l2fwd_resources *l2fwd_rsrc);
+typedef void (*event_loop_cb)(struct l2fwd_resources *l2fwd_rsrc);
 
 struct event_queues {
 	uint8_t *event_q_id;
@@ -47,6 +48,7 @@  struct event_setup_ops {
 	event_queue_setup_cb event_queue_setup;
 	event_port_setup_cb event_port_setup;
 	adapter_setup_cb adapter_setup;
+	event_loop_cb l2fwd_event_loop;
 };
 
 struct l2fwd_event_resources {
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 3c27bfb4f..958a6e0b7 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -212,8 +212,12 @@  l2fwd_launch_one_lcore(void *args)
 {
 	struct l2fwd_resources *l2fwd_rsrc = args;
 	struct l2fwd_poll_resources *poll_rsrc = l2fwd_rsrc->poll_rsrc;
+	struct l2fwd_event_resources *event_rsrc = l2fwd_rsrc->event_rsrc;
 
-	poll_rsrc->poll_main_loop(l2fwd_rsrc);
+	if (l2fwd_rsrc->event_mode)
+		event_rsrc->ops.l2fwd_event_loop(l2fwd_rsrc);
+	else
+		poll_rsrc->poll_main_loop(l2fwd_rsrc);
 
 	return 0;
 }