Skip to content

Commit

Permalink
eventdev: add event port pre-schedule modify
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Jerin Jacob <[email protected]>
  • Loading branch information
PavanNikhilesh authored and jerinjacobk committed Oct 8, 2024
1 parent acc65ee commit c1bdd86
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 7 deletions.
45 changes: 40 additions & 5 deletions app/test/test_eventdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -1335,28 +1340,56 @@ 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) {
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");
"RTE_EVENT_PRESCHEDULE_ADAPTIVE", 0);
TEST_ASSERT_SUCCESS(rc,
"Failed to test preschedule RTE_EVENT_PRESCHEDULE_ADAPTIVE");
}

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)
{
Expand Down Expand Up @@ -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,
Expand Down
16 changes: 16 additions & 0 deletions doc/guides/prog_guide/eventdev/eventdev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,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
~~~~~~~~~~~~~~~~~~~~~

Expand Down
3 changes: 3 additions & 0 deletions doc/guides/rel_notes/release_24_11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,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.

* **Updated event device library for independent enqueue feature.**

Added support for independent enqueue feature.
Expand Down
2 changes: 2 additions & 0 deletions lib/eventdev/eventdev_pmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
20 changes: 20 additions & 0 deletions lib/eventdev/eventdev_private.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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,
};

Expand All @@ -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;
}
3 changes: 3 additions & 0 deletions lib/eventdev/eventdev_trace_points.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
61 changes: 61 additions & 0 deletions lib/eventdev/rte_eventdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,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.
Expand Down Expand Up @@ -724,18 +734,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
*/
};

Expand Down Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion lib/eventdev/rte_eventdev_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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];
Expand Down
11 changes: 10 additions & 1 deletion lib/eventdev/rte_eventdev_trace_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* @file
*
* API for ethdev trace support
* API for eventdev trace support
*/

#include <rte_trace_point.h>
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions lib/eventdev/version.map
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit c1bdd86

Please sign in to comment.