* [dpdk-dev] [PATCH] pipeline: add table statistics
@ 2021-04-16 23:46 Cristian Dumitrescu
2021-04-20 0:29 ` Thomas Monjalon
0 siblings, 1 reply; 2+ messages in thread
From: Cristian Dumitrescu @ 2021-04-16 23:46 UTC (permalink / raw)
To: dev; +Cc: Yogesh Jangra
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>
---
examples/pipeline/cli.c | 54 +++++++++++++++++++++++-
lib/librte_pipeline/rte_swx_ctl.h | 38 +++++++++++++++++
lib/librte_pipeline/rte_swx_pipeline.c | 57 +++++++++++++++++++++++++-
lib/librte_pipeline/version.map | 1 +
4 files changed, 148 insertions(+), 2 deletions(-)
diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c
index ef47febaa..215dd8e85 100644
--- a/examples/pipeline/cli.c
+++ b/examples/pipeline/cli.c
@@ -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[] =
diff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h
index 4e5befb50..dee788be8 100644
--- a/lib/librte_pipeline/rte_swx_ctl.h
+++ b/lib/librte_pipeline/rte_swx_ctl.h
@@ -347,6 +347,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.
*/
diff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c
index aeb445755..4e358bbda 100644
--- a/lib/librte_pipeline/rte_swx_pipeline.c
+++ b/lib/librte_pipeline/rte_swx_pipeline.c
@@ -789,6 +789,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.
*/
@@ -1311,6 +1316,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;
@@ -3473,7 +3479,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;
@@ -3496,6 +3503,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,
@@ -3506,6 +3515,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);
@@ -9537,6 +9548,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;
@@ -9595,6 +9616,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
@@ -10350,6 +10378,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,
diff --git a/lib/librte_pipeline/version.map b/lib/librte_pipeline/version.map
index 2049d6d69..a4d7d9788 100644
--- a/lib/librte_pipeline/version.map
+++ b/lib/librte_pipeline/version.map
@@ -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;
--
2.17.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-04-20 0:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-16 23:46 [dpdk-dev] [PATCH] pipeline: add table statistics Cristian Dumitrescu
2021-04-20 0:29 ` Thomas Monjalon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).