@@ -2556,6 +2556,7 @@ instr_learner_exec(struct rte_swx_pipeline *p)
struct learner_statistics *stats = &p->learner_stats[learner_id];
uint64_t action_id, n_pkts_hit, n_pkts_action, time;
uint8_t *action_data;
+ size_t entry_id;
int done, hit;
/* Table. */
@@ -2567,6 +2568,7 @@ instr_learner_exec(struct rte_swx_pipeline *p)
l->key,
&action_id,
&action_data,
+ &entry_id,
&hit);
if (!done) {
/* Thread. */
@@ -2580,6 +2582,7 @@ instr_learner_exec(struct rte_swx_pipeline *p)
action_id = hit ? action_id : ts->default_action_id;
action_data = hit ? action_data : ts->default_action_data;
+ entry_id = hit ? (1 + entry_id) : 0;
n_pkts_hit = stats->n_pkts_hit[hit];
n_pkts_action = stats->n_pkts_action[action_id];
@@ -2591,6 +2594,7 @@ instr_learner_exec(struct rte_swx_pipeline *p)
t->action_id = action_id;
t->structs[0] = action_data;
+ t->entry_id = entry_id;
t->hit = hit;
t->learner_id = learner_id;
t->time = time;
@@ -2613,6 +2617,7 @@ instr_learner_af_exec(struct rte_swx_pipeline *p)
struct learner_statistics *stats = &p->learner_stats[learner_id];
uint64_t action_id, n_pkts_hit, n_pkts_action, time;
uint8_t *action_data;
+ size_t entry_id;
action_func_t action_func;
int done, hit;
@@ -2625,6 +2630,7 @@ instr_learner_af_exec(struct rte_swx_pipeline *p)
l->key,
&action_id,
&action_data,
+ &entry_id,
&hit);
if (!done) {
/* Thread. */
@@ -2638,6 +2644,7 @@ instr_learner_af_exec(struct rte_swx_pipeline *p)
action_id = hit ? action_id : ts->default_action_id;
action_data = hit ? action_data : ts->default_action_data;
+ entry_id = hit ? (1 + entry_id) : 0;
action_func = p->action_funcs[action_id];
n_pkts_hit = stats->n_pkts_hit[hit];
n_pkts_action = stats->n_pkts_action[action_id];
@@ -2650,6 +2657,7 @@ instr_learner_af_exec(struct rte_swx_pipeline *p)
t->action_id = action_id;
t->structs[0] = action_data;
+ t->entry_id = entry_id;
t->hit = hit;
t->learner_id = learner_id;
t->time = time;
@@ -72,6 +72,7 @@ table_keycpy(void *dst, void *src, uint32_t n_bytes)
}
#define TABLE_KEYS_PER_BUCKET 4
+#define TABLE_KEYS_PER_BUCKET_LOG2 2
#define TABLE_BUCKET_USEFUL_SIZE \
(TABLE_KEYS_PER_BUCKET * (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t)))
@@ -263,6 +264,14 @@ table_bucket_data_get(struct table *t, struct table_bucket *b, size_t bucket_key
(bucket_key_pos << t->params.data_size_log2)];
}
+static inline size_t
+table_entry_id_get(struct table *t, struct table_bucket *b, size_t bucket_key_pos)
+{
+ size_t bucket_id = ((uint8_t *)b - t->buckets) >> t->params.bucket_size_log2;
+
+ return (bucket_id << TABLE_KEYS_PER_BUCKET_LOG2) + bucket_key_pos;
+}
+
uint64_t
rte_swx_table_learner_footprint_get(struct rte_swx_table_learner_params *params)
{
@@ -332,7 +341,7 @@ struct mailbox {
/* Writer: lookup state 0. Reader(s): lookup state 1, add(). */
uint32_t input_sig;
- /* Writer: lookup state 1. Reader(s): add(). */
+ /* Writer: lookup state 0. Reader(s): lookup state 1, add(). */
uint8_t *input_key;
/* Writer: lookup state 1. Reader(s): add(). Values: 0 = miss; 1 = hit. */
@@ -358,6 +367,7 @@ rte_swx_table_learner_lookup(void *table,
uint8_t **key,
uint64_t *action_id,
uint8_t **action_data,
+ size_t *entry_id,
int *hit)
{
struct table *t = table;
@@ -412,6 +422,7 @@ rte_swx_table_learner_lookup(void *table,
*action_id = data[0];
*action_data = (uint8_t *)&data[1];
+ *entry_id = table_entry_id_get(t, b, i);
*hit = 1;
return 1;
}
@@ -173,6 +173,14 @@ rte_swx_table_learner_timeout_update(void *table,
* possibly an associated key add operation. The mailbox mechanism allows for multiple concurrent
* table key lookup and add operations into the same table.
*
+ * The table entry consists of the action ID and the action data. Each table entry is unique, even
+ * though different table entries can have identical content, i.e. same values for the action ID and
+ * the action data. The table entry ID is also returned by the table lookup operation. It can be
+ * used to index into an external array of resources such as counters, registers or meters to
+ * identify the resource directly associated with the current table entry with no need to store the
+ * corresponding index into the table entry. The index of the external resource is thus
+ * auto-generated instead of being stored in the table entry.
+ *
* @param[in] table
* Table handle.
* @param[in] mailbox
@@ -187,6 +195,9 @@ rte_swx_table_learner_timeout_update(void *table,
* @param[out] action_data
* Action data for the *action_id* action. Must point to a valid array of table *action_data_size*
* bytes. Only valid when the function returns 1 and *hit* is set to true.
+ * @param[out] entry_id
+ * Table entry unique ID. Must point to a valid 32-bit variable. Only valid when the function
+ * returns 1 and *hit* is set to true.
* @param[out] hit
* Only valid when the function returns 1. Set to non-zero (true) on table lookup hit and to zero
* (false) on table lookup miss.
@@ -202,6 +213,7 @@ rte_swx_table_learner_lookup(void *table,
uint8_t **key,
uint64_t *action_id,
uint8_t **action_data,
+ size_t *entry_id,
int *hit);
/**