avoid AltiVec keyword vector
[dpdk.git] / lib / eventdev / rte_eventdev.h
index 0c70188..6a6f6ea 100644 (file)
@@ -211,10 +211,8 @@ extern "C" {
 #endif
 
 #include <rte_common.h>
-#include <rte_config.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"
@@ -224,10 +222,16 @@ struct rte_event;
 
 /* Event device capability bitmap flags */
 #define RTE_EVENT_DEV_CAP_QUEUE_QOS           (1ULL << 0)
-/**< Event scheduling prioritization is based on the priority associated with
- *  each event queue.
+/**< Event scheduling prioritization is based on the priority and weight
+ * associated with each event queue. Events from a queue with highest priority
+ * is scheduled first. If the queues are of same priority, weight of the queues
+ * are considered to select a queue in a weighted round robin fashion.
+ * Subsequent dequeue calls from an event port could see events from the same
+ * event queue, if the queue is configured with an affinity count. Affinity
+ * count is the number of subsequent dequeue calls, in which an event port
+ * should use the same event queue if the queue is non-empty
  *
- *  @see rte_event_queue_setup()
+ *  @see rte_event_queue_setup(), rte_event_queue_attr_set()
  */
 #define RTE_EVENT_DEV_CAP_EVENT_QOS           (1ULL << 1)
 /**< Event scheduling prioritization is based on the priority associated with
@@ -299,6 +303,23 @@ struct rte_event;
  * the content of this field is implementation dependent.
  */
 
+#define RTE_EVENT_DEV_CAP_MAINTENANCE_FREE (1ULL << 10)
+/**< Event device *does not* require calls to rte_event_maintain().
+ * An event device that does not set this flag requires calls to
+ * rte_event_maintain() during periods when neither
+ * rte_event_dequeue_burst() nor rte_event_enqueue_burst() are called
+ * on a port. This will allow the event device to perform internal
+ * processing, such as flushing buffered events, return credits to a
+ * global pool, or process signaling related to load balancing.
+ */
+
+#define RTE_EVENT_DEV_CAP_RUNTIME_QUEUE_ATTR (1ULL << 11)
+/**< Event device is capable of changing the queue attributes at runtime i.e
+ * after rte_event_queue_setup() or rte_event_start() call sequence. If this
+ * flag is not set, eventdev queue attributes can only be configured during
+ * rte_event_queue_setup().
+ */
+
 /* Event device priority levels */
 #define RTE_EVENT_DEV_PRIORITY_HIGHEST   0
 /**< Highest priority expressed across eventdev subsystem
@@ -316,6 +337,26 @@ struct rte_event;
  * @see rte_event_port_link()
  */
 
+/* Event queue scheduling weights */
+#define RTE_EVENT_QUEUE_WEIGHT_HIGHEST 255
+/**< Highest weight of an event queue
+ * @see rte_event_queue_attr_get(), rte_event_queue_attr_set()
+ */
+#define RTE_EVENT_QUEUE_WEIGHT_LOWEST 0
+/**< Lowest weight of an event queue
+ * @see rte_event_queue_attr_get(), rte_event_queue_attr_set()
+ */
+
+/* Event queue scheduling affinity */
+#define RTE_EVENT_QUEUE_AFFINITY_HIGHEST 255
+/**< Highest scheduling affinity of an event queue
+ * @see rte_event_queue_attr_get(), rte_event_queue_attr_set()
+ */
+#define RTE_EVENT_QUEUE_AFFINITY_LOWEST 0
+/**< Lowest scheduling affinity of an event queue
+ * @see rte_event_queue_attr_get(), rte_event_queue_attr_set()
+ */
+
 /**
  * Get the total number of event devices that have been successfully
  * initialised.
@@ -669,6 +710,14 @@ rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
  * The schedule type of the queue.
  */
 #define RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE 4
+/**
+ * The weight of the queue.
+ */
+#define RTE_EVENT_QUEUE_ATTR_WEIGHT 5
+/**
+ * Affinity of the queue.
+ */
+#define RTE_EVENT_QUEUE_ATTR_AFFINITY 6
 
 /**
  * Get an attribute from a queue.
@@ -694,6 +743,29 @@ int
 rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
                        uint32_t *attr_value);
 
+/**
+ * Set an event queue attribute.
+ *
+ * @param dev_id
+ *   Eventdev id
+ * @param queue_id
+ *   Eventdev queue id
+ * @param attr_id
+ *   The attribute ID to set
+ * @param attr_value
+ *   The attribute value to set
+ *
+ * @return
+ *   - 0: Successfully set attribute.
+ *   - -EINVAL: invalid device, queue or attr_id.
+ *   - -ENOTSUP: device does not support setting the event attribute.
+ *   - <0: failed to set event queue attribute
+ */
+__rte_experimental
+int
+rte_event_queue_attr_set(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
+                        uint64_t attr_value);
+
 /* Event port specific APIs */
 
 /* Event port configuration bitmap flags */
@@ -709,6 +781,38 @@ rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
  *
  *  @see rte_event_port_setup(), rte_event_port_link()
  */
+#define RTE_EVENT_PORT_CFG_HINT_PRODUCER       (1ULL << 2)
+/**< Hint that this event port will primarily enqueue events to the system.
+ * A PMD can optimize its internal workings by assuming that this port is
+ * primarily going to enqueue NEW events.
+ *
+ * Note that this flag is only a hint, so PMDs must operate under the
+ * assumption that any port can enqueue an event with any type of op.
+ *
+ *  @see rte_event_port_setup()
+ */
+#define RTE_EVENT_PORT_CFG_HINT_CONSUMER       (1ULL << 3)
+/**< Hint that this event port will primarily dequeue events from the system.
+ * A PMD can optimize its internal workings by assuming that this port is
+ * primarily going to consume events, and not enqueue FORWARD or RELEASE
+ * events.
+ *
+ * Note that this flag is only a hint, so PMDs must operate under the
+ * assumption that any port can enqueue an event with any type of op.
+ *
+ *  @see rte_event_port_setup()
+ */
+#define RTE_EVENT_PORT_CFG_HINT_WORKER         (1ULL << 4)
+/**< Hint that this event port will primarily pass existing events through.
+ * A PMD can optimize its internal workings by assuming that this port is
+ * primarily going to FORWARD events, and not enqueue NEW or RELEASE events
+ * often.
+ *
+ * Note that this flag is only a hint, so PMDs must operate under the
+ * assumption that any port can enqueue an event with any type of op.
+ *
+ *  @see rte_event_port_setup()
+ */
 
 /** Event port configuration structure */
 struct rte_event_port_conf {
@@ -790,6 +894,42 @@ int
 rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
                     const struct rte_event_port_conf *port_conf);
 
+typedef void (*rte_eventdev_port_flush_t)(uint8_t dev_id,
+                                         struct rte_event event, void *arg);
+/**< Callback function prototype that can be passed during
+ * rte_event_port_release(), invoked once per a released event.
+ */
+
+/**
+ * Quiesce any core specific resources consumed by the event port.
+ *
+ * Event ports are generally coupled with lcores, and a given Hardware
+ * implementation might require the PMD to store port specific data in the
+ * lcore.
+ * When the application decides to migrate the event port to another lcore
+ * or teardown the current lcore it may to call `rte_event_port_quiesce`
+ * to make sure that all the data associated with the event port are released
+ * from the lcore, this might also include any prefetched events.
+ * While releasing the event port from the lcore, this function calls the
+ * user-provided flush callback once per event.
+ *
+ * @note Invocation of this API does not affect the existing port configuration.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The index of the event port to setup. The value must be in the range
+ *   [0, nb_event_ports - 1] previously supplied to rte_event_dev_configure().
+ * @param release_cb
+ *   Callback function invoked once per flushed event.
+ * @param args
+ *   Argument supplied to callback.
+ */
+__rte_experimental
+void
+rte_event_port_quiesce(uint8_t dev_id, uint8_t port_id,
+                      rte_eventdev_port_flush_t release_cb, void *args);
+
 /**
  * The queue depth of the port on the enqueue side
  */
@@ -944,21 +1084,31 @@ struct rte_event_vector {
        };
        /**< Union to hold common attributes of the vector array. */
        uint64_t impl_opaque;
+
+/* empty structures do not have zero size in C++ leading to compilation errors
+ * with clang about structure having different sizes in C and C++.
+ * Since these are all zero-sized arrays, we can omit the "union" wrapper for
+ * C++ builds, removing the warning.
+ */
+#ifndef __cplusplus
        /**< Implementation specific opaque value.
         * An implementation may use this field to hold implementation specific
         * value to share between dequeue and enqueue operation.
         * The application should not modify this field.
         */
        union {
+#endif
                struct rte_mbuf *mbufs[0];
                void *ptrs[0];
                uint64_t *u64s[0];
+#ifndef __cplusplus
        } __rte_aligned(16);
+#endif
        /**< 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.
         */
-};
+} __rte_aligned(16);
 
 /* Scheduler type definitions */
 #define RTE_SCHED_TYPE_ORDERED          0
@@ -1193,7 +1343,7 @@ struct rte_event {
 #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
+ * to the adapter using the ev.flow_id member.
  * @see struct rte_event_eth_rx_adapter_queue_conf::ev
  * @see struct rte_event_eth_rx_adapter_queue_conf::rx_queue_flags
  */
@@ -1324,317 +1474,6 @@ int
 rte_event_eth_tx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
                                uint32_t *caps);
 
-struct eventdev_ops;
-struct rte_eventdev;
-
-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);
-/**< @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);
-/**< @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);
-/**< @internal Dequeue burst of events from port of a device */
-
-typedef uint16_t (*event_tx_adapter_enqueue_t)(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_t)(void *port,
-                                                        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.
- */
-
-typedef uint16_t (*event_crypto_adapter_enqueue_t)(void *port,
-                                                  struct rte_event ev[],
-                                                  uint16_t nb_events);
-/**< @internal Enqueue burst of events on crypto adapter */
-
-#define RTE_EVENTDEV_NAME_MAX_LEN      (64)
-/**< @internal Max length of name of event PMD */
-
-/**
- * @internal
- * The data part, with no function pointers, associated with each device.
- *
- * This structure is safe to place in shared memory to be common among
- * different processes in a multi-process configuration.
- */
-struct rte_eventdev_data {
-       int socket_id;
-       /**< Socket ID where memory is allocated */
-       uint8_t dev_id;
-       /**< Device ID for this instance */
-       uint8_t nb_queues;
-       /**< Number of event queues. */
-       uint8_t nb_ports;
-       /**< Number of event ports. */
-       void **ports;
-       /**< Array of pointers to ports. */
-       struct rte_event_port_conf *ports_cfg;
-       /**< Array of port configuration structures. */
-       struct rte_event_queue_conf *queues_cfg;
-       /**< Array of queue configuration structures. */
-       uint16_t *links_map;
-       /**< Memory to store queues to port connections. */
-       void *dev_private;
-       /**< PMD-specific private data */
-       uint32_t event_dev_cap;
-       /**< Event device capabilities(RTE_EVENT_DEV_CAP_)*/
-       struct rte_event_dev_config dev_conf;
-       /**< Configuration applied to device. */
-       uint8_t service_inited;
-       /* Service initialization state */
-       uint32_t service_id;
-       /* Service ID*/
-       void *dev_stop_flush_arg;
-       /**< User-provided argument for event flush function */
-
-       RTE_STD_C11
-       uint8_t dev_started : 1;
-       /**< Device state: STARTED(1)/STOPPED(0) */
-
-       char name[RTE_EVENTDEV_NAME_MAX_LEN];
-       /**< Unique identifier name */
-
-       uint64_t reserved_64s[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. */
-struct rte_eventdev {
-       event_enqueue_t enqueue;
-       /**< Pointer to PMD enqueue function. */
-       event_enqueue_burst_t enqueue_burst;
-       /**< Pointer to PMD enqueue burst function. */
-       event_enqueue_burst_t enqueue_new_burst;
-       /**< Pointer to PMD enqueue burst function(op new variant) */
-       event_enqueue_burst_t enqueue_forward_burst;
-       /**< Pointer to PMD enqueue burst function(op forward variant) */
-       event_dequeue_t dequeue;
-       /**< Pointer to PMD dequeue function. */
-       event_dequeue_burst_t dequeue_burst;
-       /**< Pointer to PMD dequeue burst function. */
-       event_tx_adapter_enqueue_same_dest_t txa_enqueue_same_dest;
-       /**< Pointer to PMD eth Tx adapter burst enqueue function with
-        * events destined to same Eth port & Tx queue.
-        */
-       event_tx_adapter_enqueue_t txa_enqueue;
-       /**< Pointer to PMD eth Tx adapter enqueue function. */
-       struct rte_eventdev_data *data;
-       /**< Pointer to device data */
-       struct eventdev_ops *dev_ops;
-       /**< Functions exported by PMD */
-       struct rte_device *dev;
-       /**< Device info. supplied by probing */
-
-       RTE_STD_C11
-       uint8_t attached : 1;
-       /**< Flag indicating the device is attached */
-
-       event_crypto_adapter_enqueue_t ca_enqueue;
-       /**< Pointer to PMD crypto adapter enqueue function. */
-
-       uint64_t reserved_64s[4]; /**< Reserved for future fields */
-       void *reserved_ptrs[3];   /**< Reserved for future fields */
-} __rte_cache_aligned;
-
-extern struct rte_eventdev *rte_eventdevs;
-/** @internal The pool of rte_eventdev structures. */
-
-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_eventdev *dev = &rte_eventdevs[dev_id];
-
-#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
-       if (dev_id >= RTE_EVENT_MAX_DEVS || !rte_eventdevs[dev_id].attached) {
-               rte_errno = EINVAL;
-               return 0;
-       }
-
-       if (port_id >= dev->data->nb_ports) {
-               rte_errno = EINVAL;
-               return 0;
-       }
-#endif
-       rte_eventdev_trace_enq_burst(dev_id, port_id, ev, nb_events, fn);
-       /*
-        * Allow zero cost non burst mode routine invocation if application
-        * requests nb_events as const one
-        */
-       if (nb_events == 1)
-               return (*dev->enqueue)(dev->data->ports[port_id], ev);
-       else
-               return fn(dev->data->ports[port_id], ev, nb_events);
-}
-
-/**
- * Enqueue a burst of events objects or an event object supplied in *rte_event*
- * structure on an  event device designated by its *dev_id* through the event
- * port specified by *port_id*. Each event object specifies the event queue on
- * which it will be enqueued.
- *
- * The *nb_events* parameter is the number of event objects to enqueue which are
- * supplied in the *ev* array of *rte_event* structure.
- *
- * Event operations RTE_EVENT_OP_FORWARD and RTE_EVENT_OP_RELEASE must only be
- * enqueued to the same port that their associated events were dequeued from.
- *
- * The rte_event_enqueue_burst() function returns the number of
- * events objects it actually enqueued. A return value equal to *nb_events*
- * means that all event objects have been enqueued.
- *
- * @param dev_id
- *   The identifier of the device.
- * @param port_id
- *   The identifier of the event port.
- * @param ev
- *   Points to an array of *nb_events* objects of type *rte_event* structure
- *   which contain the event object enqueue operations to be processed.
- * @param nb_events
- *   The number of event objects to enqueue, typically number of
- *   rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
- *   available for this port.
- *
- * @return
- *   The number of event objects actually enqueued on the event device. The
- *   return value can be less than the value of the *nb_events* parameter when
- *   the event devices queue is full or if invalid parameters are specified in a
- *   *rte_event*. If the return value is less than *nb_events*, the remaining
- *   events at the end of ev[] are not consumed and the caller has to take care
- *   of them, and rte_errno is set accordingly. Possible errno values include:
- *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
- *              ID is invalid, or an event's sched type doesn't match the
- *              capabilities of the destination queue.
- *   - ENOSPC   The event port was backpressured and unable to enqueue
- *              one or more events. This error code is only applicable to
- *              closed systems.
- * @see rte_event_port_attr_get(), RTE_EVENT_PORT_ATTR_ENQ_DEPTH
- */
-static 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 struct rte_eventdev *dev = &rte_eventdevs[dev_id];
-
-       return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
-                       dev->enqueue_burst);
-}
-
-/**
- * Enqueue a burst of events objects of operation type *RTE_EVENT_OP_NEW* on
- * an event device designated by its *dev_id* through the event port specified
- * by *port_id*.
- *
- * Provides the same functionality as rte_event_enqueue_burst(), expect that
- * application can use this API when the all objects in the burst contains
- * the enqueue operation of the type *RTE_EVENT_OP_NEW*. This specialized
- * function can provide the additional hint to the PMD and optimize if possible.
- *
- * The rte_event_enqueue_new_burst() result is undefined if the enqueue burst
- * has event object of operation type != RTE_EVENT_OP_NEW.
- *
- * @param dev_id
- *   The identifier of the device.
- * @param port_id
- *   The identifier of the event port.
- * @param ev
- *   Points to an array of *nb_events* objects of type *rte_event* structure
- *   which contain the event object enqueue operations to be processed.
- * @param nb_events
- *   The number of event objects to enqueue, typically number of
- *   rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
- *   available for this port.
- *
- * @return
- *   The number of event objects actually enqueued on the event device. The
- *   return value can be less than the value of the *nb_events* parameter when
- *   the event devices queue is full or if invalid parameters are specified in a
- *   *rte_event*. If the return value is less than *nb_events*, the remaining
- *   events at the end of ev[] are not consumed and the caller has to take care
- *   of them, and rte_errno is set accordingly. Possible errno values include:
- *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
- *              ID is invalid, or an event's sched type doesn't match the
- *              capabilities of the destination queue.
- *   - ENOSPC   The event port was backpressured and unable to enqueue
- *              one or more events. This error code is only applicable to
- *              closed systems.
- * @see rte_event_port_attr_get(), RTE_EVENT_PORT_ATTR_ENQ_DEPTH
- * @see rte_event_enqueue_burst()
- */
-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_eventdev *dev = &rte_eventdevs[dev_id];
-
-       return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
-                       dev->enqueue_new_burst);
-}
-
-/**
- * Enqueue a burst of events objects of operation type *RTE_EVENT_OP_FORWARD*
- * on an event device designated by its *dev_id* through the event port
- * specified by *port_id*.
- *
- * Provides the same functionality as rte_event_enqueue_burst(), expect that
- * application can use this API when the all objects in the burst contains
- * the enqueue operation of the type *RTE_EVENT_OP_FORWARD*. This specialized
- * function can provide the additional hint to the PMD and optimize if possible.
- *
- * The rte_event_enqueue_new_burst() result is undefined if the enqueue burst
- * has event object of operation type != RTE_EVENT_OP_FORWARD.
- *
- * @param dev_id
- *   The identifier of the device.
- * @param port_id
- *   The identifier of the event port.
- * @param ev
- *   Points to an array of *nb_events* objects of type *rte_event* structure
- *   which contain the event object enqueue operations to be processed.
- * @param nb_events
- *   The number of event objects to enqueue, typically number of
- *   rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
- *   available for this port.
- *
- * @return
- *   The number of event objects actually enqueued on the event device. The
- *   return value can be less than the value of the *nb_events* parameter when
- *   the event devices queue is full or if invalid parameters are specified in a
- *   *rte_event*. If the return value is less than *nb_events*, the remaining
- *   events at the end of ev[] are not consumed and the caller has to take care
- *   of them, and rte_errno is set accordingly. Possible errno values include:
- *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
- *              ID is invalid, or an event's sched type doesn't match the
- *              capabilities of the destination queue.
- *   - ENOSPC   The event port was backpressured and unable to enqueue
- *              one or more events. This error code is only applicable to
- *              closed systems.
- * @see rte_event_port_attr_get(), RTE_EVENT_PORT_ATTR_ENQ_DEPTH
- * @see rte_event_enqueue_burst()
- */
-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_eventdev *dev = &rte_eventdevs[dev_id];
-
-       return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
-                       dev->enqueue_forward_burst);
-}
-
 /**
  * Converts nanoseconds to *timeout_ticks* value for rte_event_dequeue_burst()
  *
@@ -1665,106 +1504,9 @@ 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
- * designated by its *event_port_id*, on an event device designated
- * by its *dev_id*.
- *
- * rte_event_dequeue_burst() does not dictate the specifics of scheduling
- * algorithm as each eventdev driver may have different criteria to schedule
- * an event. However, in general, from an application perspective scheduler may
- * use the following scheme to dispatch an event to the port.
- *
- * 1) Selection of event queue based on
- *   a) The list of event queues are linked to the event port.
- *   b) If the device has RTE_EVENT_DEV_CAP_QUEUE_QOS capability then event
- *   queue selection from list is based on event queue priority relative to
- *   other event queue supplied as *priority* in rte_event_queue_setup()
- *   c) If the device has RTE_EVENT_DEV_CAP_EVENT_QOS capability then event
- *   queue selection from the list is based on event priority supplied as
- *   *priority* in rte_event_enqueue_burst()
- * 2) Selection of event
- *   a) The number of flows available in selected event queue.
- *   b) Schedule type method associated with the event
- *
- * The *nb_events* parameter is the maximum number of event objects to dequeue
- * which are returned in the *ev* array of *rte_event* structure.
- *
- * The rte_event_dequeue_burst() function returns the number of events objects
- * it actually dequeued. A return value equal to *nb_events* means that all
- * event objects have been dequeued.
- *
- * The number of events dequeued is the number of scheduler contexts held by
- * this port. These contexts are automatically released in the next
- * rte_event_dequeue_burst() invocation if the port supports implicit
- * releases, or invoking rte_event_enqueue_burst() with RTE_EVENT_OP_RELEASE
- * operation can be used to release the contexts early.
- *
- * Event operations RTE_EVENT_OP_FORWARD and RTE_EVENT_OP_RELEASE must only be
- * enqueued to the same port that their associated events were dequeued from.
- *
- * @param dev_id
- *   The identifier of the device.
- * @param port_id
- *   The identifier of the event port.
- * @param[out] ev
- *   Points to an array of *nb_events* objects of type *rte_event* structure
- *   for output to be populated with the dequeued event objects.
- * @param nb_events
- *   The maximum number of event objects to dequeue, typically number of
- *   rte_event_port_dequeue_depth() available for this port.
- *
- * @param timeout_ticks
- *   - 0 no-wait, returns immediately if there is no event.
- *   - >0 wait for the event, if the device is configured with
- *   RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT then this function will wait until
- *   at least one event is available or *timeout_ticks* time.
- *   if the device is not configured with RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT
- *   then this function will wait until the event available or
- *   *dequeue_timeout_ns* ns which was previously supplied to
- *   rte_event_dev_configure()
- *
- * @return
- * The number of event objects actually dequeued from the port. The return
- * value can be less than the value of the *nb_events* parameter when the
- * event port's queue is not full.
- *
- * @see rte_event_port_dequeue_depth()
- */
-static inline uint16_t
-rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[],
-                       uint16_t nb_events, uint64_t timeout_ticks)
-{
-       struct rte_eventdev *dev = &rte_eventdevs[dev_id];
-
-#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
-       if (dev_id >= RTE_EVENT_MAX_DEVS || !rte_eventdevs[dev_id].attached) {
-               rte_errno = EINVAL;
-               return 0;
-       }
-
-       if (port_id >= dev->data->nb_ports) {
-               rte_errno = EINVAL;
-               return 0;
-       }
-#endif
-       rte_eventdev_trace_deq_burst(dev_id, port_id, ev, nb_events);
-       /*
-        * Allow zero cost non burst mode routine invocation if application
-        * requests nb_events as const one
-        */
-       if (nb_events == 1)
-               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);
-}
-
-/**
- * Link multiple source event queues supplied in *queues* to the destination
- * event port designated by its *port_id* with associated service priority
- * supplied in *priorities* on the event device designated by its *dev_id*.
+ * Link multiple source event queues supplied in *queues* to the destination
+ * event port designated by its *port_id* with associated service priority
+ * supplied in *priorities* on the event device designated by its *dev_id*.
  *
  * The link establishment shall enable the event port *port_id* from
  * receiving events from the specified event queue(s) supplied in *queues*
@@ -2142,12 +1884,373 @@ int rte_event_dev_selftest(uint8_t dev_id);
  *    - ENOMEM - no appropriate memory area found in which to create memzone
  *    - ENAMETOOLONG - mempool name requested is too long.
  */
-__rte_experimental
 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);
 
+#include <rte_eventdev_core.h>
+
+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_fp_ops *fp_ops;
+       void *port;
+
+       fp_ops = &rte_event_fp_ops[dev_id];
+       port = fp_ops->data[port_id];
+#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
+       if (dev_id >= RTE_EVENT_MAX_DEVS ||
+           port_id >= RTE_EVENT_MAX_PORTS_PER_DEV) {
+               rte_errno = EINVAL;
+               return 0;
+       }
+
+       if (port == NULL) {
+               rte_errno = EINVAL;
+               return 0;
+       }
+#endif
+       rte_eventdev_trace_enq_burst(dev_id, port_id, ev, nb_events, (void *)fn);
+       /*
+        * Allow zero cost non burst mode routine invocation if application
+        * requests nb_events as const one
+        */
+       if (nb_events == 1)
+               return (fp_ops->enqueue)(port, ev);
+       else
+               return fn(port, ev, nb_events);
+}
+
+/**
+ * Enqueue a burst of events objects or an event object supplied in *rte_event*
+ * structure on an  event device designated by its *dev_id* through the event
+ * port specified by *port_id*. Each event object specifies the event queue on
+ * which it will be enqueued.
+ *
+ * The *nb_events* parameter is the number of event objects to enqueue which are
+ * supplied in the *ev* array of *rte_event* structure.
+ *
+ * Event operations RTE_EVENT_OP_FORWARD and RTE_EVENT_OP_RELEASE must only be
+ * enqueued to the same port that their associated events were dequeued from.
+ *
+ * The rte_event_enqueue_burst() function returns the number of
+ * events objects it actually enqueued. A return value equal to *nb_events*
+ * means that all event objects have been enqueued.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The identifier of the event port.
+ * @param ev
+ *   Points to an array of *nb_events* objects of type *rte_event* structure
+ *   which contain the event object enqueue operations to be processed.
+ * @param nb_events
+ *   The number of event objects to enqueue, typically number of
+ *   rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
+ *   available for this port.
+ *
+ * @return
+ *   The number of event objects actually enqueued on the event device. The
+ *   return value can be less than the value of the *nb_events* parameter when
+ *   the event devices queue is full or if invalid parameters are specified in a
+ *   *rte_event*. If the return value is less than *nb_events*, the remaining
+ *   events at the end of ev[] are not consumed and the caller has to take care
+ *   of them, and rte_errno is set accordingly. Possible errno values include:
+ *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
+ *              ID is invalid, or an event's sched type doesn't match the
+ *              capabilities of the destination queue.
+ *   - ENOSPC   The event port was backpressured and unable to enqueue
+ *              one or more events. This error code is only applicable to
+ *              closed systems.
+ * @see rte_event_port_attr_get(), RTE_EVENT_PORT_ATTR_ENQ_DEPTH
+ */
+static 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 struct rte_event_fp_ops *fp_ops;
+
+       fp_ops = &rte_event_fp_ops[dev_id];
+       return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
+                                        fp_ops->enqueue_burst);
+}
+
+/**
+ * Enqueue a burst of events objects of operation type *RTE_EVENT_OP_NEW* on
+ * an event device designated by its *dev_id* through the event port specified
+ * by *port_id*.
+ *
+ * Provides the same functionality as rte_event_enqueue_burst(), expect that
+ * application can use this API when the all objects in the burst contains
+ * the enqueue operation of the type *RTE_EVENT_OP_NEW*. This specialized
+ * function can provide the additional hint to the PMD and optimize if possible.
+ *
+ * The rte_event_enqueue_new_burst() result is undefined if the enqueue burst
+ * has event object of operation type != RTE_EVENT_OP_NEW.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The identifier of the event port.
+ * @param ev
+ *   Points to an array of *nb_events* objects of type *rte_event* structure
+ *   which contain the event object enqueue operations to be processed.
+ * @param nb_events
+ *   The number of event objects to enqueue, typically number of
+ *   rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
+ *   available for this port.
+ *
+ * @return
+ *   The number of event objects actually enqueued on the event device. The
+ *   return value can be less than the value of the *nb_events* parameter when
+ *   the event devices queue is full or if invalid parameters are specified in a
+ *   *rte_event*. If the return value is less than *nb_events*, the remaining
+ *   events at the end of ev[] are not consumed and the caller has to take care
+ *   of them, and rte_errno is set accordingly. Possible errno values include:
+ *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
+ *              ID is invalid, or an event's sched type doesn't match the
+ *              capabilities of the destination queue.
+ *   - ENOSPC   The event port was backpressured and unable to enqueue
+ *              one or more events. This error code is only applicable to
+ *              closed systems.
+ * @see rte_event_port_attr_get(), RTE_EVENT_PORT_ATTR_ENQ_DEPTH
+ * @see rte_event_enqueue_burst()
+ */
+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_fp_ops *fp_ops;
+
+       fp_ops = &rte_event_fp_ops[dev_id];
+       return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
+                                        fp_ops->enqueue_new_burst);
+}
+
+/**
+ * Enqueue a burst of events objects of operation type *RTE_EVENT_OP_FORWARD*
+ * on an event device designated by its *dev_id* through the event port
+ * specified by *port_id*.
+ *
+ * Provides the same functionality as rte_event_enqueue_burst(), expect that
+ * application can use this API when the all objects in the burst contains
+ * the enqueue operation of the type *RTE_EVENT_OP_FORWARD*. This specialized
+ * function can provide the additional hint to the PMD and optimize if possible.
+ *
+ * The rte_event_enqueue_new_burst() result is undefined if the enqueue burst
+ * has event object of operation type != RTE_EVENT_OP_FORWARD.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The identifier of the event port.
+ * @param ev
+ *   Points to an array of *nb_events* objects of type *rte_event* structure
+ *   which contain the event object enqueue operations to be processed.
+ * @param nb_events
+ *   The number of event objects to enqueue, typically number of
+ *   rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
+ *   available for this port.
+ *
+ * @return
+ *   The number of event objects actually enqueued on the event device. The
+ *   return value can be less than the value of the *nb_events* parameter when
+ *   the event devices queue is full or if invalid parameters are specified in a
+ *   *rte_event*. If the return value is less than *nb_events*, the remaining
+ *   events at the end of ev[] are not consumed and the caller has to take care
+ *   of them, and rte_errno is set accordingly. Possible errno values include:
+ *   - EINVAL   The port ID is invalid, device ID is invalid, an event's queue
+ *              ID is invalid, or an event's sched type doesn't match the
+ *              capabilities of the destination queue.
+ *   - ENOSPC   The event port was backpressured and unable to enqueue
+ *              one or more events. This error code is only applicable to
+ *              closed systems.
+ * @see rte_event_port_attr_get(), RTE_EVENT_PORT_ATTR_ENQ_DEPTH
+ * @see rte_event_enqueue_burst()
+ */
+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_fp_ops *fp_ops;
+
+       fp_ops = &rte_event_fp_ops[dev_id];
+       return __rte_event_enqueue_burst(dev_id, port_id, ev, nb_events,
+                                        fp_ops->enqueue_forward_burst);
+}
+
+/**
+ * Dequeue a burst of events objects or an event object from the event port
+ * designated by its *event_port_id*, on an event device designated
+ * by its *dev_id*.
+ *
+ * rte_event_dequeue_burst() does not dictate the specifics of scheduling
+ * algorithm as each eventdev driver may have different criteria to schedule
+ * an event. However, in general, from an application perspective scheduler may
+ * use the following scheme to dispatch an event to the port.
+ *
+ * 1) Selection of event queue based on
+ *   a) The list of event queues are linked to the event port.
+ *   b) If the device has RTE_EVENT_DEV_CAP_QUEUE_QOS capability then event
+ *   queue selection from list is based on event queue priority relative to
+ *   other event queue supplied as *priority* in rte_event_queue_setup()
+ *   c) If the device has RTE_EVENT_DEV_CAP_EVENT_QOS capability then event
+ *   queue selection from the list is based on event priority supplied as
+ *   *priority* in rte_event_enqueue_burst()
+ * 2) Selection of event
+ *   a) The number of flows available in selected event queue.
+ *   b) Schedule type method associated with the event
+ *
+ * The *nb_events* parameter is the maximum number of event objects to dequeue
+ * which are returned in the *ev* array of *rte_event* structure.
+ *
+ * The rte_event_dequeue_burst() function returns the number of events objects
+ * it actually dequeued. A return value equal to *nb_events* means that all
+ * event objects have been dequeued.
+ *
+ * The number of events dequeued is the number of scheduler contexts held by
+ * this port. These contexts are automatically released in the next
+ * rte_event_dequeue_burst() invocation if the port supports implicit
+ * releases, or invoking rte_event_enqueue_burst() with RTE_EVENT_OP_RELEASE
+ * operation can be used to release the contexts early.
+ *
+ * Event operations RTE_EVENT_OP_FORWARD and RTE_EVENT_OP_RELEASE must only be
+ * enqueued to the same port that their associated events were dequeued from.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The identifier of the event port.
+ * @param[out] ev
+ *   Points to an array of *nb_events* objects of type *rte_event* structure
+ *   for output to be populated with the dequeued event objects.
+ * @param nb_events
+ *   The maximum number of event objects to dequeue, typically number of
+ *   rte_event_port_dequeue_depth() available for this port.
+ *
+ * @param timeout_ticks
+ *   - 0 no-wait, returns immediately if there is no event.
+ *   - >0 wait for the event, if the device is configured with
+ *   RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT then this function will wait until
+ *   at least one event is available or *timeout_ticks* time.
+ *   if the device is not configured with RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT
+ *   then this function will wait until the event available or
+ *   *dequeue_timeout_ns* ns which was previously supplied to
+ *   rte_event_dev_configure()
+ *
+ * @return
+ * The number of event objects actually dequeued from the port. The return
+ * value can be less than the value of the *nb_events* parameter when the
+ * event port's queue is not full.
+ *
+ * @see rte_event_port_dequeue_depth()
+ */
+static inline uint16_t
+rte_event_dequeue_burst(uint8_t dev_id, uint8_t port_id, struct rte_event ev[],
+                       uint16_t nb_events, uint64_t timeout_ticks)
+{
+       const struct rte_event_fp_ops *fp_ops;
+       void *port;
+
+       fp_ops = &rte_event_fp_ops[dev_id];
+       port = fp_ops->data[port_id];
+#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
+       if (dev_id >= RTE_EVENT_MAX_DEVS ||
+           port_id >= RTE_EVENT_MAX_PORTS_PER_DEV) {
+               rte_errno = EINVAL;
+               return 0;
+       }
+
+       if (port == NULL) {
+               rte_errno = EINVAL;
+               return 0;
+       }
+#endif
+       rte_eventdev_trace_deq_burst(dev_id, port_id, ev, nb_events);
+       /*
+        * Allow zero cost non burst mode routine invocation if application
+        * requests nb_events as const one
+        */
+       if (nb_events == 1)
+               return (fp_ops->dequeue)(port, ev, timeout_ticks);
+       else
+               return (fp_ops->dequeue_burst)(port, ev, nb_events,
+                                              timeout_ticks);
+}
+
+#define RTE_EVENT_DEV_MAINT_OP_FLUSH          (1 << 0)
+/**< Force an immediately flush of any buffered events in the port,
+ * potentially at the cost of additional overhead.
+ *
+ * @see rte_event_maintain()
+ */
+
+/**
+ * Maintain an event device.
+ *
+ * This function is only relevant for event devices which do not have
+ * the @ref RTE_EVENT_DEV_CAP_MAINTENANCE_FREE flag set. Such devices
+ * require an application thread using a particular port to
+ * periodically call rte_event_maintain() on that port during periods
+ * which it is neither attempting to enqueue events to nor dequeue
+ * events from the port. rte_event_maintain() is a low-overhead
+ * function and should be called at a high rate (e.g., in the
+ * application's poll loop).
+ *
+ * No port may be left unmaintained.
+ *
+ * At the application thread's convenience, rte_event_maintain() may
+ * (but is not required to) be called even during periods when enqueue
+ * or dequeue functions are being called, at the cost of a slight
+ * increase in overhead.
+ *
+ * rte_event_maintain() may be called on event devices which have set
+ * @ref RTE_EVENT_DEV_CAP_MAINTENANCE_FREE, in which case it is a
+ * no-operation.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The identifier of the event port.
+ * @param op
+ *   0, or @ref RTE_EVENT_DEV_MAINT_OP_FLUSH.
+ * @return
+ *  - 0 on success.
+ *  - -EINVAL if *dev_id*,  *port_id*, or *op* is invalid.
+ *
+ * @see RTE_EVENT_DEV_CAP_MAINTENANCE_FREE
+ */
+__rte_experimental
+static inline int
+rte_event_maintain(uint8_t dev_id, uint8_t port_id, int op)
+{
+       const struct rte_event_fp_ops *fp_ops;
+       void *port;
+
+       fp_ops = &rte_event_fp_ops[dev_id];
+       port = fp_ops->data[port_id];
+#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
+       if (dev_id >= RTE_EVENT_MAX_DEVS ||
+           port_id >= RTE_EVENT_MAX_PORTS_PER_DEV)
+               return -EINVAL;
+
+       if (port == NULL)
+               return -EINVAL;
+
+       if (op & (~RTE_EVENT_DEV_MAINT_OP_FLUSH))
+               return -EINVAL;
+#endif
+       rte_eventdev_trace_maintain(dev_id, port_id, op);
+
+       if (fp_ops->maintain != NULL)
+               fp_ops->maintain(port, op);
+
+       return 0;
+}
+
 #ifdef __cplusplus
 }
 #endif