pipeline: add pipeline name

Add an unique name to every pipeline. This enables the library to
maintain a list of the existing pipeline objects, which can be
queried by the application.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Kamalakannan R <kamalakannan.r@intel.com>
This commit is contained in:
Cristian Dumitrescu 2022-07-28 15:11:31 +00:00 committed by Thomas Monjalon
parent 4aee6110bb
commit d69c90c85d
7 changed files with 244 additions and 3 deletions

View File

@ -533,7 +533,7 @@ pipeline_create(struct obj *obj, const char *name, int numa_node)
return NULL;
/* Resource create */
status = rte_swx_pipeline_config(&p, numa_node);
status = rte_swx_pipeline_config(&p, name, numa_node);
if (status)
goto error;

View File

@ -9,6 +9,8 @@
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_tailq.h>
#include <rte_eal_memconfig.h>
#include <rte_swx_table_selector.h>
@ -1157,12 +1159,103 @@ table_state_create(struct rte_swx_ctl_pipeline *ctl)
return status;
}
/* Global list of pipeline instances. */
TAILQ_HEAD(rte_swx_ctl_pipeline_list, rte_tailq_entry);
static struct rte_tailq_elem rte_swx_ctl_pipeline_tailq = {
.name = "RTE_SWX_CTL_PIPELINE",
};
EAL_REGISTER_TAILQ(rte_swx_ctl_pipeline_tailq)
struct rte_swx_ctl_pipeline *
rte_swx_ctl_pipeline_find(const char *name)
{
struct rte_swx_ctl_pipeline_list *ctl_list;
struct rte_tailq_entry *te = NULL;
if (!name || !name[0] || (strnlen(name, RTE_SWX_CTL_NAME_SIZE) >= RTE_SWX_CTL_NAME_SIZE))
return NULL;
ctl_list = RTE_TAILQ_CAST(rte_swx_ctl_pipeline_tailq.head, rte_swx_ctl_pipeline_list);
rte_mcfg_tailq_read_lock();
TAILQ_FOREACH(te, ctl_list, next) {
struct rte_swx_ctl_pipeline *ctl = (struct rte_swx_ctl_pipeline *)te->data;
if (!strncmp(name, ctl->info.name, sizeof(ctl->info.name))) {
rte_mcfg_tailq_read_unlock();
return ctl;
}
}
rte_mcfg_tailq_read_unlock();
return NULL;
}
static int
ctl_register(struct rte_swx_ctl_pipeline *ctl)
{
struct rte_swx_ctl_pipeline_list *ctl_list;
struct rte_tailq_entry *te = NULL;
ctl_list = RTE_TAILQ_CAST(rte_swx_ctl_pipeline_tailq.head, rte_swx_ctl_pipeline_list);
rte_mcfg_tailq_write_lock();
TAILQ_FOREACH(te, ctl_list, next) {
struct rte_swx_ctl_pipeline *ctl_crt = (struct rte_swx_ctl_pipeline *)te->data;
if (!strncmp(ctl->info.name, ctl_crt->info.name, sizeof(ctl->info.name))) {
rte_mcfg_tailq_write_unlock();
return -EEXIST;
}
}
te = calloc(1, sizeof(struct rte_tailq_entry));
if (!te) {
rte_mcfg_tailq_write_unlock();
return -ENOMEM;
}
te->data = (void *)ctl;
TAILQ_INSERT_TAIL(ctl_list, te, next);
rte_mcfg_tailq_write_unlock();
return 0;
}
static void
ctl_unregister(struct rte_swx_ctl_pipeline *ctl)
{
struct rte_swx_ctl_pipeline_list *ctl_list;
struct rte_tailq_entry *te = NULL;
ctl_list = RTE_TAILQ_CAST(rte_swx_ctl_pipeline_tailq.head, rte_swx_ctl_pipeline_list);
rte_mcfg_tailq_write_lock();
TAILQ_FOREACH(te, ctl_list, next) {
if (te->data == (void *)ctl) {
TAILQ_REMOVE(ctl_list, te, next);
rte_mcfg_tailq_write_unlock();
free(te);
return;
}
}
rte_mcfg_tailq_write_unlock();
}
void
rte_swx_ctl_pipeline_free(struct rte_swx_ctl_pipeline *ctl)
{
if (!ctl)
return;
if (ctl->info.name[0])
ctl_unregister(ctl);
action_free(ctl);
table_state_free(ctl);
@ -1441,6 +1534,12 @@ rte_swx_ctl_pipeline_create(struct rte_swx_pipeline *p)
if (status)
goto error;
if (ctl->info.name[0]) {
status = ctl_register(ctl);
if (status)
goto error;
}
return ctl;
error:

View File

@ -35,6 +35,9 @@ struct rte_swx_pipeline;
/** Pipeline info. */
struct rte_swx_ctl_pipeline_info {
/** Pipeline name. */
char name[RTE_SWX_CTL_NAME_SIZE];
/** Number of input ports. */
uint32_t n_ports_in;
@ -812,6 +815,18 @@ rte_swx_pipeline_table_state_set(struct rte_swx_pipeline *p,
/** Pipeline control opaque data structure. */
struct rte_swx_ctl_pipeline;
/**
* Pipeline control find
*
* @param[in] name
* Pipeline name.
* @return
* Valid pipeline control handle if found or NULL otherwise.
*/
__rte_experimental
struct rte_swx_ctl_pipeline *
rte_swx_ctl_pipeline_find(const char *name);
/**
* Pipeline control create
*

View File

@ -6,6 +6,8 @@
#include <errno.h>
#include <dlfcn.h>
#include <rte_tailq.h>
#include <rte_eal_memconfig.h>
#include <rte_jhash.h>
#include <rte_hash_crc.h>
@ -9578,6 +9580,95 @@ metarray_free(struct rte_swx_pipeline *p)
/*
* Pipeline.
*/
/* Global list of pipeline instances. */
TAILQ_HEAD(rte_swx_pipeline_list, rte_tailq_entry);
static struct rte_tailq_elem rte_swx_pipeline_tailq = {
.name = "RTE_SWX_PIPELINE",
};
EAL_REGISTER_TAILQ(rte_swx_pipeline_tailq)
struct rte_swx_pipeline *
rte_swx_pipeline_find(const char *name)
{
struct rte_swx_pipeline_list *pipeline_list;
struct rte_tailq_entry *te = NULL;
if (!name || !name[0] || (strnlen(name, RTE_SWX_NAME_SIZE) >= RTE_SWX_NAME_SIZE))
return NULL;
pipeline_list = RTE_TAILQ_CAST(rte_swx_pipeline_tailq.head, rte_swx_pipeline_list);
rte_mcfg_tailq_read_lock();
TAILQ_FOREACH(te, pipeline_list, next) {
struct rte_swx_pipeline *p = (struct rte_swx_pipeline *)te->data;
if (!strncmp(name, p->name, sizeof(p->name))) {
rte_mcfg_tailq_read_unlock();
return p;
}
}
rte_mcfg_tailq_read_unlock();
return NULL;
}
static int
pipeline_register(struct rte_swx_pipeline *p)
{
struct rte_swx_pipeline_list *pipeline_list;
struct rte_tailq_entry *te = NULL;
pipeline_list = RTE_TAILQ_CAST(rte_swx_pipeline_tailq.head, rte_swx_pipeline_list);
rte_mcfg_tailq_write_lock();
TAILQ_FOREACH(te, pipeline_list, next) {
struct rte_swx_pipeline *pipeline = (struct rte_swx_pipeline *)te->data;
if (!strncmp(p->name, pipeline->name, sizeof(p->name))) {
rte_mcfg_tailq_write_unlock();
return -EEXIST;
}
}
te = calloc(1, sizeof(struct rte_tailq_entry));
if (!te) {
rte_mcfg_tailq_write_unlock();
return -ENOMEM;
}
te->data = (void *)p;
TAILQ_INSERT_TAIL(pipeline_list, te, next);
rte_mcfg_tailq_write_unlock();
return 0;
}
static void
pipeline_unregister(struct rte_swx_pipeline *p)
{
struct rte_swx_pipeline_list *pipeline_list;
struct rte_tailq_entry *te = NULL;
pipeline_list = RTE_TAILQ_CAST(rte_swx_pipeline_tailq.head, rte_swx_pipeline_list);
rte_mcfg_tailq_write_lock();
TAILQ_FOREACH(te, pipeline_list, next) {
if (te->data == (void *)p) {
TAILQ_REMOVE(pipeline_list, te, next);
rte_mcfg_tailq_write_unlock();
free(te);
return;
}
}
rte_mcfg_tailq_write_unlock();
}
void
rte_swx_pipeline_free(struct rte_swx_pipeline *p)
{
@ -9586,6 +9677,9 @@ rte_swx_pipeline_free(struct rte_swx_pipeline *p)
if (!p)
return;
if (p->name[0])
pipeline_unregister(p);
lib = p->lib;
free(p->instruction_data);
@ -9720,13 +9814,14 @@ hash_funcs_register(struct rte_swx_pipeline *p)
}
int
rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
rte_swx_pipeline_config(struct rte_swx_pipeline **p, const char *name, int numa_node)
{
struct rte_swx_pipeline *pipeline = NULL;
int status = 0;
/* Check input parameters. */
CHECK(p, EINVAL);
CHECK(!name || (strnlen(name, RTE_SWX_NAME_SIZE) < RTE_SWX_NAME_SIZE), EINVAL);
/* Memory allocation. */
pipeline = calloc(1, sizeof(struct rte_swx_pipeline));
@ -9736,6 +9831,9 @@ rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
}
/* Initialization. */
if (name)
strcpy(pipeline->name, name);
TAILQ_INIT(&pipeline->struct_types);
TAILQ_INIT(&pipeline->port_in_types);
TAILQ_INIT(&pipeline->ports_in);
@ -9776,6 +9874,12 @@ rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
if (status)
goto error;
if (pipeline->name[0]) {
status = pipeline_register(pipeline);
if (status)
goto error;
}
*p = pipeline;
return 0;
@ -9966,6 +10070,7 @@ rte_swx_ctl_pipeline_info_get(struct rte_swx_pipeline *p,
TAILQ_FOREACH(table, &p->tables, node)
n_tables++;
strcpy(pipeline->name, p->name);
pipeline->n_ports_in = p->n_ports_in;
pipeline->n_ports_out = p->n_ports_out;
pipeline->n_mirroring_slots = p->n_mirroring_slots;

View File

@ -44,22 +44,38 @@ extern "C" {
/** Pipeline opaque data structure. */
struct rte_swx_pipeline;
/**
* Pipeline find
*
* @param[in] name
* Pipeline name.
* @return
* Valid pipeline handle if found or NULL otherwise.
*/
__rte_experimental
struct rte_swx_pipeline *
rte_swx_pipeline_find(const char *name);
/**
* Pipeline configure
*
* @param[out] p
* Pipeline handle. Must point to valid memory. Contains valid pipeline handle
* when the function returns successfully.
* @param[in] name
* Pipeline unique name.
* @param[in] numa_node
* Non-Uniform Memory Access (NUMA) node.
* @return
* 0 on success or the following error codes otherwise:
* -EINVAL: Invalid argument;
* -ENOMEM: Not enough space/cannot allocate memory.
* -ENOMEM: Not enough space/cannot allocate memory;
* -EEXIST: Pipeline with this name already exists.
*/
__rte_experimental
int
rte_swx_pipeline_config(struct rte_swx_pipeline **p,
const char *name,
int numa_node);
/*

View File

@ -1459,6 +1459,8 @@ instr_operand_nbo(struct thread *t, const struct instr_operand *x)
#endif
struct rte_swx_pipeline {
char name[RTE_SWX_NAME_SIZE];
struct struct_type_tailq struct_types;
struct port_in_type_tailq port_in_types;
struct port_in_tailq ports_in;

View File

@ -145,4 +145,8 @@ EXPERIMENTAL {
rte_swx_ctl_pipeline_learner_timeout_get;
rte_swx_ctl_pipeline_learner_timeout_set;
rte_swx_pipeline_hash_func_register;
# added in 22.11
rte_swx_ctl_pipeline_find;
rte_swx_pipeline_find;
};