From: Pavan Nikhilesh <pbhagavat...@marvell.com> Add event dev main loop based on enabled l2fwd options and eventdev capabilities.
Signed-off-by: Pavan Nikhilesh <pbhagavat...@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]; + 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; } -- 2.17.1