pipeline: add table statistics to SWX
Add support for table statistics for the SWX pipeline. For each table, we maintain a counter for lookup hit packets, one for lookup miss packets and one packet counter for each table action. Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> Signed-off-by: Yogesh Jangra <yogesh.jangra@intel.com>
This commit is contained in:
parent
fe16d678e7
commit
742b0a57f5
@ -1802,7 +1802,7 @@ cmd_pipeline_stats(char **tokens,
|
||||
out += strlen(out);
|
||||
}
|
||||
|
||||
snprintf(out, out_size, "Output ports:\n");
|
||||
snprintf(out, out_size, "\nOutput ports:\n");
|
||||
out_size -= strlen(out);
|
||||
out += strlen(out);
|
||||
|
||||
@ -1818,6 +1818,58 @@ cmd_pipeline_stats(char **tokens,
|
||||
out_size -= strlen(out);
|
||||
out += strlen(out);
|
||||
}
|
||||
|
||||
snprintf(out, out_size, "\nTables:\n");
|
||||
out_size -= strlen(out);
|
||||
out += strlen(out);
|
||||
|
||||
for (i = 0; i < info.n_tables; i++) {
|
||||
struct rte_swx_ctl_table_info table_info;
|
||||
uint64_t n_pkts_action[info.n_actions];
|
||||
struct rte_swx_table_stats stats = {
|
||||
.n_pkts_hit = 0,
|
||||
.n_pkts_miss = 0,
|
||||
.n_pkts_action = n_pkts_action,
|
||||
};
|
||||
uint32_t j;
|
||||
|
||||
status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
|
||||
if (status) {
|
||||
snprintf(out, out_size, "Table info get error.");
|
||||
return;
|
||||
}
|
||||
|
||||
status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
|
||||
if (status) {
|
||||
snprintf(out, out_size, "Table stats read error.");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(out, out_size, "\tTable %s:\n"
|
||||
"\t\tHit (packets): %" PRIu64 "\n"
|
||||
"\t\tMiss (packets): %" PRIu64 "\n",
|
||||
table_info.name,
|
||||
stats.n_pkts_hit,
|
||||
stats.n_pkts_miss);
|
||||
out_size -= strlen(out);
|
||||
out += strlen(out);
|
||||
|
||||
for (j = 0; j < info.n_actions; j++) {
|
||||
struct rte_swx_ctl_action_info action_info;
|
||||
|
||||
status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
|
||||
if (status) {
|
||||
snprintf(out, out_size, "Action info get error.");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
|
||||
action_info.name,
|
||||
stats.n_pkts_action[j]);
|
||||
out_size -= strlen(out);
|
||||
out += strlen(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char cmd_thread_pipeline_enable_help[] =
|
||||
|
@ -341,6 +341,44 @@ rte_swx_ctl_table_ops_get(struct rte_swx_pipeline *p,
|
||||
struct rte_swx_table_ops *table_ops,
|
||||
int *is_stub);
|
||||
|
||||
/** Table statistics. */
|
||||
struct rte_swx_table_stats {
|
||||
/** Number of packets with lookup hit. */
|
||||
uint64_t n_pkts_hit;
|
||||
|
||||
/** Number of packets with lookup miss. */
|
||||
uint64_t n_pkts_miss;
|
||||
|
||||
/** Number of packets (with either lookup hit or miss) per pipeline
|
||||
* action. Array of pipeline *n_actions* elements indedex by the
|
||||
* pipeline-level *action_id*, therefore this array has the same size
|
||||
* for all the tables within the same pipeline.
|
||||
*/
|
||||
uint64_t *n_pkts_action;
|
||||
};
|
||||
|
||||
/**
|
||||
* Table statistics counters read
|
||||
*
|
||||
* @param[in] p
|
||||
* Pipeline handle.
|
||||
* @param[in] table_name
|
||||
* Table name.
|
||||
* @param[out] stats
|
||||
* Table stats. Must point to a pre-allocated structure. The *n_pkts_action*
|
||||
* field also needs to be pre-allocated as array of pipeline *n_actions*
|
||||
* elements. The pipeline actions that are not valid for the current table
|
||||
* have their associated *n_pkts_action* element always set to zero.
|
||||
* @return
|
||||
* 0 on success or the following error codes otherwise:
|
||||
* -EINVAL: Invalid argument.
|
||||
*/
|
||||
__rte_experimental
|
||||
int
|
||||
rte_swx_ctl_pipeline_table_stats_read(struct rte_swx_pipeline *p,
|
||||
const char *table_name,
|
||||
struct rte_swx_table_stats *stats);
|
||||
|
||||
/*
|
||||
* Table Update API.
|
||||
*/
|
||||
|
@ -776,6 +776,11 @@ struct table_runtime {
|
||||
uint8_t **key;
|
||||
};
|
||||
|
||||
struct table_statistics {
|
||||
uint64_t n_pkts_hit[2]; /* 0 = Miss, 1 = Hit. */
|
||||
uint64_t *n_pkts_action;
|
||||
};
|
||||
|
||||
/*
|
||||
* Register array.
|
||||
*/
|
||||
@ -1214,6 +1219,7 @@ struct rte_swx_pipeline {
|
||||
struct port_out_runtime *out;
|
||||
struct instruction **action_instructions;
|
||||
struct rte_swx_table_state *table_state;
|
||||
struct table_statistics *table_stats;
|
||||
struct regarray_runtime *regarray_runtime;
|
||||
struct metarray_runtime *metarray_runtime;
|
||||
struct instruction *instructions;
|
||||
@ -3354,7 +3360,8 @@ instr_table_exec(struct rte_swx_pipeline *p)
|
||||
uint32_t table_id = ip->table.table_id;
|
||||
struct rte_swx_table_state *ts = &t->table_state[table_id];
|
||||
struct table_runtime *table = &t->tables[table_id];
|
||||
uint64_t action_id;
|
||||
struct table_statistics *stats = &p->table_stats[table_id];
|
||||
uint64_t action_id, n_pkts_hit, n_pkts_action;
|
||||
uint8_t *action_data;
|
||||
int done, hit;
|
||||
|
||||
@ -3377,6 +3384,8 @@ instr_table_exec(struct rte_swx_pipeline *p)
|
||||
|
||||
action_id = hit ? action_id : ts->default_action_id;
|
||||
action_data = hit ? action_data : ts->default_action_data;
|
||||
n_pkts_hit = stats->n_pkts_hit[hit];
|
||||
n_pkts_action = stats->n_pkts_action[action_id];
|
||||
|
||||
TRACE("[Thread %2u] table %u (%s, action %u)\n",
|
||||
p->thread_id,
|
||||
@ -3387,6 +3396,8 @@ instr_table_exec(struct rte_swx_pipeline *p)
|
||||
t->action_id = action_id;
|
||||
t->structs[0] = action_data;
|
||||
t->hit = hit;
|
||||
stats->n_pkts_hit[hit] = n_pkts_hit + 1;
|
||||
stats->n_pkts_action[action_id] = n_pkts_action + 1;
|
||||
|
||||
/* Thread. */
|
||||
thread_ip_action_call(p, t, action_id);
|
||||
@ -8950,6 +8961,16 @@ table_build(struct rte_swx_pipeline *p)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
/* Per pipeline: table statistics. */
|
||||
p->table_stats = calloc(p->n_tables, sizeof(struct table_statistics));
|
||||
CHECK(p->table_stats, ENOMEM);
|
||||
|
||||
for (i = 0; i < p->n_tables; i++) {
|
||||
p->table_stats[i].n_pkts_action = calloc(p->n_actions, sizeof(uint64_t));
|
||||
CHECK(p->table_stats[i].n_pkts_action, ENOMEM);
|
||||
}
|
||||
|
||||
/* Per thread: table runt-time. */
|
||||
for (i = 0; i < RTE_SWX_PIPELINE_THREADS_MAX; i++) {
|
||||
struct thread *t = &p->threads[i];
|
||||
struct table *table;
|
||||
@ -9008,6 +9029,13 @@ table_build_free(struct rte_swx_pipeline *p)
|
||||
free(t->tables);
|
||||
t->tables = NULL;
|
||||
}
|
||||
|
||||
if (p->table_stats) {
|
||||
for (i = 0; i < p->n_tables; i++)
|
||||
free(p->table_stats[i].n_pkts_action);
|
||||
|
||||
free(p->table_stats);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -9762,6 +9790,33 @@ rte_swx_ctl_pipeline_port_out_stats_read(struct rte_swx_pipeline *p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_swx_ctl_pipeline_table_stats_read(struct rte_swx_pipeline *p,
|
||||
const char *table_name,
|
||||
struct rte_swx_table_stats *stats)
|
||||
{
|
||||
struct table *table;
|
||||
struct table_statistics *table_stats;
|
||||
|
||||
if (!p || !table_name || !table_name[0] || !stats || !stats->n_pkts_action)
|
||||
return -EINVAL;
|
||||
|
||||
table = table_find(p, table_name);
|
||||
if (!table)
|
||||
return -EINVAL;
|
||||
|
||||
table_stats = &p->table_stats[table->id];
|
||||
|
||||
memcpy(&stats->n_pkts_action,
|
||||
&table_stats->n_pkts_action,
|
||||
p->n_actions * sizeof(uint64_t));
|
||||
|
||||
stats->n_pkts_hit = table_stats->n_pkts_hit[1];
|
||||
stats->n_pkts_miss = table_stats->n_pkts_hit[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_swx_ctl_regarray_info_get(struct rte_swx_pipeline *p,
|
||||
uint32_t regarray_id,
|
||||
|
@ -112,6 +112,7 @@ EXPERIMENTAL {
|
||||
rte_swx_ctl_meter_stats_read;
|
||||
rte_swx_ctl_pipeline_regarray_read;
|
||||
rte_swx_ctl_pipeline_regarray_write;
|
||||
rte_swx_ctl_pipeline_table_stats_read;
|
||||
rte_swx_ctl_regarray_info_get;
|
||||
rte_swx_pipeline_metarray_config;
|
||||
rte_swx_pipeline_regarray_config;
|
||||
|
Loading…
Reference in New Issue
Block a user