event/sw: add service capability
This commit shows how easy it is to enable a specific DPDK component with a service callback, in order to get CPU cycles for it. The beauty of this method is that the service is unaware of how much CPU time it is getting - the application can decide how to split and slice cores and map them to the registered services. Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com> Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
This commit is contained in:
parent
f038a81e1c
commit
a599eb31f2
@ -32,7 +32,9 @@ Software Eventdev Poll Mode Driver
|
||||
|
||||
The software eventdev is an implementation of the eventdev API, that provides a
|
||||
wide range of the eventdev features. The eventdev relies on a CPU core to
|
||||
perform event scheduling.
|
||||
perform event scheduling. This PMD can use the service core library to run the
|
||||
scheduling function, allowing an application to utilize the power of service
|
||||
cores to multiplex other work on the same core if required.
|
||||
|
||||
|
||||
Features
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <rte_ring.h>
|
||||
#include <rte_errno.h>
|
||||
#include <rte_event_ring.h>
|
||||
#include <rte_service_component.h>
|
||||
|
||||
#include "sw_evdev.h"
|
||||
#include "iq_ring.h"
|
||||
@ -614,6 +615,13 @@ sw_start(struct rte_eventdev *dev)
|
||||
{
|
||||
unsigned int i, j;
|
||||
struct sw_evdev *sw = sw_pmd_priv(dev);
|
||||
|
||||
/* check a service core is mapped to this service */
|
||||
struct rte_service_spec *s = rte_service_get_by_name(sw->service_name);
|
||||
if (!rte_service_is_running(s))
|
||||
SW_LOG_ERR("Warning: No Service core enabled on service %s\n",
|
||||
s->name);
|
||||
|
||||
/* check all ports are set up */
|
||||
for (i = 0; i < sw->port_count; i++)
|
||||
if (sw->ports[i].rx_worker_ring == NULL) {
|
||||
@ -716,6 +724,14 @@ set_credit_quanta(const char *key __rte_unused, const char *value, void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int32_t sw_sched_service_func(void *args)
|
||||
{
|
||||
struct rte_eventdev *dev = args;
|
||||
sw_event_schedule(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sw_probe(struct rte_vdev_device *vdev)
|
||||
{
|
||||
@ -829,6 +845,22 @@ sw_probe(struct rte_vdev_device *vdev)
|
||||
sw->credit_update_quanta = credit_quanta;
|
||||
sw->sched_quanta = sched_quanta;
|
||||
|
||||
/* register service with EAL */
|
||||
struct rte_service_spec service;
|
||||
memset(&service, 0, sizeof(struct rte_service_spec));
|
||||
snprintf(service.name, sizeof(service.name), "%s_service", name);
|
||||
snprintf(sw->service_name, sizeof(sw->service_name), "%s_service",
|
||||
name);
|
||||
service.socket_id = socket_id;
|
||||
service.callback = sw_sched_service_func;
|
||||
service.callback_userdata = (void *)dev;
|
||||
|
||||
int32_t ret = rte_service_register(&service);
|
||||
if (ret) {
|
||||
SW_LOG_ERR("service register() failed");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
|
||||
#define EVENTDEV_NAME_SW_PMD event_sw
|
||||
#define SW_PMD_NAME RTE_STR(event_sw)
|
||||
#define SW_PMD_NAME_MAX 64
|
||||
|
||||
#define SW_SCHED_TYPE_DIRECT (RTE_SCHED_TYPE_PARALLEL + 1)
|
||||
|
||||
@ -276,6 +277,8 @@ struct sw_evdev {
|
||||
/* store num stats and offset of the stats for each queue */
|
||||
uint16_t xstats_count_per_qid[RTE_EVENT_MAX_QUEUES_PER_DEV];
|
||||
uint16_t xstats_offset_for_qid[RTE_EVENT_MAX_QUEUES_PER_DEV];
|
||||
|
||||
char service_name[SW_PMD_NAME_MAX];
|
||||
};
|
||||
|
||||
static inline struct sw_evdev *
|
||||
|
Loading…
Reference in New Issue
Block a user