[dpdk-dev] [PATCH v1 1/4] net/mlx5: use meter profile lookup table
Shun Hao
shunh at nvidia.com
Fri Jul 2 11:14:43 CEST 2021
Currently a list is used to save all meter profile ids, which is
not efficient when looking up profile from huge mount of profiles.
This changes to use a l3 table instead to save meter profile ids,
so as to improve the lookup performance.
Signed-off-by: Shun Hao <shunh at nvidia.com>
Acked-by: Matan Azrad <matan at nvidia.com>
---
drivers/net/mlx5/linux/mlx5_os.c | 6 +++-
drivers/net/mlx5/mlx5.h | 2 +-
drivers/net/mlx5/mlx5_flow_meter.c | 53 ++++++++++++++++++++----------
drivers/net/mlx5/windows/mlx5_os.c | 6 +++-
4 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 92b3009786..b3f9e392ab 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1570,7 +1570,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
priv->ctrl_flows = 0;
rte_spinlock_init(&priv->flow_list_lock);
TAILQ_INIT(&priv->flow_meters);
- TAILQ_INIT(&priv->flow_meter_profiles);
+ priv->mtr_profile_tbl = mlx5_l3t_create(MLX5_L3T_TYPE_PTR);
+ if (!priv->mtr_profile_tbl)
+ goto error;
/* Hint libmlx5 to use PMD allocator for data plane resources */
mlx5_glue->dv_set_context_attr(sh->ctx,
MLX5DV_CTX_ATTR_BUF_ALLOCATORS,
@@ -1713,6 +1715,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
mlx5_vlan_vmwa_exit(priv->vmwa_context);
if (eth_dev && priv->drop_queue.hrxq)
mlx5_drop_action_destroy(eth_dev);
+ if (priv->mtr_profile_tbl)
+ mlx5_l3t_destroy(priv->mtr_profile_tbl);
if (own_domain_id)
claim_zero(rte_eth_switch_domain_free(priv->domain_id));
mlx5_cache_list_destroy(&priv->hrxqs);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 1b2dc8f815..0226327bc3 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1373,8 +1373,8 @@ struct mlx5_priv {
/* Hash table of Rx metadata register copy table. */
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_legacy_flow_meters flow_meters; /* MTR list. */
+ struct mlx5_l3t_tbl *mtr_profile_tbl; /* Meter index lookup table. */
struct mlx5_l3t_tbl *mtr_idx_tbl; /* Meter index lookup table. */
uint8_t skip_default_rss_reta; /* Skip configuration of default reta. */
uint8_t fdb_def_rule; /* Whether fdb jump to table 1 is configured. */
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index d7ce5cd2f6..87c5782956 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -91,13 +91,20 @@ mlx5_flow_meter_action_create(struct mlx5_priv *priv,
static struct mlx5_flow_meter_profile *
mlx5_flow_meter_profile_find(struct mlx5_priv *priv, uint32_t meter_profile_id)
{
- struct mlx5_mtr_profiles *fmps = &priv->flow_meter_profiles;
struct mlx5_flow_meter_profile *fmp;
+ union mlx5_l3t_data data;
+ int32_t ret;
- TAILQ_FOREACH(fmp, fmps, next)
- if (meter_profile_id == fmp->id)
- return fmp;
- return NULL;
+ if (mlx5_l3t_get_entry(priv->mtr_profile_tbl,
+ meter_profile_id, &data) || !data.ptr)
+ return NULL;
+ fmp = data.ptr;
+ /* Remove reference taken by the mlx5_l3t_get_entry. */
+ ret = mlx5_l3t_clear_entry(priv->mtr_profile_tbl,
+ meter_profile_id);
+ if (!ret || ret == -1)
+ return NULL;
+ return fmp;
}
/**
@@ -399,8 +406,8 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,
struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_mtr_profiles *fmps = &priv->flow_meter_profiles;
struct mlx5_flow_meter_profile *fmp;
+ union mlx5_l3t_data data;
int ret;
if (!priv->mtr_en)
@@ -427,8 +434,13 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,
ret = mlx5_flow_meter_param_fill(fmp, priv, error);
if (ret)
goto error;
- /* Add to list. */
- TAILQ_INSERT_TAIL(fmps, fmp, next);
+ data.ptr = fmp;
+ ret = mlx5_l3t_set_entry(priv->mtr_profile_tbl,
+ meter_profile_id, &data);
+ if (ret)
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+ NULL, "Meter profile insert fail.");
return 0;
error:
mlx5_free(fmp);
@@ -472,8 +484,10 @@ mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev,
return -rte_mtr_error_set(error, EBUSY,
RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
NULL, "Meter profile is in use.");
- /* Remove from list. */
- TAILQ_REMOVE(&priv->flow_meter_profiles, fmp, next);
+ if (mlx5_l3t_clear_entry(priv->mtr_profile_tbl, meter_profile_id))
+ return -rte_mtr_error_set(error, EBUSY,
+ RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+ NULL, "Meter profile remove fail.");
mlx5_free(fmp);
return 0;
}
@@ -1859,7 +1873,6 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
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_legacy_flow_meter *legacy_fm;
struct mlx5_flow_meter_info *fm;
@@ -1921,12 +1934,18 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error)
mlx5_l3t_destroy(priv->sh->mtrmng->policy_idx_tbl);
priv->sh->mtrmng->policy_idx_tbl = NULL;
}
- TAILQ_FOREACH_SAFE(fmp, fmps, next, tmp) {
- /* Check unused. */
- MLX5_ASSERT(!fmp->ref_cnt);
- /* Remove from list. */
- TAILQ_REMOVE(&priv->flow_meter_profiles, fmp, next);
- mlx5_free(fmp);
+ if (priv->mtr_profile_tbl) {
+ MLX5_L3T_FOREACH(priv->mtr_profile_tbl, i, entry) {
+ fmp = entry;
+ if (mlx5_flow_meter_profile_delete(dev, fmp->id,
+ error))
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "Fail to destroy "
+ "meter profile.");
+ }
+ mlx5_l3t_destroy(priv->mtr_profile_tbl);
+ priv->mtr_profile_tbl = NULL;
}
/* Delete default policy table. */
mlx5_flow_destroy_def_policy(dev);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 3fe3f55f49..e30b682822 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -566,7 +566,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
priv->flows = 0;
priv->ctrl_flows = 0;
TAILQ_INIT(&priv->flow_meters);
- TAILQ_INIT(&priv->flow_meter_profiles);
+ priv->mtr_profile_tbl = mlx5_l3t_create(MLX5_L3T_TYPE_PTR);
+ if (!priv->mtr_profile_tbl)
+ goto error;
/* Bring Ethernet device up. */
DRV_LOG(DEBUG, "port %u forcing Ethernet interface up.",
eth_dev->data->port_id);
@@ -644,6 +646,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
return eth_dev;
error:
if (priv) {
+ if (priv->mtr_profile_tbl)
+ mlx5_l3t_destroy(priv->mtr_profile_tbl);
if (own_domain_id)
claim_zero(rte_eth_switch_domain_free(priv->domain_id));
mlx5_free(priv);
--
2.20.0
More information about the dev
mailing list