examples/ip_pipeline: link routing output ports to devices

This commit implements tracking mechanism for linking routing pipeline
output ports to physical NIC ports.

Once all the pipelines of the application are initialised, mechanism is
invoked during post initialisation phase for relating routing pipeline
output with NIC ports by navigating through the intermediate pipelines,
if present.

The tracking functions of the pipelines which help in navigating through
the intermediate pipelines are moved from pipeline_<pipeline_name>_be.c
to pipeline_<pipeline_name>.c. All pipelines except passthrough pipelines
use default tracking function (pipeline/pipeline_common_fe.c).

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This commit is contained in:
Jasvinder Singh 2016-06-01 15:00:59 +01:00 committed by Thomas Monjalon
parent 32af1f421a
commit 760064838e
18 changed files with 380 additions and 124 deletions

View File

@ -205,9 +205,7 @@ struct app_pktq_out_params {
uint32_t id; /* Position in the appropriate app array */
};
#ifndef APP_PIPELINE_TYPE_SIZE
#define APP_PIPELINE_TYPE_SIZE 64
#endif
#define APP_PIPELINE_TYPE_SIZE PIPELINE_TYPE_SIZE
#define APP_MAX_PIPELINE_PKTQ_IN PIPELINE_MAX_PORT_IN
#define APP_MAX_PIPELINE_PKTQ_OUT PIPELINE_MAX_PORT_OUT
@ -651,6 +649,41 @@ app_swq_get_readers(struct app_params *app, struct app_pktq_swq_params *swq)
return n_readers;
}
static inline struct app_pipeline_params *
app_swq_get_reader(struct app_params *app,
struct app_pktq_swq_params *swq,
uint32_t *pktq_in_id)
{
struct app_pipeline_params *reader;
uint32_t pos = swq - app->swq_params;
uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
RTE_DIM(app->pipeline_params));
uint32_t n_readers = 0, id, i;
for (i = 0; i < n_pipelines; i++) {
struct app_pipeline_params *p = &app->pipeline_params[i];
uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
uint32_t j;
for (j = 0; j < n_pktq_in; j++) {
struct app_pktq_in_params *pktq = &p->pktq_in[j];
if ((pktq->type == APP_PKTQ_IN_SWQ) &&
(pktq->id == pos)) {
n_readers++;
reader = p;
id = j;
}
}
}
if (n_readers != 1)
return NULL;
*pktq_in_id = id;
return reader;
}
static inline uint32_t
app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
{
@ -676,6 +709,41 @@ app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
return n_readers;
}
static inline struct app_pipeline_params *
app_tm_get_reader(struct app_params *app,
struct app_pktq_tm_params *tm,
uint32_t *pktq_in_id)
{
struct app_pipeline_params *reader;
uint32_t pos = tm - app->tm_params;
uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
RTE_DIM(app->pipeline_params));
uint32_t n_readers = 0, id, i;
for (i = 0; i < n_pipelines; i++) {
struct app_pipeline_params *p = &app->pipeline_params[i];
uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
uint32_t j;
for (j = 0; j < n_pktq_in; j++) {
struct app_pktq_in_params *pktq = &p->pktq_in[j];
if ((pktq->type == APP_PKTQ_IN_TM) &&
(pktq->id == pos)) {
n_readers++;
reader = p;
id = j;
}
}
}
if (n_readers != 1)
return NULL;
*pktq_in_id = id;
return reader;
}
static inline uint32_t
app_source_get_readers(struct app_params *app,
struct app_pktq_source_params *source)
@ -775,6 +843,42 @@ app_swq_get_writers(struct app_params *app, struct app_pktq_swq_params *swq)
return n_writers;
}
static inline struct app_pipeline_params *
app_swq_get_writer(struct app_params *app,
struct app_pktq_swq_params *swq,
uint32_t *pktq_out_id)
{
struct app_pipeline_params *writer;
uint32_t pos = swq - app->swq_params;
uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
RTE_DIM(app->pipeline_params));
uint32_t n_writers = 0, id, i;
for (i = 0; i < n_pipelines; i++) {
struct app_pipeline_params *p = &app->pipeline_params[i];
uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
RTE_DIM(p->pktq_out));
uint32_t j;
for (j = 0; j < n_pktq_out; j++) {
struct app_pktq_out_params *pktq = &p->pktq_out[j];
if ((pktq->type == APP_PKTQ_OUT_SWQ) &&
(pktq->id == pos)) {
n_writers++;
writer = p;
id = j;
}
}
}
if (n_writers != 1)
return NULL;
*pktq_out_id = id;
return writer;
}
static inline uint32_t
app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
{
@ -801,6 +905,41 @@ app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
return n_writers;
}
static inline struct app_pipeline_params *
app_tm_get_writer(struct app_params *app,
struct app_pktq_tm_params *tm,
uint32_t *pktq_out_id)
{
struct app_pipeline_params *writer;
uint32_t pos = tm - app->tm_params;
uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
RTE_DIM(app->pipeline_params));
uint32_t n_writers = 0, id, i;
for (i = 0; i < n_pipelines; i++) {
struct app_pipeline_params *p = &app->pipeline_params[i];
uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
RTE_DIM(p->pktq_out));
uint32_t j;
for (j = 0; j < n_pktq_out; j++) {
struct app_pktq_out_params *pktq = &p->pktq_out[j];
if ((pktq->type == APP_PKTQ_OUT_TM) &&
(pktq->id == pos))
n_writers++;
writer = p;
id = j;
}
}
if (n_writers != 1)
return NULL;
*pktq_out_id = id;
return writer;
}
static inline uint32_t
app_sink_get_writers(struct app_params *app, struct app_pktq_sink_params *sink)
{
@ -899,6 +1038,10 @@ app_get_link_for_tm(struct app_params *app, struct app_pktq_tm_params *p_tm)
return &app->link_params[link_param_idx];
}
void app_pipeline_params_get(struct app_params *app,
struct app_pipeline_params *p_in,
struct pipeline_params *p_out);
int app_config_init(struct app_params *app);
int app_config_args(struct app_params *app,
@ -918,6 +1061,8 @@ int app_config_check(struct app_params *app);
int app_init(struct app_params *app);
int app_post_init(struct app_params *app);
int app_thread(void *arg);
int app_pipeline_type_register(struct app_params *app,

View File

@ -1196,7 +1196,7 @@ app_init_msgq(struct app_params *app)
}
}
static void app_pipeline_params_get(struct app_params *app,
void app_pipeline_params_get(struct app_params *app,
struct app_pipeline_params *p_in,
struct pipeline_params *p_out)
{
@ -1204,6 +1204,8 @@ static void app_pipeline_params_get(struct app_params *app,
snprintf(p_out->name, PIPELINE_NAME_SIZE, "%s", p_in->name);
snprintf(p_out->type, PIPELINE_TYPE_SIZE, "%s", p_in->type);
p_out->socket_id = (int) p_in->socket_id;
p_out->log_level = app->log_level;
@ -1498,6 +1500,27 @@ app_init_pipelines(struct app_params *app)
}
}
static void
app_post_init_pipelines(struct app_params *app)
{
uint32_t p_id;
for (p_id = 0; p_id < app->n_pipelines; p_id++) {
struct app_pipeline_params *params =
&app->pipeline_params[p_id];
struct app_pipeline_data *data = &app->pipeline_data[p_id];
int status;
if (data->ptype->fe_ops->f_post_init == NULL)
continue;
status = data->ptype->fe_ops->f_post_init(data->fe);
if (status)
rte_panic("Pipeline instance \"%s\" front-end "
"post-init error\n", params->name);
}
}
static void
app_init_threads(struct app_params *app)
{
@ -1601,6 +1624,13 @@ int app_init(struct app_params *app)
return 0;
}
int app_post_init(struct app_params *app)
{
app_post_init_pipelines(app);
return 0;
}
static int
app_pipeline_type_cmd_push(struct app_params *app,
struct pipeline_type *ptype)

View File

@ -42,13 +42,22 @@
* Pipeline type front-end operations
*/
typedef void* (*pipeline_fe_op_init)(struct pipeline_params *params, void *arg);
typedef void* (*pipeline_fe_op_init)(struct pipeline_params *params,
void *arg);
typedef int (*pipeline_fe_op_post_init)(void *pipeline);
typedef int (*pipeline_fe_op_free)(void *pipeline);
typedef int (*pipeline_fe_op_track)(struct pipeline_params *params,
uint32_t port_in,
uint32_t *port_out);
struct pipeline_fe_ops {
pipeline_fe_op_init f_init;
pipeline_fe_op_post_init f_post_init;
pipeline_fe_op_free f_free;
pipeline_fe_op_track f_track;
cmdline_parse_ctx_t *cmds;
};

View File

@ -47,6 +47,115 @@
#include "pipeline_common_fe.h"
#include "parser.h"
struct app_link_params *
app_pipeline_track_pktq_out_to_link(struct app_params *app,
uint32_t pipeline_id,
uint32_t pktq_out_id)
{
struct app_pipeline_params *p;
/* Check input arguments */
if (app == NULL)
return NULL;
APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
if (p == NULL)
return NULL;
for ( ; ; ) {
struct app_pktq_out_params *pktq_out =
&p->pktq_out[pktq_out_id];
switch (pktq_out->type) {
case APP_PKTQ_OUT_HWQ:
{
struct app_pktq_hwq_out_params *hwq_out;
hwq_out = &app->hwq_out_params[pktq_out->id];
return app_get_link_for_txq(app, hwq_out);
}
case APP_PKTQ_OUT_SWQ:
{
struct pipeline_params pp;
struct pipeline_type *ptype;
struct app_pktq_swq_params *swq;
uint32_t pktq_in_id;
int status;
swq = &app->swq_params[pktq_out->id];
p = app_swq_get_reader(app, swq, &pktq_in_id);
if (p == NULL)
return NULL;
ptype = app_pipeline_type_find(app, p->type);
if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
return NULL;
app_pipeline_params_get(app, p, &pp);
status = ptype->fe_ops->f_track(&pp,
pktq_in_id,
&pktq_out_id);
if (status)
return NULL;
break;
}
case APP_PKTQ_OUT_TM:
{
struct pipeline_params pp;
struct pipeline_type *ptype;
struct app_pktq_tm_params *tm;
uint32_t pktq_in_id;
int status;
tm = &app->tm_params[pktq_out->id];
p = app_tm_get_reader(app, tm, &pktq_in_id);
if (p == NULL)
return NULL;
ptype = app_pipeline_type_find(app, p->type);
if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
return NULL;
app_pipeline_params_get(app, p, &pp);
status = ptype->fe_ops->f_track(&pp,
pktq_in_id,
&pktq_out_id);
if (status)
return NULL;
break;
}
case APP_PKTQ_OUT_SINK:
default:
return NULL;
}
}
}
int
app_pipeline_track_default(struct pipeline_params *p,
uint32_t port_in,
uint32_t *port_out)
{
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
if (p->n_ports_out == 1) {
*port_out = 0;
return 0;
}
return -1;
}
int
app_pipeline_ping(struct app_params *app,
uint32_t pipeline_id)

View File

@ -182,6 +182,16 @@ app_msg_send_recv(struct app_params *app,
return msg_recv;
}
struct app_link_params *
app_pipeline_track_pktq_out_to_link(struct app_params *app,
uint32_t pipeline_id,
uint32_t pktq_out_id);
int
app_pipeline_track_default(struct pipeline_params *params,
uint32_t port_in,
uint32_t *port_out);
int
app_pipeline_ping(struct app_params *app,
uint32_t pipeline_id);

View File

@ -1437,7 +1437,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
static struct pipeline_fe_ops pipeline_firewall_fe_ops = {
.f_init = app_pipeline_firewall_init,
.f_post_init = NULL,
.f_free = app_pipeline_firewall_free,
.f_track = app_pipeline_track_default,
.cmds = pipeline_cmds,
};

View File

@ -564,27 +564,6 @@ pipeline_firewall_free(void *pipeline)
return 0;
}
static int
pipeline_firewall_track(void *pipeline,
__rte_unused uint32_t port_in,
uint32_t *port_out)
{
struct pipeline *p = (struct pipeline *) pipeline;
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
if (p->n_ports_in == 1) {
*port_out = 0;
return 0;
}
return -1;
}
static int
pipeline_firewall_timer(void *pipeline)
{
@ -903,5 +882,4 @@ struct pipeline_be_ops pipeline_firewall_be_ops = {
.f_free = pipeline_firewall_free,
.f_run = NULL,
.f_timer = pipeline_firewall_timer,
.f_track = pipeline_firewall_track,
};

View File

@ -1300,7 +1300,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
static struct pipeline_fe_ops pipeline_flow_actions_fe_ops = {
.f_init = app_pipeline_fa_init,
.f_post_init = NULL,
.f_free = app_pipeline_fa_free,
.f_track = app_pipeline_track_default,
.cmds = pipeline_cmds,
};

View File

@ -759,27 +759,6 @@ pipeline_fa_free(void *pipeline)
return 0;
}
static int
pipeline_fa_track(void *pipeline,
__rte_unused uint32_t port_in,
uint32_t *port_out)
{
struct pipeline *p = (struct pipeline *) pipeline;
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
if (p->n_ports_in == 1) {
*port_out = 0;
return 0;
}
return -1;
}
static int
pipeline_fa_timer(void *pipeline)
{
@ -1007,5 +986,4 @@ struct pipeline_be_ops pipeline_flow_actions_be_ops = {
.f_free = pipeline_fa_free,
.f_run = NULL,
.f_timer = pipeline_fa_timer,
.f_track = pipeline_fa_track,
};

View File

@ -1892,7 +1892,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
static struct pipeline_fe_ops pipeline_flow_classification_fe_ops = {
.f_init = app_pipeline_fc_init,
.f_post_init = NULL,
.f_free = app_pipeline_fc_free,
.f_track = app_pipeline_track_default,
.cmds = pipeline_cmds,
};

View File

@ -642,27 +642,6 @@ pipeline_fc_free(void *pipeline)
return 0;
}
static int
pipeline_fc_track(void *pipeline,
__rte_unused uint32_t port_in,
uint32_t *port_out)
{
struct pipeline *p = (struct pipeline *) pipeline;
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
if (p->n_ports_in == 1) {
*port_out = 0;
return 0;
}
return -1;
}
static int
pipeline_fc_timer(void *pipeline)
{
@ -807,5 +786,4 @@ struct pipeline_be_ops pipeline_flow_classification_be_ops = {
.f_free = pipeline_fc_free,
.f_run = NULL,
.f_timer = pipeline_fc_timer,
.f_track = pipeline_fc_track,
};

View File

@ -36,7 +36,9 @@
static struct pipeline_fe_ops pipeline_master_fe_ops = {
.f_init = NULL,
.f_post_init = NULL,
.f_free = NULL,
.f_track = NULL,
.cmds = NULL,
};

View File

@ -48,6 +48,7 @@
struct pipeline_master {
struct app_params *app;
struct cmdline *cl;
int post_init_done;
int script_file_done;
} __rte_cache_aligned;
@ -77,6 +78,7 @@ pipeline_init(__rte_unused struct pipeline_params *params, void *arg)
return NULL;
}
p->post_init_done = 0;
p->script_file_done = 0;
if (app->script_file == NULL)
p->script_file_done = 1;
@ -102,8 +104,17 @@ static int
pipeline_run(void *pipeline)
{
struct pipeline_master *p = (struct pipeline_master *) pipeline;
struct app_params *app = p->app;
int status;
/* Application post-init phase */
if (p->post_init_done == 0) {
app_post_init(app);
p->post_init_done = 1;
}
/* Run startup script file */
if (p->script_file_done == 0) {
struct app_params *app = p->app;
int fd = open(app->script_file, O_RDONLY);
@ -124,6 +135,7 @@ pipeline_run(void *pipeline)
p->script_file_done = 1;
}
/* Command Line Interface (CLI) */
status = cmdline_poll(p->cl);
if (status < 0)
rte_panic("CLI poll error (%" PRId32 ")\n", status);
@ -146,5 +158,4 @@ struct pipeline_be_ops pipeline_master_be_ops = {
.f_free = pipeline_free,
.f_run = pipeline_run,
.f_timer = pipeline_timer,
.f_track = NULL,
};

View File

@ -34,9 +34,36 @@
#include "pipeline_passthrough.h"
#include "pipeline_passthrough_be.h"
static int
app_pipeline_passthrough_track(struct pipeline_params *p,
uint32_t port_in,
uint32_t *port_out)
{
struct pipeline_passthrough_params pp;
int status;
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
status = pipeline_passthrough_parse_args(&pp, p);
if (status)
return -1;
if (pp.lb_hash_enabled)
return -1;
*port_out = port_in / (p->n_ports_in / p->n_ports_out);
return 0;
}
static struct pipeline_fe_ops pipeline_passthrough_fe_ops = {
.f_init = NULL,
.f_post_init = NULL,
.f_free = NULL,
.f_track = app_pipeline_passthrough_track,
.cmds = NULL,
};

View File

@ -547,6 +547,18 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
"dma_src_mask", dma_mask_str);
}
if (p->lb_hash_enabled)
PIPELINE_ARG_CHECK((params->n_ports_out > 1),
"Parse error in section \"%s\": entry \"lb\" not "
"allowed for single output port pipeline",
params->name);
else
PIPELINE_ARG_CHECK(((params->n_ports_in >= params->n_ports_out)
&& ((params->n_ports_in % params->n_ports_out) == 0)),
"Parse error in section \"%s\": n_ports_in needs to be "
"a multiple of n_ports_out (lb mode disabled)",
params->name);
return 0;
}
@ -579,9 +591,7 @@ pipeline_passthrough_init(struct pipeline_params *params,
/* Check input arguments */
if ((params == NULL) ||
(params->n_ports_in == 0) ||
(params->n_ports_out == 0) ||
(params->n_ports_in < params->n_ports_out) ||
(params->n_ports_in % params->n_ports_out))
(params->n_ports_out == 0))
return NULL;
/* Memory allocation */
@ -702,10 +712,13 @@ pipeline_passthrough_init(struct pipeline_params *params,
/* Add entries to tables */
for (i = 0; i < p->n_ports_in; i++) {
uint32_t port_out_id = (p_pt->params.lb_hash_enabled == 0) ?
(i / (p->n_ports_in / p->n_ports_out)) :
0;
struct rte_pipeline_table_entry default_entry = {
.action = RTE_PIPELINE_ACTION_PORT,
{.port_id = p->port_out_id[
i / (p->n_ports_in / p->n_ports_out)]},
{.port_id = p->port_out_id[port_out_id]},
};
struct rte_pipeline_table_entry *default_entry_ptr;
@ -780,25 +793,9 @@ pipeline_passthrough_timer(void *pipeline)
return 0;
}
static int
pipeline_passthrough_track(void *pipeline, uint32_t port_in, uint32_t *port_out)
{
struct pipeline *p = (struct pipeline *) pipeline;
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
*port_out = port_in / p->n_ports_in;
return 0;
}
struct pipeline_be_ops pipeline_passthrough_be_ops = {
.f_init = pipeline_passthrough_init,
.f_free = pipeline_passthrough_free,
.f_run = NULL,
.f_timer = pipeline_passthrough_timer,
.f_track = pipeline_passthrough_track,
};

View File

@ -382,8 +382,6 @@ app_pipeline_routing_add_route(struct app_params *app,
p->n_routes++;
}
print_route(entry);
/* Message buffer free */
app_msg_free(app, rsp);
return 0;
@ -676,8 +674,6 @@ app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
p->n_arp_entries++;
}
print_arp_entry(entry);
/* Message buffer free */
app_msg_free(app, rsp);
return 0;
@ -1390,7 +1386,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
static struct pipeline_fe_ops pipeline_routing_fe_ops = {
.f_init = pipeline_routing_init,
.f_post_init = NULL,
.f_free = app_pipeline_routing_free,
.f_track = app_pipeline_track_default,
.cmds = pipeline_cmds,
};

View File

@ -1418,27 +1418,6 @@ pipeline_routing_free(void *pipeline)
return 0;
}
static int
pipeline_routing_track(void *pipeline,
__rte_unused uint32_t port_in,
uint32_t *port_out)
{
struct pipeline *p = (struct pipeline *) pipeline;
/* Check input arguments */
if ((p == NULL) ||
(port_in >= p->n_ports_in) ||
(port_out == NULL))
return -1;
if (p->n_ports_in == 1) {
*port_out = 0;
return 0;
}
return -1;
}
static int
pipeline_routing_timer(void *pipeline)
{
@ -1966,5 +1945,4 @@ struct pipeline_be_ops pipeline_routing_be_ops = {
.f_free = pipeline_routing_free,
.f_run = NULL,
.f_timer = pipeline_routing_timer,
.f_track = pipeline_routing_track,
};

View File

@ -203,6 +203,10 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params *p)
#define PIPELINE_NAME_SIZE 64
#endif
#ifndef PIPELINE_TYPE_SIZE
#define PIPELINE_TYPE_SIZE 64
#endif
#ifndef PIPELINE_MAX_PORT_IN
#define PIPELINE_MAX_PORT_IN 64
#endif
@ -229,6 +233,7 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params *p)
struct pipeline_params {
char name[PIPELINE_NAME_SIZE];
char type[PIPELINE_TYPE_SIZE];
struct pipeline_port_in_params port_in[PIPELINE_MAX_PORT_IN];
struct pipeline_port_out_params port_out[PIPELINE_MAX_PORT_OUT];
@ -261,16 +266,11 @@ typedef int (*pipeline_be_op_run)(void *pipeline);
typedef int (*pipeline_be_op_timer)(void *pipeline);
typedef int (*pipeline_be_op_track)(void *pipeline,
uint32_t port_in,
uint32_t *port_out);
struct pipeline_be_ops {
pipeline_be_op_init f_init;
pipeline_be_op_free f_free;
pipeline_be_op_run f_run;
pipeline_be_op_timer f_timer;
pipeline_be_op_track f_track;
};
/* Pipeline specific config parse error messages */