@@ -390,6 +390,14 @@ To enable or disable event prefetching at a given event port, the application ca
// Disable prefetching if thread is about to be scheduled out and issue dequeue() to drain
// pending events.
+Event Prefetch Hint can be used to provide a hint to the eventdev PMD to prefetch the next event
+without releasing the current flow context. Event device that support this feature advertises the
+capability using the ``RTE_EVENT_DEV_CAP_SW_PREFETCH`` capability flag.
+If prefetching is already enabled at a event device or event port level then the hint is ignored.
+
+.. code-block:: c
+
+ rte_event_port_prefetch(dev_id, port_id, RTE_EVENT_DEV_PREFETCH);
Starting the EventDev
~~~~~~~~~~~~~~~~~~~~~
@@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev {
/**< Pointer to PMD Event switch profile function. */
event_prefetch_modify_t prefetch_modify;
/**< Pointer to PMD Event port prefetch modify function. */
+ event_prefetch_t prefetch;
+ /**< Pointer to PMD Event port prefetch function. */
uint64_t reserved_64s[3]; /**< Reserved for future fields */
void *reserved_ptrs[3]; /**< Reserved for future fields */
@@ -104,6 +104,13 @@ dummy_event_port_prefetch_modify(__rte_unused void *port,
return -EINVAL;
}
+static void
+dummy_event_port_prefetch(__rte_unused void *port,
+ __rte_unused rte_event_dev_prefetch_type_t prefetch)
+{
+ RTE_EDEV_LOG_ERR("prefetch requested for unconfigured event device");
+}
+
void
event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op)
{
@@ -123,6 +130,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op)
.dma_enqueue = dummy_event_dma_adapter_enqueue,
.profile_switch = dummy_event_port_profile_switch,
.prefetch_modify = dummy_event_port_prefetch_modify,
+ .prefetch = dummy_event_port_prefetch,
.data = dummy_data,
};
@@ -146,5 +154,6 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op,
fp_op->dma_enqueue = dev->dma_enqueue;
fp_op->profile_switch = dev->profile_switch;
fp_op->prefetch_modify = dev->prefetch_modify;
+ fp_op->prefetch = dev->prefetch;
fp_op->data = dev->data->ports;
}
@@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch,
RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_prefetch_modify,
lib.eventdev.port.prefetch.modify)
+RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_prefetch,
+ lib.eventdev.port.prefetch)
+
/* Eventdev Rx adapter trace points */
RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create,
lib.eventdev.rx.adapter.create)
@@ -480,6 +480,15 @@ struct rte_event;
* @see rte_event_port_prefetch_modify()
*/
+#define RTE_EVENT_DEV_CAP_SW_PREFETCH (1ULL << 19)
+/**< Event device supports software prefetching.
+ *
+ * When this flag is set, the application can issue prefetch request on
+ * a event port.
+ *
+ * @see rte_event_port_prefetch()
+ */
+
/* Event device priority levels */
#define RTE_EVENT_DEV_PRIORITY_HIGHEST 0
/**< Highest priority level for events and queues.
@@ -2977,6 +2986,46 @@ rte_event_port_prefetch_modify(uint8_t dev_id, uint8_t port_id, rte_event_dev_pr
return fp_ops->prefetch_modify(port, type);
}
+/**
+ * Provide a hint to the event device to prefetch events to event port .
+ *
+ * Hint the event device to prefetch events to the event port.
+ * The call doesn't not guarantee that the events will be prefetched.
+ * The call doesn't release the flow context currently held by the event port.
+ * The event device should support RTE_EVENT_DEV_CAP_SW_PREFETCH capability.
+ *
+ * When prefetching is enabled at an event device or event port level, the hint
+ * is ignored.
+ *
+ * Subsequent calls to rte_event_dequeue_burst() will dequeue the prefetch events
+ * but prefetch operation is not issued again.
+ *
+ * @param dev_id
+ * The identifier of the device.
+ * @param port_id
+ * The identifier of the event port.
+ * @param type
+ * The prefetch type to use on the event port.
+ */
+static inline void
+rte_event_port_prefetch(uint8_t dev_id, uint8_t port_id, rte_event_dev_prefetch_type_t type)
+{
+ 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;
+ if (port == NULL)
+ return;
+#endif
+ rte_eventdev_trace_port_prefetch(dev_id, port_id, type);
+
+ fp_ops->prefetch(port, type);
+}
#ifdef __cplusplus
}
#endif
@@ -52,6 +52,9 @@ typedef int (*event_profile_switch_t)(void *port, uint8_t profile);
typedef int (*event_prefetch_modify_t)(void *port, rte_event_dev_prefetch_type_t prefetch_type);
/**< @internal Modify prefetch type on the event port. */
+typedef void (*event_prefetch_t)(void *port, rte_event_dev_prefetch_type_t prefetch_type);
+/**< @internal Issue prefetch on an event port. */
+
struct __rte_cache_aligned rte_event_fp_ops {
void **data;
/**< points to array of internal port data pointers */
@@ -81,6 +84,7 @@ struct __rte_cache_aligned rte_event_fp_ops {
/**< PMD Event switch profile function. */
event_prefetch_modify_t prefetch_modify;
/**< PMD Event port prefetch switch. */
+ event_prefetch_t prefetch;
uintptr_t reserved[4];
};
@@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP(
rte_trace_point_emit_int(type);
)
+RTE_TRACE_POINT_FP(
+ rte_eventdev_trace_port_prefetch,
+ RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id, int type),
+ rte_trace_point_emit_u8(dev_id);
+ rte_trace_point_emit_u8(port_id);
+ rte_trace_point_emit_int(type);
+)
+
RTE_TRACE_POINT_FP(
rte_eventdev_trace_eth_tx_adapter_enqueue,
RTE_TRACE_POINT_ARGS(uint8_t dev_id, uint8_t port_id, void *ev_table,
@@ -151,6 +151,8 @@ EXPERIMENTAL {
# added in 24.11
rte_event_port_prefetch_modify;
__rte_eventdev_trace_port_prefetch_modify;
+ rte_event_port_prefetch;
+ __rte_eventdev_trace_port_prefetch;
};
INTERNAL {