* [RFC 0/3] Introduce event prefetching @ 2024-09-10 8:31 pbhagavatula 2024-09-10 8:31 ` [RFC 1/3] eventdev: introduce " pbhagavatula ` (4 more replies) 0 siblings, 5 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-10 8:31 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event prefetching improves scheduling performance by pre-scheduling events to event ports when dequeues are issued. This series introduces various types and levels of prefetching to the eventdev library. Prefetching Types: * RTE_EVENT_DEV_PREFETCH_NONE: No prefetching. * RTE_EVENT_DEV_PREFETCH: Always issue a prefetch when dequeue is issued. * RTE_EVENT_DEV_PREFETCH_INTELLIGENT: Delay issuing prefetch until there are no forward progress constraints with the held flow contexts. Prefetching Levels: * Event Device Level Prefetch: Prefetching can be enabled or disabled at the event device during configuration. Event devices can indicate prefetching capabilities using `RTE_EVENT_DEV_CAP_EVENT_PREFETCH` and `RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Prefetching can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PREFETCH` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start prefetching events using the new API `rte_event_port_prefetch`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_SW_PREFETCH` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the prefetch operation, which completes in parallel without affecting the dequeued event flow context and dequeue latency. On the next dequeue operation, the prefetched events are dequeued, and prefetch is initiated again. In the case of application-controlled prefetch hints, the currently held flow contexts, if any, are not affected by the prefetch operation. On the next dequeue operation, the prefetched events are returned, but prefetch is not initiated again until the application provides the hint again. If prefetching is already enabled at the event device level or event port level, the hint is ignored. Pavan Nikhilesh (3): eventdev: introduce event prefetching eventdev: allow event ports to modified prefetches eventdev: add SW event prefetch hint app/test/test_eventdev.c | 113 +++++++++++++++ doc/guides/prog_guide/eventdev/eventdev.rst | 42 ++++++ lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 19 +++ lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 152 ++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 9 ++ lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 9 files changed, 369 insertions(+), 1 deletion(-) -- 2.46.0 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [RFC 1/3] eventdev: introduce event prefetching 2024-09-10 8:31 [RFC 0/3] Introduce event prefetching pbhagavatula @ 2024-09-10 8:31 ` pbhagavatula 2024-09-10 8:31 ` [RFC 2/3] eventdev: allow event ports to modified prefetches pbhagavatula ` (3 subsequent siblings) 4 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-10 8:31 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event prefetching enhances scheduling performance by pre-scheduling events to event ports when dequeues are issued. The dequeue operation initiates the prefetch operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate prefetching capabilities using `RTE_EVENT_DEV_CAP_EVENT_PREFETCH` and `RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH` via the event device info function `info.event_dev_cap`. Applications can select the prefetch type and configure it via `rte_event_dev_config.prefetch_type` in the `rte_event_dev_configure` API. The supported prefetch types are: * `RTE_EVENT_DEV_PREFETCH_NONE` - No prefetching. * `RTE_EVENT_DEV_PREFETCH` - Always issue a prefetch on dequeue. * `RTE_EVENT_DEV_PREFETCH_INTELLIGENT` - Delay issuing prefetch until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 62 +++++++++++++++++++++ doc/guides/prog_guide/eventdev/eventdev.rst | 22 ++++++++ lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ 3 files changed, 132 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index e4e234dc98..1fd3d1fa69 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1250,6 +1250,66 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +prefetch_test(rte_event_dev_prefetch_type_t prefetch_type, const char *prefetch_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(prefetch_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Prefetch type : %s, avg cycles %" PRIu64 "\n", prefetch_name, total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +test_eventdev_prefetch_configure(void) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PREFETCH) == 0) + return TEST_SKIPPED; + + devconf_set_default_sane_values(&dev_conf, &info); + dev_conf.prefetch_type = RTE_EVENT_DEV_PREFETCH; + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = prefetch_test(RTE_EVENT_DEV_PREFETCH_NONE, "RTE_EVENT_DEV_PREFETCH_NONE"); + rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH, "RTE_EVENT_DEV_PREFETCH"); + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH) + rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH_INTELLIGENT, + "RTE_EVENT_DEV_PREFETCH_INTELLIGENT"); + + return rc; +} + static int test_eventdev_close(void) { @@ -1310,6 +1370,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_prefetch_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..89064883b7 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,28 @@ Worker path: // Process the event received. } +Event Prefetching +~~~~~~~~~~~~~~~~~ + +Event prefetching enhances scheduling performance by pre-scheduling events to event ports +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the prefetch operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the prefetched events are dequeued and prefetch is initiated +again. + +An application can use event prefetching if the event device supports it at either device +level or at a individual port level. +The application can check prefetch capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PREFETCH`` set, if present prefetching can be enabled at device +configuration time by setting appropriate prefetch type in ``rte_event_dev_config.prefetch``. + +Currently, the following prefetch types are supported: + * ``RTE_EVENT_DEV_PREFETCH_NONE`` - No prefetching. + * ``RTE_EVENT_DEV_PREFETCH`` - Always issue a prefetch when dequeue is issued. + * ``RTE_EVENT_DEV_PREFETCH_INTELLIGENT`` - Issue prefetch when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..59c323c8ee 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PREFETCH (1ULL << 16) +/**< Event device supports event prefetching. + * + * When this capability is available, the application can enable event prefetching on the event + * device to prefetch/pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The prefetch process starts with the `rte_event_dequeue_burst()` call and the + * prefetched events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH (1ULL << 17) +/**< Event device supports intelligent event prefetching. + * + * When this capability is available, the application can enable intelligent prefetching + * on the event device where the events are prefetched/pre-scheduled when + * there are no forward progress constraints with the currently held flow contexts. + * The prefetch process starts with the `rte_event_dequeue_burst()` call and the + * prefetched events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +typedef enum { + RTE_EVENT_DEV_PREFETCH_NONE = 0, + /* Disable prefetch across the event device or on a given event port. + * @ref rte_event_dev_config.prefetch_type + */ + RTE_EVENT_DEV_PREFETCH, + /* Enable prefetch always across the event device or a given event port. + * @ref rte_event_dev_config.prefetch_type + * @see RTE_EVENT_DEV_CAP_EVENT_PREFETCH + */ + RTE_EVENT_DEV_PREFETCH_INTELLIGENT, + /* Enable intelligent prefetch across the event device or a given event port. + * Delay issuing prefetch until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.prefetch_type + * @see RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH + */ +} rte_event_dev_prefetch_type_t; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +795,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + rte_event_dev_prefetch_type_t prefetch_type; + /**< Event prefetch type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PREFETCH + * @see RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [RFC 2/3] eventdev: allow event ports to modified prefetches 2024-09-10 8:31 [RFC 0/3] Introduce event prefetching pbhagavatula 2024-09-10 8:31 ` [RFC 1/3] eventdev: introduce " pbhagavatula @ 2024-09-10 8:31 ` pbhagavatula 2024-09-10 8:31 ` [RFC 3/3] eventdev: add SW event prefetch hint pbhagavatula ` (2 subsequent siblings) 4 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-10 8:31 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow prefetch types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PREFETCH` capability to indicate that the event device supports this feature. Add `rte_event_port_prefetch_modify()` API to modify the prefetch type at runtime. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 61 +++++++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 12 ++++ lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 10 ++++ lib/eventdev/eventdev_trace_points.c | 3 + lib/eventdev/rte_eventdev.h | 55 +++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 5 ++ lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 9 files changed, 157 insertions(+), 6 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index 1fd3d1fa69..af27a9f0ec 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,7 +1251,8 @@ test_eventdev_profile_switch(void) } static int -prefetch_test(rte_event_dev_prefetch_type_t prefetch_type, const char *prefetch_name) +prefetch_test(rte_event_dev_prefetch_type_t prefetch_type, const char *prefetch_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1269,7 +1270,11 @@ prefetch_test(rte_event_dev_prefetch_type_t prefetch_type, const char *prefetch_ TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(prefetch_type); + if (modify) { + rc = rte_event_port_prefetch_modify(TEST_DEV_ID, 0, prefetch_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify prefetch type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1301,11 +1306,55 @@ test_eventdev_prefetch_configure(void) rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = prefetch_test(RTE_EVENT_DEV_PREFETCH_NONE, "RTE_EVENT_DEV_PREFETCH_NONE"); - rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH, "RTE_EVENT_DEV_PREFETCH"); + rc = prefetch_test(RTE_EVENT_DEV_PREFETCH_NONE, "RTE_EVENT_DEV_PREFETCH_NONE", 0); + rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH, "RTE_EVENT_DEV_PREFETCH", 0); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH) rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH_INTELLIGENT, - "RTE_EVENT_DEV_PREFETCH_INTELLIGENT"); + "RTE_EVENT_DEV_PREFETCH_INTELLIGENT", 0); + + return rc; +} + +static int +test_eventdev_prefetch_modify(void) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PREFETCH) == 0) + return TEST_SKIPPED; + + devconf_set_default_sane_values(&dev_conf, &info); + dev_conf.prefetch_type = RTE_EVENT_DEV_PREFETCH_NONE; + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + rc = prefetch_test(RTE_EVENT_DEV_PREFETCH_NONE, "RTE_EVENT_DEV_PREFETCH_NONE", 1); + rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH, "RTE_EVENT_DEV_PREFETCH", 1); + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH) + rc |= prefetch_test(RTE_EVENT_DEV_PREFETCH_INTELLIGENT, + "RTE_EVENT_DEV_PREFETCH_INTELLIGENT", 1); return rc; } @@ -1372,6 +1421,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_prefetch_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_prefetch_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 89064883b7..8b6085512d 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -379,6 +379,18 @@ Currently, the following prefetch types are supported: * ``RTE_EVENT_DEV_PREFETCH_INTELLIGENT`` - Issue prefetch when dequeue is issued and there are no forward progress constraints. +To enable or disable event prefetching at a given event port, the application can use +``rte_event_port_prefetch_modify()`` API. + +.. code-block:: c + + rte_event_port_prefetch_modify(dev_id, port_id, RTE_EVENT_DEV_PREFETCH); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_prefetch_modify(dev_id, port_id, RTE_EVENT_DEV_PREFETCH_NONE); + // Disable prefetching if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..d93c11e9f1 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_prefetch_modify_t prefetch_modify; + /**< Pointer to PMD Event port prefetch modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..6e8beb29ad 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,14 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_prefetch_modify(__rte_unused void *port, + __rte_unused rte_event_dev_prefetch_type_t prefetch) +{ + RTE_EDEV_LOG_ERR("modify prefetch requested for unconfigured event device"); + return -EINVAL; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +122,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .prefetch_modify = dummy_event_port_prefetch_modify, .data = dummy_data, }; @@ -136,5 +145,6 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->prefetch_modify = dev->prefetch_modify; fp_op->data = dev->data->ports; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e0547d18c6 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_prefetch_modify, + lib.eventdev.port.prefetch.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 59c323c8ee..1bc6c48dd3 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PREFETCH (1ULL << 18) +/**< Event device supports event prefetching per event port. + * + * When this flag is set, the event device allows controlling the event + * prefetching/pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_prefetch_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -708,18 +718,23 @@ typedef enum { RTE_EVENT_DEV_PREFETCH_NONE = 0, /* Disable prefetch across the event device or on a given event port. * @ref rte_event_dev_config.prefetch_type + * @ref rte_event_port_prefetch_modify() */ RTE_EVENT_DEV_PREFETCH, /* Enable prefetch always across the event device or a given event port. * @ref rte_event_dev_config.prefetch_type + * @ref rte_event_port_prefetch_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PREFETCH + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PREFETCH */ RTE_EVENT_DEV_PREFETCH_INTELLIGENT, /* Enable intelligent prefetch across the event device or a given event port. * Delay issuing prefetch until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.prefetch_type + * @ref rte_event_port_prefetch_modify() * @see RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PREFETCH */ } rte_event_dev_prefetch_type_t; @@ -2922,6 +2937,46 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Change the prefetch type to use on an event port. + * + * This function is used to change the current prefetch type configured + * on an event port, the prefetch type can be set to none to disable prefetching. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PREFETCH capability. + * + * @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. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + * - -ENOTSUP if the device doesn't support prefetch or per port prefetch. + */ +static inline int +rte_event_port_prefetch_modify(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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_prefetch_modify(dev_id, port_id, type); + + return fp_ops->prefetch_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..b185fe3654 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,9 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_prefetch_modify_t)(void *port, rte_event_dev_prefetch_type_t prefetch_type); +/**< @internal Modify prefetch type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,6 +79,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ + event_prefetch_modify_t prefetch_modify; + /**< PMD Event port prefetch switch. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..06bfd48011 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_prefetch_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..62c0563fb1 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_prefetch_modify; + __rte_eventdev_trace_port_prefetch_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [RFC 3/3] eventdev: add SW event prefetch hint 2024-09-10 8:31 [RFC 0/3] Introduce event prefetching pbhagavatula 2024-09-10 8:31 ` [RFC 1/3] eventdev: introduce " pbhagavatula 2024-09-10 8:31 ` [RFC 2/3] eventdev: allow event ports to modified prefetches pbhagavatula @ 2024-09-10 8:31 ` pbhagavatula 2024-09-10 9:08 ` [RFC 0/3] Introduce event prefetching Mattias Rönnblom 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula 4 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-10 8:31 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to prefetch the next event into the event port, 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. Application can invoke `rte_event_port_prefetch` to hint the PMD. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 8 ++++ lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 9 ++++ lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 4 ++ lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 8 files changed, 85 insertions(+) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 8b6085512d..ea05de53f5 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -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 ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index d93c11e9f1..698bdcc14f 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -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 */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 6e8beb29ad..39d5234551 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -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; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e0547d18c6..199cfa742f 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -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) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 1bc6c48dd3..d487389a2c 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -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 diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index b185fe3654..66edb75649 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -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]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 06bfd48011..01fa5cba7c 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 62c0563fb1..bb291f23e3 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -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 { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [RFC 0/3] Introduce event prefetching 2024-09-10 8:31 [RFC 0/3] Introduce event prefetching pbhagavatula ` (2 preceding siblings ...) 2024-09-10 8:31 ` [RFC 3/3] eventdev: add SW event prefetch hint pbhagavatula @ 2024-09-10 9:08 ` Mattias Rönnblom 2024-09-10 11:53 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula 4 siblings, 1 reply; 77+ messages in thread From: Mattias Rönnblom @ 2024-09-10 9:08 UTC (permalink / raw) To: pbhagavatula, jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev On 2024-09-10 10:31, pbhagavatula@marvell.com wrote: > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Event prefetching improves scheduling performance by pre-scheduling events to > event ports when dequeues are issued. This series introduces various types and > levels of prefetching to the eventdev library. > I would avoid to use the term "prefetch", since that word is used for manual (software) prefetching (preloading in ARM speak). In particular, since having the event device prefetch future event-related data may potentially also be interesting to do (i.e., to have an option to prefetch user-configurable lines in the buffer pointed to by a future event). I suggest RTE_EVENT_DEV_PRESCHEDULE*. If you make prescheduling a hint, you don't need the capability flags, and no error handling. Much smaller API, less fuzz for the application. > Prefetching Types: > * RTE_EVENT_DEV_PREFETCH_NONE: No prefetching. > * RTE_EVENT_DEV_PREFETCH: Always issue a prefetch when dequeue is issued. > * RTE_EVENT_DEV_PREFETCH_INTELLIGENT: Delay issuing prefetch until there > are no forward progress constraints with the held flow contexts. > Maybe RTE_EVENT_DEV_PREFETCH_ADAPTIVE is better. I suggest that being the default. In that case, for event devices which can't preschedule or which always (by design) have to preschedule, can continue doing what they are doing and still calling this "adaptive". RTE_EVENT_DEV_PREFETCH_AUTO would also work. Setting aside the complexity issue, prescheduling hints or configuration seems like a valuable feature to include in the Eventdev API. > Prefetching Levels: > * Event Device Level Prefetch: Prefetching can be enabled or disabled at the > event device during configuration. Event devices can indicate prefetching > capabilities using `RTE_EVENT_DEV_CAP_EVENT_PREFETCH` and > `RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH` via the event device info > function `info.event_dev_cap`. > * Event Port Level Prefetch: Prefetching can be selectively enabled or disabled > at the event port during runtime. Event devices can indicate this capability > using `RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PREFETCH` via the event device info > function `info.event_port_cap`. > * Application Controlled Prefetch Hint: Applications can provide hints to the > event device to start prefetching events using the new API > `rte_event_port_prefetch`. Event devices can indicate this capabilities using > `RTE_EVENT_DEV_CAP_SW_PREFETCH` via the event device info function > `info.event_dev_cap`. > > The rte_event_dequeue_burst operation initiates the prefetch operation, which > completes in parallel without affecting the dequeued event flow context and > dequeue latency. On the next dequeue operation, the prefetched events are > dequeued, and prefetch is initiated again. > > In the case of application-controlled prefetch hints, the currently held flow > contexts, if any, are not affected by the prefetch operation. On the next > dequeue operation, the prefetched events are returned, but prefetch is not > initiated again until the application provides the hint again. If prefetching > is already enabled at the event device level or event port level, > the hint is ignored. > > Pavan Nikhilesh (3): > eventdev: introduce event prefetching > eventdev: allow event ports to modified prefetches > eventdev: add SW event prefetch hint > > app/test/test_eventdev.c | 113 +++++++++++++++ > doc/guides/prog_guide/eventdev/eventdev.rst | 42 ++++++ > lib/eventdev/eventdev_pmd.h | 4 + > lib/eventdev/eventdev_private.c | 19 +++ > lib/eventdev/eventdev_trace_points.c | 6 + > lib/eventdev/rte_eventdev.h | 152 ++++++++++++++++++++ > lib/eventdev/rte_eventdev_core.h | 9 ++ > lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- > lib/eventdev/version.map | 6 + > 9 files changed, 369 insertions(+), 1 deletion(-) > > -- > 2.46.0 ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [RFC 0/3] Introduce event prefetching 2024-09-10 9:08 ` [RFC 0/3] Introduce event prefetching Mattias Rönnblom @ 2024-09-10 11:53 ` Pavan Nikhilesh Bhagavatula 0 siblings, 0 replies; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-09-10 11:53 UTC (permalink / raw) To: Mattias Rönnblom, Jerin Jacob, Shijith Thotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev > On 2024-09-10 10:31, pbhagavatula@marvell.com wrote: > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > Event prefetching improves scheduling performance by pre-scheduling > events to > > event ports when dequeues are issued. This series introduces various types > and > > levels of prefetching to the eventdev library. > > > > I would avoid to use the term "prefetch", since that word is used for > manual (software) prefetching (preloading in ARM speak). In particular, > since having the event device prefetch future event-related data may > potentially also be interesting to do (i.e., to have an option to > prefetch user-configurable lines in the buffer pointed to by a future > event). > > I suggest RTE_EVENT_DEV_PRESCHEDULE*. Yeah, preschedule makes more sense in this context, I was too far into the RFC to make the change. I will make the change in the next version. In fact OCTEON 10 already supports event data prefetching, I have a RFC for that in the pipeline. > > If you make prescheduling a hint, you don't need the capability flags, > and no error handling. Much smaller API, less fuzz for the application. > The hint part is in 3/3, it still has a capability flag attached to it so that application don’t crash if driver doesn’t implement the API i.e., ops is NULL. We could add a NULL check for ops but since its fast path I am not sure. > > Prefetching Types: > > * RTE_EVENT_DEV_PREFETCH_NONE: No prefetching. > > * RTE_EVENT_DEV_PREFETCH: Always issue a prefetch when dequeue is > issued. > > * RTE_EVENT_DEV_PREFETCH_INTELLIGENT: Delay issuing prefetch until > there > > are no forward progress constraints with the held flow contexts. > > > > Maybe RTE_EVENT_DEV_PREFETCH_ADAPTIVE is better. I suggest that being > the default. In that case, for event devices which can't preschedule or > which always (by design) have to preschedule, can continue doing what > they are doing and still calling this "adaptive". > Adaptive sounds good. I will make the change next version. I think the driver layer can fix up if application requests to disable a preschedule type that It's already doing and can't be disabled. But claiming prefetch capability when its not supported might not be a good idea. In the end the idea is to give the application fine grained control over prescheduling. As from what we have seen customers have wanted these fine grained controls over pre-scheduling. > RTE_EVENT_DEV_PREFETCH_AUTO would also work. > > Setting aside the complexity issue, prescheduling hints or configuration > seems like a valuable feature to include in the Eventdev API. > > > Prefetching Levels: > > * Event Device Level Prefetch: Prefetching can be enabled or disabled at the > > event device during configuration. Event devices can indicate prefetching > > capabilities using `RTE_EVENT_DEV_CAP_EVENT_PREFETCH` and > > `RTE_EVENT_DEV_CAP_EVENT_INTELLIGENT_PREFETCH` via the event > device info > > function `info.event_dev_cap`. > > * Event Port Level Prefetch: Prefetching can be selectively enabled or > disabled > > at the event port during runtime. Event devices can indicate this capability > > using `RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PREFETCH` via the > event device info > > function `info.event_port_cap`. > > * Application Controlled Prefetch Hint: Applications can provide hints to the > > event device to start prefetching events using the new API > > `rte_event_port_prefetch`. Event devices can indicate this capabilities using > > `RTE_EVENT_DEV_CAP_SW_PREFETCH` via the event device info function > > `info.event_dev_cap`. > > > > The rte_event_dequeue_burst operation initiates the prefetch operation, > which > > completes in parallel without affecting the dequeued event flow context and > > dequeue latency. On the next dequeue operation, the prefetched events are > > dequeued, and prefetch is initiated again. > > > > In the case of application-controlled prefetch hints, the currently held flow > > contexts, if any, are not affected by the prefetch operation. On the next > > dequeue operation, the prefetched events are returned, but prefetch is not > > initiated again until the application provides the hint again. If prefetching > > is already enabled at the event device level or event port level, > > the hint is ignored. > > > > Pavan Nikhilesh (3): > > eventdev: introduce event prefetching > > eventdev: allow event ports to modified prefetches > > eventdev: add SW event prefetch hint > > > > app/test/test_eventdev.c | 113 +++++++++++++++ > > doc/guides/prog_guide/eventdev/eventdev.rst | 42 ++++++ > > lib/eventdev/eventdev_pmd.h | 4 + > > lib/eventdev/eventdev_private.c | 19 +++ > > lib/eventdev/eventdev_trace_points.c | 6 + > > lib/eventdev/rte_eventdev.h | 152 ++++++++++++++++++++ > > lib/eventdev/rte_eventdev_core.h | 9 ++ > > lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- > > lib/eventdev/version.map | 6 + > > 9 files changed, 369 insertions(+), 1 deletion(-) > > > > -- > > 2.46.0 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2 0/3] Introduce event pre-scheduling 2024-09-10 8:31 [RFC 0/3] Introduce event prefetching pbhagavatula ` (3 preceding siblings ...) 2024-09-10 9:08 ` [RFC 0/3] Introduce event prefetching Mattias Rönnblom @ 2024-09-17 7:11 ` pbhagavatula 2024-09-17 7:11 ` [PATCH v2 1/3] eventdev: introduce " pbhagavatula ` (3 more replies) 4 siblings, 4 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-17 7:11 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_DEV_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_DEV_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_SW_PRESCHEDULE` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias) Pavan Nikhilesh (3): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add SW event preschedule hint app/test/test_eventdev.c | 114 +++++++++++++++ doc/guides/prog_guide/eventdev/eventdev.rst | 42 ++++++ lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 22 ++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 152 ++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 11 ++ lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 9 files changed, 373 insertions(+), 3 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula @ 2024-09-17 7:11 ` pbhagavatula 2024-09-18 22:38 ` Pathak, Pravin 2024-09-17 7:11 ` [PATCH v2 2/3] eventdev: add event port pre-schedule modify pbhagavatula ` (2 subsequent siblings) 3 siblings, 1 reply; 77+ messages in thread From: pbhagavatula @ 2024-09-17 7:11 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 63 +++++++++++++++++++++ doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ 3 files changed, 133 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index e4e234dc98..cf496ee88d 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + devconf_set_default_sane_values(&dev_conf, &info); + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE"); + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE"); + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + + return rc; +} + static int test_eventdev_close(void) { @@ -1310,6 +1371,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..341b9bb2c6 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,28 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application can check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +Currently, the following pre-schedule types are supported: + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..5ea7f5a07b 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +typedef enum { + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, + /* Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_DEV_PRESCHEDULE, + /* Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + /* Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +} rte_event_dev_preschedule_type_t; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +795,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + rte_event_dev_preschedule_type_t preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-17 7:11 ` [PATCH v2 1/3] eventdev: introduce " pbhagavatula @ 2024-09-18 22:38 ` Pathak, Pravin 2024-09-19 13:13 ` Pavan Nikhilesh Bhagavatula 0 siblings, 1 reply; 77+ messages in thread From: Pathak, Pravin @ 2024-09-18 22:38 UTC (permalink / raw) To: pbhagavatula, jerinj, sthotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev > -----Original Message----- > From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> > Sent: Tuesday, September 17, 2024 3:11 AM > To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, Abdullah > <abdullah.sevincer@intel.com>; hemant.agrawal@nxp.com; > sachin.saxena@oss.nxp.com; Van Haaren, Harry <harry.van.haaren@intel.com>; > mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, Peter > <peter.mccarthy@intel.com> > Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> > Subject: [PATCH v2 1/3] eventdev: introduce event pre-scheduling > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Event pre-scheduling improves scheduling performance by assigning events to > event ports in advance when dequeues are issued. > The dequeue operation initiates the pre-schedule operation, which completes in > parallel without affecting the dequeued event flow contexts and dequeue > latency. > Is the prescheduling done to get the event more quickly in the next dequeue? The first dequeue executes pre-schedule to make events available for the next dequeue. Is this how it is supposed to work? > Event devices can indicate pre-scheduling capabilities using > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device > info function `info.event_dev_cap`. > > Applications can select the pre-schedule type and configure it through > `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. > > The supported pre-schedule types are: > * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on dequeue. > * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule > until > there are no forward progress constraints with the held flow contexts. > > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > --- > app/test/test_eventdev.c | 63 +++++++++++++++++++++ > doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ > lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ > 3 files changed, 133 insertions(+) > > diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index > e4e234dc98..cf496ee88d 100644 > --- a/app/test/test_eventdev.c > +++ b/app/test/test_eventdev.c > @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) > return TEST_SUCCESS; > } > > +static int > +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, > +const char *preschedule_name) { > +#define NB_EVENTS 1024 > + uint64_t start, total; > + struct rte_event ev; > + int rc, cnt; > + > + ev.event_type = RTE_EVENT_TYPE_CPU; > + ev.queue_id = 0; > + ev.op = RTE_EVENT_OP_NEW; > + ev.u64 = 0xBADF00D0; > + > + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > + ev.flow_id = cnt; > + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); > + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > + } > + > + RTE_SET_USED(preschedule_type); > + total = 0; > + while (cnt) { > + start = rte_rdtsc_precise(); > + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); > + if (rc) { > + total += rte_rdtsc_precise() - start; > + cnt--; > + } > + } > + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", > preschedule_name, > + total / NB_EVENTS); > + > + return TEST_SUCCESS; > +} > + > +static int > +test_eventdev_preschedule_configure(void) > +{ > + struct rte_event_dev_config dev_conf; > + struct rte_event_dev_info info; > + int rc; > + > + rte_event_dev_info_get(TEST_DEV_ID, &info); > + > + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) > == 0) > + return TEST_SKIPPED; > + > + devconf_set_default_sane_values(&dev_conf, &info); > + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; > + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); > + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); > + > + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, > "RTE_EVENT_DEV_PRESCHEDULE_NONE"); > + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, > "RTE_EVENT_DEV_PRESCHEDULE"); > + if (info.event_dev_cap & > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) > + rc |= > preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > + > "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); > + > + return rc; > +} > + > static int > test_eventdev_close(void) > { > @@ -1310,6 +1371,8 @@ static struct unit_test_suite > eventdev_common_testsuite = { > test_eventdev_start_stop), > TEST_CASE_ST(eventdev_configure_setup, > eventdev_stop_device, > test_eventdev_profile_switch), > + TEST_CASE_ST(eventdev_configure_setup, NULL, > + test_eventdev_preschedule_configure), > TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, > test_eventdev_link), > TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, > diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst > b/doc/guides/prog_guide/eventdev/eventdev.rst > index fb6dfce102..341b9bb2c6 100644 > --- a/doc/guides/prog_guide/eventdev/eventdev.rst > +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > @@ -357,6 +357,28 @@ Worker path: > // Process the event received. > } > > +Event Pre-scheduling > +~~~~~~~~~~~~~~~~~~~~ > + > +Event pre-scheduling improves scheduling performance by assigning > +events to event ports in advance when dequeues are issued. > +The `rte_event_dequeue_burst` operation initiates the pre-schedule > +operation, which completes in parallel without affecting the dequeued event > flow contexts and dequeue latency. > +On the next dequeue operation, the pre-scheduled events are dequeued > +and pre-schedule is initiated again. > + > +An application can use event pre-scheduling if the event device > +supports it at either device level or at a individual port level. > +The application can check pre-schedule capability by checking if > +``rte_event_dev_info.event_dev_cap`` > +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present > +pre-scheduling can be enabled at device configuration time by setting > appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. > + > +Currently, the following pre-schedule types are supported: > + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when > dequeue is issued. > + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when > dequeue is issued and there are > + no forward progress constraints. > + > Starting the EventDev > ~~~~~~~~~~~~~~~~~~~~~ > > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index > 08e5f9320b..5ea7f5a07b 100644 > --- a/lib/eventdev/rte_eventdev.h > +++ b/lib/eventdev/rte_eventdev.h > @@ -446,6 +446,30 @@ struct rte_event; > * @see RTE_SCHED_TYPE_PARALLEL > */ > > +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) /**< Event > +device supports event pre-scheduling. > + * > + * When this capability is available, the application can enable event > +pre-scheduling on the event > + * device to pre-schedule events to a event port when > +`rte_event_dequeue_burst()` > + * is issued. > + * The pre-schedule process starts with the `rte_event_dequeue_burst()` > +call and the > + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` > call. > + * > + * @see rte_event_dev_configure() > + */ > + > +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) > /**< > +Event device supports adaptive event pre-scheduling. > + * > + * When this capability is available, the application can enable > +adaptive pre-scheduling > + * on the event device where the events are pre-scheduled when there > +are no forward > + * progress constraints with the currently held flow contexts. > + * The pre-schedule process starts with the `rte_event_dequeue_burst()` > +call and the > + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` > call. > + * > + * @see rte_event_dev_configure() > + */ > + > /* Event device priority levels */ > #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > /**< Highest priority level for events and queues. > @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t > attr_id, > * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() > */ > > +typedef enum { > + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > + /* Disable pre-schedule across the event device or on a given event port. > + * @ref rte_event_dev_config.preschedule_type > + */ > + RTE_EVENT_DEV_PRESCHEDULE, > + /* Enable pre-schedule always across the event device or a given event > port. > + * @ref rte_event_dev_config.preschedule_type > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > + */ > + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > + /* Enable adaptive pre-schedule across the event device or a given event > port. > + * Delay issuing pre-schedule until there are no forward progress > constraints with > + * the held flow contexts. > + * @ref rte_event_dev_config.preschedule_type > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > + */ > +} rte_event_dev_preschedule_type_t; > + > /** Event device configuration structure */ struct rte_event_dev_config { > uint32_t dequeue_timeout_ns; > @@ -752,6 +795,11 @@ struct rte_event_dev_config { > * optimized for single-link usage, this field is a hint for how many > * to allocate; otherwise, regular event ports and queues will be used. > */ > + rte_event_dev_preschedule_type_t preschedule_type; > + /**< Event pre-schedule type to use across the event device, if > supported. > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > + */ > }; > > /** > -- > 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-18 22:38 ` Pathak, Pravin @ 2024-09-19 13:13 ` Pavan Nikhilesh Bhagavatula 2024-09-23 8:57 ` Mattias Rönnblom 0 siblings, 1 reply; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-09-19 13:13 UTC (permalink / raw) To: Pathak, Pravin, Jerin Jacob, Shijith Thotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev > > From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> > > Sent: Tuesday, September 17, 2024 3:11 AM > > To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, Abdullah > > <abdullah.sevincer@intel.com>; hemant.agrawal@nxp.com; > > sachin.saxena@oss.nxp.com; Van Haaren, Harry > <harry.van.haaren@intel.com>; > > mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, Peter > > <peter.mccarthy@intel.com> > > Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> > > Subject: [PATCH v2 1/3] eventdev: introduce event pre-scheduling > > > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > Event pre-scheduling improves scheduling performance by assigning events > to > > event ports in advance when dequeues are issued. > > The dequeue operation initiates the pre-schedule operation, which > completes in > > parallel without affecting the dequeued event flow contexts and dequeue > > latency. > > > Is the prescheduling done to get the event more quickly in the next dequeue? > The first dequeue executes pre-schedule to make events available for the next > dequeue. > Is this how it is supposed to work? > Yes, that is correct. > > Event devices can indicate pre-scheduling capabilities using > > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event > device > > info function `info.event_dev_cap`. > > > > Applications can select the pre-schedule type and configure it through > > `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. > > > > The supported pre-schedule types are: > > * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > > * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on > dequeue. > > * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule > > until > > there are no forward progress constraints with the held flow contexts. > > > > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > > --- > > app/test/test_eventdev.c | 63 +++++++++++++++++++++ > > doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ > > lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ > > 3 files changed, 133 insertions(+) > > > > diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index > > e4e234dc98..cf496ee88d 100644 > > --- a/app/test/test_eventdev.c > > +++ b/app/test/test_eventdev.c > > @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) > > return TEST_SUCCESS; > > } > > > > +static int > > +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, > > +const char *preschedule_name) { > > +#define NB_EVENTS 1024 > > + uint64_t start, total; > > + struct rte_event ev; > > + int rc, cnt; > > + > > + ev.event_type = RTE_EVENT_TYPE_CPU; > > + ev.queue_id = 0; > > + ev.op = RTE_EVENT_OP_NEW; > > + ev.u64 = 0xBADF00D0; > > + > > + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > > + ev.flow_id = cnt; > > + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); > > + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > > + } > > + > > + RTE_SET_USED(preschedule_type); > > + total = 0; > > + while (cnt) { > > + start = rte_rdtsc_precise(); > > + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); > > + if (rc) { > > + total += rte_rdtsc_precise() - start; > > + cnt--; > > + } > > + } > > + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", > > preschedule_name, > > + total / NB_EVENTS); > > + > > + return TEST_SUCCESS; > > +} > > + > > +static int > > +test_eventdev_preschedule_configure(void) > > +{ > > + struct rte_event_dev_config dev_conf; > > + struct rte_event_dev_info info; > > + int rc; > > + > > + rte_event_dev_info_get(TEST_DEV_ID, &info); > > + > > + if ((info.event_dev_cap & > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) > > == 0) > > + return TEST_SKIPPED; > > + > > + devconf_set_default_sane_values(&dev_conf, &info); > > + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; > > + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); > > + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); > > + > > + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, > > "RTE_EVENT_DEV_PRESCHEDULE_NONE"); > > + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, > > "RTE_EVENT_DEV_PRESCHEDULE"); > > + if (info.event_dev_cap & > > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) > > + rc |= > > preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > + > > "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); > > + > > + return rc; > > +} > > + > > static int > > test_eventdev_close(void) > > { > > @@ -1310,6 +1371,8 @@ static struct unit_test_suite > > eventdev_common_testsuite = { > > test_eventdev_start_stop), > > TEST_CASE_ST(eventdev_configure_setup, > > eventdev_stop_device, > > test_eventdev_profile_switch), > > + TEST_CASE_ST(eventdev_configure_setup, NULL, > > + test_eventdev_preschedule_configure), > > TEST_CASE_ST(eventdev_setup_device, > eventdev_stop_device, > > test_eventdev_link), > > TEST_CASE_ST(eventdev_setup_device, > eventdev_stop_device, > > diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst > > b/doc/guides/prog_guide/eventdev/eventdev.rst > > index fb6dfce102..341b9bb2c6 100644 > > --- a/doc/guides/prog_guide/eventdev/eventdev.rst > > +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > > @@ -357,6 +357,28 @@ Worker path: > > // Process the event received. > > } > > > > +Event Pre-scheduling > > +~~~~~~~~~~~~~~~~~~~~ > > + > > +Event pre-scheduling improves scheduling performance by assigning > > +events to event ports in advance when dequeues are issued. > > +The `rte_event_dequeue_burst` operation initiates the pre-schedule > > +operation, which completes in parallel without affecting the dequeued > event > > flow contexts and dequeue latency. > > +On the next dequeue operation, the pre-scheduled events are dequeued > > +and pre-schedule is initiated again. > > + > > +An application can use event pre-scheduling if the event device > > +supports it at either device level or at a individual port level. > > +The application can check pre-schedule capability by checking if > > +``rte_event_dev_info.event_dev_cap`` > > +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present > > +pre-scheduling can be enabled at device configuration time by setting > > appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. > > + > > +Currently, the following pre-schedule types are supported: > > + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > > + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when > > dequeue is issued. > > + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when > > dequeue is issued and there are > > + no forward progress constraints. > > + > > Starting the EventDev > > ~~~~~~~~~~~~~~~~~~~~~ > > > > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h > index > > 08e5f9320b..5ea7f5a07b 100644 > > --- a/lib/eventdev/rte_eventdev.h > > +++ b/lib/eventdev/rte_eventdev.h > > @@ -446,6 +446,30 @@ struct rte_event; > > * @see RTE_SCHED_TYPE_PARALLEL > > */ > > > > +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) /**< > Event > > +device supports event pre-scheduling. > > + * > > + * When this capability is available, the application can enable event > > +pre-scheduling on the event > > + * device to pre-schedule events to a event port when > > +`rte_event_dequeue_burst()` > > + * is issued. > > + * The pre-schedule process starts with the `rte_event_dequeue_burst()` > > +call and the > > + * pre-scheduled events are returned on the next > `rte_event_dequeue_burst()` > > call. > > + * > > + * @see rte_event_dev_configure() > > + */ > > + > > +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << > 17) > > /**< > > +Event device supports adaptive event pre-scheduling. > > + * > > + * When this capability is available, the application can enable > > +adaptive pre-scheduling > > + * on the event device where the events are pre-scheduled when there > > +are no forward > > + * progress constraints with the currently held flow contexts. > > + * The pre-schedule process starts with the `rte_event_dequeue_burst()` > > +call and the > > + * pre-scheduled events are returned on the next > `rte_event_dequeue_burst()` > > call. > > + * > > + * @see rte_event_dev_configure() > > + */ > > + > > /* Event device priority levels */ > > #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > > /**< Highest priority level for events and queues. > > @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t > > attr_id, > > * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() > > */ > > > > +typedef enum { > > + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > > + /* Disable pre-schedule across the event device or on a given event > port. > > + * @ref rte_event_dev_config.preschedule_type > > + */ > > + RTE_EVENT_DEV_PRESCHEDULE, > > + /* Enable pre-schedule always across the event device or a given event > > port. > > + * @ref rte_event_dev_config.preschedule_type > > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > + */ > > + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > + /* Enable adaptive pre-schedule across the event device or a given > event > > port. > > + * Delay issuing pre-schedule until there are no forward progress > > constraints with > > + * the held flow contexts. > > + * @ref rte_event_dev_config.preschedule_type > > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > + */ > > +} rte_event_dev_preschedule_type_t; > > + > > /** Event device configuration structure */ struct rte_event_dev_config { > > uint32_t dequeue_timeout_ns; > > @@ -752,6 +795,11 @@ struct rte_event_dev_config { > > * optimized for single-link usage, this field is a hint for how many > > * to allocate; otherwise, regular event ports and queues will be used. > > */ > > + rte_event_dev_preschedule_type_t preschedule_type; > > + /**< Event pre-schedule type to use across the event device, if > > supported. > > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > + */ > > }; > > > > /** > > -- > > 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-19 13:13 ` Pavan Nikhilesh Bhagavatula @ 2024-09-23 8:57 ` Mattias Rönnblom 2024-09-25 10:30 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 0 siblings, 1 reply; 77+ messages in thread From: Mattias Rönnblom @ 2024-09-23 8:57 UTC (permalink / raw) To: Pavan Nikhilesh Bhagavatula, Pathak, Pravin, Jerin Jacob, Shijith Thotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev On 2024-09-19 15:13, Pavan Nikhilesh Bhagavatula wrote: >>> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> >>> Sent: Tuesday, September 17, 2024 3:11 AM >>> To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, Abdullah >>> <abdullah.sevincer@intel.com>; hemant.agrawal@nxp.com; >>> sachin.saxena@oss.nxp.com; Van Haaren, Harry >> <harry.van.haaren@intel.com>; >>> mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, Peter >>> <peter.mccarthy@intel.com> >>> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> >>> Subject: [PATCH v2 1/3] eventdev: introduce event pre-scheduling >>> >>> From: Pavan Nikhilesh <pbhagavatula@marvell.com> >>> >>> Event pre-scheduling improves scheduling performance by assigning events >> to >>> event ports in advance when dequeues are issued. >>> The dequeue operation initiates the pre-schedule operation, which >> completes in >>> parallel without affecting the dequeued event flow contexts and dequeue >>> latency. >>> >> Is the prescheduling done to get the event more quickly in the next dequeue? >> The first dequeue executes pre-schedule to make events available for the next >> dequeue. >> Is this how it is supposed to work? >> > > Yes, that is correct. > "improves scheduling performance" may be a bit misleading, in that case. I suggest "reduces scheduling overhead" instead. You can argue it likely reduces scheduling performance, in certain scenarios. "reduces scheduling overhead, at the cost of load balancing performance." It seems to me that this should be a simple hint-type API, where the hint is used by the event device to decide if pre-scheduling should be used or not (assuming pre-scheduling on/off is even an option). The hint would just be a way for the application to express whether or not it want the scheduler to prioritize load balancing agility and port-to-port wall-time latency, or scheduling overhead, which in turn could potentially be rephrased as the app being throughput or latency/RT-oriented. It could also be useful for the event device to know which priority levels are to be considered latency-sensitive, and which are throughput-oriented - maybe in the form of a threshold. >>> Event devices can indicate pre-scheduling capabilities using >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event >> device >>> info function `info.event_dev_cap`. >>> >>> Applications can select the pre-schedule type and configure it through >>> `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. >>> >>> The supported pre-schedule types are: >>> * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. >>> * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on >> dequeue. >>> * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule >>> until >>> there are no forward progress constraints with the held flow contexts. >>> >>> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> >>> --- >>> app/test/test_eventdev.c | 63 +++++++++++++++++++++ >>> doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ >>> lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ >>> 3 files changed, 133 insertions(+) >>> >>> diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index >>> e4e234dc98..cf496ee88d 100644 >>> --- a/app/test/test_eventdev.c >>> +++ b/app/test/test_eventdev.c >>> @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) >>> return TEST_SUCCESS; >>> } >>> >>> +static int >>> +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, >>> +const char *preschedule_name) { >>> +#define NB_EVENTS 1024 >>> + uint64_t start, total; >>> + struct rte_event ev; >>> + int rc, cnt; >>> + >>> + ev.event_type = RTE_EVENT_TYPE_CPU; >>> + ev.queue_id = 0; >>> + ev.op = RTE_EVENT_OP_NEW; >>> + ev.u64 = 0xBADF00D0; >>> + >>> + for (cnt = 0; cnt < NB_EVENTS; cnt++) { >>> + ev.flow_id = cnt; >>> + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); >>> + TEST_ASSERT(rc == 1, "Failed to enqueue event"); >>> + } >>> + >>> + RTE_SET_USED(preschedule_type); >>> + total = 0; >>> + while (cnt) { >>> + start = rte_rdtsc_precise(); >>> + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); >>> + if (rc) { >>> + total += rte_rdtsc_precise() - start; >>> + cnt--; >>> + } >>> + } >>> + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", >>> preschedule_name, >>> + total / NB_EVENTS); >>> + >>> + return TEST_SUCCESS; >>> +} >>> + >>> +static int >>> +test_eventdev_preschedule_configure(void) >>> +{ >>> + struct rte_event_dev_config dev_conf; >>> + struct rte_event_dev_info info; >>> + int rc; >>> + >>> + rte_event_dev_info_get(TEST_DEV_ID, &info); >>> + >>> + if ((info.event_dev_cap & >> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) >>> == 0) >>> + return TEST_SKIPPED; >>> + >>> + devconf_set_default_sane_values(&dev_conf, &info); >>> + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; >>> + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); >>> + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); >>> + >>> + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, >>> "RTE_EVENT_DEV_PRESCHEDULE_NONE"); >>> + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, >>> "RTE_EVENT_DEV_PRESCHEDULE"); >>> + if (info.event_dev_cap & >>> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) >>> + rc |= >>> preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, >>> + >>> "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); >>> + >>> + return rc; >>> +} >>> + >>> static int >>> test_eventdev_close(void) >>> { >>> @@ -1310,6 +1371,8 @@ static struct unit_test_suite >>> eventdev_common_testsuite = { >>> test_eventdev_start_stop), >>> TEST_CASE_ST(eventdev_configure_setup, >>> eventdev_stop_device, >>> test_eventdev_profile_switch), >>> + TEST_CASE_ST(eventdev_configure_setup, NULL, >>> + test_eventdev_preschedule_configure), >>> TEST_CASE_ST(eventdev_setup_device, >> eventdev_stop_device, >>> test_eventdev_link), >>> TEST_CASE_ST(eventdev_setup_device, >> eventdev_stop_device, >>> diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst >>> b/doc/guides/prog_guide/eventdev/eventdev.rst >>> index fb6dfce102..341b9bb2c6 100644 >>> --- a/doc/guides/prog_guide/eventdev/eventdev.rst >>> +++ b/doc/guides/prog_guide/eventdev/eventdev.rst >>> @@ -357,6 +357,28 @@ Worker path: >>> // Process the event received. >>> } >>> >>> +Event Pre-scheduling >>> +~~~~~~~~~~~~~~~~~~~~ >>> + >>> +Event pre-scheduling improves scheduling performance by assigning >>> +events to event ports in advance when dequeues are issued. >>> +The `rte_event_dequeue_burst` operation initiates the pre-schedule >>> +operation, which completes in parallel without affecting the dequeued >> event >>> flow contexts and dequeue latency. >>> +On the next dequeue operation, the pre-scheduled events are dequeued >>> +and pre-schedule is initiated again. >>> + >>> +An application can use event pre-scheduling if the event device >>> +supports it at either device level or at a individual port level. >>> +The application can check pre-schedule capability by checking if >>> +``rte_event_dev_info.event_dev_cap`` >>> +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present >>> +pre-scheduling can be enabled at device configuration time by setting >>> appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. >>> + >>> +Currently, the following pre-schedule types are supported: >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. >>> + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when >>> dequeue is issued. >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when >>> dequeue is issued and there are >>> + no forward progress constraints. >>> + >>> Starting the EventDev >>> ~~~~~~~~~~~~~~~~~~~~~ >>> >>> diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h >> index >>> 08e5f9320b..5ea7f5a07b 100644 >>> --- a/lib/eventdev/rte_eventdev.h >>> +++ b/lib/eventdev/rte_eventdev.h >>> @@ -446,6 +446,30 @@ struct rte_event; >>> * @see RTE_SCHED_TYPE_PARALLEL >>> */ >>> >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) /**< >> Event >>> +device supports event pre-scheduling. >>> + * >>> + * When this capability is available, the application can enable event >>> +pre-scheduling on the event >>> + * device to pre-schedule events to a event port when >>> +`rte_event_dequeue_burst()` >>> + * is issued. >>> + * The pre-schedule process starts with the `rte_event_dequeue_burst()` >>> +call and the >>> + * pre-scheduled events are returned on the next >> `rte_event_dequeue_burst()` >>> call. >>> + * >>> + * @see rte_event_dev_configure() >>> + */ >>> + >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << >> 17) >>> /**< >>> +Event device supports adaptive event pre-scheduling. >>> + * >>> + * When this capability is available, the application can enable >>> +adaptive pre-scheduling >>> + * on the event device where the events are pre-scheduled when there >>> +are no forward >>> + * progress constraints with the currently held flow contexts. >>> + * The pre-schedule process starts with the `rte_event_dequeue_burst()` >>> +call and the >>> + * pre-scheduled events are returned on the next >> `rte_event_dequeue_burst()` >>> call. >>> + * >>> + * @see rte_event_dev_configure() >>> + */ >>> + >>> /* Event device priority levels */ >>> #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 >>> /**< Highest priority level for events and queues. >>> @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t >>> attr_id, >>> * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() >>> */ >>> >>> +typedef enum { >>> + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, >>> + /* Disable pre-schedule across the event device or on a given event >> port. >>> + * @ref rte_event_dev_config.preschedule_type >>> + */ >>> + RTE_EVENT_DEV_PRESCHEDULE, >>> + /* Enable pre-schedule always across the event device or a given event >>> port. >>> + * @ref rte_event_dev_config.preschedule_type >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE >>> + */ >>> + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, >>> + /* Enable adaptive pre-schedule across the event device or a given >> event >>> port. >>> + * Delay issuing pre-schedule until there are no forward progress >>> constraints with >>> + * the held flow contexts. >>> + * @ref rte_event_dev_config.preschedule_type >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE >>> + */ >>> +} rte_event_dev_preschedule_type_t; >>> + >>> /** Event device configuration structure */ struct rte_event_dev_config { >>> uint32_t dequeue_timeout_ns; >>> @@ -752,6 +795,11 @@ struct rte_event_dev_config { >>> * optimized for single-link usage, this field is a hint for how many >>> * to allocate; otherwise, regular event ports and queues will be used. >>> */ >>> + rte_event_dev_preschedule_type_t preschedule_type; >>> + /**< Event pre-schedule type to use across the event device, if >>> supported. >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE >>> + */ >>> }; >>> >>> /** >>> -- >>> 2.25.1 > ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-23 8:57 ` Mattias Rönnblom @ 2024-09-25 10:30 ` Pavan Nikhilesh Bhagavatula 2024-09-26 2:54 ` Pathak, Pravin 0 siblings, 1 reply; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-09-25 10:30 UTC (permalink / raw) To: Mattias Rönnblom, Pathak, Pravin, Jerin Jacob, Shijith Thotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev > On 2024-09-19 15:13, Pavan Nikhilesh Bhagavatula wrote: > >>> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> > >>> Sent: Tuesday, September 17, 2024 3:11 AM > >>> To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, Abdullah > >>> <abdullah.sevincer@intel.com>; hemant.agrawal@nxp.com; > >>> sachin.saxena@oss.nxp.com; Van Haaren, Harry > >> <harry.van.haaren@intel.com>; > >>> mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, Peter > >>> <peter.mccarthy@intel.com> > >>> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> > >>> Subject: [PATCH v2 1/3] eventdev: introduce event pre-scheduling > >>> > >>> From: Pavan Nikhilesh <pbhagavatula@marvell.com> > >>> > >>> Event pre-scheduling improves scheduling performance by assigning > events > >> to > >>> event ports in advance when dequeues are issued. > >>> The dequeue operation initiates the pre-schedule operation, which > >> completes in > >>> parallel without affecting the dequeued event flow contexts and dequeue > >>> latency. > >>> > >> Is the prescheduling done to get the event more quickly in the next > dequeue? > >> The first dequeue executes pre-schedule to make events available for the > next > >> dequeue. > >> Is this how it is supposed to work? > >> > > > > Yes, that is correct. > > > > "improves scheduling performance" may be a bit misleading, in that case. > I suggest "reduces scheduling overhead" instead. You can argue it likely > reduces scheduling performance, in certain scenarios. "reduces > scheduling overhead, at the cost of load balancing performance." > In case of OCTEON, we see double the scheduling performance with prescheduling without effecting any priority/weight aspects. > It seems to me that this should be a simple hint-type API, where the > hint is used by the event device to decide if pre-scheduling should be > used or not (assuming pre-scheduling on/off is even an option). The hint > would just be a way for the application to express whether or not it > want the scheduler to prioritize load balancing agility and port-to-port > wall-time latency, or scheduling overhead, which in turn could > potentially be rephrased as the app being throughput or latency/RT-oriented. > The three prescheduling types are designed based on real world use-cases that some of our customers require in their applications. Relying on application to provide hits might not be possible in all the cases as it is very timing sensitive. > It could also be useful for the event device to know which priority > levels are to be considered latency-sensitive, and which are > throughput-oriented - maybe in the form of a threshold. > > >>> Event devices can indicate pre-scheduling capabilities using > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event > >> device > >>> info function `info.event_dev_cap`. > >>> > >>> Applications can select the pre-schedule type and configure it through > >>> `rte_event_dev_config.preschedule_type` during > `rte_event_dev_configure`. > >>> > >>> The supported pre-schedule types are: > >>> * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > >>> * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on > >> dequeue. > >>> * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre- > schedule > >>> until > >>> there are no forward progress constraints with the held flow contexts. > >>> > >>> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > >>> --- > >>> app/test/test_eventdev.c | 63 +++++++++++++++++++++ > >>> doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ > >>> lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ > >>> 3 files changed, 133 insertions(+) > >>> > >>> diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index > >>> e4e234dc98..cf496ee88d 100644 > >>> --- a/app/test/test_eventdev.c > >>> +++ b/app/test/test_eventdev.c > >>> @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) > >>> return TEST_SUCCESS; > >>> } > >>> > >>> +static int > >>> +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, > >>> +const char *preschedule_name) { > >>> +#define NB_EVENTS 1024 > >>> + uint64_t start, total; > >>> + struct rte_event ev; > >>> + int rc, cnt; > >>> + > >>> + ev.event_type = RTE_EVENT_TYPE_CPU; > >>> + ev.queue_id = 0; > >>> + ev.op = RTE_EVENT_OP_NEW; > >>> + ev.u64 = 0xBADF00D0; > >>> + > >>> + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > >>> + ev.flow_id = cnt; > >>> + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); > >>> + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > >>> + } > >>> + > >>> + RTE_SET_USED(preschedule_type); > >>> + total = 0; > >>> + while (cnt) { > >>> + start = rte_rdtsc_precise(); > >>> + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); > >>> + if (rc) { > >>> + total += rte_rdtsc_precise() - start; > >>> + cnt--; > >>> + } > >>> + } > >>> + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", > >>> preschedule_name, > >>> + total / NB_EVENTS); > >>> + > >>> + return TEST_SUCCESS; > >>> +} > >>> + > >>> +static int > >>> +test_eventdev_preschedule_configure(void) > >>> +{ > >>> + struct rte_event_dev_config dev_conf; > >>> + struct rte_event_dev_info info; > >>> + int rc; > >>> + > >>> + rte_event_dev_info_get(TEST_DEV_ID, &info); > >>> + > >>> + if ((info.event_dev_cap & > >> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) > >>> == 0) > >>> + return TEST_SKIPPED; > >>> + > >>> + devconf_set_default_sane_values(&dev_conf, &info); > >>> + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; > >>> + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); > >>> + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); > >>> + > >>> + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, > >>> "RTE_EVENT_DEV_PRESCHEDULE_NONE"); > >>> + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, > >>> "RTE_EVENT_DEV_PRESCHEDULE"); > >>> + if (info.event_dev_cap & > >>> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) > >>> + rc |= > >>> preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > >>> + > >>> "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); > >>> + > >>> + return rc; > >>> +} > >>> + > >>> static int > >>> test_eventdev_close(void) > >>> { > >>> @@ -1310,6 +1371,8 @@ static struct unit_test_suite > >>> eventdev_common_testsuite = { > >>> test_eventdev_start_stop), > >>> TEST_CASE_ST(eventdev_configure_setup, > >>> eventdev_stop_device, > >>> test_eventdev_profile_switch), > >>> + TEST_CASE_ST(eventdev_configure_setup, NULL, > >>> + test_eventdev_preschedule_configure), > >>> TEST_CASE_ST(eventdev_setup_device, > >> eventdev_stop_device, > >>> test_eventdev_link), > >>> TEST_CASE_ST(eventdev_setup_device, > >> eventdev_stop_device, > >>> diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst > >>> b/doc/guides/prog_guide/eventdev/eventdev.rst > >>> index fb6dfce102..341b9bb2c6 100644 > >>> --- a/doc/guides/prog_guide/eventdev/eventdev.rst > >>> +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > >>> @@ -357,6 +357,28 @@ Worker path: > >>> // Process the event received. > >>> } > >>> > >>> +Event Pre-scheduling > >>> +~~~~~~~~~~~~~~~~~~~~ > >>> + > >>> +Event pre-scheduling improves scheduling performance by assigning > >>> +events to event ports in advance when dequeues are issued. > >>> +The `rte_event_dequeue_burst` operation initiates the pre-schedule > >>> +operation, which completes in parallel without affecting the dequeued > >> event > >>> flow contexts and dequeue latency. > >>> +On the next dequeue operation, the pre-scheduled events are dequeued > >>> +and pre-schedule is initiated again. > >>> + > >>> +An application can use event pre-scheduling if the event device > >>> +supports it at either device level or at a individual port level. > >>> +The application can check pre-schedule capability by checking if > >>> +``rte_event_dev_info.event_dev_cap`` > >>> +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present > >>> +pre-scheduling can be enabled at device configuration time by setting > >>> appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. > >>> + > >>> +Currently, the following pre-schedule types are supported: > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when > >>> dequeue is issued. > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule > when > >>> dequeue is issued and there are > >>> + no forward progress constraints. > >>> + > >>> Starting the EventDev > >>> ~~~~~~~~~~~~~~~~~~~~~ > >>> > >>> diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h > >> index > >>> 08e5f9320b..5ea7f5a07b 100644 > >>> --- a/lib/eventdev/rte_eventdev.h > >>> +++ b/lib/eventdev/rte_eventdev.h > >>> @@ -446,6 +446,30 @@ struct rte_event; > >>> * @see RTE_SCHED_TYPE_PARALLEL > >>> */ > >>> > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) /**< > >> Event > >>> +device supports event pre-scheduling. > >>> + * > >>> + * When this capability is available, the application can enable event > >>> +pre-scheduling on the event > >>> + * device to pre-schedule events to a event port when > >>> +`rte_event_dequeue_burst()` > >>> + * is issued. > >>> + * The pre-schedule process starts with the `rte_event_dequeue_burst()` > >>> +call and the > >>> + * pre-scheduled events are returned on the next > >> `rte_event_dequeue_burst()` > >>> call. > >>> + * > >>> + * @see rte_event_dev_configure() > >>> + */ > >>> + > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL > << > >> 17) > >>> /**< > >>> +Event device supports adaptive event pre-scheduling. > >>> + * > >>> + * When this capability is available, the application can enable > >>> +adaptive pre-scheduling > >>> + * on the event device where the events are pre-scheduled when there > >>> +are no forward > >>> + * progress constraints with the currently held flow contexts. > >>> + * The pre-schedule process starts with the `rte_event_dequeue_burst()` > >>> +call and the > >>> + * pre-scheduled events are returned on the next > >> `rte_event_dequeue_burst()` > >>> call. > >>> + * > >>> + * @see rte_event_dev_configure() > >>> + */ > >>> + > >>> /* Event device priority levels */ > >>> #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > >>> /**< Highest priority level for events and queues. > >>> @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, > uint32_t > >>> attr_id, > >>> * @see rte_event_dequeue_timeout_ticks(), > rte_event_dequeue_burst() > >>> */ > >>> > >>> +typedef enum { > >>> + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > >>> + /* Disable pre-schedule across the event device or on a given event > >> port. > >>> + * @ref rte_event_dev_config.preschedule_type > >>> + */ > >>> + RTE_EVENT_DEV_PRESCHEDULE, > >>> + /* Enable pre-schedule always across the event device or a given event > >>> port. > >>> + * @ref rte_event_dev_config.preschedule_type > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > >>> + */ > >>> + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > >>> + /* Enable adaptive pre-schedule across the event device or a given > >> event > >>> port. > >>> + * Delay issuing pre-schedule until there are no forward progress > >>> constraints with > >>> + * the held flow contexts. > >>> + * @ref rte_event_dev_config.preschedule_type > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > >>> + */ > >>> +} rte_event_dev_preschedule_type_t; > >>> + > >>> /** Event device configuration structure */ struct rte_event_dev_config { > >>> uint32_t dequeue_timeout_ns; > >>> @@ -752,6 +795,11 @@ struct rte_event_dev_config { > >>> * optimized for single-link usage, this field is a hint for how many > >>> * to allocate; otherwise, regular event ports and queues will be used. > >>> */ > >>> + rte_event_dev_preschedule_type_t preschedule_type; > >>> + /**< Event pre-schedule type to use across the event device, if > >>> supported. > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > >>> + */ > >>> }; > >>> > >>> /** > >>> -- > >>> 2.25.1 > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-25 10:30 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula @ 2024-09-26 2:54 ` Pathak, Pravin 2024-09-26 10:03 ` Pavan Nikhilesh Bhagavatula 0 siblings, 1 reply; 77+ messages in thread From: Pathak, Pravin @ 2024-09-26 2:54 UTC (permalink / raw) To: Pavan Nikhilesh Bhagavatula, Mattias Rönnblom, Jerin Jacob, Shijith Thotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev > -----Original Message----- > From: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com> > Sent: Wednesday, September 25, 2024 6:30 AM > To: Mattias Rönnblom <hofors@lysator.liu.se>; Pathak, Pravin > <pravin.pathak@intel.com>; Jerin Jacob <jerinj@marvell.com>; Shijith Thotton > <sthotton@marvell.com>; Sevincer, Abdullah <abdullah.sevincer@intel.com>; > hemant.agrawal@nxp.com; sachin.saxena@oss.nxp.com; Van Haaren, Harry > <harry.van.haaren@intel.com>; mattias.ronnblom@ericsson.com; > liangma@liangbit.com; Mccarthy, Peter <peter.mccarthy@intel.com> > Cc: dev@dpdk.org > Subject: RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre- > scheduling > > > On 2024-09-19 15:13, Pavan Nikhilesh Bhagavatula wrote: > > >>> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> > > >>> Sent: Tuesday, September 17, 2024 3:11 AM > > >>> To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, Abdullah > > >>> <abdullah.sevincer@intel.com>; hemant.agrawal@nxp.com; > > >>> sachin.saxena@oss.nxp.com; Van Haaren, Harry > > >> <harry.van.haaren@intel.com>; > > >>> mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, > > >>> Peter <peter.mccarthy@intel.com> > > >>> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> > > >>> Subject: [PATCH v2 1/3] eventdev: introduce event pre-scheduling > > >>> > > >>> From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > >>> > > >>> Event pre-scheduling improves scheduling performance by assigning > > events > > >> to > > >>> event ports in advance when dequeues are issued. > > >>> The dequeue operation initiates the pre-schedule operation, which > > >> completes in > > >>> parallel without affecting the dequeued event flow contexts and > > >>> dequeue latency. > > >>> > > >> Is the prescheduling done to get the event more quickly in the next > > dequeue? > > >> The first dequeue executes pre-schedule to make events available > > >> for the > > next > > >> dequeue. > > >> Is this how it is supposed to work? > > >> > > > > > > Yes, that is correct. > > > > > > > "improves scheduling performance" may be a bit misleading, in that case. > > I suggest "reduces scheduling overhead" instead. You can argue it > > likely reduces scheduling performance, in certain scenarios. "reduces > > scheduling overhead, at the cost of load balancing performance." > > > > In case of OCTEON, we see double the scheduling performance with > prescheduling without effecting any priority/weight aspects. > > > It seems to me that this should be a simple hint-type API, where the > > hint is used by the event device to decide if pre-scheduling should be > > used or not (assuming pre-scheduling on/off is even an option). The > > hint would just be a way for the application to express whether or not > > it want the scheduler to prioritize load balancing agility and > > port-to-port wall-time latency, or scheduling overhead, which in turn > > could potentially be rephrased as the app being throughput or latency/RT- > oriented. > > > > The three prescheduling types are designed based on real world use-cases that > some of our customers require in their applications. > Relying on application to provide hits might not be possible in all the cases as it > is very timing sensitive. > > > > It could also be useful for the event device to know which priority > > levels are to be considered latency-sensitive, and which are > > throughput-oriented - maybe in the form of a threshold. > > > > >>> Event devices can indicate pre-scheduling capabilities using > > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event > > >> device > > >>> info function `info.event_dev_cap`. What is PRESCHEDULE_ADAPTIVE? Can you please add more description? This will be more useful as per port configuration instead of device-level configuration. The application can choose a type based on its requirement on the port it is serving. As Mattias suggested, if this is made HINT flag for port configuration, other PMDs can Ignore it based on either they may not need it depending on their architecture or not support it. > > >>> > > >>> Applications can select the pre-schedule type and configure it > > >>> through `rte_event_dev_config.preschedule_type` during > > `rte_event_dev_configure`. > > >>> > > >>> The supported pre-schedule types are: > > >>> * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > > >>> * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on > > >> dequeue. > > >>> * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre- > > schedule > > >>> until > > >>> there are no forward progress constraints with the held flow contexts. > > >>> > > >>> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > > >>> --- > > >>> app/test/test_eventdev.c | 63 +++++++++++++++++++++ > > >>> doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ > > >>> lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ > > >>> 3 files changed, 133 insertions(+) > > >>> > > >>> diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c > > >>> index e4e234dc98..cf496ee88d 100644 > > >>> --- a/app/test/test_eventdev.c > > >>> +++ b/app/test/test_eventdev.c > > >>> @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) > > >>> return TEST_SUCCESS; > > >>> } > > >>> > > >>> +static int > > >>> +preschedule_test(rte_event_dev_preschedule_type_t > > >>> +preschedule_type, const char *preschedule_name) { > > >>> +#define NB_EVENTS 1024 > > >>> + uint64_t start, total; > > >>> + struct rte_event ev; > > >>> + int rc, cnt; > > >>> + > > >>> + ev.event_type = RTE_EVENT_TYPE_CPU; > > >>> + ev.queue_id = 0; > > >>> + ev.op = RTE_EVENT_OP_NEW; > > >>> + ev.u64 = 0xBADF00D0; > > >>> + > > >>> + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > > >>> + ev.flow_id = cnt; > > >>> + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); > > >>> + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > > >>> + } > > >>> + > > >>> + RTE_SET_USED(preschedule_type); > > >>> + total = 0; > > >>> + while (cnt) { > > >>> + start = rte_rdtsc_precise(); > > >>> + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); > > >>> + if (rc) { > > >>> + total += rte_rdtsc_precise() - start; > > >>> + cnt--; > > >>> + } > > >>> + } > > >>> + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", > > >>> preschedule_name, > > >>> + total / NB_EVENTS); > > >>> + > > >>> + return TEST_SUCCESS; > > >>> +} > > >>> + > > >>> +static int > > >>> +test_eventdev_preschedule_configure(void) > > >>> +{ > > >>> + struct rte_event_dev_config dev_conf; > > >>> + struct rte_event_dev_info info; > > >>> + int rc; > > >>> + > > >>> + rte_event_dev_info_get(TEST_DEV_ID, &info); > > >>> + > > >>> + if ((info.event_dev_cap & > > >> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) > > >>> == 0) > > >>> + return TEST_SKIPPED; > > >>> + > > >>> + devconf_set_default_sane_values(&dev_conf, &info); > > >>> + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; > > >>> + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); > > >>> + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); > > >>> + > > >>> + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, > > >>> "RTE_EVENT_DEV_PRESCHEDULE_NONE"); > > >>> + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, > > >>> "RTE_EVENT_DEV_PRESCHEDULE"); > > >>> + if (info.event_dev_cap & > > >>> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) > > >>> + rc |= > > >>> preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > >>> + > > >>> "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); > > >>> + > > >>> + return rc; > > >>> +} > > >>> + > > >>> static int > > >>> test_eventdev_close(void) > > >>> { > > >>> @@ -1310,6 +1371,8 @@ static struct unit_test_suite > > >>> eventdev_common_testsuite = { > > >>> test_eventdev_start_stop), > > >>> TEST_CASE_ST(eventdev_configure_setup, > > >>> eventdev_stop_device, > > >>> test_eventdev_profile_switch), > > >>> + TEST_CASE_ST(eventdev_configure_setup, NULL, > > >>> + test_eventdev_preschedule_configure), > > >>> TEST_CASE_ST(eventdev_setup_device, > > >> eventdev_stop_device, > > >>> test_eventdev_link), > > >>> TEST_CASE_ST(eventdev_setup_device, > > >> eventdev_stop_device, > > >>> diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst > > >>> b/doc/guides/prog_guide/eventdev/eventdev.rst > > >>> index fb6dfce102..341b9bb2c6 100644 > > >>> --- a/doc/guides/prog_guide/eventdev/eventdev.rst > > >>> +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > > >>> @@ -357,6 +357,28 @@ Worker path: > > >>> // Process the event received. > > >>> } > > >>> > > >>> +Event Pre-scheduling > > >>> +~~~~~~~~~~~~~~~~~~~~ > > >>> + > > >>> +Event pre-scheduling improves scheduling performance by assigning > > >>> +events to event ports in advance when dequeues are issued. > > >>> +The `rte_event_dequeue_burst` operation initiates the > > >>> +pre-schedule operation, which completes in parallel without > > >>> +affecting the dequeued > > >> event > > >>> flow contexts and dequeue latency. > > >>> +On the next dequeue operation, the pre-scheduled events are > > >>> +dequeued and pre-schedule is initiated again. > > >>> + > > >>> +An application can use event pre-scheduling if the event device > > >>> +supports it at either device level or at a individual port level. > > >>> +The application can check pre-schedule capability by checking if > > >>> +``rte_event_dev_info.event_dev_cap`` > > >>> +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present > > >>> +pre-scheduling can be enabled at device configuration time by > > >>> +setting > > >>> appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. > > >>> + > > >>> +Currently, the following pre-schedule types are supported: > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule > > >>> +when > > >>> dequeue is issued. > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule > > when > > >>> dequeue is issued and there are > > >>> + no forward progress constraints. > > >>> + > > >>> Starting the EventDev > > >>> ~~~~~~~~~~~~~~~~~~~~~ > > >>> > > >>> diff --git a/lib/eventdev/rte_eventdev.h > > >>> b/lib/eventdev/rte_eventdev.h > > >> index > > >>> 08e5f9320b..5ea7f5a07b 100644 > > >>> --- a/lib/eventdev/rte_eventdev.h > > >>> +++ b/lib/eventdev/rte_eventdev.h > > >>> @@ -446,6 +446,30 @@ struct rte_event; > > >>> * @see RTE_SCHED_TYPE_PARALLEL > > >>> */ > > >>> > > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) > /**< > > >> Event > > >>> +device supports event pre-scheduling. > > >>> + * > > >>> + * When this capability is available, the application can enable > > >>> +event pre-scheduling on the event > > >>> + * device to pre-schedule events to a event port when > > >>> +`rte_event_dequeue_burst()` > > >>> + * is issued. > > >>> + * The pre-schedule process starts with the > > >>> +`rte_event_dequeue_burst()` call and the > > >>> + * pre-scheduled events are returned on the next > > >> `rte_event_dequeue_burst()` > > >>> call. > > >>> + * > > >>> + * @see rte_event_dev_configure() */ > > >>> + > > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL > > << > > >> 17) > > >>> /**< > > >>> +Event device supports adaptive event pre-scheduling. > > >>> + * > > >>> + * When this capability is available, the application can enable > > >>> +adaptive pre-scheduling > > >>> + * on the event device where the events are pre-scheduled when > > >>> +there are no forward > > >>> + * progress constraints with the currently held flow contexts. > > >>> + * The pre-schedule process starts with the > > >>> +`rte_event_dequeue_burst()` call and the > > >>> + * pre-scheduled events are returned on the next > > >> `rte_event_dequeue_burst()` > > >>> call. > > >>> + * > > >>> + * @see rte_event_dev_configure() */ > > >>> + > > >>> /* Event device priority levels */ > > >>> #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > > >>> /**< Highest priority level for events and queues. > > >>> @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, > > uint32_t > > >>> attr_id, > > >>> * @see rte_event_dequeue_timeout_ticks(), > > rte_event_dequeue_burst() > > >>> */ > > >>> > > >>> +typedef enum { > > >>> + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > > >>> + /* Disable pre-schedule across the event device or on a given > > >>> +event > > >> port. > > >>> + * @ref rte_event_dev_config.preschedule_type > > >>> + */ > > >>> + RTE_EVENT_DEV_PRESCHEDULE, > > >>> + /* Enable pre-schedule always across the event device or a given > > >>> +event > > >>> port. > > >>> + * @ref rte_event_dev_config.preschedule_type > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > >>> + */ > > >>> + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > >>> + /* Enable adaptive pre-schedule across the event device or a > > >>> +given > > >> event > > >>> port. > > >>> + * Delay issuing pre-schedule until there are no forward > > >>> +progress > > >>> constraints with > > >>> + * the held flow contexts. > > >>> + * @ref rte_event_dev_config.preschedule_type > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > >>> + */ > > >>> +} rte_event_dev_preschedule_type_t; > > >>> + > > >>> /** Event device configuration structure */ struct > rte_event_dev_config { > > >>> uint32_t dequeue_timeout_ns; > > >>> @@ -752,6 +795,11 @@ struct rte_event_dev_config { > > >>> * optimized for single-link usage, this field is a hint for how many > > >>> * to allocate; otherwise, regular event ports and queues will be used. > > >>> */ > > >>> + rte_event_dev_preschedule_type_t preschedule_type; > > >>> + /**< Event pre-schedule type to use across the event device, if > > >>> supported. > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > >>> + */ > > >>> }; > > >>> > > >>> /** > > >>> -- > > >>> 2.25.1 > > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-26 2:54 ` Pathak, Pravin @ 2024-09-26 10:03 ` Pavan Nikhilesh Bhagavatula 2024-09-27 3:31 ` Pathak, Pravin 0 siblings, 1 reply; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-09-26 10:03 UTC (permalink / raw) To: Pathak, Pravin, Mattias Rönnblom, Jerin Jacob, Shijith Thotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev > > -----Original Message----- > > From: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com> > > Sent: Wednesday, September 25, 2024 6:30 AM > > To: Mattias Rönnblom <hofors@lysator.liu.se>; Pathak, Pravin > > <pravin.pathak@intel.com>; Jerin Jacob <jerinj@marvell.com>; Shijith > Thotton > > <sthotton@marvell.com>; Sevincer, Abdullah > <abdullah.sevincer@intel.com>; > > hemant.agrawal@nxp.com; sachin.saxena@oss.nxp.com; Van Haaren, Harry > > <harry.van.haaren@intel.com>; mattias.ronnblom@ericsson.com; > > liangma@liangbit.com; Mccarthy, Peter <peter.mccarthy@intel.com> > > Cc: dev@dpdk.org > > Subject: RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre- > > scheduling > > > > > On 2024-09-19 15:13, Pavan Nikhilesh Bhagavatula wrote: > > > >>> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> > > > >>> Sent: Tuesday, September 17, 2024 3:11 AM > > > >>> To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, Abdullah > > > >>> <abdullah.sevincer@intel.com>; hemant.agrawal@nxp.com; > > > >>> sachin.saxena@oss.nxp.com; Van Haaren, Harry > > > >> <harry.van.haaren@intel.com>; > > > >>> mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, > > > >>> Peter <peter.mccarthy@intel.com> > > > >>> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> > > > >>> Subject: [PATCH v2 1/3] eventdev: introduce event pre-scheduling > > > >>> > > > >>> From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > >>> > > > >>> Event pre-scheduling improves scheduling performance by assigning > > > events > > > >> to > > > >>> event ports in advance when dequeues are issued. > > > >>> The dequeue operation initiates the pre-schedule operation, which > > > >> completes in > > > >>> parallel without affecting the dequeued event flow contexts and > > > >>> dequeue latency. > > > >>> > > > >> Is the prescheduling done to get the event more quickly in the next > > > dequeue? > > > >> The first dequeue executes pre-schedule to make events available > > > >> for the > > > next > > > >> dequeue. > > > >> Is this how it is supposed to work? > > > >> > > > > > > > > Yes, that is correct. > > > > > > > > > > "improves scheduling performance" may be a bit misleading, in that case. > > > I suggest "reduces scheduling overhead" instead. You can argue it > > > likely reduces scheduling performance, in certain scenarios. "reduces > > > scheduling overhead, at the cost of load balancing performance." > > > > > > > In case of OCTEON, we see double the scheduling performance with > > prescheduling without effecting any priority/weight aspects. > > > > > It seems to me that this should be a simple hint-type API, where the > > > hint is used by the event device to decide if pre-scheduling should be > > > used or not (assuming pre-scheduling on/off is even an option). The > > > hint would just be a way for the application to express whether or not > > > it want the scheduler to prioritize load balancing agility and > > > port-to-port wall-time latency, or scheduling overhead, which in turn > > > could potentially be rephrased as the app being throughput or latency/RT- > > oriented. > > > > > > > The three prescheduling types are designed based on real world use-cases > that > > some of our customers require in their applications. > > Relying on application to provide hits might not be possible in all the cases as > it > > is very timing sensitive. > > > > > > > It could also be useful for the event device to know which priority > > > levels are to be considered latency-sensitive, and which are > > > throughput-oriented - maybe in the form of a threshold. > > > > > > >>> Event devices can indicate pre-scheduling capabilities using > > > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > > > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the > event > > > >> device > > > >>> info function `info.event_dev_cap`. > > What is PRESCHEDULE_ADAPTIVE? Can you please add more description? Unlike raw PRESCHEDULE where every dequeue triggers a pre-scheduling request in parallel, PRESCHEDULE_ADAPTIVE will delay issuing pre-scheduling till event device knows that the currently scheduled context can make forward progress. For example, in OCTEON HW does it when it sees that scheduling context held by the port is top/head of the flow. > This will be more useful as per port configuration instead of device-level > configuration. In the patch 2/3 I introduced port level API to control prefetches at an event port level. It is not a port configuration API because Applications might want to enable/disable prefetching in fastpath. Example use cases we see is to disable pre-scheduling when application wants to preempt an lcore and reenable it at a later point of time. > The application can choose a type based on its requirement on the port it is > serving. > As Mattias suggested, if this is made HINT flag for port configuration, other > PMDs can > Ignore it based on either they may not need it depending on their architecture > or not support it. > If PMDs support preschedules then it has to advertise via capabilities, silently ignoring feature configuration is bad. We can make the fastpath APIs as hints. > > > >>> > > > >>> Applications can select the pre-schedule type and configure it > > > >>> through `rte_event_dev_config.preschedule_type` during > > > `rte_event_dev_configure`. > > > >>> > > > >>> The supported pre-schedule types are: > > > >>> * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > > > >>> * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on > > > >> dequeue. > > > >>> * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre- > > > schedule > > > >>> until > > > >>> there are no forward progress constraints with the held flow > contexts. > > > >>> > > > >>> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > >>> --- > > > >>> app/test/test_eventdev.c | 63 +++++++++++++++++++++ > > > >>> doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ > > > >>> lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ > > > >>> 3 files changed, 133 insertions(+) > > > >>> > > > >>> diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c > > > >>> index e4e234dc98..cf496ee88d 100644 > > > >>> --- a/app/test/test_eventdev.c > > > >>> +++ b/app/test/test_eventdev.c > > > >>> @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) > > > >>> return TEST_SUCCESS; > > > >>> } > > > >>> > > > >>> +static int > > > >>> +preschedule_test(rte_event_dev_preschedule_type_t > > > >>> +preschedule_type, const char *preschedule_name) { > > > >>> +#define NB_EVENTS 1024 > > > >>> + uint64_t start, total; > > > >>> + struct rte_event ev; > > > >>> + int rc, cnt; > > > >>> + > > > >>> + ev.event_type = RTE_EVENT_TYPE_CPU; > > > >>> + ev.queue_id = 0; > > > >>> + ev.op = RTE_EVENT_OP_NEW; > > > >>> + ev.u64 = 0xBADF00D0; > > > >>> + > > > >>> + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > > > >>> + ev.flow_id = cnt; > > > >>> + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, > 1); > > > >>> + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > > > >>> + } > > > >>> + > > > >>> + RTE_SET_USED(preschedule_type); > > > >>> + total = 0; > > > >>> + while (cnt) { > > > >>> + start = rte_rdtsc_precise(); > > > >>> + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, > 1, 0); > > > >>> + if (rc) { > > > >>> + total += rte_rdtsc_precise() - start; > > > >>> + cnt--; > > > >>> + } > > > >>> + } > > > >>> + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", > > > >>> preschedule_name, > > > >>> + total / NB_EVENTS); > > > >>> + > > > >>> + return TEST_SUCCESS; > > > >>> +} > > > >>> + > > > >>> +static int > > > >>> +test_eventdev_preschedule_configure(void) > > > >>> +{ > > > >>> + struct rte_event_dev_config dev_conf; > > > >>> + struct rte_event_dev_info info; > > > >>> + int rc; > > > >>> + > > > >>> + rte_event_dev_info_get(TEST_DEV_ID, &info); > > > >>> + > > > >>> + if ((info.event_dev_cap & > > > >> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) > > > >>> == 0) > > > >>> + return TEST_SKIPPED; > > > >>> + > > > >>> + devconf_set_default_sane_values(&dev_conf, &info); > > > >>> + dev_conf.preschedule_type = > RTE_EVENT_DEV_PRESCHEDULE; > > > >>> + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); > > > >>> + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); > > > >>> + > > > >>> + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, > > > >>> "RTE_EVENT_DEV_PRESCHEDULE_NONE"); > > > >>> + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, > > > >>> "RTE_EVENT_DEV_PRESCHEDULE"); > > > >>> + if (info.event_dev_cap & > > > >>> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) > > > >>> + rc |= > > > >>> preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > > >>> + > > > >>> "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); > > > >>> + > > > >>> + return rc; > > > >>> +} > > > >>> + > > > >>> static int > > > >>> test_eventdev_close(void) > > > >>> { > > > >>> @@ -1310,6 +1371,8 @@ static struct unit_test_suite > > > >>> eventdev_common_testsuite = { > > > >>> test_eventdev_start_stop), > > > >>> TEST_CASE_ST(eventdev_configure_setup, > > > >>> eventdev_stop_device, > > > >>> test_eventdev_profile_switch), > > > >>> + TEST_CASE_ST(eventdev_configure_setup, NULL, > > > >>> + test_eventdev_preschedule_configure), > > > >>> TEST_CASE_ST(eventdev_setup_device, > > > >> eventdev_stop_device, > > > >>> test_eventdev_link), > > > >>> TEST_CASE_ST(eventdev_setup_device, > > > >> eventdev_stop_device, > > > >>> diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst > > > >>> b/doc/guides/prog_guide/eventdev/eventdev.rst > > > >>> index fb6dfce102..341b9bb2c6 100644 > > > >>> --- a/doc/guides/prog_guide/eventdev/eventdev.rst > > > >>> +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > > > >>> @@ -357,6 +357,28 @@ Worker path: > > > >>> // Process the event received. > > > >>> } > > > >>> > > > >>> +Event Pre-scheduling > > > >>> +~~~~~~~~~~~~~~~~~~~~ > > > >>> + > > > >>> +Event pre-scheduling improves scheduling performance by assigning > > > >>> +events to event ports in advance when dequeues are issued. > > > >>> +The `rte_event_dequeue_burst` operation initiates the > > > >>> +pre-schedule operation, which completes in parallel without > > > >>> +affecting the dequeued > > > >> event > > > >>> flow contexts and dequeue latency. > > > >>> +On the next dequeue operation, the pre-scheduled events are > > > >>> +dequeued and pre-schedule is initiated again. > > > >>> + > > > >>> +An application can use event pre-scheduling if the event device > > > >>> +supports it at either device level or at a individual port level. > > > >>> +The application can check pre-schedule capability by checking if > > > >>> +``rte_event_dev_info.event_dev_cap`` > > > >>> +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present > > > >>> +pre-scheduling can be enabled at device configuration time by > > > >>> +setting > > > >>> appropriate pre-schedule type in > ``rte_event_dev_config.preschedule``. > > > >>> + > > > >>> +Currently, the following pre-schedule types are supported: > > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule > > > >>> +when > > > >>> dequeue is issued. > > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule > > > when > > > >>> dequeue is issued and there are > > > >>> + no forward progress constraints. > > > >>> + > > > >>> Starting the EventDev > > > >>> ~~~~~~~~~~~~~~~~~~~~~ > > > >>> > > > >>> diff --git a/lib/eventdev/rte_eventdev.h > > > >>> b/lib/eventdev/rte_eventdev.h > > > >> index > > > >>> 08e5f9320b..5ea7f5a07b 100644 > > > >>> --- a/lib/eventdev/rte_eventdev.h > > > >>> +++ b/lib/eventdev/rte_eventdev.h > > > >>> @@ -446,6 +446,30 @@ struct rte_event; > > > >>> * @see RTE_SCHED_TYPE_PARALLEL > > > >>> */ > > > >>> > > > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) > > /**< > > > >> Event > > > >>> +device supports event pre-scheduling. > > > >>> + * > > > >>> + * When this capability is available, the application can enable > > > >>> +event pre-scheduling on the event > > > >>> + * device to pre-schedule events to a event port when > > > >>> +`rte_event_dequeue_burst()` > > > >>> + * is issued. > > > >>> + * The pre-schedule process starts with the > > > >>> +`rte_event_dequeue_burst()` call and the > > > >>> + * pre-scheduled events are returned on the next > > > >> `rte_event_dequeue_burst()` > > > >>> call. > > > >>> + * > > > >>> + * @see rte_event_dev_configure() */ > > > >>> + > > > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > (1ULL > > > << > > > >> 17) > > > >>> /**< > > > >>> +Event device supports adaptive event pre-scheduling. > > > >>> + * > > > >>> + * When this capability is available, the application can enable > > > >>> +adaptive pre-scheduling > > > >>> + * on the event device where the events are pre-scheduled when > > > >>> +there are no forward > > > >>> + * progress constraints with the currently held flow contexts. > > > >>> + * The pre-schedule process starts with the > > > >>> +`rte_event_dequeue_burst()` call and the > > > >>> + * pre-scheduled events are returned on the next > > > >> `rte_event_dequeue_burst()` > > > >>> call. > > > >>> + * > > > >>> + * @see rte_event_dev_configure() */ > > > >>> + > > > >>> /* Event device priority levels */ > > > >>> #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > > > >>> /**< Highest priority level for events and queues. > > > >>> @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, > > > uint32_t > > > >>> attr_id, > > > >>> * @see rte_event_dequeue_timeout_ticks(), > > > rte_event_dequeue_burst() > > > >>> */ > > > >>> > > > >>> +typedef enum { > > > >>> + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > > > >>> + /* Disable pre-schedule across the event device or on a given > > > >>> +event > > > >> port. > > > >>> + * @ref rte_event_dev_config.preschedule_type > > > >>> + */ > > > >>> + RTE_EVENT_DEV_PRESCHEDULE, > > > >>> + /* Enable pre-schedule always across the event device or a > given > > > >>> +event > > > >>> port. > > > >>> + * @ref rte_event_dev_config.preschedule_type > > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > > >>> + */ > > > >>> + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > > >>> + /* Enable adaptive pre-schedule across the event device or a > > > >>> +given > > > >> event > > > >>> port. > > > >>> + * Delay issuing pre-schedule until there are no forward > > > >>> +progress > > > >>> constraints with > > > >>> + * the held flow contexts. > > > >>> + * @ref rte_event_dev_config.preschedule_type > > > >>> + * @see > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > > >>> + */ > > > >>> +} rte_event_dev_preschedule_type_t; > > > >>> + > > > >>> /** Event device configuration structure */ struct > > rte_event_dev_config { > > > >>> uint32_t dequeue_timeout_ns; > > > >>> @@ -752,6 +795,11 @@ struct rte_event_dev_config { > > > >>> * optimized for single-link usage, this field is a hint for how > many > > > >>> * to allocate; otherwise, regular event ports and queues will > be used. > > > >>> */ > > > >>> + rte_event_dev_preschedule_type_t preschedule_type; > > > >>> + /**< Event pre-schedule type to use across the event device, if > > > >>> supported. > > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > > >>> + * @see > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > > >>> + */ > > > >>> }; > > > >>> > > > >>> /** > > > >>> -- > > > >>> 2.25.1 > > > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre-scheduling 2024-09-26 10:03 ` Pavan Nikhilesh Bhagavatula @ 2024-09-27 3:31 ` Pathak, Pravin 0 siblings, 0 replies; 77+ messages in thread From: Pathak, Pravin @ 2024-09-27 3:31 UTC (permalink / raw) To: Pavan Nikhilesh Bhagavatula, Mattias Rönnblom, Jerin Jacob, Shijith Thotton, Sevincer, Abdullah, hemant.agrawal, sachin.saxena, Van Haaren, Harry, mattias.ronnblom, liangma, Mccarthy, Peter Cc: dev > -----Original Message----- > From: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com> > Sent: Thursday, September 26, 2024 6:03 AM > To: Pathak, Pravin <pravin.pathak@intel.com>; Mattias Rönnblom > <hofors@lysator.liu.se>; Jerin Jacob <jerinj@marvell.com>; Shijith Thotton > <sthotton@marvell.com>; Sevincer, Abdullah <abdullah.sevincer@intel.com>; > hemant.agrawal@nxp.com; sachin.saxena@oss.nxp.com; Van Haaren, Harry > <harry.van.haaren@intel.com>; mattias.ronnblom@ericsson.com; > liangma@liangbit.com; Mccarthy, Peter <peter.mccarthy@intel.com> > Cc: dev@dpdk.org > Subject: RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event pre- > scheduling > > > > -----Original Message----- > > > From: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com> > > > Sent: Wednesday, September 25, 2024 6:30 AM > > > To: Mattias Rönnblom <hofors@lysator.liu.se>; Pathak, Pravin > > > <pravin.pathak@intel.com>; Jerin Jacob <jerinj@marvell.com>; Shijith > > Thotton > > > <sthotton@marvell.com>; Sevincer, Abdullah > > <abdullah.sevincer@intel.com>; > > > hemant.agrawal@nxp.com; sachin.saxena@oss.nxp.com; Van Haaren, > Harry > > > <harry.van.haaren@intel.com>; mattias.ronnblom@ericsson.com; > > > liangma@liangbit.com; Mccarthy, Peter <peter.mccarthy@intel.com> > > > Cc: dev@dpdk.org > > > Subject: RE: [EXTERNAL] Re: [PATCH v2 1/3] eventdev: introduce event > > > pre- scheduling > > > > > > > On 2024-09-19 15:13, Pavan Nikhilesh Bhagavatula wrote: > > > > >>> From: pbhagavatula@marvell.com <pbhagavatula@marvell.com> > > > > >>> Sent: Tuesday, September 17, 2024 3:11 AM > > > > >>> To: jerinj@marvell.com; sthotton@marvell.com; Sevincer, > > > > >>> Abdullah <abdullah.sevincer@intel.com>; > > > > >>> hemant.agrawal@nxp.com; sachin.saxena@oss.nxp.com; Van > Haaren, > > > > >>> Harry > > > > >> <harry.van.haaren@intel.com>; > > > > >>> mattias.ronnblom@ericsson.com; liangma@liangbit.com; Mccarthy, > > > > >>> Peter <peter.mccarthy@intel.com> > > > > >>> Cc: dev@dpdk.org; Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > >>> Subject: [PATCH v2 1/3] eventdev: introduce event > > > > >>> pre-scheduling > > > > >>> > > > > >>> From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > >>> > > > > >>> Event pre-scheduling improves scheduling performance by > > > > >>> assigning > > > > events > > > > >> to > > > > >>> event ports in advance when dequeues are issued. > > > > >>> The dequeue operation initiates the pre-schedule operation, > > > > >>> which > > > > >> completes in > > > > >>> parallel without affecting the dequeued event flow contexts > > > > >>> and dequeue latency. > > > > >>> > > > > >> Is the prescheduling done to get the event more quickly in the > > > > >> next > > > > dequeue? > > > > >> The first dequeue executes pre-schedule to make events > > > > >> available for the > > > > next > > > > >> dequeue. > > > > >> Is this how it is supposed to work? > > > > >> > > > > > > > > > > Yes, that is correct. > > > > > > > > > > > > > "improves scheduling performance" may be a bit misleading, in that case. > > > > I suggest "reduces scheduling overhead" instead. You can argue it > > > > likely reduces scheduling performance, in certain scenarios. > > > > "reduces scheduling overhead, at the cost of load balancing > performance." > > > > > > > > > > In case of OCTEON, we see double the scheduling performance with > > > prescheduling without effecting any priority/weight aspects. > > > > > > > It seems to me that this should be a simple hint-type API, where > > > > the hint is used by the event device to decide if pre-scheduling > > > > should be used or not (assuming pre-scheduling on/off is even an > > > > option). The hint would just be a way for the application to > > > > express whether or not it want the scheduler to prioritize load > > > > balancing agility and port-to-port wall-time latency, or > > > > scheduling overhead, which in turn could potentially be rephrased > > > > as the app being throughput or latency/RT- > > > oriented. > > > > > > > > > > The three prescheduling types are designed based on real world > > > use-cases > > that > > > some of our customers require in their applications. > > > Relying on application to provide hits might not be possible in all > > > the cases as > > it > > > is very timing sensitive. > > > > > > > > > > It could also be useful for the event device to know which > > > > priority levels are to be considered latency-sensitive, and which > > > > are throughput-oriented - maybe in the form of a threshold. > > > > > > > > >>> Event devices can indicate pre-scheduling capabilities using > > > > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > > > > >>> `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the > > event > > > > >> device > > > > >>> info function `info.event_dev_cap`. > > > > What is PRESCHEDULE_ADAPTIVE? Can you please add more description? > > Unlike raw PRESCHEDULE where every dequeue triggers a pre-scheduling > request in parallel, PRESCHEDULE_ADAPTIVE will delay issuing pre-scheduling > till event device knows that the currently scheduled context can make forward > progress. > For example, in OCTEON HW does it when it sees that scheduling context held > by the port is top/head of the flow. So adaptive can be used by different HWs to handle preschedule dynamically based on Their implementation. The end aim is to balance fair load balancing and throughput. Is this understanding correct? I am thinking of using these for DLB if possible. > > > This will be more useful as per port configuration instead of > > device-level configuration. > > In the patch 2/3 I introduced port level API to control prefetches at an event > port level. So is device level configuration a default value for all Eventdev ports and it can be changed At runtime using port level APIs? This will be nice. > > It is not a port configuration API because Applications might want to > enable/disable prefetching in fastpath. Example use cases we see is to disable > pre-scheduling when application wants to preempt an lcore and reenable it at > a later point of time. > > > > The application can choose a type based on its requirement on the port > > it is serving. > > As Mattias suggested, if this is made HINT flag for port > > configuration, other PMDs can Ignore it based on either they may not > > need it depending on their architecture or not support it. > > > > If PMDs support preschedules then it has to advertise via capabilities, silently > ignoring feature configuration is bad. > > We can make the fastpath APIs as hints. > > > > > > > >>> > > > > >>> Applications can select the pre-schedule type and configure it > > > > >>> through `rte_event_dev_config.preschedule_type` during > > > > `rte_event_dev_configure`. > > > > >>> > > > > >>> The supported pre-schedule types are: > > > > >>> * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > > > > >>> * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule > > > > >>> on > > > > >> dequeue. > > > > >>> * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre- > > > > schedule > > > > >>> until > > > > >>> there are no forward progress constraints with the held > > > > >>> flow > > contexts. > > > > >>> > > > > >>> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > >>> --- > > > > >>> app/test/test_eventdev.c | 63 +++++++++++++++++++++ > > > > >>> doc/guides/prog_guide/eventdev/eventdev.rst | 22 +++++++ > > > > >>> lib/eventdev/rte_eventdev.h | 48 ++++++++++++++++ > > > > >>> 3 files changed, 133 insertions(+) > > > > >>> > > > > >>> diff --git a/app/test/test_eventdev.c > > > > >>> b/app/test/test_eventdev.c index e4e234dc98..cf496ee88d 100644 > > > > >>> --- a/app/test/test_eventdev.c > > > > >>> +++ b/app/test/test_eventdev.c > > > > >>> @@ -1250,6 +1250,67 @@ test_eventdev_profile_switch(void) > > > > >>> return TEST_SUCCESS; > > > > >>> } > > > > >>> > > > > >>> +static int > > > > >>> +preschedule_test(rte_event_dev_preschedule_type_t > > > > >>> +preschedule_type, const char *preschedule_name) { > > > > >>> +#define NB_EVENTS 1024 > > > > >>> + uint64_t start, total; > > > > >>> + struct rte_event ev; > > > > >>> + int rc, cnt; > > > > >>> + > > > > >>> + ev.event_type = RTE_EVENT_TYPE_CPU; > > > > >>> + ev.queue_id = 0; > > > > >>> + ev.op = RTE_EVENT_OP_NEW; > > > > >>> + ev.u64 = 0xBADF00D0; > > > > >>> + > > > > >>> + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > > > > >>> + ev.flow_id = cnt; > > > > >>> + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, > > 1); > > > > >>> + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > > > > >>> + } > > > > >>> + > > > > >>> + RTE_SET_USED(preschedule_type); > > > > >>> + total = 0; > > > > >>> + while (cnt) { > > > > >>> + start = rte_rdtsc_precise(); > > > > >>> + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, > > 1, 0); > > > > >>> + if (rc) { > > > > >>> + total += rte_rdtsc_precise() - start; > > > > >>> + cnt--; > > > > >>> + } > > > > >>> + } > > > > >>> + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", > > > > >>> preschedule_name, > > > > >>> + total / NB_EVENTS); > > > > >>> + > > > > >>> + return TEST_SUCCESS; > > > > >>> +} > > > > >>> + > > > > >>> +static int > > > > >>> +test_eventdev_preschedule_configure(void) > > > > >>> +{ > > > > >>> + struct rte_event_dev_config dev_conf; > > > > >>> + struct rte_event_dev_info info; > > > > >>> + int rc; > > > > >>> + > > > > >>> + rte_event_dev_info_get(TEST_DEV_ID, &info); > > > > >>> + > > > > >>> + if ((info.event_dev_cap & > > > > >> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) > > > > >>> == 0) > > > > >>> + return TEST_SKIPPED; > > > > >>> + > > > > >>> + devconf_set_default_sane_values(&dev_conf, &info); > > > > >>> + dev_conf.preschedule_type = > > RTE_EVENT_DEV_PRESCHEDULE; > > > > >>> + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); > > > > >>> + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); > > > > >>> + > > > > >>> + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, > > > > >>> "RTE_EVENT_DEV_PRESCHEDULE_NONE"); > > > > >>> + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, > > > > >>> "RTE_EVENT_DEV_PRESCHEDULE"); > > > > >>> + if (info.event_dev_cap & > > > > >>> RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) > > > > >>> + rc |= > > > > >>> preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > > > >>> + > > > > >>> "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); > > > > >>> + > > > > >>> + return rc; > > > > >>> +} > > > > >>> + > > > > >>> static int > > > > >>> test_eventdev_close(void) > > > > >>> { > > > > >>> @@ -1310,6 +1371,8 @@ static struct unit_test_suite > > > > >>> eventdev_common_testsuite = { > > > > >>> test_eventdev_start_stop), > > > > >>> TEST_CASE_ST(eventdev_configure_setup, > > > > >>> eventdev_stop_device, > > > > >>> test_eventdev_profile_switch), > > > > >>> + TEST_CASE_ST(eventdev_configure_setup, NULL, > > > > >>> + test_eventdev_preschedule_configure), > > > > >>> TEST_CASE_ST(eventdev_setup_device, > > > > >> eventdev_stop_device, > > > > >>> test_eventdev_link), > > > > >>> TEST_CASE_ST(eventdev_setup_device, > > > > >> eventdev_stop_device, > > > > >>> diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst > > > > >>> b/doc/guides/prog_guide/eventdev/eventdev.rst > > > > >>> index fb6dfce102..341b9bb2c6 100644 > > > > >>> --- a/doc/guides/prog_guide/eventdev/eventdev.rst > > > > >>> +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > > > > >>> @@ -357,6 +357,28 @@ Worker path: > > > > >>> // Process the event received. > > > > >>> } > > > > >>> > > > > >>> +Event Pre-scheduling > > > > >>> +~~~~~~~~~~~~~~~~~~~~ > > > > >>> + > > > > >>> +Event pre-scheduling improves scheduling performance by > > > > >>> +assigning events to event ports in advance when dequeues are > issued. > > > > >>> +The `rte_event_dequeue_burst` operation initiates the > > > > >>> +pre-schedule operation, which completes in parallel without > > > > >>> +affecting the dequeued > > > > >> event > > > > >>> flow contexts and dequeue latency. > > > > >>> +On the next dequeue operation, the pre-scheduled events are > > > > >>> +dequeued and pre-schedule is initiated again. > > > > >>> + > > > > >>> +An application can use event pre-scheduling if the event > > > > >>> +device supports it at either device level or at a individual port level. > > > > >>> +The application can check pre-schedule capability by checking > > > > >>> +if ``rte_event_dev_info.event_dev_cap`` > > > > >>> +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present > > > > >>> +pre-scheduling can be enabled at device configuration time by > > > > >>> +setting > > > > >>> appropriate pre-schedule type in > > ``rte_event_dev_config.preschedule``. > > > > >>> + > > > > >>> +Currently, the following pre-schedule types are supported: > > > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > > > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a > > > > >>> +pre-schedule when > > > > >>> dequeue is issued. > > > > >>> + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue > > > > >>> + pre-schedule > > > > when > > > > >>> dequeue is issued and there are > > > > >>> + no forward progress constraints. > > > > >>> + > > > > >>> Starting the EventDev > > > > >>> ~~~~~~~~~~~~~~~~~~~~~ > > > > >>> > > > > >>> diff --git a/lib/eventdev/rte_eventdev.h > > > > >>> b/lib/eventdev/rte_eventdev.h > > > > >> index > > > > >>> 08e5f9320b..5ea7f5a07b 100644 > > > > >>> --- a/lib/eventdev/rte_eventdev.h > > > > >>> +++ b/lib/eventdev/rte_eventdev.h > > > > >>> @@ -446,6 +446,30 @@ struct rte_event; > > > > >>> * @see RTE_SCHED_TYPE_PARALLEL > > > > >>> */ > > > > >>> > > > > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) > > > /**< > > > > >> Event > > > > >>> +device supports event pre-scheduling. > > > > >>> + * > > > > >>> + * When this capability is available, the application can > > > > >>> +enable event pre-scheduling on the event > > > > >>> + * device to pre-schedule events to a event port when > > > > >>> +`rte_event_dequeue_burst()` > > > > >>> + * is issued. > > > > >>> + * The pre-schedule process starts with the > > > > >>> +`rte_event_dequeue_burst()` call and the > > > > >>> + * pre-scheduled events are returned on the next > > > > >> `rte_event_dequeue_burst()` > > > > >>> call. > > > > >>> + * > > > > >>> + * @see rte_event_dev_configure() */ > > > > >>> + > > > > >>> +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > (1ULL > > > > << > > > > >> 17) > > > > >>> /**< > > > > >>> +Event device supports adaptive event pre-scheduling. > > > > >>> + * > > > > >>> + * When this capability is available, the application can > > > > >>> +enable adaptive pre-scheduling > > > > >>> + * on the event device where the events are pre-scheduled > > > > >>> +when there are no forward > > > > >>> + * progress constraints with the currently held flow contexts. > > > > >>> + * The pre-schedule process starts with the > > > > >>> +`rte_event_dequeue_burst()` call and the > > > > >>> + * pre-scheduled events are returned on the next > > > > >> `rte_event_dequeue_burst()` > > > > >>> call. > > > > >>> + * > > > > >>> + * @see rte_event_dev_configure() */ > > > > >>> + > > > > >>> /* Event device priority levels */ > > > > >>> #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > > > > >>> /**< Highest priority level for events and queues. > > > > >>> @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, > > > > uint32_t > > > > >>> attr_id, > > > > >>> * @see rte_event_dequeue_timeout_ticks(), > > > > rte_event_dequeue_burst() > > > > >>> */ > > > > >>> > > > > >>> +typedef enum { > > > > >>> + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > > > > >>> + /* Disable pre-schedule across the event device or on a > > > > >>> +given event > > > > >> port. > > > > >>> + * @ref rte_event_dev_config.preschedule_type > > > > >>> + */ > > > > >>> + RTE_EVENT_DEV_PRESCHEDULE, > > > > >>> + /* Enable pre-schedule always across the event device or a > > given > > > > >>> +event > > > > >>> port. > > > > >>> + * @ref rte_event_dev_config.preschedule_type > > > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > > > >>> + */ > > > > >>> + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > > > > >>> + /* Enable adaptive pre-schedule across the event device or a > > > > >>> +given > > > > >> event > > > > >>> port. > > > > >>> + * Delay issuing pre-schedule until there are no forward > > > > >>> +progress > > > > >>> constraints with > > > > >>> + * the held flow contexts. > > > > >>> + * @ref rte_event_dev_config.preschedule_type > > > > >>> + * @see > > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > > > >>> + */ > > > > >>> +} rte_event_dev_preschedule_type_t; > > > > >>> + > > > > >>> /** Event device configuration structure */ struct > > > rte_event_dev_config { > > > > >>> uint32_t dequeue_timeout_ns; @@ -752,6 +795,11 @@ > struct > > > > >>> rte_event_dev_config { > > > > >>> * optimized for single-link usage, this field is a hint > > > > >>> for how > > many > > > > >>> * to allocate; otherwise, regular event ports and queues > > > > >>> will > > be used. > > > > >>> */ > > > > >>> + rte_event_dev_preschedule_type_t preschedule_type; > > > > >>> + /**< Event pre-schedule type to use across the event device, > > > > >>> +if > > > > >>> supported. > > > > >>> + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > > > > >>> + * @see > > RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > > > > >>> + */ > > > > >>> }; > > > > >>> > > > > >>> /** > > > > >>> -- > > > > >>> 2.25.1 > > > > > ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2 2/3] eventdev: add event port pre-schedule modify 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula 2024-09-17 7:11 ` [PATCH v2 1/3] eventdev: introduce " pbhagavatula @ 2024-09-17 7:11 ` pbhagavatula 2024-09-17 7:11 ` [PATCH v2 3/3] eventdev: add SW event preschedule hint pbhagavatula 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula 3 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-17 7:11 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 61 +++++++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 12 ++++ lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 10 ++++ lib/eventdev/eventdev_trace_points.c | 3 + lib/eventdev/rte_eventdev.h | 55 +++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 6 ++ lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 9 files changed, 158 insertions(+), 6 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index cf496ee88d..6c799e3d11 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,7 +1251,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name) +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1269,7 +1270,11 @@ preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char * TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1302,11 +1307,55 @@ test_eventdev_preschedule_configure(void) rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE"); - rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE", 0); + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE", 0); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE", 0); + + return rc; +} + +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + devconf_set_default_sane_values(&dev_conf, &info); + dev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_NONE; + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE", 1); + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE", 1); + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + rc |= preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE", 1); return rc; } @@ -1373,6 +1422,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 341b9bb2c6..2deab0333e 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -379,6 +379,18 @@ Currently, the following pre-schedule types are supported: * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +To enable or disable event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..f0aae766ea 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,14 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +122,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +145,6 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 5ea7f5a07b..0add0093ac 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -708,18 +718,23 @@ typedef enum { RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, /* Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_DEV_PRESCHEDULE, /* Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE */ RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, /* Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE */ } rte_event_dev_preschedule_type_t; @@ -2922,6 +2937,46 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Change the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + */ +static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + rte_event_dev_preschedule_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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..2275888a6b 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + rte_event_dev_preschedule_type_t preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,6 +80,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v2 3/3] eventdev: add SW event preschedule hint 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula 2024-09-17 7:11 ` [PATCH v2 1/3] eventdev: introduce " pbhagavatula 2024-09-17 7:11 ` [PATCH v2 2/3] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-09-17 7:11 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula 3 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-09-17 7:11 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 8 ++++ lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 12 ++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 5 +++ lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 8 files changed, 87 insertions(+), 2 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 2deab0333e..1d8b86ab66 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -390,6 +390,14 @@ To enable or disable event pre-scheduling at a given event port, the application // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Event Pre-schedule Hint can be used to provide a hint to the eventdev PMD to pre-schedule 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_PRESCHEDULE`` capability flag. +If pre-scheduling is already enabled at a event device or event port level then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index f0aae766ea..ed6e12dece 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -104,6 +104,13 @@ dummy_event_port_preschedule_modify(__rte_unused void *port, return -EINVAL; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -117,12 +124,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -146,5 +153,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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 0add0093ac..8df6a8bee1 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_SW_PRESCHEDULE (1ULL << 19) +/**< Event device supports software prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* 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_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability. + * + * When pre-scheduling is enabled at an event device or event port level, the + * hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, rte_event_dev_preschedule_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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 2275888a6b..21988abb4f 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,9 @@ typedef int (*event_preschedule_modify_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,6 +85,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 0/6] Introduce event pre-scheduling 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula ` (2 preceding siblings ...) 2024-09-17 7:11 ` [PATCH v2 3/3] eventdev: add SW event preschedule hint pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 1/6] eventdev: introduce " pbhagavatula ` (6 more replies) 3 siblings, 7 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_DEV_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_DEV_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_SW_PRESCHEDULE` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add SW event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 ++++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 42 +++++ doc/guides/rel_notes/release_24_11.rst | 11 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 40 ++++- drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 152 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 11 ++ lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 26 files changed, 573 insertions(+), 18 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 1/6] eventdev: introduce event pre-scheduling 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (5 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 22 ++++ doc/guides/rel_notes/release_24_11.rst | 8 ++ lib/eventdev/rte_eventdev.h | 48 +++++++++ 5 files changed, 187 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index e4e234dc98..d75fc8fbbc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1250,6 +1250,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(rte_event_dev_preschedule_type_t type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS( + rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1310,6 +1416,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 1cc4303fe5..c8d5ed2d74 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -22,6 +22,7 @@ carry_flow_id = maintenance_free = runtime_queue_attr = profile_links = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..341b9bb2c6 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,28 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application can check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +Currently, the following pre-schedule types are supported: + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 0ff70d9057..eae5cc326b 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -55,6 +55,14 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..5ea7f5a07b 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +typedef enum { + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, + /* Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_DEV_PRESCHEDULE, + /* Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + /* Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +} rte_event_dev_preschedule_type_t; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +795,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + rte_event_dev_preschedule_type_t preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 2/6] eventdev: add event port pre-schedule modify 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-01 6:14 ` [PATCH v3 1/6] eventdev: introduce " pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 3/6] eventdev: add SW event preschedule hint pbhagavatula ` (4 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 +++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 12 +++++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 ++++++++ lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 55 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 6 +++ lib/eventdev/rte_eventdev_trace_fp.h | 11 ++++- lib/eventdev/version.map | 4 ++ 10 files changed, 154 insertions(+), 6 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index d75fc8fbbc..af3ab689b5 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,7 +1251,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name) +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1269,7 +1270,11 @@ preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char * TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1334,13 +1339,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1348,7 +1353,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS( rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); } @@ -1356,6 +1361,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_DEV_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_DEV_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1418,6 +1451,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 341b9bb2c6..2deab0333e 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -379,6 +379,18 @@ Currently, the following pre-schedule types are supported: * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +To enable or disable event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index eae5cc326b..6e36ac7b7e 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -62,6 +62,8 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. Removed Items diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..dc37f736f8 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 5ea7f5a07b..0add0093ac 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -708,18 +718,23 @@ typedef enum { RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, /* Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_DEV_PRESCHEDULE, /* Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE */ RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, /* Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE */ } rte_event_dev_preschedule_type_t; @@ -2922,6 +2937,46 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Change the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + */ +static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + rte_event_dev_preschedule_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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..2275888a6b 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + rte_event_dev_preschedule_type_t preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,6 +80,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 3/6] eventdev: add SW event preschedule hint 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-01 6:14 ` [PATCH v3 1/6] eventdev: introduce " pbhagavatula 2024-10-01 6:14 ` [PATCH v3 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (3 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 8 ++++ doc/guides/rel_notes/release_24_11.rst | 3 +- lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 5 +++ lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 98 insertions(+), 3 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 2deab0333e..1d8b86ab66 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -390,6 +390,14 @@ To enable or disable event pre-scheduling at a given event port, the application // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Event Pre-schedule Hint can be used to provide a hint to the eventdev PMD to pre-schedule 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_PRESCHEDULE`` capability flag. +If pre-scheduling is already enabled at a event device or event port level then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 6e36ac7b7e..3ada21c084 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -64,7 +64,8 @@ New Features level pre-scheduling type. * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. - + * Added ``rte_event_port_preschedule`` to allow applications to decide when + to pre-schedule events on an event port. Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index dc37f736f8..6aed1cba9a 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint(__rte_unused void *port, return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 0add0093ac..8df6a8bee1 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_SW_PRESCHEDULE (1ULL << 19) +/**< Event device supports software prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* 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_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability. + * + * When pre-scheduling is enabled at an event device or event port level, the + * hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, rte_event_dev_preschedule_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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 2275888a6b..21988abb4f 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,9 @@ typedef int (*event_preschedule_modify_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,6 +85,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 4/6] event/cnkx: add pre-schedule support 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula ` (2 preceding siblings ...) 2024-10-01 6:14 ` [PATCH v3 3/6] eventdev: add SW event preschedule hint pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (2 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 40 ++++++++++++++++++++++++-- drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..0624f29a90 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -18,6 +18,27 @@ #define CN10K_SET_EVDEV_ENQ_OP(dev, enq_op, enq_ops) \ enq_op = enq_ops[dev->tx_offloads & (NIX_TX_OFFLOAD_MAX - 1)] +static int +cn10k_sso_hws_preschedule_modify(void *port, rte_event_dev_preschedule_type_t type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= (BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_DEV_PRESCHEDULE_NONE: + break; + case RTE_EVENT_DEV_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} + static uint32_t cn10k_sso_gw_mode_wdata(struct cnxk_sso_evdev *dev) { @@ -527,6 +548,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +563,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +591,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_DEV_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_DEV_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1237,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1293,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 5/6] app/test-eventdev: add pre-scheduling support 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula ` (3 preceding siblings ...) 2024-10-01 6:14 ` [PATCH v3 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 6:14 ` [PATCH v3 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..176c077e51 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_DEV_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v3 6/6] examples: use eventdev pre-scheduling 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula ` (4 preceding siblings ...) 2024-10-01 6:14 ` [PATCH v3 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-01 6:14 ` pbhagavatula 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 6:14 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 783f68c91e..8052e2df86 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -188,6 +188,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..077b902bdb 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..61133607d6 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d5a3cd9984 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..0b619afe91 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..333c87b01c 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..32354fc09f 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 0/6] Introduce event pre-scheduling 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula ` (5 preceding siblings ...) 2024-10-01 6:14 ` [PATCH v3 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-01 13:18 ` pbhagavatula 2024-10-01 13:18 ` [PATCH v4 1/6] eventdev: introduce " pbhagavatula ` (7 more replies) 6 siblings, 8 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:18 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_DEV_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_DEV_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_SW_PRESCHEDULE` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. v4 Changes: - Fix compilation. Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add SW event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 ++++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/cnxk.rst | 10 -- doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 42 +++++ doc/guides/rel_notes/release_24_11.rst | 11 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 19 ++- drivers/event/cnxk/cn10k_worker.c | 21 +++ drivers/event/cnxk/cn10k_worker.h | 1 + drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 152 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 11 ++ lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 29 files changed, 574 insertions(+), 28 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 1/6] eventdev: introduce event pre-scheduling 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula @ 2024-10-01 13:18 ` pbhagavatula 2024-10-04 4:47 ` Jerin Jacob 2024-10-01 13:18 ` [PATCH v4 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (6 subsequent siblings) 7 siblings, 1 reply; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:18 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 22 ++++ doc/guides/rel_notes/release_24_11.rst | 8 ++ lib/eventdev/rte_eventdev.h | 48 +++++++++ 5 files changed, 187 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index e4e234dc98..d75fc8fbbc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1250,6 +1250,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(rte_event_dev_preschedule_type_t type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS( + rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1310,6 +1416,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 1cc4303fe5..c8d5ed2d74 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -22,6 +22,7 @@ carry_flow_id = maintenance_free = runtime_queue_attr = profile_links = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..341b9bb2c6 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,28 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application can check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +Currently, the following pre-schedule types are supported: + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 0ff70d9057..eae5cc326b 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -55,6 +55,14 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..5ea7f5a07b 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,25 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +typedef enum { + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, + /* Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_DEV_PRESCHEDULE, + /* Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + /* Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +} rte_event_dev_preschedule_type_t; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +795,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + rte_event_dev_preschedule_type_t preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 1/6] eventdev: introduce event pre-scheduling 2024-10-01 13:18 ` [PATCH v4 1/6] eventdev: introduce " pbhagavatula @ 2024-10-04 4:47 ` Jerin Jacob 0 siblings, 0 replies; 77+ messages in thread From: Jerin Jacob @ 2024-10-04 4:47 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev On Tue, Oct 1, 2024 at 7:44 PM <pbhagavatula@marvell.com> wrote: > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Event pre-scheduling improves scheduling performance by assigning events > to event ports in advance when dequeues are issued. > The dequeue operation initiates the pre-schedule operation, which completes > in parallel without affecting the dequeued event flow contexts and > dequeue latency. > > Event devices can indicate pre-scheduling capabilities using > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info > function `info.event_dev_cap`. > > Applications can select the pre-schedule type and configure it through > `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. > > The supported pre-schedule types are: > * `RTE_EVENT_DEV_PRESCHEDULE_NONE` - No pre-scheduling. > * `RTE_EVENT_DEV_PRESCHEDULE` - Always issue a pre-schedule on dequeue. > * `RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until > there are no forward progress constraints with the held flow contexts. > > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> eventdev PMD maintainers, Is anyone planning to review this series more? The general outlook of the patch looks good to me. I will have a few minor comments. If there are no other comments, I will merge early next week as RC1 PR. > --- > app/test/test_eventdev.c | 108 ++++++++++++++++++++ > doc/guides/eventdevs/features/default.ini | 1 + > doc/guides/prog_guide/eventdev/eventdev.rst | 22 ++++ > doc/guides/rel_notes/release_24_11.rst | 8 ++ > lib/eventdev/rte_eventdev.h | 48 +++++++++ > 5 files changed, 187 insertions(+) > > > +Event Pre-scheduling > +~~~~~~~~~~~~~~~~~~~~ > + > +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance > +when dequeues are issued. > +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes > +in parallel without affecting the dequeued event flow contexts and dequeue latency. > +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated > +again. > + > +An application can use event pre-scheduling if the event device supports it at either device > +level or at a individual port level. > +The application can check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` can -> must > +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` set, if present pre-scheduling can be enabled at device > +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. Missing RTE_EVENT_DEV_CAP_PRESCHEDULE_ADAPTIVE cap doc. > + > +Currently, the following pre-schedule types are supported: I think, we can remove “Currently” > + * ``RTE_EVENT_DEV_PRESCHEDULE_NONE`` - No pre-scheduling. > + * ``RTE_EVENT_DEV_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. > + * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are > + no forward progress constraints. > + > > +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) > +/**< Event device supports event pre-scheduling. > + * > + * When this capability is available, the application can enable event pre-scheduling on the event > + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` > + * is issued. > + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the > + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. > + * > + * @see rte_event_dev_configure() > + */ Doxygen for the new enum is missing. > > +typedef enum { > + RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, Explicit 0 is not needed. > + /* Disable pre-schedule across the event device or on a given event port. Use Doxygen format across the series, i.e /**< > + * @ref rte_event_dev_config.preschedule_type > + */ > + RTE_EVENT_DEV_PRESCHEDULE, > + /* Enable pre-schedule always across the event device or a given event port. > + * @ref rte_event_dev_config.preschedule_type > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > + */ > + RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > + /* Enable adaptive pre-schedule across the event device or a given event port. > + * Delay issuing pre-schedule until there are no forward progress constraints with > + * the held flow contexts. > + * @ref rte_event_dev_config.preschedule_type > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > + */ > +} rte_event_dev_preschedule_type_t; > + > /** Event device configuration structure */ > struct rte_event_dev_config { > uint32_t dequeue_timeout_ns; > @@ -752,6 +795,11 @@ struct rte_event_dev_config { > * optimized for single-link usage, this field is a hint for how many > * to allocate; otherwise, regular event ports and queues will be used. > */ > + rte_event_dev_preschedule_type_t preschedule_type; Please add ABI changes in doc/guides/rel_notes/release_24_11.rst > + /**< Event pre-schedule type to use across the event device, if supported. > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > + */ > }; > > /** > -- > 2.25.1 > ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 2/6] eventdev: add event port pre-schedule modify 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-01 13:18 ` [PATCH v4 1/6] eventdev: introduce " pbhagavatula @ 2024-10-01 13:18 ` pbhagavatula 2024-10-04 5:02 ` Jerin Jacob 2024-10-01 13:18 ` [PATCH v4 3/6] eventdev: add SW event preschedule hint pbhagavatula ` (5 subsequent siblings) 7 siblings, 1 reply; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:18 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 +++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 12 +++++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 ++++++++ lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 55 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 6 +++ lib/eventdev/rte_eventdev_trace_fp.h | 11 ++++- lib/eventdev/version.map | 4 ++ 10 files changed, 154 insertions(+), 6 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index d75fc8fbbc..af3ab689b5 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,7 +1251,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name) +preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1269,7 +1270,11 @@ preschedule_test(rte_event_dev_preschedule_type_t preschedule_type, const char * TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1334,13 +1339,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1348,7 +1353,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS( rc, "Failed to test preschedule RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); } @@ -1356,6 +1361,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_DEV_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_NONE, "RTE_EVENT_DEV_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_DEV_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE, "RTE_EVENT_DEV_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_DEV_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1418,6 +1451,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 341b9bb2c6..2deab0333e 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -379,6 +379,18 @@ Currently, the following pre-schedule types are supported: * ``RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +To enable or disable event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index eae5cc326b..6e36ac7b7e 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -62,6 +62,8 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. Removed Items diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..dc37f736f8 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 5ea7f5a07b..0add0093ac 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -708,18 +718,23 @@ typedef enum { RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, /* Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_DEV_PRESCHEDULE, /* Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE */ RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, /* Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE */ } rte_event_dev_preschedule_type_t; @@ -2922,6 +2937,46 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Change the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + */ +static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + rte_event_dev_preschedule_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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..2275888a6b 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + rte_event_dev_preschedule_type_t preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,6 +80,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 2/6] eventdev: add event port pre-schedule modify 2024-10-01 13:18 ` [PATCH v4 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-04 5:02 ` Jerin Jacob 0 siblings, 0 replies; 77+ messages in thread From: Jerin Jacob @ 2024-10-04 5:02 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev On Tue, Oct 1, 2024 at 7:14 PM <pbhagavatula@marvell.com> wrote: > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Some event devices allow pre-schedule types to be modified at > runtime on an event port. > Add `RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE` capability > to indicate that the event device supports this feature. > > Add `rte_event_port_preschedule_modify()` API to modify the > pre-schedule type at runtime. > > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > > +To enable or disable event pre-scheduling at a given event port, the application can use > +``rte_event_port_preschedule_modify()`` API. # Talk about RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE capability. # Also tell this is HINT. i.e application does not need to check this cap in fast path. > + > +.. code-block:: c > + > + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); > + // Dequeue events from the event port with normal dequeue() function. > + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE_NONE); > + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain > + // pending events. > + > + > Starting the EventDev > ~~~~~~~~~~~~~~~~~~~~~ > > diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst > index eae5cc326b..6e36ac7b7e 100644 > --- a/doc/guides/rel_notes/release_24_11.rst > +++ b/doc/guides/rel_notes/release_24_11.rst > @@ -62,6 +62,8 @@ New Features > > * Added ``rte_event_dev_config::preschedule_type`` to configure the device > level pre-scheduling type. > + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type > + on a given event port. > > > Removed Items > diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h > index 7a5699f14b..9ea23aa6cd 100644 > --- a/lib/eventdev/eventdev_pmd.h > +++ b/lib/eventdev/eventdev_pmd.h > @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { > /**< Pointer to PMD DMA adapter enqueue function. */ > event_profile_switch_t profile_switch; > /**< Pointer to PMD Event switch profile function. */ > + event_preschedule_modify_t preschedule_modify; > + /**< Pointer to PMD Event port pre-schedule type modify function. */ > > uint64_t reserved_64s[3]; /**< Reserved for future fields */ > void *reserved_ptrs[3]; /**< Reserved for future fields */ > diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c > index 017f97ccab..dc37f736f8 100644 > --- a/lib/eventdev/eventdev_private.c > +++ b/lib/eventdev/eventdev_private.c > @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr > return -EINVAL; > } > > diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c > index 8024e07531..e41674123c 100644 > --- a/lib/eventdev/eventdev_trace_points.c > +++ b/lib/eventdev/eventdev_trace_points.c > @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, > RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, > lib.eventdev.port.profile.switch) > > +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, > + lib.eventdev.port.preschedule.modify) > + > /* Eventdev Rx adapter trace points */ > RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, > lib.eventdev.rx.adapter.create) > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h > index 5ea7f5a07b..0add0093ac 100644 > --- a/lib/eventdev/rte_eventdev.h > +++ b/lib/eventdev/rte_eventdev.h > @@ -470,6 +470,16 @@ struct rte_event; > * @see rte_event_dev_configure() > */ > > +#define RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE (1ULL << 18) > +/**< Event device supports event pre-scheduling per event port. > + * > + * When this flag is set, the event device allows controlling the event > + * pre-scheduling at a event port granularity. Tell it is HINT. > + * > + * @see rte_event_dev_configure() > + * @see rte_event_port_preschedule_modify() > + */ > + > /* Event device priority levels */ > #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 > /**< Highest priority level for events and queues. > @@ -708,18 +718,23 @@ typedef enum { > RTE_EVENT_DEV_PRESCHEDULE_NONE = 0, > /* Disable pre-schedule across the event device or on a given event port. > * @ref rte_event_dev_config.preschedule_type > + * @ref rte_event_port_preschedule_modify() > */ > RTE_EVENT_DEV_PRESCHEDULE, > /* Enable pre-schedule always across the event device or a given event port. > * @ref rte_event_dev_config.preschedule_type > + * @ref rte_event_port_preschedule_modify() > * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE > + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE > */ > RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE, > /* Enable adaptive pre-schedule across the event device or a given event port. > * Delay issuing pre-schedule until there are no forward progress constraints with > * the held flow contexts. > * @ref rte_event_dev_config.preschedule_type > + * @ref rte_event_port_preschedule_modify() > * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE > + * @see RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE > */ > } rte_event_dev_preschedule_type_t; > > @@ -2922,6 +2937,46 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i > return fp_ops->profile_switch(port, profile_id); > } > > +/** > + * Change the pre-schedule type to use on an event port. Modify the pre-schedule of the given event port ? > + * > + * This function is used to change the current pre-schedule type configured > + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. > + * This effects the subsequent ``rte_event_dequeue_burst`` call. > + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. Tell it is HINT and the application does not need to check the capa > + * > + * @param dev_id > + * The identifier of the device. > + * @param port_id > + * The identifier of the event port. > + * @param type > + * The preschedule type to use on the event port. > + * @return > + * - 0 on success. > + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. > + */ > +static inline int > +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, > + rte_event_dev_preschedule_type_t type) Remove rte_event_dev_preschedule_type_t and use enum rte_event_dev_preschedule_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 -EINVAL; > + > + if (port == NULL) > + return -EINVAL; > +#endif > + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); > + > + return fp_ops->preschedule_modify(port, type); > +} > + > #ifdef __cplusplus > } > #endif > diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h > index fc8e1556ab..2275888a6b 100644 > --- a/lib/eventdev/rte_eventdev_core.h > +++ b/lib/eventdev/rte_eventdev_core.h > @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ > typedef int (*event_profile_switch_t)(void *port, uint8_t profile); > /**< @internal Switch active link profile on the event port. */ > > +typedef int (*event_preschedule_modify_t)(void *port, > + rte_event_dev_preschedule_type_t preschedule_type); > +/**< @internal Modify pre-schedule type on the event port. */ > + > struct __rte_cache_aligned rte_event_fp_ops { > void **data; > /**< points to array of internal port data pointers */ > @@ -76,6 +80,8 @@ struct __rte_cache_aligned rte_event_fp_ops { > /**< PMD DMA adapter enqueue function. */ > event_profile_switch_t profile_switch; > /**< PMD Event switch profile function. */ > + event_preschedule_modify_t preschedule_modify; > + /**< PMD Event port pre-schedule switch. */ Use reserved not to break ABI > uintptr_t reserved[4]; > }; > > diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h > index 04d510ad00..78baed94de 100644 > --- a/lib/eventdev/rte_eventdev_trace_fp.h > +++ b/lib/eventdev/rte_eventdev_trace_fp.h > @@ -8,7 +8,7 @@ > /** > * @file > * > - * API for ethdev trace support > + * API for eventdev trace support > */ > > #ifdef __cplusplus > @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( > rte_trace_point_emit_u8(profile); > ) > > +RTE_TRACE_POINT_FP( > + rte_eventdev_trace_port_preschedule_modify, > + 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, > diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map > index 4947bb4ec6..b6d63ba576 100644 > --- a/lib/eventdev/version.map > +++ b/lib/eventdev/version.map > @@ -147,6 +147,10 @@ EXPERIMENTAL { > rte_event_port_profile_unlink; > rte_event_port_profile_links_get; > __rte_eventdev_trace_port_profile_switch; > + > + # added in 24.11 > + rte_event_port_preschedule_modify; > + __rte_eventdev_trace_port_preschedule_modify; > }; > > INTERNAL { > -- > 2.25.1 > ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 3/6] eventdev: add SW event preschedule hint 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-01 13:18 ` [PATCH v4 1/6] eventdev: introduce " pbhagavatula 2024-10-01 13:18 ` [PATCH v4 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-01 13:18 ` pbhagavatula 2024-10-04 5:14 ` Jerin Jacob 2024-10-01 13:18 ` [PATCH v4 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (4 subsequent siblings) 7 siblings, 1 reply; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:18 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 8 ++++ doc/guides/rel_notes/release_24_11.rst | 3 +- lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 5 +++ lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 98 insertions(+), 3 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 2deab0333e..1d8b86ab66 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -390,6 +390,14 @@ To enable or disable event pre-scheduling at a given event port, the application // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Event Pre-schedule Hint can be used to provide a hint to the eventdev PMD to pre-schedule 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_PRESCHEDULE`` capability flag. +If pre-scheduling is already enabled at a event device or event port level then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 6e36ac7b7e..3ada21c084 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -64,7 +64,8 @@ New Features level pre-scheduling type. * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. - + * Added ``rte_event_port_preschedule`` to allow applications to decide when + to pre-schedule events on an event port. Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index dc37f736f8..6aed1cba9a 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint(__rte_unused void *port, return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused rte_event_dev_preschedule_type_t preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 0add0093ac..8df6a8bee1 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_SW_PRESCHEDULE (1ULL << 19) +/**< Event device supports software prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* 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_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability. + * + * When pre-scheduling is enabled at an event device or event port level, the + * hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, rte_event_dev_preschedule_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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 2275888a6b..21988abb4f 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,9 @@ typedef int (*event_preschedule_modify_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,6 +85,8 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ uintptr_t reserved[4]; }; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 3/6] eventdev: add SW event preschedule hint 2024-10-01 13:18 ` [PATCH v4 3/6] eventdev: add SW event preschedule hint pbhagavatula @ 2024-10-04 5:14 ` Jerin Jacob 0 siblings, 0 replies; 77+ messages in thread From: Jerin Jacob @ 2024-10-04 5:14 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev On Wed, Oct 2, 2024 at 2:19 AM <pbhagavatula@marvell.com> wrote: > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Add a new eventdev API to provide a hint to the eventdev PMD to > pre-schedule the next event into the event port, without releasing > the current flow context. > Event device that support this feature advertises the capability > using the RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability flag. Change to RTE_EVENT_DEV_CAP_PRESCHEDULE_* prefix like other capas. > > Application can invoke `rte_event_port_preschedule` to hint the PMD. > > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > --- > doc/guides/prog_guide/eventdev/eventdev.rst | 8 ++++ > doc/guides/rel_notes/release_24_11.rst | 3 +- > lib/eventdev/eventdev_pmd.h | 2 + > lib/eventdev/eventdev_private.c | 21 ++++++++- > lib/eventdev/eventdev_trace_points.c | 3 ++ > lib/eventdev/rte_eventdev.h | 49 +++++++++++++++++++++ > lib/eventdev/rte_eventdev_core.h | 5 +++ > lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ > lib/eventdev/version.map | 2 + > 9 files changed, 98 insertions(+), 3 deletions(-) > > diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst > index 2deab0333e..1d8b86ab66 100644 > --- a/doc/guides/prog_guide/eventdev/eventdev.rst > +++ b/doc/guides/prog_guide/eventdev/eventdev.rst > @@ -390,6 +390,14 @@ To enable or disable event pre-scheduling at a given event port, the application > // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain > // pending events. > > +Event Pre-schedule Hint can be used to provide a hint to the eventdev PMD to pre-schedule the next pre-schedule Hint -> hint Application may provide pre-schedule hint to eventdev PMD to pre-schedule .... > +event without releasing the current flow context. Event device that support this feature advertises > +the capability using the ``RTE_EVENT_DEV_CAP_SW_PRESCHEDULE`` capability flag. SW is a very overloaded term, How about RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICT? Tell it is HINT. No need to check the capability in fast path. > +If pre-scheduling is already enabled at a event device or event port level then the hint is ignored. > + > +.. code-block:: c > + > + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_DEV_PRESCHEDULE); Since it is used at port level. Remove _DEV_. > > Starting the EventDev > ~~~~~~~~~~~~~~~~~~~~~ > diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst > index 6e36ac7b7e..3ada21c084 100644 > --- a/doc/guides/rel_notes/release_24_11.rst > +++ b/doc/guides/rel_notes/release_24_11.rst > @@ -64,7 +64,8 @@ New Features > level pre-scheduling type. > * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type > on a given event port. > - > + * Added ``rte_event_port_preschedule`` to allow applications to decide when > + to pre-schedule events on an event port. As an explicit request or so. > > Removed Items > ------------- > diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h > index 9ea23aa6cd..0bee2347ef 100644 > --- a/lib/eventdev/eventdev_pmd.h > +++ b/lib/eventdev/eventdev_pmd.h > @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { > /**< Pointer to PMD Event switch profile function. */ > event_preschedule_modify_t preschedule_modify; > /**< Pointer to PMD Event port pre-schedule type modify function. */ > + event_preschedule_t preschedule; > + /**< Pointer to PMD Event port pre-schedule function. */ > > uint64_t reserved_64s[3]; /**< Reserved for future fields */ > void *reserved_ptrs[3]; /**< Reserved for future fields */ > diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c > index dc37f736f8..6aed1cba9a 100644 > --- a/lib/eventdev/eventdev_private.c > +++ b/lib/eventdev/eventdev_private.c > @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint(__rte_unused void *port, > return -ENOTSUP; > } > > +static void > +dummy_event_port_preschedule(__rte_unused void *port, > + __rte_unused rte_event_dev_preschedule_type_t preschedule) > +{ > + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); > +} > + > +static void > +dummy_event_port_preschedule_hint(__rte_unused void *port, > + __rte_unused rte_event_dev_preschedule_type_t preschedule) > +{ > +} > + > void > event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) > { > @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) > .dequeue_burst = dummy_event_dequeue_burst, > .maintain = dummy_event_maintain, > .txa_enqueue = dummy_event_tx_adapter_enqueue, > - .txa_enqueue_same_dest = > - dummy_event_tx_adapter_enqueue_same_dest, > + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, > .ca_enqueue = dummy_event_crypto_adapter_enqueue, > .dma_enqueue = dummy_event_dma_adapter_enqueue, > .profile_switch = dummy_event_port_profile_switch, > .preschedule_modify = dummy_event_port_preschedule_modify, > + .preschedule = dummy_event_port_preschedule, > .data = dummy_data, > }; > > @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; > + fp_op->preschedule = dev->preschedule; > fp_op->data = dev->data->ports; > > if (fp_op->preschedule_modify == NULL) > fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; > + > + if (fp_op->preschedule == NULL) > + fp_op->preschedule = dummy_event_port_preschedule_hint; > } > diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c > index e41674123c..e7af1591f7 100644 > --- a/lib/eventdev/eventdev_trace_points.c > +++ b/lib/eventdev/eventdev_trace_points.c > @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, > RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, > lib.eventdev.port.preschedule.modify) > > +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, > + lib.eventdev.port.preschedule) > + > /* Eventdev Rx adapter trace points */ > RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, > lib.eventdev.rx.adapter.create) > diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h > index 0add0093ac..8df6a8bee1 100644 > --- a/lib/eventdev/rte_eventdev.h > +++ b/lib/eventdev/rte_eventdev.h > @@ -480,6 +480,15 @@ struct rte_event; > * @see rte_event_port_preschedule_modify() > */ > > +#define RTE_EVENT_DEV_CAP_SW_PRESCHEDULE (1ULL << 19) > +/**< Event device supports software prescheduling. > + * > + * When this flag is set, the application can issue preschedule request on > + * a event port. > + * > + * @see rte_event_port_preschedule() > + */ > + > /* 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_preschedule_modify(uint8_t dev_id, uint8_t port_id, > return fp_ops->preschedule_modify(port, type); > } > > +/** > + * Provide a hint to the event device to pre-schedule events to event port . > + * > + * Hint the event device to pre-schedule events to the event port. > + * The call doesn't not guarantee that the events will be pre-scheduleed. > + * The call doesn't release the flow context currently held by the event port. > + * The event device should support RTE_EVENT_DEV_CAP_SW_PRESCHEDULE capability. Reword the comments. > + * > + * When pre-scheduling is enabled at an event device or event port level, the > + * hint is ignored. > + * > + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule > + * events but pre-schedule 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 pre-schedule type to use on the event port. > + */ > +static inline void > +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, rte_event_dev_preschedule_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_preschedule(dev_id, port_id, type); > + > + fp_ops->preschedule(port, type); > +} > #ifdef __cplusplus > } > #endif > diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h > index 2275888a6b..21988abb4f 100644 > --- a/lib/eventdev/rte_eventdev_core.h > +++ b/lib/eventdev/rte_eventdev_core.h > @@ -53,6 +53,9 @@ typedef int (*event_preschedule_modify_t)(void *port, > rte_event_dev_preschedule_type_t preschedule_type); > /**< @internal Modify pre-schedule type on the event port. */ > > +typedef void (*event_preschedule_t)(void *port, rte_event_dev_preschedule_type_t preschedule_type); > +/**< @internal Issue pre-schedule on an event port. */ > + > struct __rte_cache_aligned rte_event_fp_ops { > void **data; > /**< points to array of internal port data pointers */ > @@ -82,6 +85,8 @@ struct __rte_cache_aligned rte_event_fp_ops { > /**< PMD Event switch profile function. */ > event_preschedule_modify_t preschedule_modify; > /**< PMD Event port pre-schedule switch. */ > + event_preschedule_t preschedule; > + /**< PMD Event port pre-schedule. */ Use reserved not to break ABI > uintptr_t reserved[4]; > }; ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 4/6] event/cnkx: add pre-schedule support 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula ` (2 preceding siblings ...) 2024-10-01 13:18 ` [PATCH v4 3/6] eventdev: add SW event preschedule hint pbhagavatula @ 2024-10-01 13:18 ` pbhagavatula 2024-10-01 13:19 ` [PATCH v4 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (3 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:18 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/cnxk.rst | 10 ---------- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 19 +++++++++++++++++-- drivers/event/cnxk/cn10k_worker.c | 21 +++++++++++++++++++++ drivers/event/cnxk/cn10k_worker.h | 1 + drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 7 files changed, 40 insertions(+), 15 deletions(-) diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst index d038930594..e21846f4e0 100644 --- a/doc/guides/eventdevs/cnxk.rst +++ b/doc/guides/eventdevs/cnxk.rst @@ -78,16 +78,6 @@ Runtime Config Options -a 0002:0e:00.0,single_ws=1 -- ``CN10K Getwork mode`` - - CN10K supports three getwork prefetch modes no prefetch[0], prefetch - immediately[1] and delayed prefetch on forward progress event[2]. - The default getwork mode is 2. - - For example:: - - -a 0002:0e:00.0,gw_mode=1 - - ``Event Group QoS support`` SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..5c50e72152 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -527,6 +527,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +542,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_EVENT_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +570,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_DEV_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_DEV_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1216,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1272,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cn10k_worker.c b/drivers/event/cnxk/cn10k_worker.c index d59769717e..ffe06843fa 100644 --- a/drivers/event/cnxk/cn10k_worker.c +++ b/drivers/event/cnxk/cn10k_worker.c @@ -442,3 +442,24 @@ cn10k_sso_hws_profile_switch(void *port, uint8_t profile) return 0; } + +int __rte_hot +cn10k_sso_hws_preschedule_modify(void *port, rte_event_dev_preschedule_type_t type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= (BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_DEV_PRESCHEDULE_NONE: + break; + case RTE_EVENT_DEV_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} diff --git a/drivers/event/cnxk/cn10k_worker.h b/drivers/event/cnxk/cn10k_worker.h index c5026409d7..b5898395e6 100644 --- a/drivers/event/cnxk/cn10k_worker.h +++ b/drivers/event/cnxk/cn10k_worker.h @@ -377,6 +377,7 @@ uint16_t __rte_hot cn10k_sso_hws_enq_fwd_burst(void *port, const struct rte_event ev[], uint16_t nb_events); int __rte_hot cn10k_sso_hws_profile_switch(void *port, uint8_t profile); +int __rte_hot cn10k_sso_hws_preschedule_modify(void *port, rte_event_dev_preschedule_type_t type); #define R(name, flags) \ uint16_t __rte_hot cn10k_sso_hws_deq_##name( \ diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 5/6] app/test-eventdev: add pre-scheduling support 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula ` (3 preceding siblings ...) 2024-10-01 13:18 ` [PATCH v4 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-01 13:19 ` pbhagavatula 2024-10-01 13:19 ` [PATCH v4 6/6] examples: use eventdev pre-scheduling pbhagavatula ` (2 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:19 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..176c077e51 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_DEV_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v4 6/6] examples: use eventdev pre-scheduling 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula ` (4 preceding siblings ...) 2024-10-01 13:19 ` [PATCH v4 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-01 13:19 ` pbhagavatula 2024-10-01 15:33 ` [PATCH v4 0/6] Introduce event pre-scheduling Stephen Hemminger 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-01 13:19 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 783f68c91e..8052e2df86 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -188,6 +188,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..077b902bdb 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..61133607d6 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d5a3cd9984 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..0b619afe91 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..333c87b01c 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..32354fc09f 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_DEV_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v4 0/6] Introduce event pre-scheduling 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula ` (5 preceding siblings ...) 2024-10-01 13:19 ` [PATCH v4 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-01 15:33 ` Stephen Hemminger 2024-10-03 5:46 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula 7 siblings, 1 reply; 77+ messages in thread From: Stephen Hemminger @ 2024-10-01 15:33 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev On Tue, 1 Oct 2024 18:48:55 +0530 <pbhagavatula@marvell.com> wrote: > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Event pre-scheduling improves scheduling performance by assigning events > to event ports in advance when dequeues are issued. > This series introduces various types and levels of pre-scheduling to the > eventdev library. Any numbers on how much this improves the overhead? ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v4 0/6] Introduce event pre-scheduling 2024-10-01 15:33 ` [PATCH v4 0/6] Introduce event pre-scheduling Stephen Hemminger @ 2024-10-03 5:46 ` Pavan Nikhilesh Bhagavatula 0 siblings, 0 replies; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-10-03 5:46 UTC (permalink / raw) To: Stephen Hemminger Cc: Jerin Jacob, Shijith Thotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > Event pre-scheduling improves scheduling performance by assigning events > > to event ports in advance when dequeues are issued. > > This series introduces various types and levels of pre-scheduling to the > > eventdev library. > > Any numbers on how much this improves the overhead? In case of CNXK pmd, it preschedule doubles the scheduler performance. ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 0/6] Introduce event pre-scheduling 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula ` (6 preceding siblings ...) 2024-10-01 15:33 ` [PATCH v4 0/6] Introduce event pre-scheduling Stephen Hemminger @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:24 ` [PATCH v5 1/6] eventdev: introduce " pbhagavatula ` (7 more replies) 7 siblings, 8 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. v4 Changes: - Fix compilation. v5 Changes: - Update ABI changes - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE - Various documentation fixes and updates. Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 +++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/cnxk.rst | 10 -- doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ doc/guides/rel_notes/release_24_11.rst | 13 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 19 ++- drivers/event/cnxk/cn10k_worker.c | 21 +++ drivers/event/cnxk/cn10k_worker.h | 2 + drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 159 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 14 +- lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 29 files changed, 592 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 1/6] eventdev: introduce event pre-scheduling 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:24 ` [PATCH v5 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (6 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 23 +++++ doc/guides/rel_notes/release_24_11.rst | 10 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++ 5 files changed, 191 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index 9a6c8f470c..a45d1396d7 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,6 +1251,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(enum rte_event_dev_preschedule_type type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS(rc, + "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1311,6 +1417,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 1cc4303fe5..c8d5ed2d74 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -22,6 +22,7 @@ carry_flow_id = maintenance_free = runtime_queue_attr = profile_links = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..9da5531859 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,29 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application must check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` or ``RTE_EVENT_DEV_CAP_PRESCHEDULE_ADAPTIVE`` set, if +present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +The following pre-schedule types are supported: + * ``RTE_EVENT_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 0ff70d9057..39b1314e1c 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -55,6 +55,14 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- @@ -100,6 +108,8 @@ ABI Changes Also, make sure to start the actual text at the margin. ======================================================= +* eventdev: Added ``preschedule_type`` field to ``rte_event_dev_config`` + structure. Known Issues ------------ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..4b69e74577 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,26 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +/** Event device pre-schedule type enumeration. */ +enum rte_event_dev_preschedule_type { + RTE_EVENT_PRESCHEDULE_NONE, + /**< Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_PRESCHEDULE, + /**< Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_PRESCHEDULE_ADAPTIVE, + /**< Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +}; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +796,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + enum rte_event_dev_preschedule_type preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 2/6] eventdev: add event port pre-schedule modify 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula 2024-10-04 16:24 ` [PATCH v5 1/6] eventdev: introduce " pbhagavatula @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:24 ` [PATCH v5 3/6] eventdev: add event preschedule hint pbhagavatula ` (5 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. To avoid fastpath capability checks, the API reports -ENOTSUP if the event device does not support this feature. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 ++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 16 ++++++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 +++++++ lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 60 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 ++- lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 10 files changed, 164 insertions(+), 7 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index a45d1396d7..a9258d2abc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1252,7 +1252,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1270,7 +1271,11 @@ preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const cha TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1335,13 +1340,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1349,7 +1354,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); } @@ -1357,6 +1362,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1419,6 +1452,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 9da5531859..26e77166d5 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -380,6 +380,22 @@ The following pre-schedule types are supported: * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +Event devices that support ``RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE`` capability allow +applications to modify pre-scheduling at a per port level at runtime in fast-path. +To modify event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. +This API can be called even if the event device does not support per port pre-scheduling, it +will be treated as a no-op. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 39b1314e1c..cae594096c 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -62,6 +62,8 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. Removed Items diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..cc5963b31b 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint( + __rte_unused void *port, __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 4b69e74577..d7920bfba0 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -709,18 +719,23 @@ enum rte_event_dev_preschedule_type { RTE_EVENT_PRESCHEDULE_NONE, /**< Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_PRESCHEDULE, /**< Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ RTE_EVENT_PRESCHEDULE_ADAPTIVE, /**< Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ }; @@ -2923,6 +2938,51 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Modify the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * To avoid fastpath capability checks if an event device does not support + * RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability, then this function will + * return -ENOTSUP. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + * - -ENOTSUP if the device does not support per port preschedule capability. + */ +static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..5f4c25b1c5 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,7 +80,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ - uintptr_t reserved[4]; + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ + uintptr_t reserved[3]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 3/6] eventdev: add event preschedule hint 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula 2024-10-04 16:24 ` [PATCH v5 1/6] eventdev: introduce " pbhagavatula 2024-10-04 16:24 ` [PATCH v5 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:24 ` [PATCH v5 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (4 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD, if event device does not support this feature it is treated as a no-op. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 9 ++++ doc/guides/rel_notes/release_24_11.rst | 3 +- lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 50 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 +++- lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 102 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 26e77166d5..56d62d260a 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -395,6 +395,15 @@ will be a no-op in that case. // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Application may provide a hint to the eventdev PMD to pre-schedule the next event without +releasing the current flow context. Event device that support this feature advertises +the capability via the ``RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT`` flag. +If pre-scheduling is already enabled at a event device or event port level or if the +capability is not supported then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index cae594096c..3a41263b8b 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -64,7 +64,8 @@ New Features level pre-scheduling type. * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. - + * Added ``rte_event_port_preschedule`` to allow applications provide explicit + pre-schedule hints to event ports. Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index cc5963b31b..b628f4a69e 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint( return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index d7920bfba0..ffce2ee0d9 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT (1ULL << 19) +/**< Event device supports explicit prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -2983,6 +2992,47 @@ rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability. + * + * When pre-scheduling is enabled at an event device/port level or if + * the capability is not supported, then the hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 5f4c25b1c5..2706d5e6c8 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,10 @@ typedef int (*event_preschedule_modify_t)(void *port, enum rte_event_dev_preschedule_type preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,7 +86,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ - uintptr_t reserved[3]; + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ + uintptr_t reserved[2]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 4/6] event/cnkx: add pre-schedule support 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula ` (2 preceding siblings ...) 2024-10-04 16:24 ` [PATCH v5 3/6] eventdev: add event preschedule hint pbhagavatula @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:24 ` [PATCH v5 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (3 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/cnxk.rst | 10 ---------- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 19 +++++++++++++++++-- drivers/event/cnxk/cn10k_worker.c | 21 +++++++++++++++++++++ drivers/event/cnxk/cn10k_worker.h | 2 ++ drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst index d038930594..e21846f4e0 100644 --- a/doc/guides/eventdevs/cnxk.rst +++ b/doc/guides/eventdevs/cnxk.rst @@ -78,16 +78,6 @@ Runtime Config Options -a 0002:0e:00.0,single_ws=1 -- ``CN10K Getwork mode`` - - CN10K supports three getwork prefetch modes no prefetch[0], prefetch - immediately[1] and delayed prefetch on forward progress event[2]. - The default getwork mode is 2. - - For example:: - - -a 0002:0e:00.0,gw_mode=1 - - ``Event Group QoS support`` SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..5bd779990e 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -527,6 +527,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +542,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +570,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1216,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1272,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cn10k_worker.c b/drivers/event/cnxk/cn10k_worker.c index d59769717e..a0e85face1 100644 --- a/drivers/event/cnxk/cn10k_worker.c +++ b/drivers/event/cnxk/cn10k_worker.c @@ -442,3 +442,24 @@ cn10k_sso_hws_profile_switch(void *port, uint8_t profile) return 0; } + +int __rte_hot +cn10k_sso_hws_preschedule_modify(void *port, enum rte_event_dev_preschedule_type type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= ~(BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + break; + case RTE_EVENT_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} diff --git a/drivers/event/cnxk/cn10k_worker.h b/drivers/event/cnxk/cn10k_worker.h index c5026409d7..4785cc6575 100644 --- a/drivers/event/cnxk/cn10k_worker.h +++ b/drivers/event/cnxk/cn10k_worker.h @@ -377,6 +377,8 @@ uint16_t __rte_hot cn10k_sso_hws_enq_fwd_burst(void *port, const struct rte_event ev[], uint16_t nb_events); int __rte_hot cn10k_sso_hws_profile_switch(void *port, uint8_t profile); +int __rte_hot cn10k_sso_hws_preschedule_modify(void *port, + enum rte_event_dev_preschedule_type type); #define R(name, flags) \ uint16_t __rte_hot cn10k_sso_hws_deq_##name( \ diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 5/6] app/test-eventdev: add pre-scheduling support 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula ` (3 preceding siblings ...) 2024-10-04 16:24 ` [PATCH v5 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:24 ` [PATCH v5 6/6] examples: use eventdev pre-scheduling pbhagavatula ` (2 subsequent siblings) 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..901b8ba55d 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v5 6/6] examples: use eventdev pre-scheduling 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula ` (4 preceding siblings ...) 2024-10-04 16:24 ` [PATCH v5 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-04 16:24 ` pbhagavatula 2024-10-04 16:35 ` [PATCH v5 0/6] Introduce event pre-scheduling Stephen Hemminger 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula 7 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-04 16:24 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 831d7fd53d..06384c683c 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -192,6 +192,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..c9a04cad56 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..dadddcb306 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d805264744 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..26233d1ab6 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..d86439df52 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..b390e3469d 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v5 0/6] Introduce event pre-scheduling 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula ` (5 preceding siblings ...) 2024-10-04 16:24 ` [PATCH v5 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-04 16:35 ` Stephen Hemminger 2024-10-04 16:50 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula 7 siblings, 1 reply; 77+ messages in thread From: Stephen Hemminger @ 2024-10-04 16:35 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev On Fri, 4 Oct 2024 21:54:45 +0530 <pbhagavatula@marvell.com> wrote: > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Event pre-scheduling improves scheduling performance by assigning events > to event ports in advance when dequeues are issued. > This series introduces various types and levels of pre-scheduling to the > eventdev library. > > pre-scheduling Types: > * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. > * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. > * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there > are no forward progress constraints with the held flow contexts. > > pre-scheduling Levels: > * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the > event device during configuration. Event devices can indicate pre-scheduling > capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info > function `info.event_dev_cap`. > * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled > at the event port during runtime. Event devices can indicate this capability > using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info > function `info.event_port_cap`. > * Application Controlled Prefetch Hint: Applications can provide hints to the > event device to start pre-scheduling events using the new API > `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using > `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function > `info.event_dev_cap`. > > The rte_event_dequeue_burst operation initiates the pre-schedule operation, which > completes in parallel without affecting the flow context of the dequeued events and > dequeue latency. On the next dequeue operation, the pre-scheduleed events are > dequeued, and pre-schedule operation is initiated again. > > In the case of application-controlled pre-schedule hints, the currently held flow > contexts, if any, are not affected by the pre-schedule operation. On the next > dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not > initiated again until the application provides the hint again. If pre-scheduling > is already enabled at the event device level or event port level, the hint is ignored. > > v2 Changes: > - s/prefetch/pre-schedule (Mattias). > v3 Changes: > - Add CNXK preschedule implementation. > - Update test-eventdev to use prescheduling. > - Update examples to use prescheduling. > v4 Changes: > - Fix compilation. > v5 Changes: > - Update ABI changes > - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ > - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ > - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE > - Various documentation fixes and updates. > > > Pavan Nikhilesh (6): > eventdev: introduce event pre-scheduling > eventdev: add event port pre-schedule modify > eventdev: add event preschedule hint > event/cnkx: add pre-schedule support > app/test-eventdev: add pre-scheduling support > examples: use eventdev pre-scheduling > > app/test-eventdev/evt_common.h | 45 +++-- > app/test-eventdev/evt_options.c | 17 ++ > app/test-eventdev/evt_options.h | 1 + > app/test/test_eventdev.c | 143 ++++++++++++++++ > doc/guides/eventdevs/cnxk.rst | 10 -- > doc/guides/eventdevs/features/cnxk.ini | 1 + > doc/guides/eventdevs/features/default.ini | 1 + > doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ > doc/guides/rel_notes/release_24_11.rst | 13 ++ > doc/guides/tools/testeventdev.rst | 6 + > drivers/event/cnxk/cn10k_eventdev.c | 19 ++- > drivers/event/cnxk/cn10k_worker.c | 21 +++ > drivers/event/cnxk/cn10k_worker.h | 2 + > drivers/event/cnxk/cnxk_eventdev.c | 2 - > drivers/event/cnxk/cnxk_eventdev.h | 1 - > .../pipeline_worker_generic.c | 6 + > .../eventdev_pipeline/pipeline_worker_tx.c | 6 + > examples/ipsec-secgw/event_helper.c | 6 + > examples/l2fwd-event/l2fwd_event_generic.c | 6 + > .../l2fwd-event/l2fwd_event_internal_port.c | 6 + > examples/l3fwd/l3fwd_event_generic.c | 6 + > examples/l3fwd/l3fwd_event_internal_port.c | 6 + > lib/eventdev/eventdev_pmd.h | 4 + > lib/eventdev/eventdev_private.c | 41 ++++- > lib/eventdev/eventdev_trace_points.c | 6 + > lib/eventdev/rte_eventdev.h | 159 ++++++++++++++++++ > lib/eventdev/rte_eventdev_core.h | 14 +- > lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- > lib/eventdev/version.map | 6 + > 29 files changed, 592 insertions(+), 29 deletions(-) Looks good, but the new API's should be experimental right? ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v5 0/6] Introduce event pre-scheduling 2024-10-04 16:35 ` [PATCH v5 0/6] Introduce event pre-scheduling Stephen Hemminger @ 2024-10-04 16:50 ` Pavan Nikhilesh Bhagavatula 0 siblings, 0 replies; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-10-04 16:50 UTC (permalink / raw) To: Stephen Hemminger Cc: Jerin Jacob, Shijith Thotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > > > Event pre-scheduling improves scheduling performance by assigning events > > to event ports in advance when dequeues are issued. > > This series introduces various types and levels of pre-scheduling to the > > eventdev library. > > > > pre-scheduling Types: > > * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. > > * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is > issued. > > * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until > there > > are no forward progress constraints with the held flow contexts. > > > > pre-scheduling Levels: > > * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or > disabled at the > > event device during configuration. Event devices can indicate pre- > scheduling > > capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event > device info > > function `info.event_dev_cap`. > > * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or > disabled > > at the event port during runtime. Event devices can indicate this capability > > using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event > device info > > function `info.event_port_cap`. > > * Application Controlled Prefetch Hint: Applications can provide hints to the > > event device to start pre-scheduling events using the new API > > `rte_event_port_pre-schedule`. Event devices can indicate this capabilities > using > > `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info > function > > `info.event_dev_cap`. > > > > The rte_event_dequeue_burst operation initiates the pre-schedule > operation, which > > completes in parallel without affecting the flow context of the dequeued > events and > > dequeue latency. On the next dequeue operation, the pre-scheduleed events > are > > dequeued, and pre-schedule operation is initiated again. > > > > In the case of application-controlled pre-schedule hints, the currently held > flow > > contexts, if any, are not affected by the pre-schedule operation. On the next > > dequeue operation, the pre-scheduleed events are returned, but pre- > schedule is not > > initiated again until the application provides the hint again. If pre-scheduling > > is already enabled at the event device level or event port level, the hint is > ignored. > > > > v2 Changes: > > - s/prefetch/pre-schedule (Mattias). > > v3 Changes: > > - Add CNXK preschedule implementation. > > - Update test-eventdev to use prescheduling. > > - Update examples to use prescheduling. > > v4 Changes: > > - Fix compilation. > > v5 Changes: > > - Update ABI changes > > - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ > > - > s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHE > DULE_EXPLICIT/ > > - > s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PO > RT_CAP_PER_PORT_PRESCHEDULE > > - Various documentation fixes and updates. > > > > > > Pavan Nikhilesh (6): > > eventdev: introduce event pre-scheduling > > eventdev: add event port pre-schedule modify > > eventdev: add event preschedule hint > > event/cnkx: add pre-schedule support > > app/test-eventdev: add pre-scheduling support > > examples: use eventdev pre-scheduling > > > > app/test-eventdev/evt_common.h | 45 +++-- > > app/test-eventdev/evt_options.c | 17 ++ > > app/test-eventdev/evt_options.h | 1 + > > app/test/test_eventdev.c | 143 ++++++++++++++++ > > doc/guides/eventdevs/cnxk.rst | 10 -- > > doc/guides/eventdevs/features/cnxk.ini | 1 + > > doc/guides/eventdevs/features/default.ini | 1 + > > doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ > > doc/guides/rel_notes/release_24_11.rst | 13 ++ > > doc/guides/tools/testeventdev.rst | 6 + > > drivers/event/cnxk/cn10k_eventdev.c | 19 ++- > > drivers/event/cnxk/cn10k_worker.c | 21 +++ > > drivers/event/cnxk/cn10k_worker.h | 2 + > > drivers/event/cnxk/cnxk_eventdev.c | 2 - > > drivers/event/cnxk/cnxk_eventdev.h | 1 - > > .../pipeline_worker_generic.c | 6 + > > .../eventdev_pipeline/pipeline_worker_tx.c | 6 + > > examples/ipsec-secgw/event_helper.c | 6 + > > examples/l2fwd-event/l2fwd_event_generic.c | 6 + > > .../l2fwd-event/l2fwd_event_internal_port.c | 6 + > > examples/l3fwd/l3fwd_event_generic.c | 6 + > > examples/l3fwd/l3fwd_event_internal_port.c | 6 + > > lib/eventdev/eventdev_pmd.h | 4 + > > lib/eventdev/eventdev_private.c | 41 ++++- > > lib/eventdev/eventdev_trace_points.c | 6 + > > lib/eventdev/rte_eventdev.h | 159 ++++++++++++++++++ > > lib/eventdev/rte_eventdev_core.h | 14 +- > > lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- > > lib/eventdev/version.map | 6 + > > 29 files changed, 592 insertions(+), 29 deletions(-) > > Looks good, but the new API's should be experimental right? Ah yes, my bad, Thanks Stephen, I will mark them as experimental in next version. ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 0/6] Introduce event pre-scheduling 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula ` (6 preceding siblings ...) 2024-10-04 16:35 ` [PATCH v5 0/6] Introduce event pre-scheduling Stephen Hemminger @ 2024-10-05 7:25 ` pbhagavatula 2024-10-05 7:25 ` [PATCH v6 1/6] eventdev: introduce " pbhagavatula ` (6 more replies) 7 siblings, 7 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:25 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. v4 Changes: - Fix compilation. v5 Changes: - Update ABI changes - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE - Various documentation fixes and updates. v6 Changes: - Mark new APIs as experimental (Stephen). Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 +++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/cnxk.rst | 10 -- doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ doc/guides/rel_notes/release_24_11.rst | 13 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 19 ++- drivers/event/cnxk/cn10k_worker.c | 21 +++ drivers/event/cnxk/cn10k_worker.h | 2 + drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 159 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 14 +- lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 29 files changed, 592 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 1/6] eventdev: introduce event pre-scheduling 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula @ 2024-10-05 7:25 ` pbhagavatula 2024-10-05 7:25 ` [PATCH v6 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (5 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:25 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 23 +++++ doc/guides/rel_notes/release_24_11.rst | 10 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++ 5 files changed, 191 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index 9a6c8f470c..a45d1396d7 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,6 +1251,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(enum rte_event_dev_preschedule_type type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS(rc, + "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1311,6 +1417,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 1cc4303fe5..c8d5ed2d74 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -22,6 +22,7 @@ carry_flow_id = maintenance_free = runtime_queue_attr = profile_links = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..9da5531859 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,29 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application must check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` or ``RTE_EVENT_DEV_CAP_PRESCHEDULE_ADAPTIVE`` set, if +present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +The following pre-schedule types are supported: + * ``RTE_EVENT_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index e0a9aa55a1..a294a753e7 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -67,6 +67,14 @@ New Features The new statistics are useful for debugging and profiling. +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- @@ -112,6 +120,8 @@ ABI Changes Also, make sure to start the actual text at the margin. ======================================================= +* eventdev: Added ``preschedule_type`` field to ``rte_event_dev_config`` + structure. Known Issues ------------ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..4b69e74577 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,26 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +/** Event device pre-schedule type enumeration. */ +enum rte_event_dev_preschedule_type { + RTE_EVENT_PRESCHEDULE_NONE, + /**< Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_PRESCHEDULE, + /**< Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_PRESCHEDULE_ADAPTIVE, + /**< Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +}; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +796,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + enum rte_event_dev_preschedule_type preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 2/6] eventdev: add event port pre-schedule modify 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula 2024-10-05 7:25 ` [PATCH v6 1/6] eventdev: introduce " pbhagavatula @ 2024-10-05 7:25 ` pbhagavatula 2024-10-05 7:25 ` [PATCH v6 3/6] eventdev: add event preschedule hint pbhagavatula ` (4 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:25 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. To avoid fastpath capability checks, the API reports -ENOTSUP if the event device does not support this feature. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 ++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 16 ++++++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 +++++++ lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 60 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 ++- lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 10 files changed, 164 insertions(+), 7 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index a45d1396d7..a9258d2abc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1252,7 +1252,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1270,7 +1271,11 @@ preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const cha TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1335,13 +1340,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1349,7 +1354,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); } @@ -1357,6 +1362,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1419,6 +1452,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 9da5531859..26e77166d5 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -380,6 +380,22 @@ The following pre-schedule types are supported: * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +Event devices that support ``RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE`` capability allow +applications to modify pre-scheduling at a per port level at runtime in fast-path. +To modify event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. +This API can be called even if the event device does not support per port pre-scheduling, it +will be a no-op in that case. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index a294a753e7..f7cc2ec047 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -74,6 +74,8 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. Removed Items diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..cc5963b31b 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint( + __rte_unused void *port, __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 4b69e74577..f47321b94b 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -709,18 +719,23 @@ enum rte_event_dev_preschedule_type { RTE_EVENT_PRESCHEDULE_NONE, /**< Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_PRESCHEDULE, /**< Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ RTE_EVENT_PRESCHEDULE_ADAPTIVE, /**< Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ }; @@ -2923,6 +2938,51 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Modify the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * To avoid fastpath capabilty checks if an event device does not support + * RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability, then this function will + * return -ENOTSUP. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + * - -ENOTSUP if the device does not support per port preschedule capability. + */ +__rte_experimental static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..5f4c25b1c5 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,7 +80,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ - uintptr_t reserved[4]; + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ + uintptr_t reserved[3]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 3/6] eventdev: add event preschedule hint 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula 2024-10-05 7:25 ` [PATCH v6 1/6] eventdev: introduce " pbhagavatula 2024-10-05 7:25 ` [PATCH v6 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-05 7:25 ` pbhagavatula 2024-10-05 7:25 ` [PATCH v6 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (3 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:25 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD, if event device does not support this feature it is treated as a no-op. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 9 ++++ doc/guides/rel_notes/release_24_11.rst | 3 +- lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 50 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 +++- lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 102 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 26e77166d5..56d62d260a 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -395,6 +395,15 @@ will be a no-op in that case. // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Application may provide a hint to the eventdev PMD to pre-schedule the next event without +releasing the current flow context. Event device that support this feature advertises +the capability via the ``RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT`` flag. +If pre-scheduling is already enabled at a event device or event port level or if the +capability is not supported then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index f7cc2ec047..505377826e 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -76,7 +76,8 @@ New Features level pre-scheduling type. * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. - + * Added ``rte_event_port_preschedule`` to allow applications provice explicit + pre-schedule hints to event ports. Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index cc5963b31b..b628f4a69e 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint( return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index f47321b94b..d1a315a37f 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT (1ULL << 19) +/**< Event device supports software prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -2983,6 +2992,47 @@ rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability. + * + * When pre-scheduling is enabled at an event device/port level or if + * the capability is not supported, then the hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +__rte_experimental static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 5f4c25b1c5..2706d5e6c8 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,10 @@ typedef int (*event_preschedule_modify_t)(void *port, enum rte_event_dev_preschedule_type preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,7 +86,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ - uintptr_t reserved[3]; + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ + uintptr_t reserved[2]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 4/6] event/cnkx: add pre-schedule support 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula ` (2 preceding siblings ...) 2024-10-05 7:25 ` [PATCH v6 3/6] eventdev: add event preschedule hint pbhagavatula @ 2024-10-05 7:25 ` pbhagavatula 2024-10-05 7:25 ` [PATCH v6 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (2 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:25 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/cnxk.rst | 10 ---------- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 19 +++++++++++++++++-- drivers/event/cnxk/cn10k_worker.c | 21 +++++++++++++++++++++ drivers/event/cnxk/cn10k_worker.h | 2 ++ drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst index d038930594..e21846f4e0 100644 --- a/doc/guides/eventdevs/cnxk.rst +++ b/doc/guides/eventdevs/cnxk.rst @@ -78,16 +78,6 @@ Runtime Config Options -a 0002:0e:00.0,single_ws=1 -- ``CN10K Getwork mode`` - - CN10K supports three getwork prefetch modes no prefetch[0], prefetch - immediately[1] and delayed prefetch on forward progress event[2]. - The default getwork mode is 2. - - For example:: - - -a 0002:0e:00.0,gw_mode=1 - - ``Event Group QoS support`` SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..5bd779990e 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -527,6 +527,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +542,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +570,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1216,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1272,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cn10k_worker.c b/drivers/event/cnxk/cn10k_worker.c index d59769717e..a0e85face1 100644 --- a/drivers/event/cnxk/cn10k_worker.c +++ b/drivers/event/cnxk/cn10k_worker.c @@ -442,3 +442,24 @@ cn10k_sso_hws_profile_switch(void *port, uint8_t profile) return 0; } + +int __rte_hot +cn10k_sso_hws_preschedule_modify(void *port, enum rte_event_dev_preschedule_type type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= ~(BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + break; + case RTE_EVENT_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} diff --git a/drivers/event/cnxk/cn10k_worker.h b/drivers/event/cnxk/cn10k_worker.h index c5026409d7..4785cc6575 100644 --- a/drivers/event/cnxk/cn10k_worker.h +++ b/drivers/event/cnxk/cn10k_worker.h @@ -377,6 +377,8 @@ uint16_t __rte_hot cn10k_sso_hws_enq_fwd_burst(void *port, const struct rte_event ev[], uint16_t nb_events); int __rte_hot cn10k_sso_hws_profile_switch(void *port, uint8_t profile); +int __rte_hot cn10k_sso_hws_preschedule_modify(void *port, + enum rte_event_dev_preschedule_type type); #define R(name, flags) \ uint16_t __rte_hot cn10k_sso_hws_deq_##name( \ diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 5/6] app/test-eventdev: add pre-scheduling support 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula ` (3 preceding siblings ...) 2024-10-05 7:25 ` [PATCH v6 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-05 7:25 ` pbhagavatula 2024-10-05 7:26 ` [PATCH v6 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:25 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..901b8ba55d 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v6 6/6] examples: use eventdev pre-scheduling 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula ` (4 preceding siblings ...) 2024-10-05 7:25 ` [PATCH v6 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-05 7:26 ` pbhagavatula 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:26 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 831d7fd53d..06384c683c 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -192,6 +192,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..c9a04cad56 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..dadddcb306 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d805264744 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..26233d1ab6 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..d86439df52 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..b390e3469d 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 0/6] Introduce event pre-scheduling 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula ` (5 preceding siblings ...) 2024-10-05 7:26 ` [PATCH v6 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-05 7:59 ` pbhagavatula 2024-10-05 7:59 ` [PATCH v7 1/6] eventdev: introduce " pbhagavatula ` (6 more replies) 6 siblings, 7 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:59 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. v4 Changes: - Fix compilation. v5 Changes: - Update ABI changes - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE - Various documentation fixes and updates. v6 Changes: - Mark new APIs as experimental (Stephen). v7 Changes: - Use correct patchset for rebase. Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 +++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/cnxk.rst | 10 -- doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ doc/guides/rel_notes/release_24_11.rst | 13 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 19 ++- drivers/event/cnxk/cn10k_worker.c | 21 +++ drivers/event/cnxk/cn10k_worker.h | 2 + drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 159 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 14 +- lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 29 files changed, 592 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 1/6] eventdev: introduce event pre-scheduling 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula @ 2024-10-05 7:59 ` pbhagavatula 2024-10-05 16:11 ` Stephen Hemminger 2024-10-05 7:59 ` [PATCH v7 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (5 subsequent siblings) 6 siblings, 1 reply; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:59 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 23 +++++ doc/guides/rel_notes/release_24_11.rst | 10 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++ 5 files changed, 191 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index 9a6c8f470c..a45d1396d7 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,6 +1251,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(enum rte_event_dev_preschedule_type type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS(rc, + "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1311,6 +1417,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 1cc4303fe5..c8d5ed2d74 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -22,6 +22,7 @@ carry_flow_id = maintenance_free = runtime_queue_attr = profile_links = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..9da5531859 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,29 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application must check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` or ``RTE_EVENT_DEV_CAP_PRESCHEDULE_ADAPTIVE`` set, if +present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +The following pre-schedule types are supported: + * ``RTE_EVENT_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index e0a9aa55a1..a294a753e7 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -67,6 +67,14 @@ New Features The new statistics are useful for debugging and profiling. +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- @@ -112,6 +120,8 @@ ABI Changes Also, make sure to start the actual text at the margin. ======================================================= +* eventdev: Added ``preschedule_type`` field to ``rte_event_dev_config`` + structure. Known Issues ------------ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..4b69e74577 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,26 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +/** Event device pre-schedule type enumeration. */ +enum rte_event_dev_preschedule_type { + RTE_EVENT_PRESCHEDULE_NONE, + /**< Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_PRESCHEDULE, + /**< Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_PRESCHEDULE_ADAPTIVE, + /**< Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +}; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +796,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + enum rte_event_dev_preschedule_type preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v7 1/6] eventdev: introduce event pre-scheduling 2024-10-05 7:59 ` [PATCH v7 1/6] eventdev: introduce " pbhagavatula @ 2024-10-05 16:11 ` Stephen Hemminger 2024-10-06 17:03 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 0 siblings, 1 reply; 77+ messages in thread From: Stephen Hemminger @ 2024-10-05 16:11 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev On Sat, 5 Oct 2024 13:29:56 +0530 <pbhagavatula@marvell.com> wrote: > +static int > +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) > +{ > +#define NB_EVENTS 1024 > + uint64_t start, total; > + struct rte_event ev; > + int rc, cnt; > + > + ev.event_type = RTE_EVENT_TYPE_CPU; > + ev.queue_id = 0; > + ev.op = RTE_EVENT_OP_NEW; > + ev.u64 = 0xBADF00D0; > + > + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > + ev.flow_id = cnt; > + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); > + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > + } > + > + RTE_SET_USED(preschedule_type); If you respin this patch. My preference is to use the __rte_unused attribute in the function declaration rather RTE_SET_USED(), mainly because it makes it more obvious in the start of the function. ^ permalink raw reply [flat|nested] 77+ messages in thread
* RE: [EXTERNAL] Re: [PATCH v7 1/6] eventdev: introduce event pre-scheduling 2024-10-05 16:11 ` Stephen Hemminger @ 2024-10-06 17:03 ` Pavan Nikhilesh Bhagavatula 0 siblings, 0 replies; 77+ messages in thread From: Pavan Nikhilesh Bhagavatula @ 2024-10-06 17:03 UTC (permalink / raw) To: Stephen Hemminger Cc: Jerin Jacob, Shijith Thotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, dev > On Sat, 5 Oct 2024 13:29:56 +0530 > <pbhagavatula@marvell.com> wrote: > > > +static int > > +preschedule_test(enum rte_event_dev_preschedule_type > preschedule_type, const char *preschedule_name) > > +{ > > +#define NB_EVENTS 1024 > > + uint64_t start, total; > > + struct rte_event ev; > > + int rc, cnt; > > + > > + ev.event_type = RTE_EVENT_TYPE_CPU; > > + ev.queue_id = 0; > > + ev.op = RTE_EVENT_OP_NEW; > > + ev.u64 = 0xBADF00D0; > > + > > + for (cnt = 0; cnt < NB_EVENTS; cnt++) { > > + ev.flow_id = cnt; > > + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); > > + TEST_ASSERT(rc == 1, "Failed to enqueue event"); > > + } > > + > > + RTE_SET_USED(preschedule_type); > > If you respin this patch. My preference is to use the __rte_unused attribute in > the function > declaration rather RTE_SET_USED(), mainly because it makes it more obvious > in the start of the function. Hi Stephen, I am respinning the series but the RTE_SET_USED is removed in the 2/6. - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + Thanks, Pavan. ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 2/6] eventdev: add event port pre-schedule modify 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-05 7:59 ` [PATCH v7 1/6] eventdev: introduce " pbhagavatula @ 2024-10-05 7:59 ` pbhagavatula 2024-10-05 7:59 ` [PATCH v7 3/6] eventdev: add event preschedule hint pbhagavatula ` (4 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:59 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. To avoid fastpath capability checks, the API reports -ENOTSUP if the event device does not support this feature. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 ++++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 16 ++++++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 +++++++ lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 60 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 ++- lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 10 files changed, 164 insertions(+), 7 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index a45d1396d7..a9258d2abc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1252,7 +1252,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1270,7 +1271,11 @@ preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const cha TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1335,13 +1340,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1349,7 +1354,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); } @@ -1357,6 +1362,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1419,6 +1452,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 9da5531859..dd7bf61dd0 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -380,6 +380,22 @@ The following pre-schedule types are supported: * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +Event devices that support ``RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE`` capability allow +applications to modify pre-scheduling at a per port level at runtime in fast-path. +To modify event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. +This API can be called even if the event device does not support per port pre-scheduling, it +will be treated as a no-op. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index a294a753e7..f7cc2ec047 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -74,6 +74,8 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. Removed Items diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..cc5963b31b 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint( + __rte_unused void *port, __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 4b69e74577..15606752c7 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -709,18 +719,23 @@ enum rte_event_dev_preschedule_type { RTE_EVENT_PRESCHEDULE_NONE, /**< Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_PRESCHEDULE, /**< Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ RTE_EVENT_PRESCHEDULE_ADAPTIVE, /**< Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ }; @@ -2923,6 +2938,51 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Modify the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * To avoid fastpath capability checks if an event device does not support + * RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability, then this function will + * return -ENOTSUP. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + * - -ENOTSUP if the device does not support per port preschedule capability. + */ +__rte_experimental static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..5f4c25b1c5 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,7 +80,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ - uintptr_t reserved[4]; + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ + uintptr_t reserved[3]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 3/6] eventdev: add event preschedule hint 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-05 7:59 ` [PATCH v7 1/6] eventdev: introduce " pbhagavatula 2024-10-05 7:59 ` [PATCH v7 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-05 7:59 ` pbhagavatula 2024-10-05 7:59 ` [PATCH v7 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (3 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:59 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD, if event device does not support this feature it is treated as a no-op. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 9 ++++ doc/guides/rel_notes/release_24_11.rst | 3 +- lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 50 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 +++- lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 102 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index dd7bf61dd0..6a30b9fabc 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -395,6 +395,15 @@ will be treated as a no-op. // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Application may provide a hint to the eventdev PMD to pre-schedule the next event without +releasing the current flow context. Event device that support this feature advertises +the capability via the ``RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT`` flag. +If pre-scheduling is already enabled at a event device or event port level or if the +capability is not supported then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index f7cc2ec047..e4ba9c2d53 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -76,7 +76,8 @@ New Features level pre-scheduling type. * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. - + * Added ``rte_event_port_preschedule`` to allow applications provide explicit + pre-schedule hints to event ports. Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index cc5963b31b..b628f4a69e 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint( return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 15606752c7..518a52ecb9 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT (1ULL << 19) +/**< Event device supports explicit prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -2983,6 +2992,47 @@ rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability. + * + * When pre-scheduling is enabled at an event device/port level or if + * the capability is not supported, then the hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +__rte_experimental static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 5f4c25b1c5..2706d5e6c8 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,10 @@ typedef int (*event_preschedule_modify_t)(void *port, enum rte_event_dev_preschedule_type preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,7 +86,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ - uintptr_t reserved[3]; + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ + uintptr_t reserved[2]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 4/6] event/cnkx: add pre-schedule support 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula ` (2 preceding siblings ...) 2024-10-05 7:59 ` [PATCH v7 3/6] eventdev: add event preschedule hint pbhagavatula @ 2024-10-05 7:59 ` pbhagavatula 2024-10-05 8:00 ` [PATCH v7 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (2 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 7:59 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/cnxk.rst | 10 ---------- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 19 +++++++++++++++++-- drivers/event/cnxk/cn10k_worker.c | 21 +++++++++++++++++++++ drivers/event/cnxk/cn10k_worker.h | 2 ++ drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst index d038930594..e21846f4e0 100644 --- a/doc/guides/eventdevs/cnxk.rst +++ b/doc/guides/eventdevs/cnxk.rst @@ -78,16 +78,6 @@ Runtime Config Options -a 0002:0e:00.0,single_ws=1 -- ``CN10K Getwork mode`` - - CN10K supports three getwork prefetch modes no prefetch[0], prefetch - immediately[1] and delayed prefetch on forward progress event[2]. - The default getwork mode is 2. - - For example:: - - -a 0002:0e:00.0,gw_mode=1 - - ``Event Group QoS support`` SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..5bd779990e 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -527,6 +527,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +542,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +570,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1216,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1272,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cn10k_worker.c b/drivers/event/cnxk/cn10k_worker.c index d59769717e..a0e85face1 100644 --- a/drivers/event/cnxk/cn10k_worker.c +++ b/drivers/event/cnxk/cn10k_worker.c @@ -442,3 +442,24 @@ cn10k_sso_hws_profile_switch(void *port, uint8_t profile) return 0; } + +int __rte_hot +cn10k_sso_hws_preschedule_modify(void *port, enum rte_event_dev_preschedule_type type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= ~(BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + break; + case RTE_EVENT_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} diff --git a/drivers/event/cnxk/cn10k_worker.h b/drivers/event/cnxk/cn10k_worker.h index c5026409d7..4785cc6575 100644 --- a/drivers/event/cnxk/cn10k_worker.h +++ b/drivers/event/cnxk/cn10k_worker.h @@ -377,6 +377,8 @@ uint16_t __rte_hot cn10k_sso_hws_enq_fwd_burst(void *port, const struct rte_event ev[], uint16_t nb_events); int __rte_hot cn10k_sso_hws_profile_switch(void *port, uint8_t profile); +int __rte_hot cn10k_sso_hws_preschedule_modify(void *port, + enum rte_event_dev_preschedule_type type); #define R(name, flags) \ uint16_t __rte_hot cn10k_sso_hws_deq_##name( \ diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 5/6] app/test-eventdev: add pre-scheduling support 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula ` (3 preceding siblings ...) 2024-10-05 7:59 ` [PATCH v7 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-05 8:00 ` pbhagavatula 2024-10-05 8:00 ` [PATCH v7 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 8:00 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..901b8ba55d 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v7 6/6] examples: use eventdev pre-scheduling 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula ` (4 preceding siblings ...) 2024-10-05 8:00 ` [PATCH v7 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-05 8:00 ` pbhagavatula 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-05 8:00 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 831d7fd53d..06384c683c 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -192,6 +192,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..c9a04cad56 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..dadddcb306 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d805264744 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..26233d1ab6 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..d86439df52 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..b390e3469d 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 0/6] Introduce event pre-scheduling 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula ` (5 preceding siblings ...) 2024-10-05 8:00 ` [PATCH v7 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-06 17:06 ` [PATCH v8 1/6] eventdev: introduce " pbhagavatula ` (6 more replies) 6 siblings, 7 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. v4 Changes: - Fix compilation. v5 Changes: - Update ABI changes - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE - Various documentation fixes and updates. v6 Changes: - Mark new APIs as experimental (Stephen). v7 Changes: - Use correct patchset for rebase. v8 Changes: - fix checkpatch issues. Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 +++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/cnxk.rst | 10 -- doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ doc/guides/rel_notes/release_24_11.rst | 13 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 19 ++- drivers/event/cnxk/cn10k_worker.c | 21 +++ drivers/event/cnxk/cn10k_worker.h | 2 + drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 161 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 14 +- lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 29 files changed, 594 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 1/6] eventdev: introduce event pre-scheduling 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-06 17:06 ` [PATCH v8 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (5 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 23 +++++ doc/guides/rel_notes/release_24_11.rst | 10 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++ 5 files changed, 191 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index 9a6c8f470c..a45d1396d7 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,6 +1251,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(enum rte_event_dev_preschedule_type type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS(rc, + "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1311,6 +1417,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 1cc4303fe5..c8d5ed2d74 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -22,6 +22,7 @@ carry_flow_id = maintenance_free = runtime_queue_attr = profile_links = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index fb6dfce102..9da5531859 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,29 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application must check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` or ``RTE_EVENT_DEV_CAP_PRESCHEDULE_ADAPTIVE`` set, if +present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +The following pre-schedule types are supported: + * ``RTE_EVENT_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index e0a9aa55a1..a294a753e7 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -67,6 +67,14 @@ New Features The new statistics are useful for debugging and profiling. +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- @@ -112,6 +120,8 @@ ABI Changes Also, make sure to start the actual text at the margin. ======================================================= +* eventdev: Added ``preschedule_type`` field to ``rte_event_dev_config`` + structure. Known Issues ------------ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 08e5f9320b..4b69e74577 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -446,6 +446,30 @@ struct rte_event; * @see RTE_SCHED_TYPE_PARALLEL */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 16) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 17) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -680,6 +704,26 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +/** Event device pre-schedule type enumeration. */ +enum rte_event_dev_preschedule_type { + RTE_EVENT_PRESCHEDULE_NONE, + /**< Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_PRESCHEDULE, + /**< Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_PRESCHEDULE_ADAPTIVE, + /**< Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +}; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -752,6 +796,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + enum rte_event_dev_preschedule_type preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 2/6] eventdev: add event port pre-schedule modify 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-06 17:06 ` [PATCH v8 1/6] eventdev: introduce " pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-06 17:06 ` [PATCH v8 3/6] eventdev: add event preschedule hint pbhagavatula ` (4 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. To avoid fastpath capability checks, the API reports -ENOTSUP if the event device does not support this feature. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 +++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 16 ++++++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 +++++++ lib/eventdev/eventdev_trace_points.c | 3 + lib/eventdev/rte_eventdev.h | 61 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 ++- lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 10 files changed, 165 insertions(+), 7 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index a45d1396d7..a9258d2abc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1252,7 +1252,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1270,7 +1271,11 @@ preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const cha TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1335,13 +1340,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1349,7 +1354,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); } @@ -1357,6 +1362,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1419,6 +1452,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 9da5531859..dd7bf61dd0 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -380,6 +380,22 @@ The following pre-schedule types are supported: * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +Event devices that support ``RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE`` capability allow +applications to modify pre-scheduling at a per port level at runtime in fast-path. +To modify event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. +This API can be called even if the event device does not support per port pre-scheduling, it +will be treated as a no-op. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index a294a753e7..f7cc2ec047 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -74,6 +74,8 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. Removed Items diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..cc5963b31b 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint( + __rte_unused void *port, __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 4b69e74577..8f36a4f7f8 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -470,6 +470,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE (1ULL << 18) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -709,18 +719,23 @@ enum rte_event_dev_preschedule_type { RTE_EVENT_PRESCHEDULE_NONE, /**< Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_PRESCHEDULE, /**< Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ RTE_EVENT_PRESCHEDULE_ADAPTIVE, /**< Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ }; @@ -2923,6 +2938,52 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Modify the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * To avoid fastpath capability checks if an event device does not support + * RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability, then this function will + * return -ENOTSUP. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + * - -ENOTSUP if the device does not support per port preschedule capability. + */ +__rte_experimental +static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..5f4c25b1c5 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,7 +80,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ - uintptr_t reserved[4]; + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ + uintptr_t reserved[3]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 3/6] eventdev: add event preschedule hint 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-06 17:06 ` [PATCH v8 1/6] eventdev: introduce " pbhagavatula 2024-10-06 17:06 ` [PATCH v8 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-07 12:24 ` Jerin Jacob 2024-10-06 17:06 ` [PATCH v8 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (3 subsequent siblings) 6 siblings, 1 reply; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD, if event device does not support this feature it is treated as a no-op. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 9 ++++ doc/guides/rel_notes/release_24_11.rst | 3 +- lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 51 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 +++- lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 103 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index dd7bf61dd0..6a30b9fabc 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -395,6 +395,15 @@ will be treated as a no-op. // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Application may provide a hint to the eventdev PMD to pre-schedule the next event without +releasing the current flow context. Event device that support this feature advertises +the capability via the ``RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT`` flag. +If pre-scheduling is already enabled at a event device or event port level or if the +capability is not supported then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index f7cc2ec047..e4ba9c2d53 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -76,7 +76,8 @@ New Features level pre-scheduling type. * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. - + * Added ``rte_event_port_preschedule`` to allow applications provide explicit + pre-schedule hints to event ports. Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index cc5963b31b..b628f4a69e 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint( return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 8f36a4f7f8..894b547a64 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -480,6 +480,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT (1ULL << 19) +/**< Event device supports explicit prescheduling. + * + * When this flag is set, the application can issue preschedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -2984,6 +2993,48 @@ rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability. + * + * When pre-scheduling is enabled at an event device/port level or if + * the capability is not supported, then the hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +__rte_experimental +static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 5f4c25b1c5..2706d5e6c8 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,10 @@ typedef int (*event_preschedule_modify_t)(void *port, enum rte_event_dev_preschedule_type preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,7 +86,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ - uintptr_t reserved[3]; + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ + uintptr_t reserved[2]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v8 3/6] eventdev: add event preschedule hint 2024-10-06 17:06 ` [PATCH v8 3/6] eventdev: add event preschedule hint pbhagavatula @ 2024-10-07 12:24 ` Jerin Jacob 0 siblings, 0 replies; 77+ messages in thread From: Jerin Jacob @ 2024-10-07 12:24 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, dev On Sun, Oct 6, 2024 at 10:44 PM <pbhagavatula@marvell.com> wrote: > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Add a new eventdev API to provide a hint to the eventdev PMD to > pre-schedule the next event into the event port, without releasing > the current flow context. > Event device that support this feature advertises the capability > using the RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability flag. > > Application can invoke `rte_event_port_preschedule` to hint the PMD, > if event device does not support this feature it is treated as a no-op. > > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> > --- > Starting the EventDev > ~~~~~~~~~~~~~~~~~~~~~ > diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst > index f7cc2ec047..e4ba9c2d53 100644 > --- a/doc/guides/rel_notes/release_24_11.rst > +++ b/doc/guides/rel_notes/release_24_11.rst > @@ -76,7 +76,8 @@ New Features > level pre-scheduling type. > * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type > on a given event port. > - 1) Don't delete this new line. Also add new line between features. Final one should like below, <NEWLINE> * **Added event device pre-scheduling support.** <NEWLINE> Added support for pre-scheduling of events to event ports to improve scheduling performance and latency. <NEWLINE> * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. <NEWLINE> * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. <NEWLINE> * Added ``rte_event_port_preschedule`` to allow applications provide explicit pre-schedule hints to event ports. <NEWLINE> <NEWLINE> 2)Due to the merge of https://patches.dpdk.org/project/dpdk/list/?series=33326 Capa flags value are changed. Please rebase. > + * Added ``rte_event_port_preschedule`` to allow applications provide explicit > + pre-schedule hints to event ports. > ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 4/6] event/cnkx: add pre-schedule support 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula ` (2 preceding siblings ...) 2024-10-06 17:06 ` [PATCH v8 3/6] eventdev: add event preschedule hint pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-06 17:06 ` [PATCH v8 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (2 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/cnxk.rst | 10 ---------- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 19 +++++++++++++++++-- drivers/event/cnxk/cn10k_worker.c | 21 +++++++++++++++++++++ drivers/event/cnxk/cn10k_worker.h | 2 ++ drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst index d038930594..e21846f4e0 100644 --- a/doc/guides/eventdevs/cnxk.rst +++ b/doc/guides/eventdevs/cnxk.rst @@ -78,16 +78,6 @@ Runtime Config Options -a 0002:0e:00.0,single_ws=1 -- ``CN10K Getwork mode`` - - CN10K supports three getwork prefetch modes no prefetch[0], prefetch - immediately[1] and delayed prefetch on forward progress event[2]. - The default getwork mode is 2. - - For example:: - - -a 0002:0e:00.0,gw_mode=1 - - ``Event Group QoS support`` SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..5bd779990e 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -527,6 +527,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +542,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +570,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1216,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1272,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cn10k_worker.c b/drivers/event/cnxk/cn10k_worker.c index d59769717e..a0e85face1 100644 --- a/drivers/event/cnxk/cn10k_worker.c +++ b/drivers/event/cnxk/cn10k_worker.c @@ -442,3 +442,24 @@ cn10k_sso_hws_profile_switch(void *port, uint8_t profile) return 0; } + +int __rte_hot +cn10k_sso_hws_preschedule_modify(void *port, enum rte_event_dev_preschedule_type type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= ~(BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + break; + case RTE_EVENT_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} diff --git a/drivers/event/cnxk/cn10k_worker.h b/drivers/event/cnxk/cn10k_worker.h index c5026409d7..4785cc6575 100644 --- a/drivers/event/cnxk/cn10k_worker.h +++ b/drivers/event/cnxk/cn10k_worker.h @@ -377,6 +377,8 @@ uint16_t __rte_hot cn10k_sso_hws_enq_fwd_burst(void *port, const struct rte_event ev[], uint16_t nb_events); int __rte_hot cn10k_sso_hws_profile_switch(void *port, uint8_t profile); +int __rte_hot cn10k_sso_hws_preschedule_modify(void *port, + enum rte_event_dev_preschedule_type type); #define R(name, flags) \ uint16_t __rte_hot cn10k_sso_hws_deq_##name( \ diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 5/6] app/test-eventdev: add pre-scheduling support 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula ` (3 preceding siblings ...) 2024-10-06 17:06 ` [PATCH v8 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-06 17:06 ` [PATCH v8 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..901b8ba55d 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v8 6/6] examples: use eventdev pre-scheduling 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula ` (4 preceding siblings ...) 2024-10-06 17:06 ` [PATCH v8 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-06 17:06 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-06 17:06 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 831d7fd53d..06384c683c 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -192,6 +192,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..c9a04cad56 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..dadddcb306 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d805264744 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..26233d1ab6 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..d86439df52 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..b390e3469d 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 0/6] Introduce event pre-scheduling 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula ` (5 preceding siblings ...) 2024-10-06 17:06 ` [PATCH v8 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 1/6] eventdev: introduce " pbhagavatula ` (6 more replies) 6 siblings, 7 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. This series introduces various types and levels of pre-scheduling to the eventdev library. pre-scheduling Types: * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. pre-scheduling Levels: * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the event device during configuration. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled at the event port during runtime. Event devices can indicate this capability using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info function `info.event_port_cap`. * Application Controlled Prefetch Hint: Applications can provide hints to the event device to start pre-scheduling events using the new API `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function `info.event_dev_cap`. The rte_event_dequeue_burst operation initiates the pre-schedule operation, which completes in parallel without affecting the flow context of the dequeued events and dequeue latency. On the next dequeue operation, the pre-scheduleed events are dequeued, and pre-schedule operation is initiated again. In the case of application-controlled pre-schedule hints, the currently held flow contexts, if any, are not affected by the pre-schedule operation. On the next dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not initiated again until the application provides the hint again. If pre-scheduling is already enabled at the event device level or event port level, the hint is ignored. v2 Changes: - s/prefetch/pre-schedule (Mattias). v3 Changes: - Add CNXK preschedule implementation. - Update test-eventdev to use prescheduling. - Update examples to use prescheduling. v4 Changes: - Fix compilation. v5 Changes: - Update ABI changes - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE - Various documentation fixes and updates. v6 Changes: - Mark new APIs as experimental (Stephen). v7 Changes: - Use correct patchset for rebase. v8 Changes: - fix checkpatch issues. v9 Changes: - Rebase update capability bits, fix release notes format. Pavan Nikhilesh (6): eventdev: introduce event pre-scheduling eventdev: add event port pre-schedule modify eventdev: add event preschedule hint event/cnkx: add pre-schedule support app/test-eventdev: add pre-scheduling support examples: use eventdev pre-scheduling app/test-eventdev/evt_common.h | 45 +++-- app/test-eventdev/evt_options.c | 17 ++ app/test-eventdev/evt_options.h | 1 + app/test/test_eventdev.c | 143 ++++++++++++++++ doc/guides/eventdevs/cnxk.rst | 10 -- doc/guides/eventdevs/features/cnxk.ini | 1 + doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 48 ++++++ doc/guides/rel_notes/release_24_11.rst | 16 ++ doc/guides/tools/testeventdev.rst | 6 + drivers/event/cnxk/cn10k_eventdev.c | 19 ++- drivers/event/cnxk/cn10k_worker.c | 21 +++ drivers/event/cnxk/cn10k_worker.h | 2 + drivers/event/cnxk/cnxk_eventdev.c | 2 - drivers/event/cnxk/cnxk_eventdev.h | 1 - .../pipeline_worker_generic.c | 6 + .../eventdev_pipeline/pipeline_worker_tx.c | 6 + examples/ipsec-secgw/event_helper.c | 6 + examples/l2fwd-event/l2fwd_event_generic.c | 6 + .../l2fwd-event/l2fwd_event_internal_port.c | 6 + examples/l3fwd/l3fwd_event_generic.c | 6 + examples/l3fwd/l3fwd_event_internal_port.c | 6 + lib/eventdev/eventdev_pmd.h | 4 + lib/eventdev/eventdev_private.c | 41 ++++- lib/eventdev/eventdev_trace_points.c | 6 + lib/eventdev/rte_eventdev.h | 161 ++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 14 +- lib/eventdev/rte_eventdev_trace_fp.h | 19 ++- lib/eventdev/version.map | 6 + 29 files changed, 597 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 1/6] eventdev: introduce event pre-scheduling 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 2/6] eventdev: add event port pre-schedule modify pbhagavatula ` (5 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Event pre-scheduling improves scheduling performance by assigning events to event ports in advance when dequeues are issued. The dequeue operation initiates the pre-schedule operation, which completes in parallel without affecting the dequeued event flow contexts and dequeue latency. Event devices can indicate pre-scheduling capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info function `info.event_dev_cap`. Applications can select the pre-schedule type and configure it through `rte_event_dev_config.preschedule_type` during `rte_event_dev_configure`. The supported pre-schedule types are: * `RTE_EVENT_PRESCHEDULE_NONE` - No pre-scheduling. * `RTE_EVENT_PRESCHEDULE` - Always issue a pre-schedule on dequeue. * `RTE_EVENT_PRESCHEDULE_ADAPTIVE` - Delay issuing pre-schedule until there are no forward progress constraints with the held flow contexts. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 108 ++++++++++++++++++++ doc/guides/eventdevs/features/default.ini | 1 + doc/guides/prog_guide/eventdev/eventdev.rst | 23 +++++ doc/guides/rel_notes/release_24_11.rst | 10 ++ lib/eventdev/rte_eventdev.h | 49 +++++++++ 5 files changed, 191 insertions(+) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index 9a6c8f470c..a45d1396d7 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1251,6 +1251,112 @@ test_eventdev_profile_switch(void) return TEST_SUCCESS; } +static int +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +{ +#define NB_EVENTS 1024 + uint64_t start, total; + struct rte_event ev; + int rc, cnt; + + ev.event_type = RTE_EVENT_TYPE_CPU; + ev.queue_id = 0; + ev.op = RTE_EVENT_OP_NEW; + ev.u64 = 0xBADF00D0; + + for (cnt = 0; cnt < NB_EVENTS; cnt++) { + ev.flow_id = cnt; + rc = rte_event_enqueue_burst(TEST_DEV_ID, 0, &ev, 1); + TEST_ASSERT(rc == 1, "Failed to enqueue event"); + } + + RTE_SET_USED(preschedule_type); + total = 0; + while (cnt) { + start = rte_rdtsc_precise(); + rc = rte_event_dequeue_burst(TEST_DEV_ID, 0, &ev, 1, 0); + if (rc) { + total += rte_rdtsc_precise() - start; + cnt--; + } + } + printf("Preschedule type : %s, avg cycles %" PRIu64 "\n", preschedule_name, + total / NB_EVENTS); + + return TEST_SUCCESS; +} + +static int +preschedule_configure(enum rte_event_dev_preschedule_type type, struct rte_event_dev_info *info) +{ + struct rte_event_dev_config dev_conf; + struct rte_event_queue_conf qcfg; + struct rte_event_port_conf pcfg; + int rc; + + devconf_set_default_sane_values(&dev_conf, info); + dev_conf.nb_event_ports = 1; + dev_conf.nb_event_queues = 1; + dev_conf.preschedule_type = type; + + rc = rte_event_dev_configure(TEST_DEV_ID, &dev_conf); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + + rc = rte_event_port_default_conf_get(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get port0 default config"); + rc = rte_event_port_setup(TEST_DEV_ID, 0, &pcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup port0"); + + rc = rte_event_queue_default_conf_get(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to get queue0 default config"); + rc = rte_event_queue_setup(TEST_DEV_ID, 0, &qcfg); + TEST_ASSERT_SUCCESS(rc, "Failed to setup queue0"); + + rc = rte_event_port_link(TEST_DEV_ID, 0, NULL, NULL, 0); + TEST_ASSERT(rc == (int)dev_conf.nb_event_queues, "Failed to link port, device %d", + TEST_DEV_ID); + + rc = rte_event_dev_start(TEST_DEV_ID); + TEST_ASSERT_SUCCESS(rc, "Failed to start event device"); + + return 0; +} + +static int +test_eventdev_preschedule_configure(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rte_event_dev_stop(TEST_DEV_ID); + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + TEST_ASSERT_SUCCESS(rc, + "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1311,6 +1417,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_start_stop), TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, test_eventdev_profile_switch), + TEST_CASE_ST(eventdev_configure_setup, NULL, + test_eventdev_preschedule_configure), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/eventdevs/features/default.ini b/doc/guides/eventdevs/features/default.ini index 7c4ee99238..fa24ba38b4 100644 --- a/doc/guides/eventdevs/features/default.ini +++ b/doc/guides/eventdevs/features/default.ini @@ -23,6 +23,7 @@ maintenance_free = runtime_queue_attr = profile_links = independent_enq = +preschedule = ; ; Features of a default Ethernet Rx adapter. diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index 515744d8ec..a630ac7ebe 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -357,6 +357,29 @@ Worker path: // Process the event received. } +Event Pre-scheduling +~~~~~~~~~~~~~~~~~~~~ + +Event pre-scheduling improves scheduling performance by assigning events to event ports in advance +when dequeues are issued. +The `rte_event_dequeue_burst` operation initiates the pre-schedule operation, which completes +in parallel without affecting the dequeued event flow contexts and dequeue latency. +On the next dequeue operation, the pre-scheduled events are dequeued and pre-schedule is initiated +again. + +An application can use event pre-scheduling if the event device supports it at either device +level or at a individual port level. +The application must check pre-schedule capability by checking if ``rte_event_dev_info.event_dev_cap`` +has the bit ``RTE_EVENT_DEV_CAP_PRESCHEDULE`` or ``RTE_EVENT_DEV_CAP_PRESCHEDULE_ADAPTIVE`` set, if +present pre-scheduling can be enabled at device +configuration time by setting appropriate pre-schedule type in ``rte_event_dev_config.preschedule``. + +The following pre-schedule types are supported: + * ``RTE_EVENT_PRESCHEDULE_NONE`` - No pre-scheduling. + * ``RTE_EVENT_PRESCHEDULE`` - Always issue a pre-schedule when dequeue is issued. + * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are + no forward progress constraints. + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index f806c08244..94e1d30777 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -79,6 +79,14 @@ New Features * Updated DSW driver for independent enqueue feature. +* **Added event device pre-scheduling support.** + + Added support for pre-scheduling of events to event ports to improve + scheduling performance and latency. + + * Added ``rte_event_dev_config::preschedule_type`` to configure the device + level pre-scheduling type. + Removed Items ------------- @@ -124,6 +132,8 @@ ABI Changes Also, make sure to start the actual text at the margin. ======================================================= +* eventdev: Added ``preschedule_type`` field to ``rte_event_dev_config`` + structure. Known Issues ------------ diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 73a44b2ac5..00bbd3b28f 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -465,6 +465,30 @@ struct rte_event; * only applies to ports that have enabled independent enqueue feature. */ +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE (1ULL << 17) +/**< Event device supports event pre-scheduling. + * + * When this capability is available, the application can enable event pre-scheduling on the event + * device to pre-schedule events to a event port when `rte_event_dequeue_burst()` + * is issued. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + +#define RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE (1ULL << 18) +/**< Event device supports adaptive event pre-scheduling. + * + * When this capability is available, the application can enable adaptive pre-scheduling + * on the event device where the events are pre-scheduled when there are no forward + * progress constraints with the currently held flow contexts. + * The pre-schedule process starts with the `rte_event_dequeue_burst()` call and the + * pre-scheduled events are returned on the next `rte_event_dequeue_burst()` call. + * + * @see rte_event_dev_configure() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -699,6 +723,26 @@ rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id, * @see rte_event_dequeue_timeout_ticks(), rte_event_dequeue_burst() */ +/** Event device pre-schedule type enumeration. */ +enum rte_event_dev_preschedule_type { + RTE_EVENT_PRESCHEDULE_NONE, + /**< Disable pre-schedule across the event device or on a given event port. + * @ref rte_event_dev_config.preschedule_type + */ + RTE_EVENT_PRESCHEDULE, + /**< Enable pre-schedule always across the event device or a given event port. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + */ + RTE_EVENT_PRESCHEDULE_ADAPTIVE, + /**< Enable adaptive pre-schedule across the event device or a given event port. + * Delay issuing pre-schedule until there are no forward progress constraints with + * the held flow contexts. + * @ref rte_event_dev_config.preschedule_type + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ +}; + /** Event device configuration structure */ struct rte_event_dev_config { uint32_t dequeue_timeout_ns; @@ -771,6 +815,11 @@ struct rte_event_dev_config { * optimized for single-link usage, this field is a hint for how many * to allocate; otherwise, regular event ports and queues will be used. */ + enum rte_event_dev_preschedule_type preschedule_type; + /**< Event pre-schedule type to use across the event device, if supported. + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + */ }; /** -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 2/6] eventdev: add event port pre-schedule modify 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-07 13:09 ` [PATCH v9 1/6] eventdev: introduce " pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 3/6] eventdev: add event preschedule hint pbhagavatula ` (4 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Some event devices allow pre-schedule types to be modified at runtime on an event port. Add `RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE` capability to indicate that the event device supports this feature. Add `rte_event_port_preschedule_modify()` API to modify the pre-schedule type at runtime. To avoid fastpath capability checks, the API reports -ENOTSUP if the event device does not support this feature. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test/test_eventdev.c | 45 +++++++++++++-- doc/guides/prog_guide/eventdev/eventdev.rst | 16 ++++++ doc/guides/rel_notes/release_24_11.rst | 3 + lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 20 +++++++ lib/eventdev/eventdev_trace_points.c | 3 + lib/eventdev/rte_eventdev.h | 61 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 ++- lib/eventdev/rte_eventdev_trace_fp.h | 11 +++- lib/eventdev/version.map | 4 ++ 10 files changed, 166 insertions(+), 7 deletions(-) diff --git a/app/test/test_eventdev.c b/app/test/test_eventdev.c index a45d1396d7..a9258d2abc 100644 --- a/app/test/test_eventdev.c +++ b/app/test/test_eventdev.c @@ -1252,7 +1252,8 @@ test_eventdev_profile_switch(void) } static int -preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name) +preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const char *preschedule_name, + uint8_t modify) { #define NB_EVENTS 1024 uint64_t start, total; @@ -1270,7 +1271,11 @@ preschedule_test(enum rte_event_dev_preschedule_type preschedule_type, const cha TEST_ASSERT(rc == 1, "Failed to enqueue event"); } - RTE_SET_USED(preschedule_type); + if (modify) { + rc = rte_event_port_preschedule_modify(TEST_DEV_ID, 0, preschedule_type); + TEST_ASSERT_SUCCESS(rc, "Failed to modify preschedule type"); + } + total = 0; while (cnt) { start = rte_rdtsc_precise(); @@ -1335,13 +1340,13 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_NONE"); rte_event_dev_stop(TEST_DEV_ID); rc = preschedule_configure(RTE_EVENT_PRESCHEDULE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); - rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE"); if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { @@ -1349,7 +1354,7 @@ test_eventdev_preschedule_configure(void) rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_ADAPTIVE, &info); TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, - "RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 0); TEST_ASSERT_SUCCESS(rc, "Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); } @@ -1357,6 +1362,34 @@ test_eventdev_preschedule_configure(void) return TEST_SUCCESS; } +static int +test_eventdev_preschedule_modify(void) +{ + struct rte_event_dev_info info; + int rc; + + rte_event_dev_info_get(TEST_DEV_ID, &info); + if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE) == 0) + return TEST_SKIPPED; + + rc = preschedule_configure(RTE_EVENT_PRESCHEDULE_NONE, &info); + TEST_ASSERT_SUCCESS(rc, "Failed to configure eventdev"); + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_NONE, "RTE_EVENT_PRESCHEDULE_NONE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_NONE"); + + rc = preschedule_test(RTE_EVENT_PRESCHEDULE, "RTE_EVENT_PRESCHEDULE", 1); + TEST_ASSERT_SUCCESS(rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE"); + + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) { + rc = preschedule_test(RTE_EVENT_PRESCHEDULE_ADAPTIVE, + "RTE_EVENT_PRESCHEDULE_ADAPTIVE", 1); + TEST_ASSERT_SUCCESS( + rc, "Failed to test per port preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE"); + } + + return TEST_SUCCESS; +} + static int test_eventdev_close(void) { @@ -1419,6 +1452,8 @@ static struct unit_test_suite eventdev_common_testsuite = { test_eventdev_profile_switch), TEST_CASE_ST(eventdev_configure_setup, NULL, test_eventdev_preschedule_configure), + TEST_CASE_ST(eventdev_configure_setup, eventdev_stop_device, + test_eventdev_preschedule_modify), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, test_eventdev_link), TEST_CASE_ST(eventdev_setup_device, eventdev_stop_device, diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index a630ac7ebe..e3fbfb11f4 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -380,6 +380,22 @@ The following pre-schedule types are supported: * ``RTE_EVENT_PRESCHEDULE_ADAPTIVE`` - Issue pre-schedule when dequeue is issued and there are no forward progress constraints. +Event devices that support ``RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE`` capability allow +applications to modify pre-scheduling at a per port level at runtime in fast-path. +To modify event pre-scheduling at a given event port, the application can use +``rte_event_port_preschedule_modify()`` API. +This API can be called even if the event device does not support per port pre-scheduling, it +will be treated as a no-op. + +.. code-block:: c + + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE); + // Dequeue events from the event port with normal dequeue() function. + rte_event_port_preschedule_modify(dev_id, port_id, RTE_EVENT_PRESCHEDULE_NONE); + // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain + // pending events. + + Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 94e1d30777..e13a7479ce 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -87,6 +87,9 @@ New Features * Added ``rte_event_dev_config::preschedule_type`` to configure the device level pre-scheduling type. + * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type + on a given event port. + Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 7a5699f14b..9ea23aa6cd 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -184,6 +184,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< Pointer to PMD Event switch profile function. */ + event_preschedule_modify_t preschedule_modify; + /**< Pointer to PMD Event port pre-schedule type modify function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index 017f97ccab..cc5963b31b 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -96,6 +96,21 @@ dummy_event_port_profile_switch(__rte_unused void *port, __rte_unused uint8_t pr return -EINVAL; } +static int +dummy_event_port_preschedule_modify(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("modify pre-schedule requested for unconfigured event device"); + return -EINVAL; +} + +static int +dummy_event_port_preschedule_modify_hint( + __rte_unused void *port, __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + return -ENOTSUP; +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -114,6 +129,7 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, + .preschedule_modify = dummy_event_port_preschedule_modify, .data = dummy_data, }; @@ -136,5 +152,9 @@ event_dev_fp_ops_set(struct rte_event_fp_ops *fp_op, fp_op->ca_enqueue = dev->ca_enqueue; fp_op->dma_enqueue = dev->dma_enqueue; fp_op->profile_switch = dev->profile_switch; + fp_op->preschedule_modify = dev->preschedule_modify; fp_op->data = dev->data->ports; + + if (fp_op->preschedule_modify == NULL) + fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index 8024e07531..e41674123c 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -49,6 +49,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_maintain, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, lib.eventdev.port.profile.switch) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, + lib.eventdev.port.preschedule.modify) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 00bbd3b28f..3aba4cd66c 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -489,6 +489,16 @@ struct rte_event; * @see rte_event_dev_configure() */ +#define RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE (1ULL << 19) +/**< Event device supports event pre-scheduling per event port. + * + * When this flag is set, the event device allows controlling the event + * pre-scheduling at a event port granularity. + * + * @see rte_event_dev_configure() + * @see rte_event_port_preschedule_modify() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -728,18 +738,23 @@ enum rte_event_dev_preschedule_type { RTE_EVENT_PRESCHEDULE_NONE, /**< Disable pre-schedule across the event device or on a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() */ RTE_EVENT_PRESCHEDULE, /**< Enable pre-schedule always across the event device or a given event port. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ RTE_EVENT_PRESCHEDULE_ADAPTIVE, /**< Enable adaptive pre-schedule across the event device or a given event port. * Delay issuing pre-schedule until there are no forward progress constraints with * the held flow contexts. * @ref rte_event_dev_config.preschedule_type + * @ref rte_event_port_preschedule_modify() * @see RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE + * @see RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE */ }; @@ -2954,6 +2969,52 @@ rte_event_port_profile_switch(uint8_t dev_id, uint8_t port_id, uint8_t profile_i return fp_ops->profile_switch(port, profile_id); } +/** + * Modify the pre-schedule type to use on an event port. + * + * This function is used to change the current pre-schedule type configured + * on an event port, the pre-schedule type can be set to none to disable pre-scheduling. + * This effects the subsequent ``rte_event_dequeue_burst`` call. + * The event device should support RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability. + * + * To avoid fastpath capability checks if an event device does not support + * RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE capability, then this function will + * return -ENOTSUP. + * + * @param dev_id + * The identifier of the device. + * @param port_id + * The identifier of the event port. + * @param type + * The preschedule type to use on the event port. + * @return + * - 0 on success. + * - -EINVAL if *dev_id*, *port_id*, or *type* is invalid. + * - -ENOTSUP if the device does not support per port preschedule capability. + */ +__rte_experimental +static inline int +rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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 -EINVAL; + + if (port == NULL) + return -EINVAL; +#endif + rte_eventdev_trace_port_preschedule_modify(dev_id, port_id, type); + + return fp_ops->preschedule_modify(port, type); +} + #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index fc8e1556ab..5f4c25b1c5 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -49,6 +49,10 @@ typedef uint16_t (*event_dma_adapter_enqueue_t)(void *port, struct rte_event ev[ typedef int (*event_profile_switch_t)(void *port, uint8_t profile); /**< @internal Switch active link profile on the event port. */ +typedef int (*event_preschedule_modify_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Modify pre-schedule type on the event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -76,7 +80,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD DMA adapter enqueue function. */ event_profile_switch_t profile_switch; /**< PMD Event switch profile function. */ - uintptr_t reserved[4]; + event_preschedule_modify_t preschedule_modify; + /**< PMD Event port pre-schedule switch. */ + uintptr_t reserved[3]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 04d510ad00..78baed94de 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -8,7 +8,7 @@ /** * @file * - * API for ethdev trace support + * API for eventdev trace support */ #ifdef __cplusplus @@ -54,6 +54,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_u8(profile); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule_modify, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index 4947bb4ec6..b6d63ba576 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -147,6 +147,10 @@ EXPERIMENTAL { rte_event_port_profile_unlink; rte_event_port_profile_links_get; __rte_eventdev_trace_port_profile_switch; + + # added in 24.11 + rte_event_port_preschedule_modify; + __rte_eventdev_trace_port_preschedule_modify; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 3/6] eventdev: add event preschedule hint 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-07 13:09 ` [PATCH v9 1/6] eventdev: introduce " pbhagavatula 2024-10-07 13:09 ` [PATCH v9 2/6] eventdev: add event port pre-schedule modify pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 4/6] event/cnkx: add pre-schedule support pbhagavatula ` (3 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add a new eventdev API to provide a hint to the eventdev PMD to pre-schedule the next event into the event port, without releasing the current flow context. Event device that support this feature advertises the capability using the RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability flag. Application can invoke `rte_event_port_preschedule` to hint the PMD, if event device does not support this feature it is treated as a no-op. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/prog_guide/eventdev/eventdev.rst | 9 ++++ doc/guides/rel_notes/release_24_11.rst | 3 ++ lib/eventdev/eventdev_pmd.h | 2 + lib/eventdev/eventdev_private.c | 21 ++++++++- lib/eventdev/eventdev_trace_points.c | 3 ++ lib/eventdev/rte_eventdev.h | 51 +++++++++++++++++++++ lib/eventdev/rte_eventdev_core.h | 8 +++- lib/eventdev/rte_eventdev_trace_fp.h | 8 ++++ lib/eventdev/version.map | 2 + 9 files changed, 104 insertions(+), 3 deletions(-) diff --git a/doc/guides/prog_guide/eventdev/eventdev.rst b/doc/guides/prog_guide/eventdev/eventdev.rst index e3fbfb11f4..d360cf86cd 100644 --- a/doc/guides/prog_guide/eventdev/eventdev.rst +++ b/doc/guides/prog_guide/eventdev/eventdev.rst @@ -395,6 +395,15 @@ will be treated as a no-op. // Disable pre-scheduling if thread is about to be scheduled out and issue dequeue() to drain // pending events. +Application may provide a hint to the eventdev PMD to pre-schedule the next event without +releasing the current flow context. Event device that support this feature advertises +the capability via the ``RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT`` flag. +If pre-scheduling is already enabled at a event device or event port level or if the +capability is not supported then the hint is ignored. + +.. code-block:: c + + rte_event_port_preschedule(dev_id, port_id, RTE_EVENT_PRESCHEDULE); Starting the EventDev ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index e13a7479ce..2671cae9a8 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -90,6 +90,9 @@ New Features * Added ``rte_event_port_preschedule_modify`` to modify pre-scheduling type on a given event port. + * Added ``rte_event_port_preschedule`` to allow applications provide explicit + pre-schedule hints to event ports. + Removed Items ------------- diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h index 9ea23aa6cd..0bee2347ef 100644 --- a/lib/eventdev/eventdev_pmd.h +++ b/lib/eventdev/eventdev_pmd.h @@ -186,6 +186,8 @@ struct __rte_cache_aligned rte_eventdev { /**< Pointer to PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< Pointer to PMD Event port pre-schedule type modify function. */ + event_preschedule_t preschedule; + /**< Pointer to PMD Event port pre-schedule function. */ uint64_t reserved_64s[3]; /**< Reserved for future fields */ void *reserved_ptrs[3]; /**< Reserved for future fields */ diff --git a/lib/eventdev/eventdev_private.c b/lib/eventdev/eventdev_private.c index cc5963b31b..b628f4a69e 100644 --- a/lib/eventdev/eventdev_private.c +++ b/lib/eventdev/eventdev_private.c @@ -111,6 +111,19 @@ dummy_event_port_preschedule_modify_hint( return -ENOTSUP; } +static void +dummy_event_port_preschedule(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ + RTE_EDEV_LOG_ERR("pre-schedule requested for unconfigured event device"); +} + +static void +dummy_event_port_preschedule_hint(__rte_unused void *port, + __rte_unused enum rte_event_dev_preschedule_type preschedule) +{ +} + void event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) { @@ -124,12 +137,12 @@ event_dev_fp_ops_reset(struct rte_event_fp_ops *fp_op) .dequeue_burst = dummy_event_dequeue_burst, .maintain = dummy_event_maintain, .txa_enqueue = dummy_event_tx_adapter_enqueue, - .txa_enqueue_same_dest = - dummy_event_tx_adapter_enqueue_same_dest, + .txa_enqueue_same_dest = dummy_event_tx_adapter_enqueue_same_dest, .ca_enqueue = dummy_event_crypto_adapter_enqueue, .dma_enqueue = dummy_event_dma_adapter_enqueue, .profile_switch = dummy_event_port_profile_switch, .preschedule_modify = dummy_event_port_preschedule_modify, + .preschedule = dummy_event_port_preschedule, .data = dummy_data, }; @@ -153,8 +166,12 @@ 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->preschedule_modify = dev->preschedule_modify; + fp_op->preschedule = dev->preschedule; fp_op->data = dev->data->ports; if (fp_op->preschedule_modify == NULL) fp_op->preschedule_modify = dummy_event_port_preschedule_modify_hint; + + if (fp_op->preschedule == NULL) + fp_op->preschedule = dummy_event_port_preschedule_hint; } diff --git a/lib/eventdev/eventdev_trace_points.c b/lib/eventdev/eventdev_trace_points.c index e41674123c..e7af1591f7 100644 --- a/lib/eventdev/eventdev_trace_points.c +++ b/lib/eventdev/eventdev_trace_points.c @@ -52,6 +52,9 @@ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_profile_switch, RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule_modify, lib.eventdev.port.preschedule.modify) +RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_port_preschedule, + lib.eventdev.port.preschedule) + /* Eventdev Rx adapter trace points */ RTE_TRACE_POINT_REGISTER(rte_eventdev_trace_eth_rx_adapter_create, lib.eventdev.rx.adapter.create) diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h index 3aba4cd66c..06cf8896e0 100644 --- a/lib/eventdev/rte_eventdev.h +++ b/lib/eventdev/rte_eventdev.h @@ -499,6 +499,15 @@ struct rte_event; * @see rte_event_port_preschedule_modify() */ +#define RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT (1ULL << 20) +/**< Event device supports explicit pre-scheduling. + * + * When this flag is set, the application can issue pre-schedule request on + * a event port. + * + * @see rte_event_port_preschedule() + */ + /* Event device priority levels */ #define RTE_EVENT_DEV_PRIORITY_HIGHEST 0 /**< Highest priority level for events and queues. @@ -3015,6 +3024,48 @@ rte_event_port_preschedule_modify(uint8_t dev_id, uint8_t port_id, return fp_ops->preschedule_modify(port, type); } +/** + * Provide a hint to the event device to pre-schedule events to event port . + * + * Hint the event device to pre-schedule events to the event port. + * The call doesn't not guarantee that the events will be pre-scheduleed. + * The call doesn't release the flow context currently held by the event port. + * The event device should support RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT capability. + * + * When pre-scheduling is enabled at an event device/port level or if + * the capability is not supported, then the hint is ignored. + * + * Subsequent calls to rte_event_dequeue_burst() will dequeue the pre-schedule + * events but pre-schedule 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 pre-schedule type to use on the event port. + */ +__rte_experimental +static inline void +rte_event_port_preschedule(uint8_t dev_id, uint8_t port_id, + enum rte_event_dev_preschedule_type 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_preschedule(dev_id, port_id, type); + + fp_ops->preschedule(port, type); +} #ifdef __cplusplus } #endif diff --git a/lib/eventdev/rte_eventdev_core.h b/lib/eventdev/rte_eventdev_core.h index 5f4c25b1c5..2706d5e6c8 100644 --- a/lib/eventdev/rte_eventdev_core.h +++ b/lib/eventdev/rte_eventdev_core.h @@ -53,6 +53,10 @@ typedef int (*event_preschedule_modify_t)(void *port, enum rte_event_dev_preschedule_type preschedule_type); /**< @internal Modify pre-schedule type on the event port. */ +typedef void (*event_preschedule_t)(void *port, + enum rte_event_dev_preschedule_type preschedule_type); +/**< @internal Issue pre-schedule on an event port. */ + struct __rte_cache_aligned rte_event_fp_ops { void **data; /**< points to array of internal port data pointers */ @@ -82,7 +86,9 @@ struct __rte_cache_aligned rte_event_fp_ops { /**< PMD Event switch profile function. */ event_preschedule_modify_t preschedule_modify; /**< PMD Event port pre-schedule switch. */ - uintptr_t reserved[3]; + event_preschedule_t preschedule; + /**< PMD Event port pre-schedule. */ + uintptr_t reserved[2]; }; extern struct rte_event_fp_ops rte_event_fp_ops[RTE_EVENT_MAX_DEVS]; diff --git a/lib/eventdev/rte_eventdev_trace_fp.h b/lib/eventdev/rte_eventdev_trace_fp.h index 78baed94de..8290f8a248 100644 --- a/lib/eventdev/rte_eventdev_trace_fp.h +++ b/lib/eventdev/rte_eventdev_trace_fp.h @@ -63,6 +63,14 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(type); ) +RTE_TRACE_POINT_FP( + rte_eventdev_trace_port_preschedule, + 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, diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map index b6d63ba576..42a5867aba 100644 --- a/lib/eventdev/version.map +++ b/lib/eventdev/version.map @@ -151,6 +151,8 @@ EXPERIMENTAL { # added in 24.11 rte_event_port_preschedule_modify; __rte_eventdev_trace_port_preschedule_modify; + rte_event_port_preschedule; + __rte_eventdev_trace_port_preschedule; }; INTERNAL { -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 4/6] event/cnkx: add pre-schedule support 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula ` (2 preceding siblings ...) 2024-10-07 13:09 ` [PATCH v9 3/6] eventdev: add event preschedule hint pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula ` (2 subsequent siblings) 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add device level and port level pre-schedule support for cnxk eventdev. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- doc/guides/eventdevs/cnxk.rst | 10 ---------- doc/guides/eventdevs/features/cnxk.ini | 1 + drivers/event/cnxk/cn10k_eventdev.c | 19 +++++++++++++++++-- drivers/event/cnxk/cn10k_worker.c | 21 +++++++++++++++++++++ drivers/event/cnxk/cn10k_worker.h | 2 ++ drivers/event/cnxk/cnxk_eventdev.c | 2 -- drivers/event/cnxk/cnxk_eventdev.h | 1 - 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst index d038930594..e21846f4e0 100644 --- a/doc/guides/eventdevs/cnxk.rst +++ b/doc/guides/eventdevs/cnxk.rst @@ -78,16 +78,6 @@ Runtime Config Options -a 0002:0e:00.0,single_ws=1 -- ``CN10K Getwork mode`` - - CN10K supports three getwork prefetch modes no prefetch[0], prefetch - immediately[1] and delayed prefetch on forward progress event[2]. - The default getwork mode is 2. - - For example:: - - -a 0002:0e:00.0,gw_mode=1 - - ``Event Group QoS support`` SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight diff --git a/doc/guides/eventdevs/features/cnxk.ini b/doc/guides/eventdevs/features/cnxk.ini index d1516372fa..5ba528f086 100644 --- a/doc/guides/eventdevs/features/cnxk.ini +++ b/doc/guides/eventdevs/features/cnxk.ini @@ -17,6 +17,7 @@ carry_flow_id = Y maintenance_free = Y runtime_queue_attr = Y profile_links = Y +preschedule = Y [Eth Rx adapter Features] internal_port = Y diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c index 2d7b169974..5bd779990e 100644 --- a/drivers/event/cnxk/cn10k_eventdev.c +++ b/drivers/event/cnxk/cn10k_eventdev.c @@ -527,6 +527,7 @@ cn10k_sso_fp_fns_set(struct rte_eventdev *event_dev) event_dev->dma_enqueue = cn10k_dma_adapter_enqueue; event_dev->profile_switch = cn10k_sso_hws_profile_switch; + event_dev->preschedule_modify = cn10k_sso_hws_preschedule_modify; #else RTE_SET_USED(event_dev); #endif @@ -541,6 +542,9 @@ cn10k_sso_info_get(struct rte_eventdev *event_dev, dev_info->driver_name = RTE_STR(EVENTDEV_NAME_CN10K_PMD); cnxk_sso_info_get(dev, dev_info); dev_info->max_event_port_enqueue_depth = UINT32_MAX; + dev_info->event_dev_cap |= RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE | + RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE | + RTE_EVENT_DEV_CAP_PER_PORT_PRESCHEDULE; } static int @@ -566,6 +570,19 @@ cn10k_sso_dev_configure(const struct rte_eventdev *event_dev) if (rc < 0) goto cnxk_rsrc_fini; + switch (event_dev->data->dev_conf.preschedule_type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + dev->gw_mode = CN10K_GW_MODE_NONE; + break; + case RTE_EVENT_PRESCHEDULE: + dev->gw_mode = CN10K_GW_MODE_PREF; + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + dev->gw_mode = CN10K_GW_MODE_PREF_WFE; + break; + } + rc = cnxk_setup_event_ports(event_dev, cn10k_sso_init_hws_mem, cn10k_sso_hws_setup); if (rc < 0) @@ -1199,7 +1216,6 @@ cn10k_sso_init(struct rte_eventdev *event_dev) return 0; } - dev->gw_mode = CN10K_GW_MODE_PREF_WFE; rc = cnxk_sso_init(event_dev); if (rc < 0) return rc; @@ -1256,7 +1272,6 @@ RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>" CNXK_SSO_GGRP_QOS "=<string>" CNXK_SSO_FORCE_BP "=1" - CN10K_SSO_GW_MODE "=<int>" CN10K_SSO_STASH "=<string>" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=<int>" diff --git a/drivers/event/cnxk/cn10k_worker.c b/drivers/event/cnxk/cn10k_worker.c index d59769717e..a0e85face1 100644 --- a/drivers/event/cnxk/cn10k_worker.c +++ b/drivers/event/cnxk/cn10k_worker.c @@ -442,3 +442,24 @@ cn10k_sso_hws_profile_switch(void *port, uint8_t profile) return 0; } + +int __rte_hot +cn10k_sso_hws_preschedule_modify(void *port, enum rte_event_dev_preschedule_type type) +{ + struct cn10k_sso_hws *ws = port; + + ws->gw_wdata &= ~(BIT(19) | BIT(20)); + switch (type) { + default: + case RTE_EVENT_PRESCHEDULE_NONE: + break; + case RTE_EVENT_PRESCHEDULE: + ws->gw_wdata |= BIT(19); + break; + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + ws->gw_wdata |= BIT(19) | BIT(20); + break; + } + + return 0; +} diff --git a/drivers/event/cnxk/cn10k_worker.h b/drivers/event/cnxk/cn10k_worker.h index c5026409d7..4785cc6575 100644 --- a/drivers/event/cnxk/cn10k_worker.h +++ b/drivers/event/cnxk/cn10k_worker.h @@ -377,6 +377,8 @@ uint16_t __rte_hot cn10k_sso_hws_enq_fwd_burst(void *port, const struct rte_event ev[], uint16_t nb_events); int __rte_hot cn10k_sso_hws_profile_switch(void *port, uint8_t profile); +int __rte_hot cn10k_sso_hws_preschedule_modify(void *port, + enum rte_event_dev_preschedule_type type); #define R(name, flags) \ uint16_t __rte_hot cn10k_sso_hws_deq_##name( \ diff --git a/drivers/event/cnxk/cnxk_eventdev.c b/drivers/event/cnxk/cnxk_eventdev.c index 4b2d6bffa6..c1df481827 100644 --- a/drivers/event/cnxk/cnxk_eventdev.c +++ b/drivers/event/cnxk/cnxk_eventdev.c @@ -624,8 +624,6 @@ cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs) &dev->force_ena_bp); rte_kvargs_process(kvlist, CN9K_SSO_SINGLE_WS, &parse_kvargs_flag, &single_ws); - rte_kvargs_process(kvlist, CN10K_SSO_GW_MODE, &parse_kvargs_value, - &dev->gw_mode); rte_kvargs_process(kvlist, CN10K_SSO_STASH, &parse_sso_kvargs_stash_dict, dev); dev->dual_ws = !single_ws; diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h index ece49394e7..f147ef3c78 100644 --- a/drivers/event/cnxk/cnxk_eventdev.h +++ b/drivers/event/cnxk/cnxk_eventdev.h @@ -30,7 +30,6 @@ #define CNXK_SSO_GGRP_QOS "qos" #define CNXK_SSO_FORCE_BP "force_rx_bp" #define CN9K_SSO_SINGLE_WS "single_ws" -#define CN10K_SSO_GW_MODE "gw_mode" #define CN10K_SSO_STASH "stash" #define CNXK_SSO_MAX_PROFILES 2 -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 5/6] app/test-eventdev: add pre-scheduling support 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula ` (3 preceding siblings ...) 2024-10-07 13:09 ` [PATCH v9 4/6] event/cnkx: add pre-schedule support pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-07 13:09 ` [PATCH v9 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-08 5:17 ` [PATCH v9 0/6] Introduce event pre-scheduling Jerin Jacob 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen Cc: dev, Pavan Nikhilesh From: Pavan Nikhilesh <pbhagavatula@marvell.com> Add support to configure pre-scheduling for eventdev test application. Option `--preschedule` 0 - Disable pre-scheduling. 1 - Enable pre-scheduling. 2 - Enable pre-schedule with adaptive mode (Default). Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- app/test-eventdev/evt_common.h | 45 ++++++++++++++++++++++++------- app/test-eventdev/evt_options.c | 17 ++++++++++++ app/test-eventdev/evt_options.h | 1 + doc/guides/tools/testeventdev.rst | 6 +++++ 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/test-eventdev/evt_common.h b/app/test-eventdev/evt_common.h index dbe1e5c0c4..901b8ba55d 100644 --- a/app/test-eventdev/evt_common.h +++ b/app/test-eventdev/evt_common.h @@ -64,6 +64,8 @@ struct evt_options { uint8_t nb_timer_adptrs; uint8_t timdev_use_burst; uint8_t per_port_pool; + uint8_t preschedule; + uint8_t preschedule_opted; uint8_t sched_type_list[EVT_MAX_STAGES]; uint16_t mbuf_sz; uint16_t wkr_deq_dep; @@ -184,6 +186,30 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, return ret; } + if (opt->preschedule_opted && opt->preschedule) { + switch (opt->preschedule) { + case RTE_EVENT_PRESCHEDULE_ADAPTIVE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + case RTE_EVENT_PRESCHEDULE: + if (!(info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE)) { + evt_err("Preschedule type %d not supported", opt->preschedule); + return -EINVAL; + } + break; + default: + break; + } + } + + if (!opt->preschedule_opted) { + if (info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + opt->preschedule = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + } + if (opt->deq_tmo_nsec) { if (opt->deq_tmo_nsec < info.min_dequeue_timeout_ns) { opt->deq_tmo_nsec = info.min_dequeue_timeout_ns; @@ -198,16 +224,15 @@ evt_configure_eventdev(struct evt_options *opt, uint8_t nb_queues, } const struct rte_event_dev_config config = { - .dequeue_timeout_ns = opt->deq_tmo_nsec, - .nb_event_queues = nb_queues, - .nb_event_ports = nb_ports, - .nb_single_link_event_port_queues = 0, - .nb_events_limit = info.max_num_events, - .nb_event_queue_flows = opt->nb_flows, - .nb_event_port_dequeue_depth = - info.max_event_port_dequeue_depth, - .nb_event_port_enqueue_depth = - info.max_event_port_enqueue_depth, + .dequeue_timeout_ns = opt->deq_tmo_nsec, + .nb_event_queues = nb_queues, + .nb_event_ports = nb_ports, + .nb_single_link_event_port_queues = 0, + .nb_events_limit = info.max_num_events, + .nb_event_queue_flows = opt->nb_flows, + .nb_event_port_dequeue_depth = info.max_event_port_dequeue_depth, + .nb_event_port_enqueue_depth = info.max_event_port_enqueue_depth, + .preschedule_type = opt->preschedule, }; return rte_event_dev_configure(opt->dev_id, &config); diff --git a/app/test-eventdev/evt_options.c b/app/test-eventdev/evt_options.c index fb5a0a255f..323d1e724d 100644 --- a/app/test-eventdev/evt_options.c +++ b/app/test-eventdev/evt_options.c @@ -130,6 +130,17 @@ evt_parse_tx_pkt_sz(struct evt_options *opt, const char *arg __rte_unused) return ret; } +static int +evt_parse_preschedule(struct evt_options *opt, const char *arg __rte_unused) +{ + int ret; + + ret = parser_read_uint8(&(opt->preschedule), arg); + opt->preschedule_opted = 1; + + return ret; +} + static int evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) { @@ -510,6 +521,10 @@ usage(char *program) " across all the ethernet devices before\n" " event workers start.\n" "\t--tx_pkt_sz : Packet size to use with Tx first." + "\t--preschedule : Pre-schedule type to use.\n" + " 0 - disable pre-schedule\n" + " 1 - pre-schedule\n" + " 2 - pre-schedule adaptive (Default)\n" ); printf("available tests:\n"); evt_test_dump_names(); @@ -598,6 +613,7 @@ static struct option lgopts[] = { { EVT_HELP, 0, 0, 0 }, { EVT_TX_FIRST, 1, 0, 0 }, { EVT_TX_PKT_SZ, 1, 0, 0 }, + { EVT_PRESCHEDULE, 1, 0, 0 }, { NULL, 0, 0, 0 } }; @@ -647,6 +663,7 @@ evt_opts_parse_long(int opt_idx, struct evt_options *opt) { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, { EVT_TX_FIRST, evt_parse_tx_first}, { EVT_TX_PKT_SZ, evt_parse_tx_pkt_sz}, + { EVT_PRESCHEDULE, evt_parse_preschedule}, }; for (i = 0; i < RTE_DIM(parsermap); i++) { diff --git a/app/test-eventdev/evt_options.h b/app/test-eventdev/evt_options.h index 646060c7c6..18a893b704 100644 --- a/app/test-eventdev/evt_options.h +++ b/app/test-eventdev/evt_options.h @@ -59,6 +59,7 @@ #define EVT_PER_PORT_POOL ("per_port_pool") #define EVT_TX_FIRST ("tx_first") #define EVT_TX_PKT_SZ ("tx_pkt_sz") +#define EVT_PRESCHEDULE ("preschedule") #define EVT_HELP ("help") void evt_options_default(struct evt_options *opt); diff --git a/doc/guides/tools/testeventdev.rst b/doc/guides/tools/testeventdev.rst index 00eb702571..38e2ec0c36 100644 --- a/doc/guides/tools/testeventdev.rst +++ b/doc/guides/tools/testeventdev.rst @@ -236,6 +236,12 @@ The following are the application command-line options: Packet size to use for `--tx_first`. Only applicable for `pipeline_atq` and `pipeline_queue` tests. +* ``--preschedule`` + + Enable pre-scheduling of events. + 0 - Disable pre-scheduling. + 1 - Enable pre-scheduling. + 2 - Enable pre-schedule with adaptive mode (Default). Eventdev Tests -------------- -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* [PATCH v9 6/6] examples: use eventdev pre-scheduling 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula ` (4 preceding siblings ...) 2024-10-07 13:09 ` [PATCH v9 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula @ 2024-10-07 13:09 ` pbhagavatula 2024-10-08 5:17 ` [PATCH v9 0/6] Introduce event pre-scheduling Jerin Jacob 6 siblings, 0 replies; 77+ messages in thread From: pbhagavatula @ 2024-10-07 13:09 UTC (permalink / raw) To: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, Radu Nicolau, Akhil Goyal, Sunil Kumar Kori, Pavan Nikhilesh Cc: dev From: Pavan Nikhilesh <pbhagavatula@marvell.com> Enable event pre-scheduling if supported by the event device. Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com> --- examples/eventdev_pipeline/pipeline_worker_generic.c | 6 ++++++ examples/eventdev_pipeline/pipeline_worker_tx.c | 6 ++++++ examples/ipsec-secgw/event_helper.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_generic.c | 6 ++++++ examples/l2fwd-event/l2fwd_event_internal_port.c | 6 ++++++ examples/l3fwd/l3fwd_event_generic.c | 6 ++++++ examples/l3fwd/l3fwd_event_internal_port.c | 6 ++++++ 7 files changed, 42 insertions(+) diff --git a/examples/eventdev_pipeline/pipeline_worker_generic.c b/examples/eventdev_pipeline/pipeline_worker_generic.c index 831d7fd53d..06384c683c 100644 --- a/examples/eventdev_pipeline/pipeline_worker_generic.c +++ b/examples/eventdev_pipeline/pipeline_worker_generic.c @@ -192,6 +192,12 @@ setup_eventdev_generic(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c index 98a52f3892..c9a04cad56 100644 --- a/examples/eventdev_pipeline/pipeline_worker_tx.c +++ b/examples/eventdev_pipeline/pipeline_worker_tx.c @@ -505,6 +505,12 @@ setup_eventdev_worker_tx_enq(struct worker_data *worker_data) config.nb_event_port_enqueue_depth = dev_info.max_event_port_enqueue_depth; + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + config.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(dev_id, &config); if (ret < 0) { printf("%d: Error configuring device\n", __LINE__); diff --git a/examples/ipsec-secgw/event_helper.c b/examples/ipsec-secgw/event_helper.c index 89fb7e62a5..dadddcb306 100644 --- a/examples/ipsec-secgw/event_helper.c +++ b/examples/ipsec-secgw/event_helper.c @@ -669,6 +669,12 @@ eh_initialize_eventdev(struct eventmode_conf *em_conf) eventdev_conf.nb_event_port_enqueue_depth = evdev_default_conf.max_event_port_enqueue_depth; + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (evdev_default_conf.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + eventdev_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + /* Configure event device */ ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); if (ret < 0) { diff --git a/examples/l2fwd-event/l2fwd_event_generic.c b/examples/l2fwd-event/l2fwd_event_generic.c index 1977e23261..d805264744 100644 --- a/examples/l2fwd-event/l2fwd_event_generic.c +++ b/examples/l2fwd-event/l2fwd_event_generic.c @@ -86,6 +86,12 @@ l2fwd_event_device_setup_generic(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l2fwd-event/l2fwd_event_internal_port.c b/examples/l2fwd-event/l2fwd_event_internal_port.c index 717a7bceb8..26233d1ab6 100644 --- a/examples/l2fwd-event/l2fwd_event_internal_port.c +++ b/examples/l2fwd-event/l2fwd_event_internal_port.c @@ -82,6 +82,12 @@ l2fwd_event_device_setup_internal_port(struct l2fwd_resources *rsrc) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_generic.c b/examples/l3fwd/l3fwd_event_generic.c index ddb6e5c38d..d86439df52 100644 --- a/examples/l3fwd/l3fwd_event_generic.c +++ b/examples/l3fwd/l3fwd_event_generic.c @@ -74,6 +74,12 @@ l3fwd_event_device_setup_generic(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); diff --git a/examples/l3fwd/l3fwd_event_internal_port.c b/examples/l3fwd/l3fwd_event_internal_port.c index cb49a8b9fa..b390e3469d 100644 --- a/examples/l3fwd/l3fwd_event_internal_port.c +++ b/examples/l3fwd/l3fwd_event_internal_port.c @@ -73,6 +73,12 @@ l3fwd_event_device_setup_internal_port(void) evt_rsrc->has_burst = !!(dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE); + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE; + + if (dev_info.event_dev_cap & RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE) + event_d_conf.preschedule_type = RTE_EVENT_PRESCHEDULE_ADAPTIVE; + ret = rte_event_dev_configure(event_d_id, &event_d_conf); if (ret < 0) rte_panic("Error in configuring event device\n"); -- 2.25.1 ^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PATCH v9 0/6] Introduce event pre-scheduling 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula ` (5 preceding siblings ...) 2024-10-07 13:09 ` [PATCH v9 6/6] examples: use eventdev pre-scheduling pbhagavatula @ 2024-10-08 5:17 ` Jerin Jacob 6 siblings, 0 replies; 77+ messages in thread From: Jerin Jacob @ 2024-10-08 5:17 UTC (permalink / raw) To: pbhagavatula Cc: jerinj, sthotton, abdullah.sevincer, hemant.agrawal, sachin.saxena, harry.van.haaren, mattias.ronnblom, liangma, peter.mccarthy, stephen, dev On Tue, Oct 8, 2024 at 3:14 AM <pbhagavatula@marvell.com> wrote: > > From: Pavan Nikhilesh <pbhagavatula@marvell.com> > > Event pre-scheduling improves scheduling performance by assigning events > to event ports in advance when dequeues are issued. > This series introduces various types and levels of pre-scheduling to the > eventdev library. > > pre-scheduling Types: > * RTE_EVENT_PRESCHEDULE_NONE: No pre-scheduling. > * RTE_EVENT_PRESCHEDULE: Always issue a pre-schedule when dequeue is issued. > * RTE_EVENT_PRESCHEDULE_ADAPTIVE: Delay issuing pre-schedule until there > are no forward progress constraints with the held flow contexts. > > pre-scheduling Levels: > * Event Device Level Pre-scheduling: Pre-scheduling can be enabled or disabled at the > event device during configuration. Event devices can indicate pre-scheduling > capabilities using `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE` and > `RTE_EVENT_DEV_CAP_EVENT_PRESCHEDULE_ADAPTIVE` via the event device info > function `info.event_dev_cap`. > * Event Port Level Prefetch: Pre-scheduling can be selectively enabled or disabled > at the event port during runtime. Event devices can indicate this capability > using `RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE` via the event device info > function `info.event_port_cap`. > * Application Controlled Prefetch Hint: Applications can provide hints to the > event device to start pre-scheduling events using the new API > `rte_event_port_pre-schedule`. Event devices can indicate this capabilities using > `RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT` via the event device info function > `info.event_dev_cap`. > > The rte_event_dequeue_burst operation initiates the pre-schedule operation, which > completes in parallel without affecting the flow context of the dequeued events and > dequeue latency. On the next dequeue operation, the pre-scheduleed events are > dequeued, and pre-schedule operation is initiated again. > > In the case of application-controlled pre-schedule hints, the currently held flow > contexts, if any, are not affected by the pre-schedule operation. On the next > dequeue operation, the pre-scheduleed events are returned, but pre-schedule is not > initiated again until the application provides the hint again. If pre-scheduling > is already enabled at the event device level or event port level, the hint is ignored. > > v2 Changes: > - s/prefetch/pre-schedule (Mattias). > v3 Changes: > - Add CNXK preschedule implementation. > - Update test-eventdev to use prescheduling. > - Update examples to use prescheduling. > v4 Changes: > - Fix compilation. > v5 Changes: > - Update ABI changes > - s/RTE_EVENT_DEV_PRESCHEDULE/RTE_EVENT_PRESCHEDULE/ > - s/RTE_EVENT_DEV_CAP_SW_PRESCHEDULE/RTE_EVENT_DEV_CAP_PRESCHEDULE_EXPLICIT/ > - s/RTE_EVENT_PORT_CAP_EVENT_PER_PORT_PRESCHEDULE/RTE_EVENT_PORT_CAP_PER_PORT_PRESCHEDULE > - Various documentation fixes and updates. > v6 Changes: > - Mark new APIs as experimental (Stephen). > v7 Changes: > - Use correct patchset for rebase. > v8 Changes: > - fix checkpatch issues. > v9 Changes: > - Rebase update capability bits, fix release notes format. Series-Acked-by: Jerin Jacob <jerinj@marvell.com> Series applied to dpdk-next-net-eventdev/for-main. Thanks ^ permalink raw reply [flat|nested] 77+ messages in thread
end of thread, other threads:[~2024-10-08 5:18 UTC | newest] Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-09-10 8:31 [RFC 0/3] Introduce event prefetching pbhagavatula 2024-09-10 8:31 ` [RFC 1/3] eventdev: introduce " pbhagavatula 2024-09-10 8:31 ` [RFC 2/3] eventdev: allow event ports to modified prefetches pbhagavatula 2024-09-10 8:31 ` [RFC 3/3] eventdev: add SW event prefetch hint pbhagavatula 2024-09-10 9:08 ` [RFC 0/3] Introduce event prefetching Mattias Rönnblom 2024-09-10 11:53 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-09-17 7:11 ` [PATCH v2 0/3] Introduce event pre-scheduling pbhagavatula 2024-09-17 7:11 ` [PATCH v2 1/3] eventdev: introduce " pbhagavatula 2024-09-18 22:38 ` Pathak, Pravin 2024-09-19 13:13 ` Pavan Nikhilesh Bhagavatula 2024-09-23 8:57 ` Mattias Rönnblom 2024-09-25 10:30 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-09-26 2:54 ` Pathak, Pravin 2024-09-26 10:03 ` Pavan Nikhilesh Bhagavatula 2024-09-27 3:31 ` Pathak, Pravin 2024-09-17 7:11 ` [PATCH v2 2/3] eventdev: add event port pre-schedule modify pbhagavatula 2024-09-17 7:11 ` [PATCH v2 3/3] eventdev: add SW event preschedule hint pbhagavatula 2024-10-01 6:14 ` [PATCH v3 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-01 6:14 ` [PATCH v3 1/6] eventdev: introduce " pbhagavatula 2024-10-01 6:14 ` [PATCH v3 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-01 6:14 ` [PATCH v3 3/6] eventdev: add SW event preschedule hint pbhagavatula 2024-10-01 6:14 ` [PATCH v3 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-01 6:14 ` [PATCH v3 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-01 6:14 ` [PATCH v3 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-01 13:18 ` [PATCH v4 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-01 13:18 ` [PATCH v4 1/6] eventdev: introduce " pbhagavatula 2024-10-04 4:47 ` Jerin Jacob 2024-10-01 13:18 ` [PATCH v4 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-04 5:02 ` Jerin Jacob 2024-10-01 13:18 ` [PATCH v4 3/6] eventdev: add SW event preschedule hint pbhagavatula 2024-10-04 5:14 ` Jerin Jacob 2024-10-01 13:18 ` [PATCH v4 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-01 13:19 ` [PATCH v4 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-01 13:19 ` [PATCH v4 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-01 15:33 ` [PATCH v4 0/6] Introduce event pre-scheduling Stephen Hemminger 2024-10-03 5:46 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-10-04 16:24 ` [PATCH v5 " pbhagavatula 2024-10-04 16:24 ` [PATCH v5 1/6] eventdev: introduce " pbhagavatula 2024-10-04 16:24 ` [PATCH v5 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-04 16:24 ` [PATCH v5 3/6] eventdev: add event preschedule hint pbhagavatula 2024-10-04 16:24 ` [PATCH v5 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-04 16:24 ` [PATCH v5 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-04 16:24 ` [PATCH v5 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-04 16:35 ` [PATCH v5 0/6] Introduce event pre-scheduling Stephen Hemminger 2024-10-04 16:50 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-10-05 7:25 ` [PATCH v6 " pbhagavatula 2024-10-05 7:25 ` [PATCH v6 1/6] eventdev: introduce " pbhagavatula 2024-10-05 7:25 ` [PATCH v6 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-05 7:25 ` [PATCH v6 3/6] eventdev: add event preschedule hint pbhagavatula 2024-10-05 7:25 ` [PATCH v6 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-05 7:25 ` [PATCH v6 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-05 7:26 ` [PATCH v6 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-05 7:59 ` [PATCH v7 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-05 7:59 ` [PATCH v7 1/6] eventdev: introduce " pbhagavatula 2024-10-05 16:11 ` Stephen Hemminger 2024-10-06 17:03 ` [EXTERNAL] " Pavan Nikhilesh Bhagavatula 2024-10-05 7:59 ` [PATCH v7 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-05 7:59 ` [PATCH v7 3/6] eventdev: add event preschedule hint pbhagavatula 2024-10-05 7:59 ` [PATCH v7 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-05 8:00 ` [PATCH v7 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-05 8:00 ` [PATCH v7 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-06 17:06 ` [PATCH v8 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-06 17:06 ` [PATCH v8 1/6] eventdev: introduce " pbhagavatula 2024-10-06 17:06 ` [PATCH v8 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-06 17:06 ` [PATCH v8 3/6] eventdev: add event preschedule hint pbhagavatula 2024-10-07 12:24 ` Jerin Jacob 2024-10-06 17:06 ` [PATCH v8 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-06 17:06 ` [PATCH v8 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-06 17:06 ` [PATCH v8 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-07 13:09 ` [PATCH v9 0/6] Introduce event pre-scheduling pbhagavatula 2024-10-07 13:09 ` [PATCH v9 1/6] eventdev: introduce " pbhagavatula 2024-10-07 13:09 ` [PATCH v9 2/6] eventdev: add event port pre-schedule modify pbhagavatula 2024-10-07 13:09 ` [PATCH v9 3/6] eventdev: add event preschedule hint pbhagavatula 2024-10-07 13:09 ` [PATCH v9 4/6] event/cnkx: add pre-schedule support pbhagavatula 2024-10-07 13:09 ` [PATCH v9 5/6] app/test-eventdev: add pre-scheduling support pbhagavatula 2024-10-07 13:09 ` [PATCH v9 6/6] examples: use eventdev pre-scheduling pbhagavatula 2024-10-08 5:17 ` [PATCH v9 0/6] Introduce event pre-scheduling Jerin Jacob
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).