diff --git a/doc/guides/prog_guide/eventdev.rst b/doc/guides/prog_guide/eventdev.rst
index ccde086f6..fda9c3743 100644
--- a/doc/guides/prog_guide/eventdev.rst
+++ b/doc/guides/prog_guide/eventdev.rst
@@ -63,13 +63,45 @@ the actual event being scheduled is. The payload is a union of the following:
 * ``uint64_t u64``
 * ``void *event_ptr``
 * ``struct rte_mbuf *mbuf``
+* ``struct rte_event_vector *vec``
 
-These three items in a union occupy the same 64 bits at the end of the rte_event
+These four items in a union occupy the same 64 bits at the end of the rte_event
 structure. The application can utilize the 64 bits directly by accessing the
-u64 variable, while the event_ptr and mbuf are provided as convenience
+u64 variable, while the event_ptr, mbuf, vec are provided as a convenience
 variables.  For example the mbuf pointer in the union can used to schedule a
 DPDK packet.
 
+Event Vector
+~~~~~~~~~~~~
+
+The rte_event_vector struct contains a vector of elements defined by the event
+type specified in the ``rte_event``. The event_vector structure contains the
+following data:
+
+* ``nb_elem`` - The number of elements held within the vector.
+
+Similar to ``rte_event`` the payload of event vector is also a union, allowing
+flexibility in what the actual vector is.
+
+* ``struct rte_mbuf *mbufs[0]`` - An array of mbufs.
+* ``void *ptrs[0]`` - An array of pointers.
+* ``uint64_t *u64s[0]`` - An array of uint64_t elements.
+
+The size of the event vector is related to the total number of elements it is
+configured to hold, this is achieved by making `rte_event_vector` a variable
+length structure.
+A helper function is provided to create a mempool that holds event vector, which
+takes name of the pool, total number of required ``rte_event_vector``,
+cache size, number of elements in each ``rte_event_vector`` and socket id.
+
+.. code-block:: c
+
+        rte_event_vector_pool_create("vector_pool", nb_event_vectors, cache_sz,
+                                     nb_elements_per_vector, socket_id);
+
+The function ``rte_event_vector_pool_create`` creates mempool with the best
+platform mempool ops.
+
 Queues
 ~~~~~~
 
diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
index ce1fc2ce0..dda8d0387 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"
 
@@ -221,20 +223,20 @@ struct rte_mbuf; /* we just use mbuf pointers; no need to include rte_mbuf.h */
 struct rte_event;
 
 /* Event device capability bitmap flags */
-#define RTE_EVENT_DEV_CAP_QUEUE_QOS           (1ULL << 0)
+#define RTE_EVENT_DEV_CAP_QUEUE_QOS (1ULL << 0)
 /**< Event scheduling prioritization is based on the priority associated with
  *  each event queue.
  *
  *  @see rte_event_queue_setup()
  */
-#define RTE_EVENT_DEV_CAP_EVENT_QOS           (1ULL << 1)
+#define RTE_EVENT_DEV_CAP_EVENT_QOS (1ULL << 1)
 /**< Event scheduling prioritization is based on the priority associated with
  *  each event. Priority of each event is supplied in *rte_event* structure
  *  on each enqueue operation.
  *
  *  @see rte_event_enqueue_burst()
  */
-#define RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED   (1ULL << 2)
+#define RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED (1ULL << 2)
 /**< Event device operates in distributed scheduling mode.
  * In distributed scheduling mode, event scheduling happens in HW or
  * rte_event_dequeue_burst() or the combination of these two.
@@ -243,14 +245,14 @@ struct rte_event;
  *
  * @see rte_event_dequeue_burst()
  */
-#define RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES     (1ULL << 3)
+#define RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES (1ULL << 3)
 /**< Event device is capable of enqueuing events of any type to any queue.
  * If this capability is not set, the queue only supports events of the
  *  *RTE_SCHED_TYPE_* type that it was created with.
  *
  * @see RTE_SCHED_TYPE_* values
  */
-#define RTE_EVENT_DEV_CAP_BURST_MODE          (1ULL << 4)
+#define RTE_EVENT_DEV_CAP_BURST_MODE (1ULL << 4)
 /**< Event device is capable of operating in burst mode for enqueue(forward,
  * release) and dequeue operation. If this capability is not set, application
  * still uses the rte_event_dequeue_burst() and rte_event_enqueue_burst() but
@@ -258,7 +260,7 @@ struct rte_event;
  *
  * @see rte_event_dequeue_burst() rte_event_enqueue_burst()
  */
-#define RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE    (1ULL << 5)
+#define RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE (1ULL << 5)
 /**< Event device ports support disabling the implicit release feature, in
  * which the port will release all unreleased events in its dequeue operation.
  * If this capability is set and the port is configured with implicit release
@@ -269,7 +271,7 @@ struct rte_event;
  * @see rte_event_dequeue_burst() rte_event_enqueue_burst()
  */
 
-#define RTE_EVENT_DEV_CAP_NONSEQ_MODE         (1ULL << 6)
+#define RTE_EVENT_DEV_CAP_NONSEQ_MODE (1ULL << 6)
 /**< Event device is capable of operating in none sequential mode. The path
  * of the event is not necessary to be sequential. Application can change
  * the path of event at runtime. If the flag is not set, then event each event
@@ -279,7 +281,7 @@ struct rte_event;
  * qid which is not the next in the sequence.
  */
 
-#define RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK   (1ULL << 7)
+#define RTE_EVENT_DEV_CAP_RUNTIME_PORT_LINK (1ULL << 7)
 /**< Event device is capable of configuring the queue/port link at runtime.
  * If the flag is not set, the eventdev queue/port link is only can be
  * configured during  initialization.
@@ -298,17 +300,17 @@ struct rte_event;
  */
 
 /* Event device priority levels */
-#define RTE_EVENT_DEV_PRIORITY_HIGHEST   0
+#define RTE_EVENT_DEV_PRIORITY_HIGHEST 0
 /**< Highest priority expressed across eventdev subsystem
  * @see rte_event_queue_setup(), rte_event_enqueue_burst()
  * @see rte_event_port_link()
  */
-#define RTE_EVENT_DEV_PRIORITY_NORMAL    128
+#define RTE_EVENT_DEV_PRIORITY_NORMAL 128
 /**< Normal priority expressed across eventdev subsystem
  * @see rte_event_queue_setup(), rte_event_enqueue_burst()
  * @see rte_event_port_link()
  */
-#define RTE_EVENT_DEV_PRIORITY_LOWEST    255
+#define RTE_EVENT_DEV_PRIORITY_LOWEST 255
 /**< Lowest priority expressed across eventdev subsystem
  * @see rte_event_queue_setup(), rte_event_enqueue_burst()
  * @see rte_event_port_link()
@@ -321,8 +323,7 @@ struct rte_event;
  * @return
  *   The total number of usable event devices.
  */
-uint8_t
-rte_event_dev_count(void);
+uint8_t rte_event_dev_count(void);
 
 /**
  * Get the device identifier for the named event device.
@@ -334,8 +335,7 @@ rte_event_dev_count(void);
  *   Returns event device identifier on success.
  *   - <0: Failure to find named event device.
  */
-int
-rte_event_dev_get_dev_id(const char *name);
+int rte_event_dev_get_dev_id(const char *name);
 
 /**
  * Return the NUMA socket to which a device is connected.
@@ -347,15 +347,14 @@ rte_event_dev_get_dev_id(const char *name);
  *   a default of zero if the socket could not be determined.
  *   -(-EINVAL)  dev_id value is out of range.
  */
-int
-rte_event_dev_socket_id(uint8_t dev_id);
+int rte_event_dev_socket_id(uint8_t dev_id);
 
 /**
  * Event device information
  */
 struct rte_event_dev_info {
-	const char *driver_name;	/**< Event driver name */
-	struct rte_device *dev;	/**< Device information */
+	const char *driver_name; /**< Event driver name */
+	struct rte_device *dev;	 /**< Device information */
 	uint32_t min_dequeue_timeout_ns;
 	/**< Minimum supported global dequeue timeout(ns) by this device */
 	uint32_t max_dequeue_timeout_ns;
@@ -420,8 +419,7 @@ struct rte_event_dev_info {
  *   - <0: Error code returned by the driver info get function.
  *
  */
-int
-rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info);
+int rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info);
 
 /**
  * The count of ports.
@@ -448,10 +446,8 @@ rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info);
  *   - 0: Successfully retrieved attribute value
  *   - -EINVAL: Invalid device or  *attr_id* provided, or *attr_value* is NULL
  */
-int
-rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id,
-		       uint32_t *attr_value);
-
+int rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id,
+			   uint32_t *attr_value);
 
 /* Event device configuration bitmap flags */
 #define RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT (1ULL << 0)
@@ -539,20 +535,19 @@ struct rte_event_dev_config {
  *   - 0: Success, device configured.
  *   - <0: Error code returned by the driver configuration function.
  */
-int
-rte_event_dev_configure(uint8_t dev_id,
-			const struct rte_event_dev_config *dev_conf);
+int rte_event_dev_configure(uint8_t dev_id,
+			    const struct rte_event_dev_config *dev_conf);
 
 /* Event queue specific APIs */
 
 /* Event queue configuration bitmap flags */
-#define RTE_EVENT_QUEUE_CFG_ALL_TYPES          (1ULL << 0)
+#define RTE_EVENT_QUEUE_CFG_ALL_TYPES (1ULL << 0)
 /**< Allow ATOMIC,ORDERED,PARALLEL schedule type enqueue
  *
  * @see RTE_SCHED_TYPE_ORDERED, RTE_SCHED_TYPE_ATOMIC, RTE_SCHED_TYPE_PARALLEL
  * @see rte_event_enqueue_burst()
  */
-#define RTE_EVENT_QUEUE_CFG_SINGLE_LINK        (1ULL << 1)
+#define RTE_EVENT_QUEUE_CFG_SINGLE_LINK (1ULL << 1)
 /**< This event queue links only to a single event port.
  *
  *  @see rte_event_port_setup(), rte_event_port_link()
@@ -621,9 +616,8 @@ struct rte_event_queue_conf {
  * @see rte_event_queue_setup()
  *
  */
-int
-rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id,
-				 struct rte_event_queue_conf *queue_conf);
+int rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id,
+				     struct rte_event_queue_conf *queue_conf);
 
 /**
  * Allocate and set up an event queue for an event device.
@@ -643,9 +637,8 @@ rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id,
  *   - 0: Success, event queue correctly set up.
  *   - <0: event queue configuration failed
  */
-int
-rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
-		      const struct rte_event_queue_conf *queue_conf);
+int rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
+			  const struct rte_event_queue_conf *queue_conf);
 
 /**
  * The priority of the queue.
@@ -688,21 +681,20 @@ rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
  *   RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE and event_queue_cfg is set to
  *   RTE_EVENT_QUEUE_CFG_ALL_TYPES
  */
-int
-rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
-			uint32_t *attr_value);
+int rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
+			     uint32_t *attr_value);
 
 /* Event port specific APIs */
 
 /* Event port configuration bitmap flags */
-#define RTE_EVENT_PORT_CFG_DISABLE_IMPL_REL    (1ULL << 0)
+#define RTE_EVENT_PORT_CFG_DISABLE_IMPL_REL (1ULL << 0)
 /**< Configure the port not to release outstanding events in
  * rte_event_dev_dequeue_burst(). If set, all events received through
  * the port must be explicitly released with RTE_EVENT_OP_RELEASE or
  * RTE_EVENT_OP_FORWARD. Must be unset if the device is not
  * RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE capable.
  */
-#define RTE_EVENT_PORT_CFG_SINGLE_LINK         (1ULL << 1)
+#define RTE_EVENT_PORT_CFG_SINGLE_LINK (1ULL << 1)
 /**< This event port links only to a single event queue.
  *
  *  @see rte_event_port_setup(), rte_event_port_link()
@@ -760,9 +752,8 @@ struct rte_event_port_conf {
  * @see rte_event_port_setup()
  *
  */
-int
-rte_event_port_default_conf_get(uint8_t dev_id, uint8_t port_id,
-				struct rte_event_port_conf *port_conf);
+int rte_event_port_default_conf_get(uint8_t dev_id, uint8_t port_id,
+				    struct rte_event_port_conf *port_conf);
 
 /**
  * Allocate and set up an event port for an event device.
@@ -784,9 +775,8 @@ rte_event_port_default_conf_get(uint8_t dev_id, uint8_t port_id,
  *   - (-EDQUOT) Quota exceeded(Application tried to link the queue configured
  *   with RTE_EVENT_QUEUE_CFG_SINGLE_LINK to more than one event ports)
  */
-int
-rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
-		     const struct rte_event_port_conf *port_conf);
+int rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
+			 const struct rte_event_port_conf *port_conf);
 
 /**
  * The queue depth of the port on the enqueue side
@@ -821,9 +811,8 @@ rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
  *   - 0: Successfully returned value
  *   - (-EINVAL) Invalid device, port or attr_id, or attr_value was NULL
  */
-int
-rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id,
-			uint32_t *attr_value);
+int rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id,
+			    uint32_t *attr_value);
 
 /**
  * Start an event device.
@@ -841,8 +830,7 @@ rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id,
  *   - -ESTALE : Not all ports of the device are configured
  *   - -ENOLINK: Not all queues are linked, which could lead to deadlock.
  */
-int
-rte_event_dev_start(uint8_t dev_id);
+int rte_event_dev_start(uint8_t dev_id);
 
 /**
  * Stop an event device.
@@ -862,11 +850,10 @@ rte_event_dev_start(uint8_t dev_id);
  *
  * @see rte_event_dev_stop_flush_callback_register()
  */
-void
-rte_event_dev_stop(uint8_t dev_id);
+void rte_event_dev_stop(uint8_t dev_id);
 
 typedef void (*eventdev_stop_flush_t)(uint8_t dev_id, struct rte_event event,
-		void *arg);
+				      void *arg);
 /**< Callback function called during rte_event_dev_stop(), invoked once per
  * flushed event.
  */
@@ -895,9 +882,9 @@ typedef void (*eventdev_stop_flush_t)(uint8_t dev_id, struct rte_event event,
  *
  * @see rte_event_dev_stop()
  */
-int
-rte_event_dev_stop_flush_callback_register(uint8_t dev_id,
-		eventdev_stop_flush_t callback, void *userdata);
+int rte_event_dev_stop_flush_callback_register(uint8_t dev_id,
+					       eventdev_stop_flush_t callback,
+					       void *userdata);
 
 /**
  * Close an event device. The device cannot be restarted!
@@ -910,11 +897,29 @@ rte_event_dev_stop_flush_callback_register(uint8_t dev_id,
  *  - <0 on failure to close device
  *  - (-EAGAIN) if device is busy
  */
-int
-rte_event_dev_close(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
+#define RTE_SCHED_TYPE_ORDERED 0
 /**< Ordered scheduling
  *
  * Events from an ordered flow of an event queue can be scheduled to multiple
@@ -941,7 +946,7 @@ rte_event_dev_close(uint8_t dev_id);
  * @see rte_event_queue_setup(), rte_event_dequeue_burst(), RTE_EVENT_OP_RELEASE
  */
 
-#define RTE_SCHED_TYPE_ATOMIC           1
+#define RTE_SCHED_TYPE_ATOMIC 1
 /**< Atomic scheduling
  *
  * Events from an atomic flow of an event queue can be scheduled only to a
@@ -960,7 +965,7 @@ rte_event_dev_close(uint8_t dev_id);
  * @see rte_event_queue_setup(), rte_event_dequeue_burst(), RTE_EVENT_OP_RELEASE
  */
 
-#define RTE_SCHED_TYPE_PARALLEL         2
+#define RTE_SCHED_TYPE_PARALLEL 2
 /**< Parallel scheduling
  *
  * The scheduler performs priority scheduling, load balancing, etc. functions
@@ -974,27 +979,42 @@ rte_event_dev_close(uint8_t dev_id);
  */
 
 /* Event types to classify the event source */
-#define RTE_EVENT_TYPE_ETHDEV           0x0
+#define RTE_EVENT_TYPE_ETHDEV 0x0
 /**< The event generated from ethdev subsystem */
-#define RTE_EVENT_TYPE_CRYPTODEV        0x1
+#define RTE_EVENT_TYPE_CRYPTODEV 0x1
 /**< The event generated from crypodev subsystem */
-#define RTE_EVENT_TYPE_TIMER		0x2
+#define RTE_EVENT_TYPE_TIMER 0x2
 /**< The event generated from event timer adapter */
-#define RTE_EVENT_TYPE_CPU              0x3
+#define RTE_EVENT_TYPE_CPU 0x3
 /**< The event generated from cpu for pipelining.
  * Application may use *sub_event_type* to further classify the event
  */
-#define RTE_EVENT_TYPE_ETH_RX_ADAPTER   0x4
+#define RTE_EVENT_TYPE_ETH_RX_ADAPTER 0x4
 /**< The event generated from event eth Rx adapter */
-#define RTE_EVENT_TYPE_MAX              0x10
+#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 */
 
 /* Event enqueue operations */
-#define RTE_EVENT_OP_NEW                0
+#define RTE_EVENT_OP_NEW 0
 /**< The event producers use this operation to inject a new event to the
  * event device.
  */
-#define RTE_EVENT_OP_FORWARD            1
+#define RTE_EVENT_OP_FORWARD 1
 /**< The CPU use this operation to forward the event to different event queue or
  * change to new application specific flow or schedule type to enable
  * pipelining.
@@ -1002,7 +1022,7 @@ rte_event_dev_close(uint8_t dev_id);
  * This operation must only be enqueued to the same port that the
  * event to be forwarded was dequeued from.
  */
-#define RTE_EVENT_OP_RELEASE            2
+#define RTE_EVENT_OP_RELEASE 2
 /**< Release the flow context associated with the schedule type.
  *
  * If current flow's scheduler type method is *RTE_SCHED_TYPE_ATOMIC*
@@ -1046,30 +1066,30 @@ struct rte_event {
 		uint64_t event;
 		/** Event attributes for dequeue or enqueue operation */
 		struct {
-			uint32_t flow_id:20;
+			uint32_t flow_id : 20;
 			/**< Targeted flow identifier for the enqueue and
 			 * dequeue operation.
 			 * The value must be in the range of
 			 * [0, nb_event_queue_flows - 1] which
 			 * previously supplied to rte_event_dev_configure().
 			 */
-			uint32_t sub_event_type:8;
+			uint32_t sub_event_type : 8;
 			/**< Sub-event types based on the event source.
 			 * @see RTE_EVENT_TYPE_CPU
 			 */
-			uint32_t event_type:4;
+			uint32_t event_type : 4;
 			/**< Event type to classify the event source.
 			 * @see RTE_EVENT_TYPE_ETHDEV, (RTE_EVENT_TYPE_*)
 			 */
-			uint8_t op:2;
+			uint8_t op : 2;
 			/**< The type of event enqueue operation - new/forward/
 			 * etc.This field is not preserved across an instance
 			 * and is undefined on dequeue.
 			 * @see RTE_EVENT_OP_NEW, (RTE_EVENT_OP_*)
 			 */
-			uint8_t rsvd:4;
+			uint8_t rsvd : 4;
 			/**< Reserved for future use */
-			uint8_t sched_type:2;
+			uint8_t sched_type : 2;
 			/**< Scheduler synchronization type (RTE_SCHED_TYPE_*)
 			 * associated with flow id on a given event queue
 			 * for the enqueue and dequeue operation.
@@ -1108,19 +1128,21 @@ 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. */
 	};
 };
 
 /* Ethdev Rx adapter capability bitmap flags */
-#define RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT	0x1
+#define RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT 0x1
 /**< This flag is sent when the packet transfer mechanism is in HW.
  * Ethdev can send packets to the event device using internal event port.
  */
-#define RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ	0x2
+#define RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ 0x2
 /**< Adapter supports multiple event queues per ethdev. Every ethdev
  * Rx queue can be connected to a unique event queue.
  */
-#define RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID	0x4
+#define RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID 0x4
 /**< The application can override the adapter generated flow ID in the
  * event. This flow ID can be specified when adding an ethdev Rx queue
  * to the adapter using the ev member of struct rte_event_eth_rx_adapter
@@ -1147,9 +1169,8 @@ struct rte_event {
  *   - <0: Error code returned by the driver function.
  *
  */
-int
-rte_event_eth_rx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
-				uint32_t *caps);
+int rte_event_eth_rx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
+				      uint32_t *caps);
 
 #define RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT (1ULL << 0)
 /**< This flag is set when the timer mechanism is in HW. */
@@ -1167,30 +1188,29 @@ rte_event_eth_rx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
  *   - 0: Success, driver provided event timer adapter capabilities.
  *   - <0: Error code returned by the driver function.
  */
-int
-rte_event_timer_adapter_caps_get(uint8_t dev_id, uint32_t *caps);
+int rte_event_timer_adapter_caps_get(uint8_t dev_id, uint32_t *caps);
 
 /* Crypto adapter capability bitmap flag */
-#define RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW   0x1
+#define RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_NEW 0x1
 /**< Flag indicates HW is capable of generating events in
  * RTE_EVENT_OP_NEW enqueue operation. Cryptodev will send
  * packets to the event device as new events using an internal
  * event port.
  */
 
-#define RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD   0x2
+#define RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_OP_FWD 0x2
 /**< Flag indicates HW is capable of generating events in
  * RTE_EVENT_OP_FORWARD enqueue operation. Cryptodev will send
  * packets to the event device as forwarded event using an
  * internal event port.
  */
 
-#define RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND  0x4
+#define RTE_EVENT_CRYPTO_ADAPTER_CAP_INTERNAL_PORT_QP_EV_BIND 0x4
 /**< Flag indicates HW is capable of mapping crypto queue pair to
  * event queue.
  */
 
-#define RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA   0x8
+#define RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA 0x8
 /**< Flag indicates HW/SW supports a mechanism to store and retrieve
  * the private data information along with the crypto session.
  */
@@ -1215,12 +1235,11 @@ rte_event_timer_adapter_caps_get(uint8_t dev_id, uint32_t *caps);
  *   - <0: Error code returned by the driver function.
  *
  */
-int
-rte_event_crypto_adapter_caps_get(uint8_t dev_id, uint8_t cdev_id,
-				  uint32_t *caps);
+int rte_event_crypto_adapter_caps_get(uint8_t dev_id, uint8_t cdev_id,
+				      uint32_t *caps);
 
 /* Ethdev Tx adapter capability bitmap flags */
-#define RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT	0x1
+#define RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT 0x1
 /**< This flag is sent when the PMD supports a packet transmit callback
  */
 
@@ -1241,9 +1260,8 @@ rte_event_crypto_adapter_caps_get(uint8_t dev_id, uint8_t cdev_id,
  *   - <0: Error code returned by the driver function.
  *
  */
-int
-rte_event_eth_tx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
-				uint32_t *caps);
+int rte_event_eth_tx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
+				      uint32_t *caps);
 
 struct rte_eventdev_ops;
 struct rte_eventdev;
@@ -1252,28 +1270,31 @@ typedef uint16_t (*event_enqueue_t)(void *port, const struct rte_event *ev);
 /**< @internal Enqueue event on port of a device */
 
 typedef uint16_t (*event_enqueue_burst_t)(void *port,
-			const struct rte_event ev[], uint16_t nb_events);
+					  const struct rte_event ev[],
+					  uint16_t nb_events);
 /**< @internal Enqueue burst of events on port of a device */
 
 typedef uint16_t (*event_dequeue_t)(void *port, struct rte_event *ev,
-		uint64_t timeout_ticks);
+				    uint64_t timeout_ticks);
 /**< @internal Dequeue event from port of a device */
 
 typedef uint16_t (*event_dequeue_burst_t)(void *port, struct rte_event ev[],
-		uint16_t nb_events, uint64_t timeout_ticks);
+					  uint16_t nb_events,
+					  uint64_t timeout_ticks);
 /**< @internal Dequeue burst of events from port of a device */
 
-typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
-				struct rte_event ev[], uint16_t nb_events);
+typedef uint16_t (*event_tx_adapter_enqueue)(void *port, struct rte_event ev[],
+					     uint16_t nb_events);
 /**< @internal Enqueue burst of events on port of a device */
 
 typedef uint16_t (*event_tx_adapter_enqueue_same_dest)(void *port,
-		struct rte_event ev[], uint16_t nb_events);
+						       struct rte_event ev[],
+						       uint16_t nb_events);
 /**< @internal Enqueue burst of events on port of a device supporting
  * burst having same destination Ethernet port & Tx queue.
  */
 
-#define RTE_EVENTDEV_NAME_MAX_LEN	(64)
+#define RTE_EVENTDEV_NAME_MAX_LEN (64)
 /**< @internal Max length of name of event PMD */
 
 /**
@@ -1321,7 +1342,7 @@ struct rte_eventdev_data {
 	/**< Unique identifier name */
 
 	uint64_t reserved_64s[4]; /**< Reserved for future fields */
-	void *reserved_ptrs[4];   /**< Reserved for future fields */
+	void *reserved_ptrs[4];	  /**< Reserved for future fields */
 } __rte_cache_aligned;
 
 /** @internal The data structure associated with each event device. */
@@ -1356,7 +1377,7 @@ struct rte_eventdev {
 	/**< Flag indicating the device is attached */
 
 	uint64_t reserved_64s[4]; /**< Reserved for future fields */
-	void *reserved_ptrs[4];   /**< Reserved for future fields */
+	void *reserved_ptrs[4];	  /**< Reserved for future fields */
 } __rte_cache_aligned;
 
 extern struct rte_eventdev *rte_eventdevs;
@@ -1364,8 +1385,8 @@ extern struct rte_eventdev *rte_eventdevs;
 
 static __rte_always_inline uint16_t
 __rte_event_enqueue_burst(uint8_t dev_id, uint8_t port_id,
-			const struct rte_event ev[], uint16_t nb_events,
-			const event_enqueue_burst_t fn)
+			  const struct rte_event ev[], uint16_t nb_events,
+			  const event_enqueue_burst_t fn)
 {
 	const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
 
@@ -1441,7 +1462,7 @@ rte_event_enqueue_burst(uint8_t dev_id, uint8_t port_id,
 	const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
 
 	return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
-			dev->enqueue_burst);
+					 dev->enqueue_burst);
 }
 
 /**
@@ -1487,12 +1508,12 @@ rte_event_enqueue_burst(uint8_t dev_id, uint8_t port_id,
  */
 static inline uint16_t
 rte_event_enqueue_new_burst(uint8_t dev_id, uint8_t port_id,
-			const struct rte_event ev[], uint16_t nb_events)
+			    const struct rte_event ev[], uint16_t nb_events)
 {
 	const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
 
 	return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
-			dev->enqueue_new_burst);
+					 dev->enqueue_new_burst);
 }
 
 /**
@@ -1538,12 +1559,12 @@ rte_event_enqueue_new_burst(uint8_t dev_id, uint8_t port_id,
  */
 static inline uint16_t
 rte_event_enqueue_forward_burst(uint8_t dev_id, uint8_t port_id,
-			const struct rte_event ev[], uint16_t nb_events)
+				const struct rte_event ev[], uint16_t nb_events)
 {
 	const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
 
 	return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
-			dev->enqueue_forward_burst);
+					 dev->enqueue_forward_burst);
 }
 
 /**
@@ -1571,9 +1592,8 @@ rte_event_enqueue_forward_burst(uint8_t dev_id, uint8_t port_id,
  * @see rte_event_dev_configure()
  *
  */
-int
-rte_event_dequeue_timeout_ticks(uint8_t dev_id, uint64_t ns,
-					uint64_t *timeout_ticks);
+int rte_event_dequeue_timeout_ticks(uint8_t dev_id, uint64_t ns,
+				    uint64_t *timeout_ticks);
 
 /**
  * Dequeue a burst of events objects or an event object from the event port
@@ -1664,12 +1684,11 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[],
 	 * requests nb_events as const one
 	 */
 	if (nb_events == 1)
-		return (*dev->dequeue)(
-			dev->data->ports[port_id], ev, timeout_ticks);
+		return (*dev->dequeue)(dev->data->ports[port_id], ev,
+				       timeout_ticks);
 	else
-		return (*dev->dequeue_burst)(
-			dev->data->ports[port_id], ev, nb_events,
-				timeout_ticks);
+		return (*dev->dequeue_burst)(dev->data->ports[port_id], ev,
+					     nb_events, timeout_ticks);
 }
 
 /**
@@ -1732,10 +1751,8 @@ rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[],
  * (EINVAL) Invalid parameter
  *
  */
-int
-rte_event_port_link(uint8_t dev_id, uint8_t port_id,
-		    const uint8_t queues[], const uint8_t priorities[],
-		    uint16_t nb_links);
+int rte_event_port_link(uint8_t dev_id, uint8_t port_id, const uint8_t queues[],
+			const uint8_t priorities[], uint16_t nb_links);
 
 /**
  * Unlink multiple source event queues supplied in *queues* from the destination
@@ -1776,9 +1793,8 @@ rte_event_port_link(uint8_t dev_id, uint8_t port_id,
  * the rte_errno accordingly, Possible rte_errno values are
  * (EINVAL) Invalid parameter
  */
-int
-rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
-		      uint8_t queues[], uint16_t nb_unlinks);
+int rte_event_port_unlink(uint8_t dev_id, uint8_t port_id, uint8_t queues[],
+			  uint16_t nb_unlinks);
 
 /**
  * Returns the number of unlinks in progress.
@@ -1801,8 +1817,7 @@ rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
  * A negative return value indicates an error, -EINVAL indicates an invalid
  * parameter passed for *dev_id* or *port_id*.
  */
-int
-rte_event_port_unlinks_in_progress(uint8_t dev_id, uint8_t port_id);
+int rte_event_port_unlinks_in_progress(uint8_t dev_id, uint8_t port_id);
 
 /**
  * Retrieve the list of source event queues and its associated service priority
@@ -1831,9 +1846,8 @@ rte_event_port_unlinks_in_progress(uint8_t dev_id, uint8_t port_id);
  * - <0 on failure.
  *
  */
-int
-rte_event_port_links_get(uint8_t dev_id, uint8_t port_id,
-			 uint8_t queues[], uint8_t priorities[]);
+int rte_event_port_links_get(uint8_t dev_id, uint8_t port_id, uint8_t queues[],
+			     uint8_t priorities[]);
 
 /**
  * Retrieve the service ID of the event dev. If the adapter doesn't use
@@ -1850,8 +1864,7 @@ rte_event_port_links_get(uint8_t dev_id, uint8_t port_id,
  *   - <0: Error code on failure, if the event dev doesn't use a rte_service
  *   function, this function returns -ESRCH.
  */
-int
-rte_event_dev_service_id_get(uint8_t dev_id, uint32_t *service_id);
+int rte_event_dev_service_id_get(uint8_t dev_id, uint32_t *service_id);
 
 /**
  * Dump internal information about *dev_id* to the FILE* provided in *f*.
@@ -1866,8 +1879,7 @@ rte_event_dev_service_id_get(uint8_t dev_id, uint32_t *service_id);
  *   - 0: on success
  *   - <0: on failure.
  */
-int
-rte_event_dev_dump(uint8_t dev_id, FILE *f);
+int rte_event_dev_dump(uint8_t dev_id, FILE *f);
 
 /** Maximum name length for extended statistics counters */
 #define RTE_EVENT_DEV_XSTATS_NAME_SIZE 64
@@ -1923,13 +1935,10 @@ struct rte_event_dev_xstats_name {
  *        -EINVAL for invalid mode, queue port or id parameters
  *        -ENOTSUP if the device doesn't support this function.
  */
-int
-rte_event_dev_xstats_names_get(uint8_t dev_id,
-			       enum rte_event_dev_xstats_mode mode,
-			       uint8_t queue_port_id,
-			       struct rte_event_dev_xstats_name *xstats_names,
-			       unsigned int *ids,
-			       unsigned int size);
+int rte_event_dev_xstats_names_get(
+	uint8_t dev_id, enum rte_event_dev_xstats_mode mode,
+	uint8_t queue_port_id, struct rte_event_dev_xstats_name *xstats_names,
+	unsigned int *ids, unsigned int size);
 
 /**
  * Retrieve extended statistics of an event device.
@@ -1957,12 +1966,10 @@ rte_event_dev_xstats_names_get(uint8_t dev_id,
  *        -EINVAL for invalid mode, queue port or id parameters
  *        -ENOTSUP if the device doesn't support this function.
  */
-int
-rte_event_dev_xstats_get(uint8_t dev_id,
-			 enum rte_event_dev_xstats_mode mode,
-			 uint8_t queue_port_id,
-			 const unsigned int ids[],
-			 uint64_t values[], unsigned int n);
+int rte_event_dev_xstats_get(uint8_t dev_id,
+			     enum rte_event_dev_xstats_mode mode,
+			     uint8_t queue_port_id, const unsigned int ids[],
+			     uint64_t values[], unsigned int n);
 
 /**
  * Retrieve the value of a single stat by requesting it by name.
@@ -1980,9 +1987,8 @@ rte_event_dev_xstats_get(uint8_t dev_id,
  *   - positive value or zero: the stat value
  *   - negative value: -EINVAL if stat not found, -ENOTSUP if not supported.
  */
-uint64_t
-rte_event_dev_xstats_by_name_get(uint8_t dev_id, const char *name,
-				 unsigned int *id);
+uint64_t rte_event_dev_xstats_by_name_get(uint8_t dev_id, const char *name,
+					  unsigned int *id);
 
 /**
  * Reset the values of the xstats of the selected component in the device.
@@ -2004,12 +2010,10 @@ rte_event_dev_xstats_by_name_get(uint8_t dev_id, const char *name,
  *   - zero: successfully reset the statistics to zero
  *   - negative value: -EINVAL invalid parameters, -ENOTSUP if not supported.
  */
-int
-rte_event_dev_xstats_reset(uint8_t dev_id,
-			   enum rte_event_dev_xstats_mode mode,
-			   int16_t queue_port_id,
-			   const uint32_t ids[],
-			   uint32_t nb_ids);
+int rte_event_dev_xstats_reset(uint8_t dev_id,
+			       enum rte_event_dev_xstats_mode mode,
+			       int16_t queue_port_id, const uint32_t ids[],
+			       uint32_t nb_ids);
 
 /**
  * Trigger the eventdev self test.
@@ -2023,6 +2027,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)
+{
+	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 {
