From 394a0739c880328d4ae43e86590dfde1bcfbfa4b Mon Sep 17 00:00:00 2001 From: Jasvinder Singh Date: Thu, 29 Mar 2018 19:31:27 +0100 Subject: [PATCH] pipeline: add statistics read action Add implementation of stats read action Signed-off-by: Cristian Dumitrescu --- lib/librte_pipeline/rte_pipeline_version.map | 1 + lib/librte_pipeline/rte_table_action.c | 111 +++++++++++++++++++ lib/librte_pipeline/rte_table_action.h | 78 +++++++++++++ 3 files changed, 190 insertions(+) diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map index 938858550d..8241efc2c4 100644 --- a/lib/librte_pipeline/rte_pipeline_version.map +++ b/lib/librte_pipeline/rte_pipeline_version.map @@ -61,6 +61,7 @@ EXPERIMENTAL { rte_table_action_profile_free; rte_table_action_profile_freeze; rte_table_action_table_params_get; + rte_table_action_stats_read; rte_table_action_ttl_read; } DPDK_16.04; diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index c77bfb7eea..8bcc4eb37f 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -1113,6 +1113,41 @@ pkt_ipv6_work_ttl(struct ipv6_hdr *ip, return drop; } +/** + * RTE_TABLE_ACTION_STATS + */ +static int +stats_cfg_check(struct rte_table_action_stats_config *stats) +{ + if ((stats->n_packets_enabled == 0) && (stats->n_bytes_enabled == 0)) + return -EINVAL; + + return 0; +} + +struct stats_data { + uint64_t n_packets; + uint64_t n_bytes; +} __attribute__((__packed__)); + +static int +stats_apply(struct stats_data *data, + struct rte_table_action_stats_params *p) +{ + data->n_packets = p->n_packets; + data->n_bytes = p->n_bytes; + + return 0; +} + +static __rte_always_inline void +pkt_work_stats(struct stats_data *data, + uint16_t total_length) +{ + data->n_packets++; + data->n_bytes += total_length; +} + /** * Action profile */ @@ -1126,6 +1161,7 @@ action_valid(enum rte_table_action_type action) case RTE_TABLE_ACTION_ENCAP: case RTE_TABLE_ACTION_NAT: case RTE_TABLE_ACTION_TTL: + case RTE_TABLE_ACTION_STATS: return 1; default: return 0; @@ -1143,6 +1179,7 @@ struct ap_config { struct rte_table_action_encap_config encap; struct rte_table_action_nat_config nat; struct rte_table_action_ttl_config ttl; + struct rte_table_action_stats_config stats; }; static size_t @@ -1159,6 +1196,8 @@ action_cfg_size(enum rte_table_action_type action) return sizeof(struct rte_table_action_nat_config); case RTE_TABLE_ACTION_TTL: return sizeof(struct rte_table_action_ttl_config); + case RTE_TABLE_ACTION_STATS: + return sizeof(struct rte_table_action_stats_config); default: return 0; } @@ -1184,6 +1223,9 @@ action_cfg_get(struct ap_config *ap_config, case RTE_TABLE_ACTION_TTL: return &ap_config->ttl; + case RTE_TABLE_ACTION_STATS: + return &ap_config->stats; + default: return NULL; } @@ -1231,6 +1273,9 @@ action_data_size(enum rte_table_action_type action, case RTE_TABLE_ACTION_TTL: return sizeof(struct ttl_data); + case RTE_TABLE_ACTION_STATS: + return sizeof(struct stats_data); + default: return 0; } @@ -1322,6 +1367,10 @@ rte_table_action_profile_action_register(struct rte_table_action_profile *profil status = ttl_cfg_check(action_config); break; + case RTE_TABLE_ACTION_STATS: + status = stats_cfg_check(action_config); + break; + default: status = 0; break; @@ -1459,6 +1508,10 @@ rte_table_action_apply(struct rte_table_action *action, return ttl_apply(action_data, action_params); + case RTE_TABLE_ACTION_STATS: + return stats_apply(action_data, + action_params); + default: return -EINVAL; } @@ -1653,6 +1706,41 @@ rte_table_action_ttl_read(struct rte_table_action *action, return 0; } +int +rte_table_action_stats_read(struct rte_table_action *action, + void *data, + struct rte_table_action_stats_counters *stats, + int clear) +{ + struct stats_data *stats_data; + + /* Check input arguments */ + if ((action == NULL) || + ((action->cfg.action_mask & + (1LLU << RTE_TABLE_ACTION_STATS)) == 0) || + (data == NULL)) + return -EINVAL; + + stats_data = action_data_get(data, action, + RTE_TABLE_ACTION_STATS); + + /* Read */ + if (stats) { + stats->n_packets = stats_data->n_packets; + stats->n_bytes = stats_data->n_bytes; + stats->n_packets_valid = 1; + stats->n_bytes_valid = 1; + } + + /* Clear */ + if (clear) { + stats_data->n_packets = 0; + stats_data->n_bytes = 0; + } + + return 0; +} + static __rte_always_inline uint64_t pkt_work(struct rte_mbuf *mbuf, struct rte_pipeline_table_entry *table_entry, @@ -1736,6 +1824,13 @@ pkt_work(struct rte_mbuf *mbuf, drop_mask |= pkt_ipv6_work_ttl(ip, data); } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) { + void *data = + action_data_get(table_entry, action, RTE_TABLE_ACTION_STATS); + + pkt_work_stats(data, total_length); + } + return drop_mask; } @@ -1965,6 +2060,22 @@ pkt4_work(struct rte_mbuf **mbufs, } } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) { + void *data0 = + action_data_get(table_entry0, action, RTE_TABLE_ACTION_STATS); + void *data1 = + action_data_get(table_entry1, action, RTE_TABLE_ACTION_STATS); + void *data2 = + action_data_get(table_entry2, action, RTE_TABLE_ACTION_STATS); + void *data3 = + action_data_get(table_entry3, action, RTE_TABLE_ACTION_STATS); + + pkt_work_stats(data0, total_length0); + pkt_work_stats(data1, total_length1); + pkt_work_stats(data2, total_length2); + pkt_work_stats(data3, total_length3); + } + return drop_mask0 | (drop_mask1 << 1) | (drop_mask2 << 2) | diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index 57ac4f9161..53b9866c8e 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -83,6 +83,9 @@ enum rte_table_action_type { /** Time to Live (TTL) update. */ RTE_TABLE_ACTION_TTL, + + /** Statistics. */ + RTE_TABLE_ACTION_STATS, }; /** Common action configuration (per table action profile). */ @@ -488,6 +491,56 @@ struct rte_table_action_ttl_counters { uint64_t n_packets; }; +/** + * RTE_TABLE_ACTION_STATS + */ +/** Stats action configuration (per table action profile). */ +struct rte_table_action_stats_config { + /** When non-zero, the *n_packets* stats counter is enabled, otherwise + * disabled. + * + * @see struct rte_table_action_stats_counters + */ + int n_packets_enabled; + + /** When non-zero, the *n_bytes* stats counter is enabled, otherwise + * disabled. + * + * @see struct rte_table_action_stats_counters + */ + int n_bytes_enabled; +}; + +/** Stats action parameters (per table rule). */ +struct rte_table_action_stats_params { + /** Initial value for the *n_packets* stats counter. Typically set to 0. + * + * @see struct rte_table_action_stats_counters + */ + uint64_t n_packets; + + /** Initial value for the *n_bytes* stats counter. Typically set to 0. + * + * @see struct rte_table_action_stats_counters + */ + uint64_t n_bytes; +}; + +/** Stats action counters (per table rule). */ +struct rte_table_action_stats_counters { + /** Number of packets. Valid only when *n_packets_valid* is non-zero. */ + uint64_t n_packets; + + /** Number of bytes. Valid only when *n_bytes_valid* is non-zero. */ + uint64_t n_bytes; + + /** When non-zero, the *n_packets* field is valid, otherwise invalid. */ + int n_packets_valid; + + /** When non-zero, the *n_bytes* field is valid, otherwise invalid. */ + int n_bytes_valid; +}; + /** * Table action profile. */ @@ -737,6 +790,31 @@ rte_table_action_ttl_read(struct rte_table_action *action, struct rte_table_action_ttl_counters *stats, int clear); +/** + * Table action stats read. + * + * @param[in] action + * Handle to table action object (needs to be valid). + * @param[in] data + * Data byte array (typically table rule data) with stats action previously + * applied on it. + * @param[inout] stats + * When non-NULL, it points to the area where the stats counters read from + * *data* are saved. + * @param[in] clear + * When non-zero, the stats counters are cleared (i.e. set to zero), otherwise + * the counters are not modified. When the read operation is enabled (*stats* + * is non-NULL), the clear operation is performed after the read operation is + * completed. + * @return + * Zero on success, non-zero error code otherwise. + */ +int __rte_experimental +rte_table_action_stats_read(struct rte_table_action *action, + void *data, + struct rte_table_action_stats_counters *stats, + int clear); + #ifdef __cplusplus } #endif -- 2.20.1