11b2143aaSPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause 21b2143aaSPavan Nikhilesh * Copyright(C) 2019 Marvell International Ltd. 31b2143aaSPavan Nikhilesh */ 41b2143aaSPavan Nikhilesh 51b2143aaSPavan Nikhilesh #include <stdbool.h> 61b2143aaSPavan Nikhilesh #include <getopt.h> 71b2143aaSPavan Nikhilesh 81b2143aaSPavan Nikhilesh #include <rte_cycles.h> 91b2143aaSPavan Nikhilesh #include <rte_ethdev.h> 101b2143aaSPavan Nikhilesh #include <rte_eventdev.h> 111b2143aaSPavan Nikhilesh #include <rte_event_eth_rx_adapter.h> 121b2143aaSPavan Nikhilesh #include <rte_event_eth_tx_adapter.h> 131b2143aaSPavan Nikhilesh #include <rte_lcore.h> 141b2143aaSPavan Nikhilesh #include <rte_malloc.h> 151b2143aaSPavan Nikhilesh #include <rte_spinlock.h> 161b2143aaSPavan Nikhilesh 171b2143aaSPavan Nikhilesh #include "l2fwd_event.h" 181b2143aaSPavan Nikhilesh 19080f57bcSPavan Nikhilesh #define L2FWD_EVENT_SINGLE 0x1 20080f57bcSPavan Nikhilesh #define L2FWD_EVENT_BURST 0x2 21080f57bcSPavan Nikhilesh #define L2FWD_EVENT_TX_DIRECT 0x4 22080f57bcSPavan Nikhilesh #define L2FWD_EVENT_TX_ENQ 0x8 23080f57bcSPavan Nikhilesh #define L2FWD_EVENT_UPDT_MAC 0x10 24080f57bcSPavan Nikhilesh 25bcb6f841SPavan Nikhilesh static inline int 26bcb6f841SPavan Nikhilesh l2fwd_event_service_enable(uint32_t service_id) 27bcb6f841SPavan Nikhilesh { 28bcb6f841SPavan Nikhilesh uint8_t min_service_count = UINT8_MAX; 29bcb6f841SPavan Nikhilesh uint32_t slcore_array[RTE_MAX_LCORE]; 30bcb6f841SPavan Nikhilesh unsigned int slcore = 0; 31bcb6f841SPavan Nikhilesh uint8_t service_count; 32bcb6f841SPavan Nikhilesh int32_t slcore_count; 33bcb6f841SPavan Nikhilesh 34bcb6f841SPavan Nikhilesh if (!rte_service_lcore_count()) 35bcb6f841SPavan Nikhilesh return -ENOENT; 36bcb6f841SPavan Nikhilesh 37bcb6f841SPavan Nikhilesh slcore_count = rte_service_lcore_list(slcore_array, RTE_MAX_LCORE); 38bcb6f841SPavan Nikhilesh if (slcore_count < 0) 39bcb6f841SPavan Nikhilesh return -ENOENT; 40bcb6f841SPavan Nikhilesh /* Get the core which has least number of services running. */ 41bcb6f841SPavan Nikhilesh while (slcore_count--) { 42bcb6f841SPavan Nikhilesh /* Reset default mapping */ 438b33aa7eSPavan Nikhilesh if (rte_service_map_lcore_set(service_id, 448b33aa7eSPavan Nikhilesh slcore_array[slcore_count], 0) != 0) 458b33aa7eSPavan Nikhilesh return -ENOENT; 46bcb6f841SPavan Nikhilesh service_count = rte_service_lcore_count_services( 47bcb6f841SPavan Nikhilesh slcore_array[slcore_count]); 48bcb6f841SPavan Nikhilesh if (service_count < min_service_count) { 49bcb6f841SPavan Nikhilesh slcore = slcore_array[slcore_count]; 50bcb6f841SPavan Nikhilesh min_service_count = service_count; 51bcb6f841SPavan Nikhilesh } 52bcb6f841SPavan Nikhilesh } 538b33aa7eSPavan Nikhilesh if (rte_service_map_lcore_set(service_id, slcore, 1) != 0) 54bcb6f841SPavan Nikhilesh return -ENOENT; 55bcb6f841SPavan Nikhilesh rte_service_lcore_start(slcore); 56bcb6f841SPavan Nikhilesh 57bcb6f841SPavan Nikhilesh return 0; 58bcb6f841SPavan Nikhilesh } 59bcb6f841SPavan Nikhilesh 60bcb6f841SPavan Nikhilesh void 61bcb6f841SPavan Nikhilesh l2fwd_event_service_setup(struct l2fwd_resources *rsrc) 62bcb6f841SPavan Nikhilesh { 63bcb6f841SPavan Nikhilesh struct l2fwd_event_resources *evt_rsrc = rsrc->evt_rsrc; 64bcb6f841SPavan Nikhilesh struct rte_event_dev_info evdev_info; 65bcb6f841SPavan Nikhilesh uint32_t service_id, caps; 66bcb6f841SPavan Nikhilesh int ret, i; 67bcb6f841SPavan Nikhilesh 689a212dc0SConor Fogarty /* Running eventdev scheduler service on service core. 8< */ 69bcb6f841SPavan Nikhilesh rte_event_dev_info_get(evt_rsrc->event_d_id, &evdev_info); 70345a22d5SPavan Nikhilesh if (!(evdev_info.event_dev_cap & RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED)) { 71bcb6f841SPavan Nikhilesh ret = rte_event_dev_service_id_get(evt_rsrc->event_d_id, 72bcb6f841SPavan Nikhilesh &service_id); 73bcb6f841SPavan Nikhilesh if (ret != -ESRCH && ret != 0) 74bcb6f841SPavan Nikhilesh rte_panic("Error in starting eventdev service\n"); 75bcb6f841SPavan Nikhilesh l2fwd_event_service_enable(service_id); 76bcb6f841SPavan Nikhilesh } 779a212dc0SConor Fogarty /* >8 End of running eventdev scheduler service on service core. */ 78bcb6f841SPavan Nikhilesh 799a212dc0SConor Fogarty /* Gets service ID for RX/TX adapters. 8< */ 80bcb6f841SPavan Nikhilesh for (i = 0; i < evt_rsrc->rx_adptr.nb_rx_adptr; i++) { 81bcb6f841SPavan Nikhilesh ret = rte_event_eth_rx_adapter_caps_get(evt_rsrc->event_d_id, 82bcb6f841SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i], &caps); 83bcb6f841SPavan Nikhilesh if (ret < 0) 84bcb6f841SPavan Nikhilesh rte_panic("Failed to get Rx adapter[%d] caps\n", 85bcb6f841SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i]); 86bcb6f841SPavan Nikhilesh ret = rte_event_eth_rx_adapter_service_id_get( 87bcb6f841SPavan Nikhilesh evt_rsrc->event_d_id, 88bcb6f841SPavan Nikhilesh &service_id); 89bcb6f841SPavan Nikhilesh if (ret != -ESRCH && ret != 0) 90bcb6f841SPavan Nikhilesh rte_panic("Error in starting Rx adapter[%d] service\n", 91bcb6f841SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i]); 92bcb6f841SPavan Nikhilesh l2fwd_event_service_enable(service_id); 93bcb6f841SPavan Nikhilesh } 94bcb6f841SPavan Nikhilesh 95bcb6f841SPavan Nikhilesh for (i = 0; i < evt_rsrc->tx_adptr.nb_tx_adptr; i++) { 96bcb6f841SPavan Nikhilesh ret = rte_event_eth_tx_adapter_caps_get(evt_rsrc->event_d_id, 97bcb6f841SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i], &caps); 98bcb6f841SPavan Nikhilesh if (ret < 0) 99bcb6f841SPavan Nikhilesh rte_panic("Failed to get Rx adapter[%d] caps\n", 100bcb6f841SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i]); 101bcb6f841SPavan Nikhilesh ret = rte_event_eth_tx_adapter_service_id_get( 102bcb6f841SPavan Nikhilesh evt_rsrc->event_d_id, 103bcb6f841SPavan Nikhilesh &service_id); 104bcb6f841SPavan Nikhilesh if (ret != -ESRCH && ret != 0) 105bcb6f841SPavan Nikhilesh rte_panic("Error in starting Rx adapter[%d] service\n", 106bcb6f841SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i]); 107bcb6f841SPavan Nikhilesh l2fwd_event_service_enable(service_id); 108bcb6f841SPavan Nikhilesh } 1099a212dc0SConor Fogarty /* >8 End of get service ID for RX/TX adapters. */ 110bcb6f841SPavan Nikhilesh } 111bcb6f841SPavan Nikhilesh 11269de9488SSunil Kumar Kori static void 11369de9488SSunil Kumar Kori l2fwd_event_capability_setup(struct l2fwd_event_resources *evt_rsrc) 11469de9488SSunil Kumar Kori { 11569de9488SSunil Kumar Kori uint32_t caps = 0; 11669de9488SSunil Kumar Kori uint16_t i; 11769de9488SSunil Kumar Kori int ret; 11869de9488SSunil Kumar Kori 11969de9488SSunil Kumar Kori RTE_ETH_FOREACH_DEV(i) { 12069de9488SSunil Kumar Kori ret = rte_event_eth_tx_adapter_caps_get(0, i, &caps); 12169de9488SSunil Kumar Kori if (ret) 12269de9488SSunil Kumar Kori rte_panic("Invalid capability for Tx adptr port %d\n", 12369de9488SSunil Kumar Kori i); 12469de9488SSunil Kumar Kori 12569de9488SSunil Kumar Kori evt_rsrc->tx_mode_q |= !(caps & 12669de9488SSunil Kumar Kori RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT); 12769de9488SSunil Kumar Kori } 12869de9488SSunil Kumar Kori 12969de9488SSunil Kumar Kori if (evt_rsrc->tx_mode_q) 13069de9488SSunil Kumar Kori l2fwd_event_set_generic_ops(&evt_rsrc->ops); 13169de9488SSunil Kumar Kori else 13269de9488SSunil Kumar Kori l2fwd_event_set_internal_port_ops(&evt_rsrc->ops); 13369de9488SSunil Kumar Kori } 13469de9488SSunil Kumar Kori 135080f57bcSPavan Nikhilesh static __rte_noinline int 136080f57bcSPavan Nikhilesh l2fwd_get_free_event_port(struct l2fwd_event_resources *evt_rsrc) 137080f57bcSPavan Nikhilesh { 138080f57bcSPavan Nikhilesh static int index; 139080f57bcSPavan Nikhilesh int port_id; 140080f57bcSPavan Nikhilesh 141080f57bcSPavan Nikhilesh rte_spinlock_lock(&evt_rsrc->evp.lock); 142080f57bcSPavan Nikhilesh if (index >= evt_rsrc->evp.nb_ports) { 143080f57bcSPavan Nikhilesh printf("No free event port is available\n"); 144*1f41deacSHemant Agrawal rte_spinlock_unlock(&evt_rsrc->evp.lock); 145080f57bcSPavan Nikhilesh return -1; 146080f57bcSPavan Nikhilesh } 147080f57bcSPavan Nikhilesh 148080f57bcSPavan Nikhilesh port_id = evt_rsrc->evp.event_p_id[index]; 149080f57bcSPavan Nikhilesh index++; 150080f57bcSPavan Nikhilesh rte_spinlock_unlock(&evt_rsrc->evp.lock); 151080f57bcSPavan Nikhilesh 152080f57bcSPavan Nikhilesh return port_id; 153080f57bcSPavan Nikhilesh } 154080f57bcSPavan Nikhilesh 155080f57bcSPavan Nikhilesh static __rte_always_inline void 156080f57bcSPavan Nikhilesh l2fwd_event_fwd(struct l2fwd_resources *rsrc, struct rte_event *ev, 157080f57bcSPavan Nikhilesh const uint8_t tx_q_id, const uint64_t timer_period, 158080f57bcSPavan Nikhilesh const uint32_t flags) 159080f57bcSPavan Nikhilesh { 160080f57bcSPavan Nikhilesh struct rte_mbuf *mbuf = ev->mbuf; 161080f57bcSPavan Nikhilesh uint16_t dst_port; 162080f57bcSPavan Nikhilesh 163080f57bcSPavan Nikhilesh rte_prefetch0(rte_pktmbuf_mtod(mbuf, void *)); 164080f57bcSPavan Nikhilesh dst_port = rsrc->dst_ports[mbuf->port]; 165080f57bcSPavan Nikhilesh 166080f57bcSPavan Nikhilesh if (timer_period > 0) 16792e68d9cSTyler Retzlaff rte_atomic_fetch_add_explicit(&rsrc->port_stats[mbuf->port].rx, 16892e68d9cSTyler Retzlaff 1, rte_memory_order_relaxed); 169080f57bcSPavan Nikhilesh mbuf->port = dst_port; 170080f57bcSPavan Nikhilesh 171080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_UPDT_MAC) 172080f57bcSPavan Nikhilesh l2fwd_mac_updating(mbuf, dst_port, &rsrc->eth_addr[dst_port]); 173080f57bcSPavan Nikhilesh 174080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_TX_ENQ) { 175080f57bcSPavan Nikhilesh ev->queue_id = tx_q_id; 176080f57bcSPavan Nikhilesh ev->op = RTE_EVENT_OP_FORWARD; 177080f57bcSPavan Nikhilesh } 178080f57bcSPavan Nikhilesh 179080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_TX_DIRECT) 180080f57bcSPavan Nikhilesh rte_event_eth_tx_adapter_txq_set(mbuf, 0); 181080f57bcSPavan Nikhilesh 182080f57bcSPavan Nikhilesh if (timer_period > 0) 18392e68d9cSTyler Retzlaff rte_atomic_fetch_add_explicit(&rsrc->port_stats[mbuf->port].tx, 18492e68d9cSTyler Retzlaff 1, rte_memory_order_relaxed); 185080f57bcSPavan Nikhilesh } 186080f57bcSPavan Nikhilesh 187080f57bcSPavan Nikhilesh static __rte_always_inline void 188080f57bcSPavan Nikhilesh l2fwd_event_loop_single(struct l2fwd_resources *rsrc, 189080f57bcSPavan Nikhilesh const uint32_t flags) 190080f57bcSPavan Nikhilesh { 191080f57bcSPavan Nikhilesh struct l2fwd_event_resources *evt_rsrc = rsrc->evt_rsrc; 192080f57bcSPavan Nikhilesh const int port_id = l2fwd_get_free_event_port(evt_rsrc); 193080f57bcSPavan Nikhilesh const uint8_t tx_q_id = evt_rsrc->evq.event_q_id[ 194080f57bcSPavan Nikhilesh evt_rsrc->evq.nb_queues - 1]; 195080f57bcSPavan Nikhilesh const uint64_t timer_period = rsrc->timer_period; 196080f57bcSPavan Nikhilesh const uint8_t event_d_id = evt_rsrc->event_d_id; 197622ebb6bSPavan Nikhilesh uint8_t enq = 0, deq = 0; 198080f57bcSPavan Nikhilesh struct rte_event ev; 199080f57bcSPavan Nikhilesh 200080f57bcSPavan Nikhilesh if (port_id < 0) 201080f57bcSPavan Nikhilesh return; 202080f57bcSPavan Nikhilesh 203080f57bcSPavan Nikhilesh printf("%s(): entering eventdev main loop on lcore %u\n", __func__, 204080f57bcSPavan Nikhilesh rte_lcore_id()); 205080f57bcSPavan Nikhilesh 206080f57bcSPavan Nikhilesh while (!rsrc->force_quit) { 207080f57bcSPavan Nikhilesh /* Read packet from eventdev */ 208622ebb6bSPavan Nikhilesh deq = rte_event_dequeue_burst(event_d_id, port_id, &ev, 1, 0); 209622ebb6bSPavan Nikhilesh if (!deq) 210080f57bcSPavan Nikhilesh continue; 211080f57bcSPavan Nikhilesh 212080f57bcSPavan Nikhilesh l2fwd_event_fwd(rsrc, &ev, tx_q_id, timer_period, flags); 213080f57bcSPavan Nikhilesh 214080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_TX_ENQ) { 215622ebb6bSPavan Nikhilesh do { 216622ebb6bSPavan Nikhilesh enq = rte_event_enqueue_burst(event_d_id, 217622ebb6bSPavan Nikhilesh port_id, &ev, 1); 218622ebb6bSPavan Nikhilesh } while (!enq && !rsrc->force_quit); 219080f57bcSPavan Nikhilesh } 220080f57bcSPavan Nikhilesh 221080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_TX_DIRECT) { 222622ebb6bSPavan Nikhilesh do { 223622ebb6bSPavan Nikhilesh enq = rte_event_eth_tx_adapter_enqueue( 224622ebb6bSPavan Nikhilesh event_d_id, port_id, &ev, 1, 0); 225622ebb6bSPavan Nikhilesh } while (!enq && !rsrc->force_quit); 226080f57bcSPavan Nikhilesh } 227080f57bcSPavan Nikhilesh } 228622ebb6bSPavan Nikhilesh 229622ebb6bSPavan Nikhilesh l2fwd_event_worker_cleanup(event_d_id, port_id, &ev, enq, deq, 0); 230080f57bcSPavan Nikhilesh } 231080f57bcSPavan Nikhilesh 232080f57bcSPavan Nikhilesh static __rte_always_inline void 233080f57bcSPavan Nikhilesh l2fwd_event_loop_burst(struct l2fwd_resources *rsrc, 234080f57bcSPavan Nikhilesh const uint32_t flags) 235080f57bcSPavan Nikhilesh { 236080f57bcSPavan Nikhilesh struct l2fwd_event_resources *evt_rsrc = rsrc->evt_rsrc; 237080f57bcSPavan Nikhilesh const int port_id = l2fwd_get_free_event_port(evt_rsrc); 238080f57bcSPavan Nikhilesh const uint8_t tx_q_id = evt_rsrc->evq.event_q_id[ 239080f57bcSPavan Nikhilesh evt_rsrc->evq.nb_queues - 1]; 240080f57bcSPavan Nikhilesh const uint64_t timer_period = rsrc->timer_period; 241080f57bcSPavan Nikhilesh const uint8_t event_d_id = evt_rsrc->event_d_id; 242080f57bcSPavan Nikhilesh const uint8_t deq_len = evt_rsrc->deq_depth; 243080f57bcSPavan Nikhilesh struct rte_event ev[MAX_PKT_BURST]; 244622ebb6bSPavan Nikhilesh uint16_t nb_rx = 0, nb_tx = 0; 245080f57bcSPavan Nikhilesh uint8_t i; 246080f57bcSPavan Nikhilesh 247080f57bcSPavan Nikhilesh if (port_id < 0) 248080f57bcSPavan Nikhilesh return; 249080f57bcSPavan Nikhilesh 250080f57bcSPavan Nikhilesh printf("%s(): entering eventdev main loop on lcore %u\n", __func__, 251080f57bcSPavan Nikhilesh rte_lcore_id()); 252080f57bcSPavan Nikhilesh 253080f57bcSPavan Nikhilesh while (!rsrc->force_quit) { 2549a212dc0SConor Fogarty /* Read packet from eventdev. 8< */ 255080f57bcSPavan Nikhilesh nb_rx = rte_event_dequeue_burst(event_d_id, port_id, ev, 256080f57bcSPavan Nikhilesh deq_len, 0); 257080f57bcSPavan Nikhilesh if (nb_rx == 0) 258080f57bcSPavan Nikhilesh continue; 259080f57bcSPavan Nikhilesh 260080f57bcSPavan Nikhilesh for (i = 0; i < nb_rx; i++) { 261080f57bcSPavan Nikhilesh l2fwd_event_fwd(rsrc, &ev[i], tx_q_id, timer_period, 262080f57bcSPavan Nikhilesh flags); 263080f57bcSPavan Nikhilesh } 2649a212dc0SConor Fogarty /* >8 End of reading packets from eventdev. */ 265080f57bcSPavan Nikhilesh 266080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_TX_ENQ) { 2679a212dc0SConor Fogarty /* Forwarding to destination ports. 8< */ 268080f57bcSPavan Nikhilesh nb_tx = rte_event_enqueue_burst(event_d_id, port_id, 269080f57bcSPavan Nikhilesh ev, nb_rx); 270080f57bcSPavan Nikhilesh while (nb_tx < nb_rx && !rsrc->force_quit) 271080f57bcSPavan Nikhilesh nb_tx += rte_event_enqueue_burst(event_d_id, 272080f57bcSPavan Nikhilesh port_id, ev + nb_tx, 273080f57bcSPavan Nikhilesh nb_rx - nb_tx); 2749a212dc0SConor Fogarty /* >8 End of forwarding to destination ports. */ 275080f57bcSPavan Nikhilesh } 276080f57bcSPavan Nikhilesh 277080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_TX_DIRECT) { 278080f57bcSPavan Nikhilesh nb_tx = rte_event_eth_tx_adapter_enqueue(event_d_id, 279080f57bcSPavan Nikhilesh port_id, ev, 280080f57bcSPavan Nikhilesh nb_rx, 0); 281080f57bcSPavan Nikhilesh while (nb_tx < nb_rx && !rsrc->force_quit) 282080f57bcSPavan Nikhilesh nb_tx += rte_event_eth_tx_adapter_enqueue( 283080f57bcSPavan Nikhilesh event_d_id, port_id, 284080f57bcSPavan Nikhilesh ev + nb_tx, nb_rx - nb_tx, 0); 285080f57bcSPavan Nikhilesh } 286080f57bcSPavan Nikhilesh } 287622ebb6bSPavan Nikhilesh 2887af8167aSShijith Thotton l2fwd_event_worker_cleanup(event_d_id, port_id, ev, nb_tx, nb_rx, 0); 289080f57bcSPavan Nikhilesh } 290080f57bcSPavan Nikhilesh 291080f57bcSPavan Nikhilesh static __rte_always_inline void 292080f57bcSPavan Nikhilesh l2fwd_event_loop(struct l2fwd_resources *rsrc, 293080f57bcSPavan Nikhilesh const uint32_t flags) 294080f57bcSPavan Nikhilesh { 295080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_SINGLE) 296080f57bcSPavan Nikhilesh l2fwd_event_loop_single(rsrc, flags); 297080f57bcSPavan Nikhilesh if (flags & L2FWD_EVENT_BURST) 298080f57bcSPavan Nikhilesh l2fwd_event_loop_burst(rsrc, flags); 299080f57bcSPavan Nikhilesh } 300080f57bcSPavan Nikhilesh 301080f57bcSPavan Nikhilesh static void __rte_noinline 302080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_d(struct l2fwd_resources *rsrc) 303080f57bcSPavan Nikhilesh { 304080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, 305080f57bcSPavan Nikhilesh L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_SINGLE); 306080f57bcSPavan Nikhilesh } 307080f57bcSPavan Nikhilesh 308080f57bcSPavan Nikhilesh static void __rte_noinline 309080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_d_brst(struct l2fwd_resources *rsrc) 310080f57bcSPavan Nikhilesh { 311080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_BURST); 312080f57bcSPavan Nikhilesh } 313080f57bcSPavan Nikhilesh 314080f57bcSPavan Nikhilesh static void __rte_noinline 315080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_q(struct l2fwd_resources *rsrc) 316080f57bcSPavan Nikhilesh { 317080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_SINGLE); 318080f57bcSPavan Nikhilesh } 319080f57bcSPavan Nikhilesh 320080f57bcSPavan Nikhilesh static void __rte_noinline 321080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_q_brst(struct l2fwd_resources *rsrc) 322080f57bcSPavan Nikhilesh { 323080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_BURST); 324080f57bcSPavan Nikhilesh } 325080f57bcSPavan Nikhilesh 326080f57bcSPavan Nikhilesh static void __rte_noinline 327080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_d_mac(struct l2fwd_resources *rsrc) 328080f57bcSPavan Nikhilesh { 329080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_UPDT_MAC | 330080f57bcSPavan Nikhilesh L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_SINGLE); 331080f57bcSPavan Nikhilesh } 332080f57bcSPavan Nikhilesh 333080f57bcSPavan Nikhilesh static void __rte_noinline 334080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_d_brst_mac(struct l2fwd_resources *rsrc) 335080f57bcSPavan Nikhilesh { 336080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_UPDT_MAC | 337080f57bcSPavan Nikhilesh L2FWD_EVENT_TX_DIRECT | L2FWD_EVENT_BURST); 338080f57bcSPavan Nikhilesh } 339080f57bcSPavan Nikhilesh 340080f57bcSPavan Nikhilesh static void __rte_noinline 341080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_q_mac(struct l2fwd_resources *rsrc) 342080f57bcSPavan Nikhilesh { 343080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_UPDT_MAC | 344080f57bcSPavan Nikhilesh L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_SINGLE); 345080f57bcSPavan Nikhilesh } 346080f57bcSPavan Nikhilesh 347080f57bcSPavan Nikhilesh static void __rte_noinline 348080f57bcSPavan Nikhilesh l2fwd_event_main_loop_tx_q_brst_mac(struct l2fwd_resources *rsrc) 349080f57bcSPavan Nikhilesh { 350080f57bcSPavan Nikhilesh l2fwd_event_loop(rsrc, L2FWD_EVENT_UPDT_MAC | 351080f57bcSPavan Nikhilesh L2FWD_EVENT_TX_ENQ | L2FWD_EVENT_BURST); 352080f57bcSPavan Nikhilesh } 353080f57bcSPavan Nikhilesh 354796b07e9SShijith Thotton static __rte_always_inline void 355796b07e9SShijith Thotton l2fwd_event_vector_fwd(struct l2fwd_resources *rsrc, 356796b07e9SShijith Thotton struct rte_event_vector *vec, 357796b07e9SShijith Thotton const uint64_t timer_period, const uint32_t flags) 358796b07e9SShijith Thotton { 359796b07e9SShijith Thotton struct rte_mbuf **mbufs = vec->mbufs; 360796b07e9SShijith Thotton uint16_t i, j; 361796b07e9SShijith Thotton 362796b07e9SShijith Thotton rte_prefetch0(rte_pktmbuf_mtod(mbufs[0], void *)); 363796b07e9SShijith Thotton 364796b07e9SShijith Thotton /* If vector attribute is valid, mbufs will be from same port/queue */ 365796b07e9SShijith Thotton if (vec->attr_valid) { 366796b07e9SShijith Thotton vec->port = rsrc->dst_ports[mbufs[0]->port]; 367796b07e9SShijith Thotton if (flags & L2FWD_EVENT_TX_DIRECT) 368796b07e9SShijith Thotton vec->queue = 0; 369796b07e9SShijith Thotton 370796b07e9SShijith Thotton if (timer_period > 0) 37192e68d9cSTyler Retzlaff rte_atomic_fetch_add_explicit(&rsrc->port_stats[mbufs[0]->port].rx, 37292e68d9cSTyler Retzlaff vec->nb_elem, rte_memory_order_relaxed); 373796b07e9SShijith Thotton 374796b07e9SShijith Thotton for (i = 0, j = 1; i < vec->nb_elem; i++, j++) { 375796b07e9SShijith Thotton if (j < vec->nb_elem) 376796b07e9SShijith Thotton rte_prefetch0( 377796b07e9SShijith Thotton rte_pktmbuf_mtod(mbufs[j], void *)); 378796b07e9SShijith Thotton 379796b07e9SShijith Thotton if (flags & L2FWD_EVENT_UPDT_MAC) 380796b07e9SShijith Thotton l2fwd_mac_updating( 381796b07e9SShijith Thotton mbufs[i], vec->port, 382796b07e9SShijith Thotton &rsrc->eth_addr[vec->port]); 383796b07e9SShijith Thotton } 384796b07e9SShijith Thotton 385796b07e9SShijith Thotton if (timer_period > 0) 38692e68d9cSTyler Retzlaff rte_atomic_fetch_add_explicit(&rsrc->port_stats[vec->port].tx, 38792e68d9cSTyler Retzlaff vec->nb_elem, rte_memory_order_relaxed); 388796b07e9SShijith Thotton } else { 389796b07e9SShijith Thotton for (i = 0, j = 1; i < vec->nb_elem; i++, j++) { 390796b07e9SShijith Thotton if (timer_period > 0) 39192e68d9cSTyler Retzlaff rte_atomic_fetch_add_explicit( 392796b07e9SShijith Thotton &rsrc->port_stats[mbufs[i]->port].rx, 1, 39392e68d9cSTyler Retzlaff rte_memory_order_relaxed); 394796b07e9SShijith Thotton 395796b07e9SShijith Thotton if (j < vec->nb_elem) 396796b07e9SShijith Thotton rte_prefetch0( 397796b07e9SShijith Thotton rte_pktmbuf_mtod(mbufs[j], void *)); 398796b07e9SShijith Thotton 399796b07e9SShijith Thotton mbufs[i]->port = rsrc->dst_ports[mbufs[i]->port]; 400796b07e9SShijith Thotton 401796b07e9SShijith Thotton if (flags & L2FWD_EVENT_UPDT_MAC) 402796b07e9SShijith Thotton l2fwd_mac_updating( 403796b07e9SShijith Thotton mbufs[i], mbufs[i]->port, 404796b07e9SShijith Thotton &rsrc->eth_addr[mbufs[i]->port]); 405796b07e9SShijith Thotton 406796b07e9SShijith Thotton if (flags & L2FWD_EVENT_TX_DIRECT) 407796b07e9SShijith Thotton rte_event_eth_tx_adapter_txq_set(mbufs[i], 0); 408796b07e9SShijith Thotton 409796b07e9SShijith Thotton if (timer_period > 0) 41092e68d9cSTyler Retzlaff rte_atomic_fetch_add_explicit( 411796b07e9SShijith Thotton &rsrc->port_stats[mbufs[i]->port].tx, 1, 41292e68d9cSTyler Retzlaff rte_memory_order_relaxed); 413796b07e9SShijith Thotton } 414796b07e9SShijith Thotton } 415796b07e9SShijith Thotton } 416796b07e9SShijith Thotton 417796b07e9SShijith Thotton static __rte_always_inline void 418796b07e9SShijith Thotton l2fwd_event_loop_vector(struct l2fwd_resources *rsrc, const uint32_t flags) 419796b07e9SShijith Thotton { 420796b07e9SShijith Thotton struct l2fwd_event_resources *evt_rsrc = rsrc->evt_rsrc; 421796b07e9SShijith Thotton const int port_id = l2fwd_get_free_event_port(evt_rsrc); 422796b07e9SShijith Thotton const uint8_t tx_q_id = 423796b07e9SShijith Thotton evt_rsrc->evq.event_q_id[evt_rsrc->evq.nb_queues - 1]; 424796b07e9SShijith Thotton const uint64_t timer_period = rsrc->timer_period; 425796b07e9SShijith Thotton const uint8_t event_d_id = evt_rsrc->event_d_id; 426796b07e9SShijith Thotton const uint8_t deq_len = evt_rsrc->deq_depth; 427796b07e9SShijith Thotton struct rte_event ev[MAX_PKT_BURST]; 428622ebb6bSPavan Nikhilesh uint16_t nb_rx = 0, nb_tx = 0; 429796b07e9SShijith Thotton uint8_t i; 430796b07e9SShijith Thotton 431796b07e9SShijith Thotton if (port_id < 0) 432796b07e9SShijith Thotton return; 433796b07e9SShijith Thotton 434796b07e9SShijith Thotton printf("%s(): entering eventdev main loop on lcore %u\n", __func__, 435796b07e9SShijith Thotton rte_lcore_id()); 436796b07e9SShijith Thotton 437796b07e9SShijith Thotton while (!rsrc->force_quit) { 438796b07e9SShijith Thotton nb_rx = rte_event_dequeue_burst(event_d_id, port_id, ev, 439796b07e9SShijith Thotton deq_len, 0); 440796b07e9SShijith Thotton if (nb_rx == 0) 441796b07e9SShijith Thotton continue; 442796b07e9SShijith Thotton 443796b07e9SShijith Thotton for (i = 0; i < nb_rx; i++) { 444796b07e9SShijith Thotton if (flags & L2FWD_EVENT_TX_ENQ) { 445796b07e9SShijith Thotton ev[i].queue_id = tx_q_id; 446796b07e9SShijith Thotton ev[i].op = RTE_EVENT_OP_FORWARD; 447796b07e9SShijith Thotton } 448796b07e9SShijith Thotton 449796b07e9SShijith Thotton l2fwd_event_vector_fwd(rsrc, ev[i].vec, timer_period, 450796b07e9SShijith Thotton flags); 451796b07e9SShijith Thotton } 452796b07e9SShijith Thotton 453796b07e9SShijith Thotton if (flags & L2FWD_EVENT_TX_ENQ) { 454796b07e9SShijith Thotton nb_tx = rte_event_enqueue_burst(event_d_id, port_id, ev, 455796b07e9SShijith Thotton nb_rx); 456796b07e9SShijith Thotton while (nb_tx < nb_rx && !rsrc->force_quit) 457796b07e9SShijith Thotton nb_tx += rte_event_enqueue_burst( 458796b07e9SShijith Thotton event_d_id, port_id, ev + nb_tx, 459796b07e9SShijith Thotton nb_rx - nb_tx); 460796b07e9SShijith Thotton } 461796b07e9SShijith Thotton 462796b07e9SShijith Thotton if (flags & L2FWD_EVENT_TX_DIRECT) { 463796b07e9SShijith Thotton nb_tx = rte_event_eth_tx_adapter_enqueue( 464796b07e9SShijith Thotton event_d_id, port_id, ev, nb_rx, 0); 465796b07e9SShijith Thotton while (nb_tx < nb_rx && !rsrc->force_quit) 466796b07e9SShijith Thotton nb_tx += rte_event_eth_tx_adapter_enqueue( 467796b07e9SShijith Thotton event_d_id, port_id, ev + nb_tx, 468796b07e9SShijith Thotton nb_rx - nb_tx, 0); 469796b07e9SShijith Thotton } 470796b07e9SShijith Thotton } 471622ebb6bSPavan Nikhilesh 4727af8167aSShijith Thotton l2fwd_event_worker_cleanup(event_d_id, port_id, ev, nb_tx, nb_rx, 1); 473796b07e9SShijith Thotton } 474796b07e9SShijith Thotton 475796b07e9SShijith Thotton static void __rte_noinline 476796b07e9SShijith Thotton l2fwd_event_main_loop_tx_d_vec(struct l2fwd_resources *rsrc) 477796b07e9SShijith Thotton { 478796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, L2FWD_EVENT_TX_DIRECT); 479796b07e9SShijith Thotton } 480796b07e9SShijith Thotton 481796b07e9SShijith Thotton static void __rte_noinline 482796b07e9SShijith Thotton l2fwd_event_main_loop_tx_d_brst_vec(struct l2fwd_resources *rsrc) 483796b07e9SShijith Thotton { 484796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, L2FWD_EVENT_TX_DIRECT); 485796b07e9SShijith Thotton } 486796b07e9SShijith Thotton 487796b07e9SShijith Thotton static void __rte_noinline 488796b07e9SShijith Thotton l2fwd_event_main_loop_tx_q_vec(struct l2fwd_resources *rsrc) 489796b07e9SShijith Thotton { 490796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, L2FWD_EVENT_TX_ENQ); 491796b07e9SShijith Thotton } 492796b07e9SShijith Thotton 493796b07e9SShijith Thotton static void __rte_noinline 494796b07e9SShijith Thotton l2fwd_event_main_loop_tx_q_brst_vec(struct l2fwd_resources *rsrc) 495796b07e9SShijith Thotton { 496796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, L2FWD_EVENT_TX_ENQ); 497796b07e9SShijith Thotton } 498796b07e9SShijith Thotton 499796b07e9SShijith Thotton static void __rte_noinline 500796b07e9SShijith Thotton l2fwd_event_main_loop_tx_d_mac_vec(struct l2fwd_resources *rsrc) 501796b07e9SShijith Thotton { 502796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, 503796b07e9SShijith Thotton L2FWD_EVENT_UPDT_MAC | L2FWD_EVENT_TX_DIRECT); 504796b07e9SShijith Thotton } 505796b07e9SShijith Thotton 506796b07e9SShijith Thotton static void __rte_noinline 507796b07e9SShijith Thotton l2fwd_event_main_loop_tx_d_brst_mac_vec(struct l2fwd_resources *rsrc) 508796b07e9SShijith Thotton { 509796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, 510796b07e9SShijith Thotton L2FWD_EVENT_UPDT_MAC | L2FWD_EVENT_TX_DIRECT); 511796b07e9SShijith Thotton } 512796b07e9SShijith Thotton 513796b07e9SShijith Thotton static void __rte_noinline 514796b07e9SShijith Thotton l2fwd_event_main_loop_tx_q_mac_vec(struct l2fwd_resources *rsrc) 515796b07e9SShijith Thotton { 516796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, 517796b07e9SShijith Thotton L2FWD_EVENT_UPDT_MAC | L2FWD_EVENT_TX_ENQ); 518796b07e9SShijith Thotton } 519796b07e9SShijith Thotton 520796b07e9SShijith Thotton static void __rte_noinline 521796b07e9SShijith Thotton l2fwd_event_main_loop_tx_q_brst_mac_vec(struct l2fwd_resources *rsrc) 522796b07e9SShijith Thotton { 523796b07e9SShijith Thotton l2fwd_event_loop_vector(rsrc, 524796b07e9SShijith Thotton L2FWD_EVENT_UPDT_MAC | L2FWD_EVENT_TX_ENQ); 525796b07e9SShijith Thotton } 526796b07e9SShijith Thotton 5271b2143aaSPavan Nikhilesh void 5281b2143aaSPavan Nikhilesh l2fwd_event_resource_setup(struct l2fwd_resources *rsrc) 5291b2143aaSPavan Nikhilesh { 530080f57bcSPavan Nikhilesh /* [MAC_UPDT][TX_MODE][BURST] */ 531796b07e9SShijith Thotton const event_loop_cb event_loop[2][2][2][2] = { 532796b07e9SShijith Thotton [0][0][0][0] = l2fwd_event_main_loop_tx_d, 533796b07e9SShijith Thotton [0][0][0][1] = l2fwd_event_main_loop_tx_d_brst, 534796b07e9SShijith Thotton [0][0][1][0] = l2fwd_event_main_loop_tx_q, 535796b07e9SShijith Thotton [0][0][1][1] = l2fwd_event_main_loop_tx_q_brst, 536796b07e9SShijith Thotton [0][1][0][0] = l2fwd_event_main_loop_tx_d_mac, 537796b07e9SShijith Thotton [0][1][0][1] = l2fwd_event_main_loop_tx_d_brst_mac, 538796b07e9SShijith Thotton [0][1][1][0] = l2fwd_event_main_loop_tx_q_mac, 539796b07e9SShijith Thotton [0][1][1][1] = l2fwd_event_main_loop_tx_q_brst_mac, 540796b07e9SShijith Thotton [1][0][0][0] = l2fwd_event_main_loop_tx_d_vec, 541796b07e9SShijith Thotton [1][0][0][1] = l2fwd_event_main_loop_tx_d_brst_vec, 542796b07e9SShijith Thotton [1][0][1][0] = l2fwd_event_main_loop_tx_q_vec, 543796b07e9SShijith Thotton [1][0][1][1] = l2fwd_event_main_loop_tx_q_brst_vec, 544796b07e9SShijith Thotton [1][1][0][0] = l2fwd_event_main_loop_tx_d_mac_vec, 545796b07e9SShijith Thotton [1][1][0][1] = l2fwd_event_main_loop_tx_d_brst_mac_vec, 546796b07e9SShijith Thotton [1][1][1][0] = l2fwd_event_main_loop_tx_q_mac_vec, 547796b07e9SShijith Thotton [1][1][1][1] = l2fwd_event_main_loop_tx_q_brst_mac_vec, 548080f57bcSPavan Nikhilesh }; 5491b2143aaSPavan Nikhilesh struct l2fwd_event_resources *evt_rsrc; 5503b5476dbSSunil Kumar Kori uint32_t event_queue_cfg; 551080f57bcSPavan Nikhilesh int ret; 5521b2143aaSPavan Nikhilesh 5531b2143aaSPavan Nikhilesh if (!rte_event_dev_count()) 5541b2143aaSPavan Nikhilesh rte_panic("No Eventdev found\n"); 5551b2143aaSPavan Nikhilesh 5561b2143aaSPavan Nikhilesh evt_rsrc = rte_zmalloc("l2fwd_event", 5571b2143aaSPavan Nikhilesh sizeof(struct l2fwd_event_resources), 0); 5581b2143aaSPavan Nikhilesh if (evt_rsrc == NULL) 5591b2143aaSPavan Nikhilesh rte_panic("Failed to allocate memory\n"); 5601b2143aaSPavan Nikhilesh 5611b2143aaSPavan Nikhilesh rsrc->evt_rsrc = evt_rsrc; 56269de9488SSunil Kumar Kori 56369de9488SSunil Kumar Kori /* Setup eventdev capability callbacks */ 56469de9488SSunil Kumar Kori l2fwd_event_capability_setup(evt_rsrc); 5656ab87600SSunil Kumar Kori 5666ab87600SSunil Kumar Kori /* Event device configuration */ 5673b5476dbSSunil Kumar Kori event_queue_cfg = evt_rsrc->ops.event_device_setup(rsrc); 5683b5476dbSSunil Kumar Kori 5693b5476dbSSunil Kumar Kori /* Event queue configuration */ 5703b5476dbSSunil Kumar Kori evt_rsrc->ops.event_queue_setup(rsrc, event_queue_cfg); 5713b5476dbSSunil Kumar Kori 5723b5476dbSSunil Kumar Kori /* Event port configuration */ 5733b5476dbSSunil Kumar Kori evt_rsrc->ops.event_port_setup(rsrc); 57450f05aa6SSunil Kumar Kori 57550f05aa6SSunil Kumar Kori /* Rx/Tx adapters configuration */ 57650f05aa6SSunil Kumar Kori evt_rsrc->ops.adapter_setup(rsrc); 577080f57bcSPavan Nikhilesh 578080f57bcSPavan Nikhilesh /* Start event device */ 579080f57bcSPavan Nikhilesh ret = rte_event_dev_start(evt_rsrc->event_d_id); 580080f57bcSPavan Nikhilesh if (ret < 0) 581080f57bcSPavan Nikhilesh rte_panic("Error in starting eventdev\n"); 582080f57bcSPavan Nikhilesh 583796b07e9SShijith Thotton evt_rsrc->ops.l2fwd_event_loop = 584796b07e9SShijith Thotton event_loop[rsrc->evt_vec.enabled][rsrc->mac_updating] 585796b07e9SShijith Thotton [evt_rsrc->tx_mode_q][evt_rsrc->has_burst]; 5861b2143aaSPavan Nikhilesh } 587