>On 19/03/2021 20:57, pbhagavat...@marvell.com wrote: >> From: Pavan Nikhilesh <pbhagavat...@marvell.com> >> >> Introduce rte_event_vector datastructure which is capable of holding >> multiple uintptr_t of the same flow thereby allowing applications >> to vectorize their pipeline and reducing the complexity of pipelining >> the events across multiple stages. >> This approach also reduces the scheduling overhead on a event >device. >> >> Add a event vector mempool create handler to create mempools >based on >> the best mempool ops available on a given platform. >> >> Signed-off-by: Pavan Nikhilesh <pbhagavat...@marvell.com> >> --- >> doc/guides/prog_guide/eventdev.rst | 36 +++++++++- >> lib/librte_eventdev/rte_eventdev.h | 112 >++++++++++++++++++++++++++++- >> lib/librte_eventdev/version.map | 3 + >> 3 files changed, 148 insertions(+), 3 deletions(-) >> > >[SNIP] > >> >> diff --git a/lib/librte_eventdev/rte_eventdev.h >b/lib/librte_eventdev/rte_eventdev.h >> index ce1fc2ce0..5586a3f15 100644 >> --- a/lib/librte_eventdev/rte_eventdev.h >> +++ b/lib/librte_eventdev/rte_eventdev.h >> @@ -212,8 +212,10 @@ extern "C" { >> >> #include <rte_common.h> >> #include <rte_config.h> >> -#include <rte_memory.h> >> #include <rte_errno.h> >> +#include <rte_mbuf_pool_ops.h> >> +#include <rte_memory.h> >> +#include <rte_mempool.h> >> >> #include "rte_eventdev_trace_fp.h" >> >> @@ -913,6 +915,25 @@ >rte_event_dev_stop_flush_callback_register(uint8_t dev_id, >> int >> rte_event_dev_close(uint8_t dev_id); >> >> +/** >> + * Event vector structure. >> + */ >> +struct rte_event_vector { >> + uint64_t nb_elem : 16; >> + /**< Number of elements in this event vector. */ >> + uint64_t rsvd : 48; >> + uint64_t impl_opaque; >> + union { >> + struct rte_mbuf *mbufs[0]; >> + void *ptrs[0]; >> + uint64_t *u64s[0]; >> + } __rte_aligned(16); >> + /**< Start of the vector array union. Depending upon the event >type the >> + * vector array can be an array of mbufs or pointers or opaque >u64 >> + * values. >> + */ >> +}; >> + >> /* Scheduler type definitions */ >> #define RTE_SCHED_TYPE_ORDERED 0 >> /**< Ordered scheduling >> @@ -986,6 +1007,21 @@ rte_event_dev_close(uint8_t dev_id); >> */ >> #define RTE_EVENT_TYPE_ETH_RX_ADAPTER 0x4 >> /**< The event generated from event eth Rx adapter */ >> +#define RTE_EVENT_TYPE_VECTOR 0x8 >> +/**< Indicates that event is a vector. >> + * All vector event types should be an logical OR of >EVENT_TYPE_VECTOR. >> + * This simplifies the pipeline design as we can split processing the >events >> + * between vector events and normal event across event types. >> + * Example: >> + * if (ev.event_type & RTE_EVENT_TYPE_VECTOR) { >> + * // Classify and handle vector event. >> + * } else { >> + * // Classify and handle event. >> + * } >> + */ >> +#define RTE_EVENT_TYPE_CPU_VECTOR >(RTE_EVENT_TYPE_VECTOR | RTE_EVENT_TYPE_CPU) >> +/**< The event vector generated from cpu for pipelining. */ >> + >> #define RTE_EVENT_TYPE_MAX 0x10 >> /**< Maximum number of event types */ >> >> @@ -1108,6 +1144,8 @@ struct rte_event { >> /**< Opaque event pointer */ >> struct rte_mbuf *mbuf; >> /**< mbuf pointer if dequeued event is associated with >mbuf */ >> + struct rte_event_vector *vec; >> + /**< Event vector pointer. */ >> }; >> }; >> >> @@ -2023,6 +2061,78 @@ rte_event_dev_xstats_reset(uint8_t >dev_id, >> */ >> int rte_event_dev_selftest(uint8_t dev_id); >> >> +/** >> + * Get the memory required per event vector based on the number of >elements per >> + * vector. >> + * This should be used to create the mempool that holds the event >vectors. >> + * >> + * @param name >> + * The name of the vector pool. >> + * @param n >> + * The number of elements in the mbuf pool. >> + * @param cache_size >> + * Size of the per-core object cache. See rte_mempool_create() for >> + * details. >> + * @param nb_elem >> + * The number of elements then a single event vector should be >able to hold. >> + * @param socket_id >> + * The socket identifier where the memory should be allocated. The >> + * value can be *SOCKET_ID_ANY* if there is no NUMA constraint >for the >> + * reserved zone >> + * >> + * @return >> + * The pointer to the newly allocated mempool, on success. NULL >on error >> + * with rte_errno set appropriately. Possible rte_errno values >include: >> + * - E_RTE_NO_CONFIG - function could not get pointer to >rte_config structure >> + * - E_RTE_SECONDARY - function was called from a secondary >process instance >> + * - EINVAL - cache size provided is too large, or priv_size is not >aligned. >> + * - ENOSPC - the maximum number of memzones has already been >allocated >> + * - EEXIST - a memzone with the same name already exists >> + * - ENOMEM - no appropriate memory area found in which to >create memzone >> + */ >> +__rte_experimental >> +static inline struct rte_mempool * >> +rte_event_vector_pool_create(const char *name, unsigned int n, >> + unsigned int cache_size, uint16_t nb_elem, >> + int socket_id) > >Handling in-lined function is tricky at best from an ABI stability PoV. > >Since this function is used at initialization time and I would suggest since >performance is not issue here. >There is no need for this function to be an inline.
Makes sense, I will move it to .c in the next version. Thanks, Pavan. > >> +{ >> + const char *mp_ops_name; >> + struct rte_mempool *mp; >> + unsigned int elt_sz; >> + int ret; >> + >> + if (!nb_elem) { >> + RTE_LOG(ERR, EVENTDEV, >> + "Invalid number of elements=%d requested\n", >nb_elem); >> + rte_errno = -EINVAL; >> + return NULL; >> + } >> + >> + elt_sz = >> + sizeof(struct rte_event_vector) + (nb_elem * >sizeof(uintptr_t)); >> + mp = rte_mempool_create_empty(name, n, elt_sz, cache_size, >0, socket_id, >> + 0); >> + if (mp == NULL) >> + return NULL; >> + >> + mp_ops_name = rte_mbuf_best_mempool_ops(); >> + ret = rte_mempool_set_ops_byname(mp, mp_ops_name, >NULL); >> + if (ret != 0) { >> + RTE_LOG(ERR, EVENTDEV, "error setting mempool >handler\n"); >> + goto err; >> + } >> + >> + ret = rte_mempool_populate_default(mp); >> + if (ret < 0) >> + goto err; >> + >> + return mp; >> +err: >> + rte_mempool_free(mp); >> + rte_errno = -ret; >> + return NULL; >> +} >> + >> #ifdef __cplusplus >> } >> #endif >> diff --git a/lib/librte_eventdev/version.map >b/lib/librte_eventdev/version.map >> index 3e5c09cfd..a070ef56e 100644 >> --- a/lib/librte_eventdev/version.map >> +++ b/lib/librte_eventdev/version.map >> @@ -138,6 +138,9 @@ EXPERIMENTAL { >> __rte_eventdev_trace_port_setup; >> # added in 20.11 >> rte_event_pmd_pci_probe_named; >> + >> + #added in 21.05 >> + rte_event_vector_pool_create; >> }; >> >> INTERNAL { >>