From: Li Zhang <lizh@nvidia.com>
To: dekelp@nvidia.com, orika@nvidia.com, viacheslavo@nvidia.com,
matan@nvidia.com, shahafs@nvidia.com
Cc: dev@dpdk.org, thomas@monjalon.net, rasland@nvidia.com, roniba@nvidia.com
Subject: [dpdk-dev] [PATCH v3 09/14] net/mlx5: flow meter pool to manage meter object
Date: Tue, 13 Apr 2021 03:10:27 +0300 [thread overview]
Message-ID: <20210413001033.1999355-10-lizh@nvidia.com> (raw)
In-Reply-To: <20210413001033.1999355-1-lizh@nvidia.com>
Add ASO flow meter pool to manage meter object
Signed-off-by: Li Zhang <lizh@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
drivers/net/mlx5/mlx5.c | 2 +-
drivers/net/mlx5/mlx5.h | 207 ++++++++++++-
drivers/net/mlx5/mlx5_flow.c | 70 ++++-
drivers/net/mlx5/mlx5_flow.h | 196 +++----------
drivers/net/mlx5/mlx5_flow_dv.c | 203 ++++++++++++-
drivers/net/mlx5/mlx5_flow_meter.c | 450 ++++++++++++++++++-----------
6 files changed, 769 insertions(+), 359 deletions(-)
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 734dee9f19..6440edbc92 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -280,7 +280,7 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {
* for meter idx, so not set grow_trunk to avoid meter index
* not jump continually.
*/
- .size = sizeof(struct mlx5_flow_meter),
+ .size = sizeof(struct mlx5_legacy_flow_meter),
.trunk_size = 64,
.need_lock = 1,
.release_mem_en = 1,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b50acaca41..2017df4bd5 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -20,6 +20,7 @@
#include <rte_interrupts.h>
#include <rte_errno.h>
#include <rte_flow.h>
+#include <rte_mtr.h>
#include <mlx5_glue.h>
#include <mlx5_devx_cmds.h>
@@ -573,6 +574,193 @@ struct mlx5_dev_shared_port {
/* Aging information for per port. */
};
+/*ASO flow meter structures*/
+/* Modify this value if enum rte_mtr_color changes. */
+#define RTE_MTR_DROPPED RTE_COLORS
+
+/* Meter policer statistics */
+struct mlx5_flow_policer_stats {
+ uint32_t pass_cnt;
+ /**< Color counter for pass. */
+ uint32_t drop_cnt;
+ /**< Color counter for drop. */
+};
+
+/* Meter table structure. */
+struct mlx5_meter_domain_info {
+ struct mlx5_flow_tbl_resource *tbl;
+ /**< Meter table. */
+ struct mlx5_flow_tbl_resource *sfx_tbl;
+ /**< Meter suffix table. */
+ struct mlx5_flow_dv_matcher *drop_matcher;
+ /**< Matcher for Drop. */
+ struct mlx5_flow_dv_matcher *color_matcher;
+ /**< Matcher for Color. */
+ void *jump_actn;
+ /**< Meter match action. */
+ void *green_rule;
+ /**< Meter green rule. */
+ void *drop_rule;
+ /**< Meter drop rule. */
+};
+
+/* Meter table set for TX RX FDB. */
+struct mlx5_meter_domains_infos {
+ uint32_t ref_cnt;
+ /**< Table user count. */
+ struct mlx5_meter_domain_info egress;
+ /**< TX meter table. */
+ struct mlx5_meter_domain_info ingress;
+ /**< RX meter table. */
+ struct mlx5_meter_domain_info transfer;
+ /**< FDB meter table. */
+ void *drop_actn;
+ /**< Drop action as not matched. */
+ void *green_count;
+ /**< Counters for green rule. */
+ void *drop_count;
+ /**< Counters for green rule. */
+ void *meter_action;
+ /**< Flow meter action. */
+};
+
+/* Meter parameter structure. */
+struct mlx5_flow_meter_info {
+ uint32_t meter_id;
+ /**< Meter id. */
+ struct mlx5_flow_meter_profile *profile;
+ /**< Meter profile parameters. */
+ rte_spinlock_t sl; /**< Meter action spinlock. */
+ /** Policer actions (per meter output color). */
+ enum rte_mtr_policer_action action[RTE_COLORS];
+ /** Set of stats counters to be enabled.
+ * @see enum rte_mtr_stats_type
+ */
+ uint32_t green_bytes:1;
+ /** Set green bytes stats to be enabled. */
+ uint32_t green_pkts:1;
+ /** Set green packets stats to be enabled. */
+ uint32_t red_bytes:1;
+ /** Set red bytes stats to be enabled. */
+ uint32_t red_pkts:1;
+ /** Set red packets stats to be enabled. */
+ uint32_t bytes_dropped:1;
+ /** Set bytes dropped stats to be enabled. */
+ uint32_t pkts_dropped:1;
+ /** Set packets dropped stats to be enabled. */
+ uint32_t active_state:1;
+ /**< Meter hw active state. */
+ uint32_t shared:1;
+ /**< Meter shared or not. */
+ uint32_t is_enable:1;
+ /**< Meter disable/enable state. */
+ uint32_t ingress:1;
+ /**< Rule applies to egress traffic. */
+ uint32_t egress:1;
+ /**
+ * Instead of simply matching the properties of traffic as it would
+ * appear on a given DPDK port ID, enabling this attribute transfers
+ * a flow rule to the lowest possible level of any device endpoints
+ * found in the pattern.
+ *
+ * When supported, this effectively enables an application to
+ * re-route traffic not necessarily intended for it (e.g. coming
+ * from or addressed to different physical ports, VFs or
+ * applications) at the device level.
+ *
+ * It complements the behavior of some pattern items such as
+ * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
+ *
+ * When transferring flow rules, ingress and egress attributes keep
+ * their original meaning, as if processing traffic emitted or
+ * received by the application.
+ */
+ uint32_t transfer:1;
+ struct mlx5_meter_domains_infos *mfts;
+ /**< Flow table created for this meter. */
+ struct mlx5_flow_policer_stats policer_stats;
+ /**< Meter policer statistics. */
+ uint32_t ref_cnt;
+ /**< Use count. */
+ struct mlx5_indexed_pool *flow_ipool;
+ /**< Index pool for flow id. */
+};
+
+/* RFC2697 parameter structure. */
+struct mlx5_flow_meter_srtcm_rfc2697_prm {
+ rte_be32_t cbs_cir;
+ /*
+ * bit 24-28: cbs_exponent, bit 16-23 cbs_mantissa,
+ * bit 8-12: cir_exponent, bit 0-7 cir_mantissa.
+ */
+ rte_be32_t ebs_eir;
+ /*
+ * bit 24-28: ebs_exponent, bit 16-23 ebs_mantissa,
+ * bit 8-12: eir_exponent, bit 0-7 eir_mantissa.
+ */
+};
+
+/* Flow meter profile structure. */
+struct mlx5_flow_meter_profile {
+ TAILQ_ENTRY(mlx5_flow_meter_profile) next;
+ /**< Pointer to the next flow meter structure. */
+ uint32_t id; /**< Profile id. */
+ struct rte_mtr_meter_profile profile; /**< Profile detail. */
+ union {
+ struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;
+ /**< srtcm_rfc2697 struct. */
+ };
+ uint32_t ref_cnt; /**< Use count. */
+};
+
+/* 2 meters in each ASO cache line */
+#define MLX5_MTRS_CONTAINER_RESIZE 64
+/*
+ * The pool index and offset of meter in the pool array makes up the
+ * meter index. In case the meter is from pool 0 and offset 0, it
+ * should plus 1 to avoid index 0, since 0 means invalid meter index
+ * currently.
+ */
+#define MLX5_MAKE_MTR_IDX(pi, offset) \
+ ((pi) * MLX5_ASO_MTRS_PER_POOL + (offset) + 1)
+
+/*aso flow meter state*/
+enum mlx5_aso_mtr_state {
+ ASO_METER_FREE, /* In free list. */
+ ASO_METER_WAIT, /* ACCESS_ASO WQE in progress. */
+ ASO_METER_READY, /* CQE received. */
+};
+
+/* Generic aso_flow_meter information. */
+struct mlx5_aso_mtr {
+ LIST_ENTRY(mlx5_aso_mtr) next;
+ struct mlx5_flow_meter_info fm;
+ /**< Pointer to the next aso flow meter structure. */
+ uint8_t state; /**< ASO flow meter state. */
+ uint8_t offset;
+};
+
+/* Generic aso_flow_meter pool structure. */
+struct mlx5_aso_mtr_pool {
+ struct mlx5_aso_mtr mtrs[MLX5_ASO_MTRS_PER_POOL];
+ /*Must be the first in pool*/
+ struct mlx5_devx_obj *devx_obj;
+ /* The devx object of the minimum aso flow meter ID. */
+ uint32_t index; /* Pool index in management structure. */
+};
+
+LIST_HEAD(aso_meter_list, mlx5_aso_mtr);
+/* Pools management structure for ASO flow meter pools. */
+struct mlx5_aso_mtr_pools_mng {
+ volatile uint16_t n_valid; /* Number of valid pools. */
+ uint16_t n; /* Number of pools. */
+ rte_spinlock_t mtrsl; /* The ASO flow meter free list lock. */
+ struct mlx5_l3t_tbl *mtr_idx_tbl; /* Meter index lookup table. */
+ struct aso_meter_list meters; /* Free ASO flow meter list. */
+ struct mlx5_aso_sq sq; /*SQ using by ASO flow meter. */
+ struct mlx5_aso_mtr_pool **pools; /* ASO flow meter pool array. */
+};
+
/* Table key of the hash organization. */
union mlx5_flow_tbl_key {
struct {
@@ -699,6 +887,7 @@ struct mlx5_dev_ctx_shared {
uint32_t rq_ts_format:2; /* RQ timestamp formats supported. */
uint32_t sq_ts_format:2; /* SQ timestamp formats supported. */
uint32_t qp_ts_format:2; /* QP timestamp formats supported. */
+ uint32_t meter_aso_en:1; /* Flow Meter ASO is supported. */
uint32_t max_port; /* Maximal IB device port index. */
struct mlx5_bond_info bond; /* Bonding information. */
void *ctx; /* Verbs/DV/DevX context. */
@@ -759,6 +948,8 @@ struct mlx5_dev_ctx_shared {
struct mlx5_geneve_tlv_option_resource *geneve_tlv_option_resource;
/* Management structure for geneve tlv option */
rte_spinlock_t geneve_tlv_opt_sl; /* Lock for geneve tlv resource */
+ struct mlx5_aso_mtr_pools_mng *mtrmng;
+ /* Meter pools management structure. */
struct mlx5_dev_shared_port port[]; /* per device port data array. */
};
@@ -776,7 +967,7 @@ struct mlx5_proc_priv {
/* MTR profile list. */
TAILQ_HEAD(mlx5_mtr_profiles, mlx5_flow_meter_profile);
/* MTR list. */
-TAILQ_HEAD(mlx5_flow_meters, mlx5_flow_meter);
+TAILQ_HEAD(mlx5_legacy_flow_meters, mlx5_legacy_flow_meter);
/* RSS description. */
struct mlx5_flow_rss_desc {
@@ -994,7 +1185,7 @@ struct mlx5_priv {
uint8_t mtr_sfx_reg; /* Meter prefix-suffix flow match REG_C. */
uint8_t mtr_color_reg; /* Meter color match REG_C. */
struct mlx5_mtr_profiles flow_meter_profiles; /* MTR profile list. */
- struct mlx5_flow_meters flow_meters; /* MTR list. */
+ struct mlx5_legacy_flow_meters flow_meters; /* MTR list. */
uint8_t skip_default_rss_reta; /* Skip configuration of default reta. */
uint8_t fdb_def_rule; /* Whether fdb jump to table 1 is configured. */
struct mlx5_mp_id mp_id; /* ID of a multi-process process */
@@ -1273,13 +1464,15 @@ int mlx5_pmd_socket_init(void);
/* mlx5_flow_meter.c */
int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg);
-struct mlx5_flow_meter *mlx5_flow_meter_find(struct mlx5_priv *priv,
- uint32_t meter_id);
+struct mlx5_flow_meter_info *mlx5_flow_meter_find(struct mlx5_priv *priv,
+ uint32_t meter_id, uint32_t *mtr_idx);
+struct mlx5_flow_meter_info *
+flow_dv_meter_find_by_idx(struct mlx5_priv *priv, uint32_t idx);
int mlx5_flow_meter_attach(struct mlx5_priv *priv,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr,
struct rte_flow_error *error);
-void mlx5_flow_meter_detach(struct mlx5_flow_meter *fm);
+void mlx5_flow_meter_detach(struct mlx5_flow_meter_info *fm);
/* mlx5_os.c */
struct rte_pci_driver;
@@ -1324,7 +1517,7 @@ void mlx5_txpp_interrupt_handler(void *cb_arg);
eth_tx_burst_t mlx5_select_tx_function(struct rte_eth_dev *dev);
-/* mlx5_flow_age.c */
+/* mlx5_flow_aso.c */
int mlx5_aso_queue_init(struct mlx5_dev_ctx_shared *sh);
int mlx5_aso_queue_start(struct mlx5_dev_ctx_shared *sh);
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 9f4b926cc3..ac39ac13ab 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4359,6 +4359,8 @@ flow_create_split_inner(struct rte_eth_dev *dev,
*
* @param[in] dev
* Pointer to Ethernet device.
+ * @param[in] flow
+ * Parent flow structure pointer.
* @param[in] fm
* Pointer to flow meter structure.
* @param[in] items
@@ -4371,10 +4373,6 @@ flow_create_split_inner(struct rte_eth_dev *dev,
* Suffix flow actions.
* @param[out] actions_pre
* Prefix flow actions.
- * @param[out] pattern_sfx
- * The pattern items for the suffix flow.
- * @param[out] tag_sfx
- * Pointer to suffix flow tag.
* @param[out] error
* Perform verbose error reporting if not NULL.
*
@@ -4383,7 +4381,8 @@ flow_create_split_inner(struct rte_eth_dev *dev,
*/
static uint32_t
flow_meter_split_prep(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct rte_flow *flow,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_item items[],
struct rte_flow_item sfx_items[],
const struct rte_flow_action actions[],
@@ -4504,7 +4503,7 @@ flow_meter_split_prep(struct rte_eth_dev *dev,
0, error),
.offset = mtr_id_offset,
.length = mtr_reg_bits,
- .data = fm->idx,
+ .data = flow->meter,
};
/*
* The color Reg bits used by flow_id are growing from
@@ -5232,9 +5231,10 @@ flow_create_split_meter(struct rte_eth_dev *dev,
struct rte_flow_item *sfx_items = NULL;
struct mlx5_flow *dev_flow = NULL;
struct rte_flow_attr sfx_attr = *attr;
- struct mlx5_flow_meter *fm = NULL;
+ struct mlx5_flow_meter_info *fm = NULL;
bool has_mtr = false;
uint32_t meter_id;
+ uint32_t mtr_idx = 0;
uint32_t mtr_tag_id = 0;
size_t act_size;
size_t item_size;
@@ -5246,14 +5246,13 @@ flow_create_split_meter(struct rte_eth_dev *dev,
&meter_id);
if (has_mtr) {
if (flow->meter) {
- fm = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MTR],
- flow->meter);
+ fm = flow_dv_meter_find_by_idx(priv, flow->meter);
if (!fm)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, "Meter not found.");
} else {
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, &mtr_idx);
if (!fm)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -5262,7 +5261,7 @@ flow_create_split_meter(struct rte_eth_dev *dev,
&sfx_attr, error);
if (ret)
return -rte_errno;
- flow->meter = fm->idx;
+ flow->meter = mtr_idx;
}
wks->fm = fm;
/* The prefix actions: meter, decap, encap, tag, end. */
@@ -5282,9 +5281,10 @@ flow_create_split_meter(struct rte_eth_dev *dev,
sfx_items = (struct rte_flow_item *)((char *)sfx_actions +
act_size);
pre_actions = sfx_actions + actions_n;
- mtr_tag_id = flow_meter_split_prep(dev, fm, items, sfx_items,
- actions, sfx_actions,
- pre_actions, error);
+ mtr_tag_id = flow_meter_split_prep(dev, flow, fm, items,
+ sfx_items, actions,
+ sfx_actions, pre_actions,
+ error);
if (!mtr_tag_id) {
ret = -rte_errno;
goto exit;
@@ -6621,7 +6621,7 @@ mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev,
*/
int
mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr)
{
const struct mlx5_flow_driver_ops *fops;
@@ -6643,7 +6643,7 @@ mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev,
*/
int
mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr)
{
const struct mlx5_flow_driver_ops *fops;
@@ -6652,6 +6652,44 @@ mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,
return fops->destroy_policer_rules(dev, fm, attr);
}
+/**
+ * Allocate the needed aso flow meter id.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ *
+ * @return
+ * Index to aso flow meter on success, NULL otherwise.
+ */
+uint32_t
+mlx5_flow_mtr_alloc(struct rte_eth_dev *dev)
+{
+ const struct mlx5_flow_driver_ops *fops;
+
+ fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV);
+ return fops->create_meter(dev);
+}
+
+/**
+ * Free the aso flow meter id.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_idx
+ * Index to aso flow meter to be free.
+ *
+ * @return
+ * 0 on success.
+ */
+void
+mlx5_flow_mtr_free(struct rte_eth_dev *dev, uint32_t mtr_idx)
+{
+ const struct mlx5_flow_driver_ops *fops;
+
+ fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV);
+ fops->free_meter(dev, mtr_idx);
+}
+
/**
* Allocate a counter.
*
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 11482f178f..b0a743477c 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -827,148 +827,17 @@ struct mlx5_flow {
#define MLX5_FLOW_METER_DISABLE 0
#define MLX5_FLOW_METER_ENABLE 1
-#define MLX5_MAN_WIDTH 8
-/* Modify this value if enum rte_mtr_color changes. */
-#define RTE_MTR_DROPPED RTE_COLORS
-
-/* Meter policer statistics */
-struct mlx5_flow_policer_stats {
- uint32_t pass_cnt;
- /**< Color counter for pass. */
- uint32_t drop_cnt;
- /**< Color counter for drop. */
-};
-
-/* Meter table structure. */
-struct mlx5_meter_domain_info {
- struct mlx5_flow_tbl_resource *tbl;
- /**< Meter table. */
- struct mlx5_flow_tbl_resource *sfx_tbl;
- /**< Meter suffix table. */
- struct mlx5_flow_dv_matcher *drop_matcher;
- /**< Matcher for Drop. */
- struct mlx5_flow_dv_matcher *color_matcher;
- /**< Matcher for Color. */
- void *jump_actn;
- /**< Meter match action. */
- void *green_rule;
- /**< Meter green rule. */
- void *drop_rule;
- /**< Meter drop rule. */
-};
-
-/* Meter table set for TX RX FDB. */
-struct mlx5_meter_domains_infos {
- uint32_t ref_cnt;
- /**< Table user count. */
- struct mlx5_meter_domain_info egress;
- /**< TX meter table. */
- struct mlx5_meter_domain_info ingress;
- /**< RX meter table. */
- struct mlx5_meter_domain_info transfer;
- /**< FDB meter table. */
- void *green_count;
- /**< Counters for green rule. */
- void *drop_count;
- /**< Counters for green rule. */
- uint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];
- /**< Flow meter parameter. */
- size_t fmp_size;
- /**< Flow meter parameter size. */
- void *meter_action;
- /**< Flow meter action. */
-};
+#define MLX5_ASO_CQE_RESPONSE_DELAY 10
+#define MLX5_MTR_POLL_CQE_TIMES 100000u
-/* Meter parameter structure. */
-struct mlx5_flow_meter {
- TAILQ_ENTRY(mlx5_flow_meter) next;
+#define MLX5_MAN_WIDTH 8
+/* Legacy Meter parameter structure. */
+struct mlx5_legacy_flow_meter {
+ struct mlx5_flow_meter_info fm;
+ /* Must be the first in struct. */
+ TAILQ_ENTRY(mlx5_legacy_flow_meter) next;
/**< Pointer to the next flow meter structure. */
uint32_t idx; /* Index to meter object. */
- uint32_t meter_id;
- /**< Meter id. */
- struct mlx5_flow_meter_profile *profile;
- /**< Meter profile parameters. */
-
- rte_spinlock_t sl; /**< Meter action spinlock. */
-
- /** Policer actions (per meter output color). */
- enum rte_mtr_policer_action action[RTE_COLORS];
-
- uint32_t green_bytes:1;
- /** Set green bytes stats to be enabled. */
- uint32_t green_pkts:1;
- /** Set green packets stats to be enabled. */
- uint32_t red_bytes:1;
- /** Set red bytes stats to be enabled. */
- uint32_t red_pkts:1;
- /** Set red packets stats to be enabled. */
- uint32_t bytes_dropped:1;
- /** Set bytes dropped stats to be enabled. */
- uint32_t pkts_dropped:1;
- /** Set packets dropped stats to be enabled. */
-
- /**< Rule applies to ingress traffic. */
- uint32_t ingress:1;
-
- /**< Rule applies to egress traffic. */
- uint32_t egress:1;
- /**
- * Instead of simply matching the properties of traffic as it would
- * appear on a given DPDK port ID, enabling this attribute transfers
- * a flow rule to the lowest possible level of any device endpoints
- * found in the pattern.
- *
- * When supported, this effectively enables an application to
- * re-route traffic not necessarily intended for it (e.g. coming
- * from or addressed to different physical ports, VFs or
- * applications) at the device level.
- *
- * It complements the behavior of some pattern items such as
- * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
- *
- * When transferring flow rules, ingress and egress attributes keep
- * their original meaning, as if processing traffic emitted or
- * received by the application.
- */
- uint32_t transfer:1;
- struct mlx5_meter_domains_infos *mfts;
- /**< Flow table created for this meter. */
- struct mlx5_flow_policer_stats policer_stats;
- /**< Meter policer statistics. */
- uint32_t ref_cnt;
- /**< Use count. */
- uint32_t active_state:1;
- /**< Meter state. */
- uint32_t shared:1;
- /**< Meter shared or not. */
- struct mlx5_indexed_pool *flow_ipool;
- /**< Index pool for flow id. */
-};
-
-/* RFC2697 parameter structure. */
-struct mlx5_flow_meter_srtcm_rfc2697_prm {
- /* green_saturation_value = cbs_mantissa * 2^cbs_exponent */
- uint32_t cbs_exponent:5;
- uint32_t cbs_mantissa:8;
- /* cir = 8G * cir_mantissa * 1/(2^cir_exponent) Bytes/Sec */
- uint32_t cir_exponent:5;
- uint32_t cir_mantissa:8;
- /* yellow _saturation_value = ebs_mantissa * 2^ebs_exponent */
- uint32_t ebs_exponent:5;
- uint32_t ebs_mantissa:8;
-};
-
-/* Flow meter profile structure. */
-struct mlx5_flow_meter_profile {
- TAILQ_ENTRY(mlx5_flow_meter_profile) next;
- /**< Pointer to the next flow meter structure. */
- uint32_t meter_profile_id; /**< Profile id. */
- struct rte_mtr_meter_profile profile; /**< Profile detail. */
- union {
- struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;
- /**< srtcm_rfc2697 struct. */
- };
- uint32_t ref_cnt; /**< Use count. */
};
#define MLX5_MAX_TUNNELS 256
@@ -1094,7 +963,7 @@ struct rte_flow {
/**< Device flow handles that are part of the flow. */
uint32_t drv_type:2; /**< Driver type. */
uint32_t tunnel:1;
- uint32_t meter:16; /**< Holds flow meter id. */
+ uint32_t meter:24; /**< Holds flow meter id. */
uint32_t rix_mreg_copy;
/**< Index to metadata register copy table resource. */
uint32_t counter; /**< Holds flow counter. */
@@ -1181,7 +1050,7 @@ struct mlx5_flow_workspace {
struct mlx5_flow_rss_desc rss_desc;
uint32_t rssq_num; /* Allocated queue num in rss_desc. */
uint32_t flow_idx; /* Intermediate device flow index. */
- struct mlx5_flow_meter *fm; /* Pointer to the meter in flow. */
+ struct mlx5_flow_meter_info *fm; /* Pointer to the meter in flow. */
};
struct mlx5_flow_split_info {
@@ -1227,12 +1096,16 @@ typedef int (*mlx5_flow_destroy_mtr_tbls_t)(struct rte_eth_dev *dev,
struct mlx5_meter_domains_infos *tbls);
typedef int (*mlx5_flow_create_policer_rules_t)
(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr);
typedef int (*mlx5_flow_destroy_policer_rules_t)
(struct rte_eth_dev *dev,
- const struct mlx5_flow_meter *fm,
+ const struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr);
+typedef uint32_t (*mlx5_flow_mtr_alloc_t)
+ (struct rte_eth_dev *dev);
+typedef void (*mlx5_flow_mtr_free_t)(struct rte_eth_dev *dev,
+ uint32_t mtr_idx);
typedef uint32_t (*mlx5_flow_counter_alloc_t)
(struct rte_eth_dev *dev);
typedef void (*mlx5_flow_counter_free_t)(struct rte_eth_dev *dev,
@@ -1287,6 +1160,8 @@ struct mlx5_flow_driver_ops {
mlx5_flow_destroy_mtr_tbls_t destroy_mtr_tbls;
mlx5_flow_create_policer_rules_t prepare_policer_rules;
mlx5_flow_destroy_policer_rules_t destroy_policer_rules;
+ mlx5_flow_mtr_alloc_t create_meter;
+ mlx5_flow_mtr_free_t free_meter;
mlx5_flow_counter_alloc_t counter_alloc;
mlx5_flow_counter_free_t counter_free;
mlx5_flow_counter_query_t counter_query;
@@ -1346,6 +1221,32 @@ tunnel_use_standard_attr_group_translate
return verdict;
}
+/**
+ * Get DV flow aso meter by index.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ * @param[in] idx
+ * mlx5 flow aso meter index in the container.
+ * @param[out] ppool
+ * mlx5 flow aso meter pool in the container,
+ *
+ * @return
+ * Pointer to the aso meter, NULL otherwise.
+ */
+static inline struct mlx5_aso_mtr *
+mlx5_aso_meter_by_idx(struct mlx5_priv *priv, uint32_t idx)
+{
+ struct mlx5_aso_mtr_pool *pool;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+
+ /* Decrease to original index. */
+ idx--;
+ MLX5_ASSERT(idx / MLX5_ASO_MTRS_PER_POOL < mtrmng->n);
+ pool = mtrmng->pools[idx / MLX5_ASO_MTRS_PER_POOL];
+ return &pool->mtrs[idx % MLX5_ASO_MTRS_PER_POOL];
+}
+
int mlx5_flow_group_to_table(struct rte_eth_dev *dev,
const struct mlx5_flow_tunnel *tunnel,
uint32_t group, uint32_t *table,
@@ -1489,10 +1390,10 @@ struct mlx5_meter_domains_infos *mlx5_flow_create_mtr_tbls
int mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev,
struct mlx5_meter_domains_infos *tbl);
int mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr);
int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr);
int mlx5_flow_meter_flush(struct rte_eth_dev *dev,
struct rte_mtr_error *error);
@@ -1588,12 +1489,11 @@ struct mlx5_aso_age_action *flow_aso_age_get_by_idx(struct rte_eth_dev *dev,
int flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev,
const struct rte_flow_item *item,
struct rte_flow_error *error);
-
void flow_release_workspace(void *data);
int mlx5_flow_os_init_workspace_once(void);
void *mlx5_flow_os_get_specific_workspace(void);
int mlx5_flow_os_set_specific_workspace(struct mlx5_flow_workspace *data);
void mlx5_flow_os_release_workspace(void);
-
-
+uint32_t mlx5_flow_mtr_alloc(struct rte_eth_dev *dev);
+void mlx5_flow_mtr_free(struct rte_eth_dev *dev, uint32_t mtr_idx);
#endif /* RTE_PMD_MLX5_FLOW_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index b0bb2eb053..fda87bf845 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -4865,7 +4865,7 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,
{
struct mlx5_priv *priv = dev->data->dev_private;
const struct rte_flow_action_meter *am = action->conf;
- struct mlx5_flow_meter *fm;
+ struct mlx5_flow_meter_info *fm;
if (!am)
return rte_flow_error_set(error, EINVAL,
@@ -4885,7 +4885,7 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"meter action not supported");
- fm = mlx5_flow_meter_find(priv, am->mtr_id);
+ fm = mlx5_flow_meter_find(priv, am->mtr_id, NULL);
if (!fm)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -5938,6 +5938,161 @@ flow_dv_counter_free(struct rte_eth_dev *dev, uint32_t counter)
}
}
+/**
+ * Resize a meter id container.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ *
+ * @return
+ * 0 on success, otherwise negative errno value and rte_errno is set.
+ */
+static int
+flow_dv_mtr_container_resize(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ void *old_pools = mtrmng->pools;
+ uint32_t resize = mtrmng->n + MLX5_MTRS_CONTAINER_RESIZE;
+ uint32_t mem_size = sizeof(struct mlx5_aso_mtr_pool *) * resize;
+ void *pools = mlx5_malloc(MLX5_MEM_ZERO, mem_size, 0, SOCKET_ID_ANY);
+
+ if (!pools) {
+ rte_errno = ENOMEM;
+ return -ENOMEM;
+ }
+ if (old_pools)
+ memcpy(pools, old_pools, mtrmng->n *
+ sizeof(struct mlx5_aso_mtr_pool *));
+ mtrmng->n = resize;
+ mtrmng->pools = pools;
+ if (old_pools)
+ mlx5_free(old_pools);
+ return 0;
+}
+
+/**
+ * Prepare a new meter and/or a new meter pool.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ * @param[out] mtr_free
+ * Where to put the pointer of a new meter.g.
+ *
+ * @return
+ * The meter pool pointer and @mtr_free is set on success,
+ * NULL otherwise and rte_errno is set.
+ */
+static struct mlx5_aso_mtr_pool *
+flow_dv_mtr_pool_create(struct rte_eth_dev *dev,
+ struct mlx5_aso_mtr **mtr_free)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ struct mlx5_aso_mtr_pool *pool = NULL;
+ struct mlx5_devx_obj *dcs = NULL;
+ uint32_t i;
+ uint32_t log_obj_size;
+
+ log_obj_size = rte_log2_u32(MLX5_ASO_MTRS_PER_POOL >> 1);
+ dcs = mlx5_devx_cmd_create_flow_meter_aso_obj(priv->sh->ctx,
+ priv->sh->pdn, log_obj_size);
+ if (!dcs) {
+ rte_errno = ENODATA;
+ return NULL;
+ }
+ pool = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*pool), 0, SOCKET_ID_ANY);
+ if (!pool) {
+ rte_errno = ENOMEM;
+ claim_zero(mlx5_devx_cmd_destroy(dcs));
+ return NULL;
+ }
+ pool->devx_obj = dcs;
+ pool->index = mtrmng->n_valid;
+ if (pool->index == mtrmng->n && flow_dv_mtr_container_resize(dev)) {
+ mlx5_free(pool);
+ claim_zero(mlx5_devx_cmd_destroy(dcs));
+ return NULL;
+ }
+ mtrmng->pools[pool->index] = pool;
+ mtrmng->n_valid++;
+ for (i = 1; i < MLX5_ASO_MTRS_PER_POOL; ++i) {
+ pool->mtrs[i].offset = i;
+ pool->mtrs[i].fm.meter_id = UINT32_MAX;
+ LIST_INSERT_HEAD(&mtrmng->meters,
+ &pool->mtrs[i], next);
+ }
+ pool->mtrs[0].offset = 0;
+ pool->mtrs[0].fm.meter_id = UINT32_MAX;
+ *mtr_free = &pool->mtrs[0];
+ return pool;
+}
+
+/**
+ * Release a flow meter into pool.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ * @param[in] mtr_idx
+ * Index to aso flow meter.
+ */
+static void
+flow_dv_aso_mtr_release_to_pool(struct rte_eth_dev *dev, uint32_t mtr_idx)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ struct mlx5_aso_mtr *aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx);
+
+ MLX5_ASSERT(aso_mtr);
+ rte_spinlock_lock(&mtrmng->mtrsl);
+ memset(&aso_mtr->fm, 0, sizeof(struct mlx5_flow_meter_info));
+ aso_mtr->state = ASO_METER_FREE;
+ aso_mtr->fm.meter_id = UINT32_MAX;
+ LIST_INSERT_HEAD(&mtrmng->meters, aso_mtr, next);
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+}
+
+/**
+ * Allocate a aso flow meter.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ *
+ * @return
+ * Index to aso flow meter on success, 0 otherwise and rte_errno is set.
+ */
+static uint32_t
+flow_dv_mtr_alloc(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_aso_mtr *mtr_free = NULL;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ struct mlx5_aso_mtr_pool *pool;
+ uint32_t mtr_idx = 0;
+
+ if (!priv->config.devx) {
+ rte_errno = ENOTSUP;
+ return 0;
+ }
+ /* Allocate the flow meter memory. */
+ /* Get free meters from management. */
+ rte_spinlock_lock(&mtrmng->mtrsl);
+ mtr_free = LIST_FIRST(&mtrmng->meters);
+ if (mtr_free)
+ LIST_REMOVE(mtr_free, next);
+ if (!mtr_free && !flow_dv_mtr_pool_create(dev, &mtr_free)) {
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+ return 0;
+ }
+ mtr_free->state = ASO_METER_WAIT;
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+ pool = container_of(mtr_free,
+ struct mlx5_aso_mtr_pool,
+ mtrs[mtr_free->offset]);
+ mtr_idx = MLX5_MAKE_MTR_IDX(pool->index, mtr_free->offset);
+ return mtr_idx;
+}
+
/**
* Verify the @p attributes will be correctly understood by the NIC and store
* them in the @p flow if everything is correct.
@@ -12568,7 +12723,7 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
{
struct mlx5_flow_handle *dev_handle;
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meter *fm = NULL;
+ struct mlx5_flow_meter_info *fm = NULL;
uint32_t srss = 0;
if (!flow)
@@ -12579,8 +12734,7 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
flow->counter = 0;
}
if (flow->meter) {
- fm = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MTR],
- flow->meter);
+ fm = flow_dv_meter_find_by_idx(priv, flow->meter);
if (fm)
mlx5_flow_meter_detach(fm);
flow->meter = 0;
@@ -13678,7 +13832,7 @@ flow_dv_destroy_domain_policer_rule(struct rte_eth_dev *dev,
*/
static int
flow_dv_destroy_policer_rules(struct rte_eth_dev *dev,
- const struct mlx5_flow_meter *fm,
+ const struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr)
{
struct mlx5_meter_domains_infos *mtb = fm ? fm->mfts : NULL;
@@ -13701,6 +13855,8 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev,
* Pointer to Ethernet device.
* @param[in] fm
* Pointer to flow meter structure.
+ * @param[in] mtr_idx
+ * meter index.
* @param[in] mtb
* Pointer to DV meter table set.
* @param[out] drop_rule
@@ -13713,7 +13869,8 @@ flow_dv_destroy_policer_rules(struct rte_eth_dev *dev,
*/
static int
flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
+ uint32_t mtr_idx,
struct mlx5_meter_domain_info *dtb,
void **drop_rule,
void **green_rule)
@@ -13761,7 +13918,7 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,
/* Create Drop flow, matching meter_id only. */
i = 0;
flow_dv_match_meta_reg(matcher.buf, value.buf, mtr_id_reg_c,
- (fm->idx << mtr_id_offset), UINT32_MAX);
+ (mtr_idx << mtr_id_offset), UINT32_MAX);
if (mtb->drop_count)
actions[i++] = mtb->drop_count;
actions[i++] = priv->sh->dr_drop_action;
@@ -13775,7 +13932,7 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,
i = 0;
if (priv->mtr_reg_share) {
flow_dv_match_meta_reg(matcher.buf, value.buf, color_reg_c,
- ((fm->idx << mtr_id_offset) |
+ ((mtr_idx << mtr_id_offset) |
rte_col_2_mlx5_col(RTE_COLOR_GREEN)),
UINT32_MAX);
} else {
@@ -13783,7 +13940,7 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,
rte_col_2_mlx5_col(RTE_COLOR_GREEN),
UINT32_MAX);
flow_dv_match_meta_reg(matcher.buf, value.buf, mtr_id_reg_c,
- fm->idx, UINT32_MAX);
+ mtr_idx, UINT32_MAX);
}
if (mtb->green_count)
actions[i++] = mtb->green_count;
@@ -13816,9 +13973,10 @@ flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev,
*/
static int
flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_meter_domains_infos *mtb = fm->mfts;
bool initialized = false;
struct mlx5_flow_counter *cnt;
@@ -13828,6 +13986,7 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,
void *ingress_green_rule = NULL;
void *transfer_drop_rule = NULL;
void *transfer_green_rule = NULL;
+ uint32_t mtr_idx;
int ret;
/* Get the statistics counters for green/drop. */
@@ -13854,9 +14013,23 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,
*/
if (mtb->egress.drop_rule)
initialized = true;
+ if (priv->sh->meter_aso_en) {
+ struct mlx5_aso_mtr *aso_mtr = NULL;
+ struct mlx5_aso_mtr_pool *pool;
+
+ aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm);
+ pool = container_of(aso_mtr, struct mlx5_aso_mtr_pool,
+ mtrs[aso_mtr->offset]);
+ mtr_idx = MLX5_MAKE_MTR_IDX(pool->index, aso_mtr->offset);
+ } else {
+ struct mlx5_legacy_flow_meter *legacy_fm;
+
+ legacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm);
+ mtr_idx = legacy_fm->idx;
+ }
if (attr->egress) {
ret = flow_dv_create_policer_forward_rule(dev,
- fm, &mtb->egress,
+ fm, mtr_idx, &mtb->egress,
&egress_drop_rule, &egress_green_rule);
if (ret) {
DRV_LOG(ERR, "Failed to create egress policer.");
@@ -13865,7 +14038,7 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,
}
if (attr->ingress) {
ret = flow_dv_create_policer_forward_rule(dev,
- fm, &mtb->ingress,
+ fm, mtr_idx, &mtb->ingress,
&ingress_drop_rule, &ingress_green_rule);
if (ret) {
DRV_LOG(ERR, "Failed to create ingress policer.");
@@ -13874,7 +14047,7 @@ flow_dv_prepare_policer_rules(struct rte_eth_dev *dev,
}
if (attr->transfer) {
ret = flow_dv_create_policer_forward_rule(dev,
- fm, &mtb->transfer,
+ fm, mtr_idx, &mtb->transfer,
&transfer_drop_rule, &transfer_green_rule);
if (ret) {
DRV_LOG(ERR, "Failed to create transfer policer.");
@@ -14214,6 +14387,8 @@ const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
.destroy_mtr_tbls = flow_dv_destroy_mtr_tbl,
.prepare_policer_rules = flow_dv_prepare_policer_rules,
.destroy_policer_rules = flow_dv_destroy_policer_rules,
+ .create_meter = flow_dv_mtr_alloc,
+ .free_meter = flow_dv_aso_mtr_release_to_pool,
.counter_alloc = flow_dv_counter_allocate,
.counter_free = flow_dv_counter_free,
.counter_query = flow_dv_counter_query,
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 2a37decaaf..956a6c33e7 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -28,40 +28,43 @@
*/
static void *
mlx5_flow_meter_action_create(struct mlx5_priv *priv,
- struct mlx5_flow_meter *fm)
+ struct mlx5_flow_meter_info *fm)
{
#ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
struct mlx5dv_dr_flow_meter_attr mtr_init;
- void *attr = fm->mfts->fmp;
+ uint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];
struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm =
&fm->profile->srtcm_prm;
+ uint32_t cbs_cir = rte_be_to_cpu_32(srtcm->cbs_cir);
+ uint32_t ebs_eir = rte_be_to_cpu_32(srtcm->ebs_eir);
+ uint32_t val;
- fm->mfts->fmp_size = MLX5_ST_SZ_BYTES(flow_meter_parameters);
- memset(attr, 0, fm->mfts->fmp_size);
- MLX5_SET(flow_meter_parameters, attr, valid, 1);
- MLX5_SET(flow_meter_parameters, attr, bucket_overflow, 1);
- MLX5_SET(flow_meter_parameters, attr,
- start_color, MLX5_FLOW_COLOR_GREEN);
- MLX5_SET(flow_meter_parameters, attr, both_buckets_on_green, 0);
- MLX5_SET(flow_meter_parameters,
- attr, cbs_exponent, srtcm->cbs_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, cbs_mantissa, srtcm->cbs_mantissa);
- MLX5_SET(flow_meter_parameters,
- attr, cir_exponent, srtcm->cir_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, cir_mantissa, srtcm->cir_mantissa);
- MLX5_SET(flow_meter_parameters,
- attr, ebs_exponent, srtcm->ebs_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, ebs_mantissa, srtcm->ebs_mantissa);
+ memset(fmp, 0, MLX5_ST_SZ_BYTES(flow_meter_parameters));
+ MLX5_SET(flow_meter_parameters, fmp, valid, 1);
+ MLX5_SET(flow_meter_parameters, fmp, bucket_overflow, 1);
+ MLX5_SET(flow_meter_parameters, fmp,
+ start_color, MLX5_FLOW_COLOR_GREEN);
+ MLX5_SET(flow_meter_parameters, fmp, both_buckets_on_green, 0);
+ val = (cbs_cir >> ASO_DSEG_CBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
+ MLX5_SET(flow_meter_parameters, fmp, cbs_exponent, val);
+ val = (cbs_cir >> ASO_DSEG_CBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;
+ MLX5_SET(flow_meter_parameters, fmp, cbs_mantissa, val);
+ val = (cbs_cir >> ASO_DSEG_CIR_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
+ MLX5_SET(flow_meter_parameters, fmp, cir_exponent, val);
+ val = (cbs_cir & ASO_DSEG_MAN_MASK);
+ MLX5_SET(flow_meter_parameters, fmp, cir_mantissa, val);
+ val = (ebs_eir >> ASO_DSEG_EBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
+ MLX5_SET(flow_meter_parameters, fmp, ebs_exponent, val);
+ val = (ebs_eir >> ASO_DSEG_EBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;
+ MLX5_SET(flow_meter_parameters, fmp, ebs_mantissa, val);
mtr_init.next_table =
fm->transfer ? fm->mfts->transfer.tbl->obj :
- fm->egress ? fm->mfts->egress.tbl->obj :
- fm->mfts->ingress.tbl->obj;
+ fm->egress ? fm->mfts->egress.tbl->obj :
+ fm->mfts->ingress.tbl->obj;
mtr_init.reg_c_index = priv->mtr_color_reg - REG_C_0;
- mtr_init.flow_meter_parameter = fm->mfts->fmp;
- mtr_init.flow_meter_parameter_sz = fm->mfts->fmp_size;
+ mtr_init.flow_meter_parameter = fmp;
+ mtr_init.flow_meter_parameter_sz =
+ MLX5_ST_SZ_BYTES(flow_meter_parameters);
mtr_init.active = fm->active_state;
return mlx5_glue->dv_create_flow_action_meter(&mtr_init);
#else
@@ -89,7 +92,7 @@ mlx5_flow_meter_profile_find(struct mlx5_priv *priv, uint32_t meter_profile_id)
struct mlx5_flow_meter_profile *fmp;
TAILQ_FOREACH(fmp, fmps, next)
- if (meter_profile_id == fmp->meter_profile_id)
+ if (meter_profile_id == fmp->id)
return fmp;
return NULL;
}
@@ -239,44 +242,51 @@ mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
{
struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm = &fmp->srtcm_prm;
uint8_t man, exp;
+ uint32_t cbs_exp, cbs_man, cir_exp, cir_man;
+ uint32_t ebs_exp, ebs_man;
if (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_PROFILE,
NULL, "Metering algorithm not supported.");
+ /* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */
+ mlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,
+ &man, &exp);
+ /* Check if cir mantissa is too large. */
+ if (exp > ASO_DSEG_CIR_EXP_MASK)
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
+ "meter profile parameter cir is"
+ " not supported.");
+ cir_man = man;
+ cir_exp = exp;
/* cbs = cbs_mantissa * 2^cbs_exponent */
mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.cbs,
&man, &exp);
- srtcm->cbs_mantissa = man;
- srtcm->cbs_exponent = exp;
/* Check if cbs mantissa is too large. */
- if (srtcm->cbs_exponent != exp)
- return -rte_mtr_error_set(error, EINVAL,
+ if (exp > ASO_DSEG_EXP_MASK)
+ return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
- "Metering profile parameter cbs is"
- " invalid.");
- /* ebs = ebs_mantissa * 2^ebs_exponent */
+ "meter profile parameter cbs is"
+ " not supported.");
+ cbs_man = man;
+ cbs_exp = exp;
+ srtcm->cbs_cir = rte_cpu_to_be_32(cbs_exp << ASO_DSEG_CBS_EXP_OFFSET |
+ cbs_man << ASO_DSEG_CBS_MAN_OFFSET |
+ cir_exp << ASO_DSEG_CIR_EXP_OFFSET |
+ cir_man);
mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.ebs,
&man, &exp);
- srtcm->ebs_mantissa = man;
- srtcm->ebs_exponent = exp;
/* Check if ebs mantissa is too large. */
- if (srtcm->ebs_exponent != exp)
- return -rte_mtr_error_set(error, EINVAL,
- RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
- "Metering profile parameter ebs is"
- " invalid.");
- /* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */
- mlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,
- &man, &exp);
- srtcm->cir_mantissa = man;
- srtcm->cir_exponent = exp;
- /* Check if cir mantissa is too large. */
- if (srtcm->cir_exponent != exp)
- return -rte_mtr_error_set(error, EINVAL,
+ if (exp > ASO_DSEG_EXP_MASK)
+ return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
- "Metering profile parameter cir is"
- " invalid.");
+ "meter profile parameter ebs is"
+ " not supported.");
+ ebs_man = man;
+ ebs_exp = exp;
+ srtcm->ebs_eir = rte_cpu_to_be_32(ebs_exp << ASO_DSEG_EBS_EXP_OFFSET |
+ ebs_man << ASO_DSEG_EBS_MAN_OFFSET);
return 0;
}
@@ -306,7 +316,11 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,
RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
"Meter is not supported");
memset(cap, 0, sizeof(*cap));
- cap->n_max = 1 << qattr->log_max_flow_meter;
+ if (priv->sh->meter_aso_en)
+ /* 2 meters per one ASO cache line. */
+ cap->n_max = 1 << (qattr->log_max_num_meter_aso + 1);
+ else
+ cap->n_max = 1 << qattr->log_max_flow_meter;
cap->n_shared_max = cap->n_max;
cap->identical = 1;
cap->shared_identical = 1;
@@ -365,7 +379,7 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,
NULL, "Meter profile memory "
"alloc failed.");
/* Fill profile info. */
- fmp->meter_profile_id = meter_profile_id;
+ fmp->id = meter_profile_id;
fmp->profile = *profile;
/* Fill the flow meter parameters for the PRM. */
ret = mlx5_flow_meter_param_fill(fmp, error);
@@ -499,7 +513,7 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,
NULL,
"Green color only supports recolor green action.");
/* Validate meter id. */
- if (mlx5_flow_meter_find(priv, meter_id))
+ if (mlx5_flow_meter_find(priv, meter_id, NULL))
return -rte_mtr_error_set(error, EEXIST,
RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
"Meter object already exists.");
@@ -524,7 +538,7 @@ mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,
*/
static int
mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm,
uint64_t modify_bits, uint32_t active_state)
{
@@ -533,33 +547,37 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
uint32_t *attr;
struct mlx5dv_dr_flow_meter_attr mod_attr = { 0 };
int ret;
+ uint32_t cbs_cir, ebs_eir, val;
/* Fill command parameters. */
mod_attr.reg_c_index = priv->mtr_color_reg - REG_C_0;
mod_attr.flow_meter_parameter = in;
- mod_attr.flow_meter_parameter_sz = fm->mfts->fmp_size;
+ mod_attr.flow_meter_parameter_sz =
+ MLX5_ST_SZ_BYTES(flow_meter_parameters);
if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE)
mod_attr.active = !!active_state;
else
mod_attr.active = 0;
attr = in;
+ cbs_cir = rte_be_to_cpu_32(srtcm->cbs_cir);
+ ebs_eir = rte_be_to_cpu_32(srtcm->ebs_eir);
if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS) {
- MLX5_SET(flow_meter_parameters,
- attr, cbs_exponent, srtcm->cbs_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, cbs_mantissa, srtcm->cbs_mantissa);
+ val = (cbs_cir >> ASO_DSEG_CBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
+ MLX5_SET(flow_meter_parameters, attr, cbs_exponent, val);
+ val = (cbs_cir >> ASO_DSEG_CBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;
+ MLX5_SET(flow_meter_parameters, attr, cbs_mantissa, val);
}
if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {
- MLX5_SET(flow_meter_parameters,
- attr, cir_exponent, srtcm->cir_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, cir_mantissa, srtcm->cir_mantissa);
+ val = (cbs_cir >> ASO_DSEG_CIR_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
+ MLX5_SET(flow_meter_parameters, attr, cir_exponent, val);
+ val = cbs_cir & ASO_DSEG_MAN_MASK;
+ MLX5_SET(flow_meter_parameters, attr, cir_mantissa, val);
}
if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS) {
- MLX5_SET(flow_meter_parameters,
- attr, ebs_exponent, srtcm->ebs_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, ebs_mantissa, srtcm->ebs_mantissa);
+ val = (ebs_eir >> ASO_DSEG_EBS_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
+ MLX5_SET(flow_meter_parameters, attr, ebs_exponent, val);
+ val = (ebs_eir >> ASO_DSEG_EBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;
+ MLX5_SET(flow_meter_parameters, attr, ebs_mantissa, val);
}
/* Apply modifications to meter only if it was created. */
if (fm->mfts->meter_action) {
@@ -572,26 +590,6 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
/* Update succeedded modify meter parameters. */
if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE)
fm->active_state = !!active_state;
- attr = fm->mfts->fmp;
- if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS) {
- MLX5_SET(flow_meter_parameters,
- attr, cbs_exponent, srtcm->cbs_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, cbs_mantissa, srtcm->cbs_mantissa);
- }
- if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {
- MLX5_SET(flow_meter_parameters,
- attr, cir_exponent, srtcm->cir_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, cir_mantissa, srtcm->cir_mantissa);
- }
- if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS) {
- MLX5_SET(flow_meter_parameters,
- attr, ebs_exponent, srtcm->ebs_exponent);
- MLX5_SET(flow_meter_parameters,
- attr, ebs_mantissa, srtcm->ebs_mantissa);
- }
-
return 0;
#else
(void)priv;
@@ -604,7 +602,7 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
}
static void
-mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter *fm,
+mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter_info *fm,
uint64_t stats_mask)
{
fm->green_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_GREEN) ? 1 : 0;
@@ -639,9 +637,10 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meters *fms = &priv->flow_meters;
+ struct mlx5_legacy_flow_meters *fms = &priv->flow_meters;
struct mlx5_flow_meter_profile *fmp;
- struct mlx5_flow_meter *fm;
+ struct mlx5_legacy_flow_meter *legacy_fm;
+ struct mlx5_flow_meter_info *fm;
const struct rte_flow_attr attr = {
.ingress = 1,
.egress = 1,
@@ -653,8 +652,9 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
.need_lock = 1,
.type = "mlx5_flow_mtr_flow_id_pool",
};
+ struct mlx5_aso_mtr *aso_mtr;
+ uint32_t mtr_idx;
int ret;
- uint32_t idx = 0;
uint8_t mtr_id_bits;
uint8_t mtr_reg_bits = priv->mtr_reg_share ?
MLX5_MTR_IDLE_BITS_IN_COLOR_REG : MLX5_REG_BITS;
@@ -674,19 +674,31 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
NULL, "Meter profile id not valid.");
/* Allocate the flow meter memory. */
- fm = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_MTR], &idx);
- if (fm == NULL)
- return -rte_mtr_error_set(error, ENOMEM,
- RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
- "Memory alloc failed for meter.");
- mtr_id_bits = MLX5_REG_BITS - __builtin_clz(idx);
+ if (priv->sh->meter_aso_en) {
+ mtr_idx = mlx5_flow_mtr_alloc(dev);
+ if (!mtr_idx)
+ return -rte_mtr_error_set(error, ENOMEM,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Memory alloc failed for meter.");
+ aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx);
+ fm = &aso_mtr->fm;
+ } else {
+ legacy_fm = mlx5_ipool_zmalloc
+ (priv->sh->ipool[MLX5_IPOOL_MTR], &mtr_idx);
+ if (legacy_fm == NULL)
+ return -rte_mtr_error_set(error, ENOMEM,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Memory alloc failed for meter.");
+ legacy_fm->idx = mtr_idx;
+ fm = &legacy_fm->fm;
+ }
+ mtr_id_bits = MLX5_REG_BITS - __builtin_clz(mtr_idx);
if ((mtr_id_bits + priv->max_mtr_flow_bits) > mtr_reg_bits) {
DRV_LOG(ERR, "Meter number exceeds max limit.");
goto error;
}
if (mtr_id_bits > priv->max_mtr_bits)
priv->max_mtr_bits = mtr_id_bits;
- fm->idx = idx;
/* Fill the flow meter parameters. */
fm->meter_id = meter_id;
fm->profile = fmp;
@@ -712,10 +724,11 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
if (ret)
goto error;
/* Add to the flow meter list. */
- TAILQ_INSERT_TAIL(fms, fm, next);
+ if (!priv->sh->meter_aso_en)
+ TAILQ_INSERT_TAIL(fms, legacy_fm, next);
fm->active_state = 1; /* Config meter starts as active. */
fm->shared = !!shared;
- fm->profile->ref_cnt++;
+ __atomic_add_fetch(&fm->profile->ref_cnt, 1, __ATOMIC_RELAXED);
fm->flow_ipool = mlx5_ipool_create(&flow_ipool_cfg);
if (!fm->flow_ipool)
goto error;
@@ -729,12 +742,57 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
mlx5_counter_free(dev, fm->policer_stats.pass_cnt);
if (fm->policer_stats.drop_cnt)
mlx5_counter_free(dev, fm->policer_stats.drop_cnt);
- mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], idx);
+ if (priv->sh->meter_aso_en)
+ mlx5_flow_mtr_free(dev, mtr_idx);
+ else
+ mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], mtr_idx);
return -rte_mtr_error_set(error, -ret,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL, "Failed to create devx meter.");
}
+static int
+mlx5_flow_meter_params_flush(struct rte_eth_dev *dev,
+ struct mlx5_flow_meter_info *fm,
+ const struct rte_flow_attr *attr,
+ uint32_t mtr_idx)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_legacy_flow_meters *fms = &priv->flow_meters;
+ struct mlx5_flow_meter_profile *fmp;
+ struct mlx5_legacy_flow_meter *legacy_fm = NULL;
+
+ /* Meter object must not have any owner. */
+ MLX5_ASSERT(!fm->ref_cnt);
+ /* Get meter profile. */
+ fmp = fm->profile;
+ if (fmp == NULL)
+ return -1;
+ /* Update dependencies. */
+ __atomic_sub_fetch(&fmp->ref_cnt, 1, __ATOMIC_RELAXED);
+ /* Remove from list. */
+ if (!priv->sh->meter_aso_en) {
+ legacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm);
+ TAILQ_REMOVE(fms, legacy_fm, next);
+ }
+ /* Free policer counters. */
+ if (fm->policer_stats.pass_cnt)
+ mlx5_counter_free(dev, fm->policer_stats.pass_cnt);
+ if (fm->policer_stats.drop_cnt)
+ mlx5_counter_free(dev, fm->policer_stats.drop_cnt);
+ /* Free meter flow table. */
+ if (fm->flow_ipool)
+ mlx5_ipool_destroy(fm->flow_ipool);
+ mlx5_flow_destroy_policer_rules(dev, fm, attr);
+ mlx5_flow_destroy_mtr_tbls(dev, fm->mfts);
+ if (priv->sh->meter_aso_en)
+ mlx5_flow_mtr_free(dev, mtr_idx);
+ else
+ mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR],
+ legacy_fm->idx);
+ return 0;
+}
+
/**
* Destroy meter rules.
*
@@ -753,21 +811,21 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meters *fms = &priv->flow_meters;
- struct mlx5_flow_meter_profile *fmp;
- struct mlx5_flow_meter *fm;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ struct mlx5_flow_meter_info *fm;
const struct rte_flow_attr attr = {
.ingress = 1,
.egress = 1,
.transfer = priv->config.dv_esw_en ? 1 : 0,
};
+ uint32_t mtr_idx = 0;
if (!priv->mtr_en)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
"Meter is not supported");
/* Meter object must exist. */
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, &mtr_idx);
if (fm == NULL)
return -rte_mtr_error_set(error, ENOENT,
RTE_MTR_ERROR_TYPE_MTR_ID,
@@ -777,24 +835,17 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
return -rte_mtr_error_set(error, EBUSY,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL, "Meter object is being used.");
- /* Get the meter profile. */
- fmp = fm->profile;
- MLX5_ASSERT(fmp);
- /* Update dependencies. */
- fmp->ref_cnt--;
- /* Remove from the flow meter list. */
- TAILQ_REMOVE(fms, fm, next);
- /* Free policer counters. */
- if (fm->policer_stats.pass_cnt)
- mlx5_counter_free(dev, fm->policer_stats.pass_cnt);
- if (fm->policer_stats.drop_cnt)
- mlx5_counter_free(dev, fm->policer_stats.drop_cnt);
- /* Free meter flow table */
- if (fm->flow_ipool)
- mlx5_ipool_destroy(fm->flow_ipool);
- mlx5_flow_destroy_policer_rules(dev, fm, &attr);
- mlx5_flow_destroy_mtr_tbls(dev, fm->mfts);
- mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], fm->idx);
+ if (priv->sh->meter_aso_en) {
+ if (mlx5_l3t_clear_entry(mtrmng->mtr_idx_tbl, meter_id))
+ return -rte_mtr_error_set(error, EBUSY,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Fail to delete ASO Meter in index table.");
+ }
+ /* Destroy the meter profile. */
+ if (mlx5_flow_meter_params_flush(dev, fm, &attr, mtr_idx))
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "MTR object meter profile invalid.");
return 0;
}
@@ -815,17 +866,13 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id,
*/
static int
mlx5_flow_meter_modify_state(struct mlx5_priv *priv,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
uint32_t new_state,
struct rte_mtr_error *error)
{
static const struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm = {
- .cbs_exponent = 20,
- .cbs_mantissa = 191,
- .cir_exponent = 0,
- .cir_mantissa = 200,
- .ebs_exponent = 0,
- .ebs_mantissa = 0,
+ .cbs_cir = RTE_BE32(MLX5_IFC_FLOW_METER_DISABLE_CBS_CIR_VAL),
+ .ebs_eir = 0,
};
uint64_t modify_bits = MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS |
MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR;
@@ -867,7 +914,7 @@ mlx5_flow_meter_enable(struct rte_eth_dev *dev,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meter *fm;
+ struct mlx5_flow_meter_info *fm;
int ret;
if (!priv->mtr_en)
@@ -875,7 +922,7 @@ mlx5_flow_meter_enable(struct rte_eth_dev *dev,
RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
"Meter is not supported");
/* Meter object must exist. */
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, NULL);
if (fm == NULL)
return -rte_mtr_error_set(error, ENOENT,
RTE_MTR_ERROR_TYPE_MTR_ID,
@@ -908,7 +955,7 @@ mlx5_flow_meter_disable(struct rte_eth_dev *dev,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meter *fm;
+ struct mlx5_flow_meter_info *fm;
int ret;
if (!priv->mtr_en)
@@ -916,7 +963,7 @@ mlx5_flow_meter_disable(struct rte_eth_dev *dev,
RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
"Meter is not supported");
/* Meter object must exist. */
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, NULL);
if (fm == NULL)
return -rte_mtr_error_set(error, ENOENT,
RTE_MTR_ERROR_TYPE_MTR_ID,
@@ -954,7 +1001,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev,
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_meter_profile *fmp;
struct mlx5_flow_meter_profile *old_fmp;
- struct mlx5_flow_meter *fm;
+ struct mlx5_flow_meter_info *fm;
uint64_t modify_bits = MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS |
MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR;
int ret;
@@ -970,7 +1017,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev,
RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
NULL, "Meter profile not found.");
/* Meter object must exist. */
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, NULL);
if (fm == NULL)
return -rte_mtr_error_set(error, ENOENT,
RTE_MTR_ERROR_TYPE_MTR_ID,
@@ -1020,7 +1067,7 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meter *fm;
+ struct mlx5_flow_meter_info *fm;
const struct rte_flow_attr attr = {
.ingress = 1,
.egress = 1,
@@ -1034,7 +1081,7 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev,
RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
"Meter is not supported");
/* Meter object must exist. */
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, NULL);
if (fm == NULL)
return -rte_mtr_error_set(error, ENOENT,
RTE_MTR_ERROR_TYPE_MTR_ID,
@@ -1134,7 +1181,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meter *fm;
+ struct mlx5_flow_meter_info *fm;
struct mlx5_flow_policer_stats *ps;
uint64_t pkts;
uint64_t bytes;
@@ -1145,7 +1192,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev,
RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
"Meter is not supported");
/* Meter object must exist. */
- fm = mlx5_flow_meter_find(priv, meter_id);
+ fm = mlx5_flow_meter_find(priv, meter_id, NULL);
if (fm == NULL)
return -rte_mtr_error_set(error, ENOENT,
RTE_MTR_ERROR_TYPE_MTR_ID,
@@ -1239,18 +1286,68 @@ mlx5_flow_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
* @return
* Pointer to the profile found on success, NULL otherwise.
*/
-struct mlx5_flow_meter *
-mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id)
+struct mlx5_flow_meter_info *
+mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id,
+ uint32_t *mtr_idx)
{
- struct mlx5_flow_meters *fms = &priv->flow_meters;
- struct mlx5_flow_meter *fm;
+ struct mlx5_legacy_flow_meter *legacy_fm;
+ struct mlx5_legacy_flow_meters *fms = &priv->flow_meters;
+ struct mlx5_aso_mtr *aso_mtr;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ union mlx5_l3t_data data;
- TAILQ_FOREACH(fm, fms, next)
- if (meter_id == fm->meter_id)
- return fm;
+ if (priv->sh->meter_aso_en) {
+ rte_spinlock_lock(&mtrmng->mtrsl);
+ if (!mtrmng->n_valid) {
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+ return NULL;
+ }
+ if (mlx5_l3t_get_entry(mtrmng->mtr_idx_tbl, meter_id, &data) ||
+ !data.dword) {
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+ return NULL;
+ }
+ if (mtr_idx)
+ *mtr_idx = data.dword;
+ aso_mtr = mlx5_aso_meter_by_idx(priv, data.dword);
+ mlx5_l3t_clear_entry(mtrmng->mtr_idx_tbl, meter_id);
+ if (meter_id == aso_mtr->fm.meter_id) {
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+ return &aso_mtr->fm;
+ }
+ rte_spinlock_unlock(&mtrmng->mtrsl);
+ } else {
+ TAILQ_FOREACH(legacy_fm, fms, next)
+ if (meter_id == legacy_fm->fm.meter_id)
+ return &legacy_fm->fm;
+ }
return NULL;
}
+/**
+ * Find meter by index.
+ *
+ * @param priv
+ * Pointer to mlx5_priv.
+ * @param idx
+ * Meter index.
+ *
+ * @return
+ * Pointer to the profile found on success, NULL otherwise.
+ */
+struct mlx5_flow_meter_info *
+flow_dv_meter_find_by_idx(struct mlx5_priv *priv, uint32_t idx)
+{
+ struct mlx5_aso_mtr *aso_mtr;
+
+ if (priv->sh->meter_aso_en) {
+ aso_mtr = mlx5_aso_meter_by_idx(priv, idx);
+ return &aso_mtr->fm;
+ } else {
+ return mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MTR], idx);
+ }
+}
+
/**
* Attach meter to flow.
* Unidirectional Meter creation can only be done
@@ -1270,7 +1367,7 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id)
*/
int
mlx5_flow_meter_attach(struct mlx5_priv *priv,
- struct mlx5_flow_meter *fm,
+ struct mlx5_flow_meter_info *fm,
const struct rte_flow_attr *attr,
struct rte_flow_error *error)
{
@@ -1319,7 +1416,7 @@ mlx5_flow_meter_attach(struct mlx5_priv *priv,
* Pointer to flow meter.
*/
void
-mlx5_flow_meter_detach(struct mlx5_flow_meter *fm)
+mlx5_flow_meter_detach(struct mlx5_flow_meter_info *fm)
{
#ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
rte_spinlock_lock(&fm->sl);
@@ -1352,39 +1449,46 @@ int
mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_flow_meters *fms = &priv->flow_meters;
+ struct mlx5_aso_mtr_pools_mng *mtrmng = priv->sh->mtrmng;
+ struct mlx5_legacy_flow_meters *fms = &priv->flow_meters;
struct mlx5_mtr_profiles *fmps = &priv->flow_meter_profiles;
struct mlx5_flow_meter_profile *fmp;
- struct mlx5_flow_meter *fm;
+ struct mlx5_legacy_flow_meter *legacy_fm;
+ struct mlx5_flow_meter_info *fm;
+ struct mlx5_aso_mtr_pool *mtr_pool;
const struct rte_flow_attr attr = {
.ingress = 1,
.egress = 1,
.transfer = priv->config.dv_esw_en ? 1 : 0,
};
void *tmp;
+ uint32_t i, offset, mtr_idx;
- TAILQ_FOREACH_SAFE(fm, fms, next, tmp) {
- /* Meter object must not have any owner. */
- MLX5_ASSERT(!fm->ref_cnt);
- /* Get meter profile. */
- fmp = fm->profile;
- if (fmp == NULL)
- return -rte_mtr_error_set(error, EINVAL,
- RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
- NULL, "MTR object meter profile invalid.");
- /* Update dependencies. */
- fmp->ref_cnt--;
- /* Remove from list. */
- TAILQ_REMOVE(fms, fm, next);
- /* Free policer counters. */
- if (fm->policer_stats.pass_cnt)
- mlx5_counter_free(dev, fm->policer_stats.pass_cnt);
- if (fm->policer_stats.drop_cnt)
- mlx5_counter_free(dev, fm->policer_stats.drop_cnt);
- /* Free meter flow table. */
- mlx5_flow_destroy_policer_rules(dev, fm, &attr);
- mlx5_flow_destroy_mtr_tbls(dev, fm->mfts);
- mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], fm->idx);
+ if (priv->sh->meter_aso_en) {
+ i = mtrmng->n_valid;
+ while (i--) {
+ mtr_pool = mtrmng->pools[i];
+ for (offset = 0; offset < MLX5_ASO_MTRS_PER_POOL;
+ offset++) {
+ fm = &mtr_pool->mtrs[offset].fm;
+ mtr_idx = MLX5_MAKE_MTR_IDX(i, offset);
+ if (fm->meter_id != UINT32_MAX &&
+ mlx5_flow_meter_params_flush(dev,
+ fm, &attr, mtr_idx))
+ return -rte_mtr_error_set
+ (error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "MTR object meter profile invalid.");
+ }
+ }
+ } else {
+ TAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) {
+ fm = &legacy_fm->fm;
+ if (mlx5_flow_meter_params_flush(dev, fm, &attr, 0))
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "MTR object meter profile invalid.");
+ }
}
TAILQ_FOREACH_SAFE(fmp, fmps, next, tmp) {
/* Check unused. */
--
2.27.0
next prev parent reply other threads:[~2021-04-13 0:11 UTC|newest]
Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-31 7:36 [dpdk-dev] [PATCH 00/13] Add ASO meter support in MLX5 PMD Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 01/13] net/mlx5: support three level table walk Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 02/13] net/mlx5: fix meter statistics Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 03/13] net/mlx5: optimize " Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 04/13] net/mlx5: use mask for meter register setting Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 05/13] common/mlx5: add definitions for ASO flow meter Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 06/13] common/mlx5: add read ASO flow meter HCA capability Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 07/13] common/mlx5: add DevX API to create ASO flow meter object Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 08/13] net/mlx5: flow meter pool to manage " Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 09/13] net/mlx5: init/uninit flow meter queue for WQE Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 10/13] net/mlx5: aso flow meter send WQE and CQE handle Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 11/13] net/mlx5: add support of ASO meter action Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 12/13] net/mlx5: make ASO meter queue thread-safe Li Zhang
2021-03-31 7:36 ` [dpdk-dev] [PATCH 13/13] net/mlx5: allow multiple flow tables on the same level Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 00/13] Add ASO meter support in MLX5 PMD Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 01/13] net/mlx5: support three level table walk Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 02/13] net/mlx5: fix meter statistics Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 03/13] net/mlx5: optimize " Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 04/13] net/mlx5: use mask for meter register setting Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 05/13] common/mlx5: add definitions for ASO flow meter Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 06/13] common/mlx5: add read ASO flow meter HCA capability Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 07/13] common/mlx5: add DevX API to create ASO flow meter object Li Zhang
2021-04-13 16:50 ` Kinsella, Ray
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 08/13] net/mlx5: flow meter pool to manage " Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 09/13] net/mlx5: init/uninit flow meter queue for WQE Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 10/13] net/mlx5: aso flow meter send WQE and CQE handle Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 11/13] net/mlx5: add support of ASO meter action Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 12/13] net/mlx5: make ASO meter queue thread-safe Li Zhang
2021-04-02 15:16 ` [dpdk-dev] [PATCH v2 13/13] net/mlx5: allow multiple flow tables on the same level Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 00/14] Add ASO meter support in MLX5 PMD Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 01/14] net/mlx5: support three level table walk Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 02/14] common/mlx5: add color register idle bits definition Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 03/14] net/mlx5: fix meter statistics Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 04/14] net/mlx5: optimize " Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 05/14] net/mlx5: use mask for meter register setting Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 06/14] common/mlx5: add definitions for ASO flow meter Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 07/14] common/mlx5: add read ASO flow meter HCA capability Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 08/14] common/mlx5: add DevX API to create ASO flow meter object Li Zhang
2021-04-13 0:10 ` Li Zhang [this message]
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 10/14] net/mlx5: initialize the flow meter ASO SQ Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 11/14] net/mlx5: aso flow meter send WQE and CQE handle Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 12/14] net/mlx5: add support of ASO meter action Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 13/14] net/mlx5: make ASO meter queue thread-safe Li Zhang
2021-04-13 0:10 ` [dpdk-dev] [PATCH v3 14/14] net/mlx5: allow multiple flow tables on the same level Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 00/14] Add ASO meter support in MLX5 PMD Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 01/14] net/mlx5: support three level table walk Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 02/14] common/mlx5: add color register idle bits definition Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 03/14] net/mlx5: fix meter statistics Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 04/14] net/mlx5: optimize " Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 05/14] net/mlx5: use mask for meter register setting Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 06/14] common/mlx5: add definitions for ASO flow meter Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 07/14] common/mlx5: add read ASO flow meter HCA capability Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 08/14] common/mlx5: add DevX API to create ASO flow meter object Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 09/14] net/mlx5: flow meter pool to manage " Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 10/14] net/mlx5: initialize the flow meter ASO SQ Li Zhang
2021-04-15 13:05 ` Raslan Darawsheh
2021-04-15 14:21 ` Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 11/14] net/mlx5: aso flow meter send WQE and CQE handle Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 12/14] net/mlx5: add support of ASO meter action Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 13/14] net/mlx5: make ASO meter queue thread-safe Li Zhang
2021-04-14 2:57 ` [dpdk-dev] [PATCH v4 14/14] net/mlx5: allow multiple flow tables on the same level Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 00/14] Add ASO meter support in MLX5 PMD Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 01/14] net/mlx5: support three level table walk Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 02/14] common/mlx5: add color register idle bits definition Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 03/14] net/mlx5: fix meter statistics Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 04/14] net/mlx5: optimize " Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 05/14] net/mlx5: use mask for meter register setting Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 06/14] common/mlx5: add definitions for ASO flow meter Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 07/14] common/mlx5: add read ASO flow meter HCA capability Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 08/14] common/mlx5: add DevX API to create ASO flow meter object Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 09/14] net/mlx5: flow meter pool to manage " Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 10/14] net/mlx5: initialize the flow meter ASO SQ Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 11/14] net/mlx5: aso flow meter send WQE and CQE handle Li Zhang
2021-04-19 21:46 ` Ferruh Yigit
2021-04-19 22:02 ` Thomas Monjalon
2021-04-20 10:35 ` Jiawei(Jonny) Wang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 12/14] net/mlx5: add support of ASO meter action Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 13/14] net/mlx5: make ASO meter queue thread-safe Li Zhang
2021-04-15 15:11 ` [dpdk-dev] [PATCH v5 14/14] net/mlx5: allow multiple flow tables on the same level Li Zhang
2021-04-18 19:33 ` [dpdk-dev] [PATCH v5 00/14] Add ASO meter support in MLX5 PMD Raslan Darawsheh
2021-04-19 21:42 ` Ferruh Yigit
2021-04-19 21:59 ` Thomas Monjalon
2021-04-20 10:33 ` Jiawei(Jonny) Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 00/15] " Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 01/15] net/mlx5: support three level table walk Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 02/15] common/mlx5: add color register idle bits definition Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 03/15] net/mlx5: fix meter statistics Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 04/15] net/mlx5: optimize " Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 05/15] net/mlx5: use mask for meter register setting Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 06/15] common/mlx5: add definitions for ASO flow meter Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 07/15] common/mlx5: add read ASO flow meter HCA capability Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 08/15] common/mlx5: add DevX API to create ASO flow meter object Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 09/15] net/mlx5: flow meter pool to manage " Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 10/15] net/mlx5: initialize the flow meter ASO SQ Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 11/15] net/mlx5: add meter ASO queue management Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 12/15] net/mlx5: add support of ASO meter action Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 13/15] net/mlx5: make ASO meter queue thread-safe Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 14/15] net/mlx5: allow multiple flow tables on the same level Jiawei Wang
2021-04-20 10:55 ` [dpdk-dev] [PATCH v6 15/15] doc: update release notes for ASO meter Jiawei Wang
2021-04-21 6:50 ` Raslan Darawsheh
2021-04-21 8:58 ` Ferruh Yigit
2021-04-21 6:51 ` [dpdk-dev] [PATCH v6 00/15] Add ASO meter support in MLX5 PMD Raslan Darawsheh
2021-04-21 8:31 ` Ferruh Yigit
2021-04-21 8:33 ` Asaf Penso
2021-04-21 8:58 ` Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210413001033.1999355-10-lizh@nvidia.com \
--to=lizh@nvidia.com \
--cc=dekelp@nvidia.com \
--cc=dev@dpdk.org \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=rasland@nvidia.com \
--cc=roniba@nvidia.com \
--cc=shahafs@nvidia.com \
--cc=thomas@monjalon.net \
--cc=viacheslavo@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).