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:
Harry van Haaren 2017-07-11 15:19:31 +01:00 committed by Thomas Monjalon
parent f038a81e1c
commit a599eb31f2
3 changed files with 38 additions and 1 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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 *