From: Bing Zhao <bingz@nvidia.com>
To: <viacheslavo@nvidia.com>, <matan@nvidia.com>
Cc: <dev@dpdk.org>, <orika@nvidia.com>, <rasland@nvidia.com>,
<thomas@monjalon.net>, <lizh@nvidia.com>, <shunh@nvidia.com>
Subject: [dpdk-dev] [PATCH v2 3/7] net/mlx5: added support for yellow policy rules
Date: Sun, 18 Jul 2021 20:18:13 +0300 [thread overview]
Message-ID: <20210718171817.23822-4-bingz@nvidia.com> (raw)
In-Reply-To: <20210718171817.23822-1-bingz@nvidia.com>
When creating a meter policy, both / either of the action rules for
green and yellow colors may be provided. After validation, usually
the actions are created before the meter is using by a flow rule.
If there is action specified for the yellow color, the action rules
should be created together with green color in the same time. The
action of green / yellow color can be empty, then the default
behavior is the jump action of the rule, just the same as that of
the default policy.
If the fate action of either one color is queue / RSS, all the
actions rules will be created on the flow splitting stage instead of
the policy adding stage.
Signed-off-by: Bing Zhao <bingz@nvidia.com>
---
drivers/net/mlx5/mlx5.h | 4 +++
drivers/net/mlx5/mlx5_flow_dv.c | 50 +++++++++++++++------------
drivers/net/mlx5/mlx5_flow_meter.c | 54 ++++++++++++++++++++----------
3 files changed, 68 insertions(+), 40 deletions(-)
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 791696caf4..c3e1298ebd 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -744,6 +744,10 @@ struct mlx5_flow_meter_policy {
/* Is queue action in policy table. */
uint32_t is_hierarchy:1;
/* Is meter action in policy table. */
+ uint32_t skip_y:1;
+ /* If yellow color policy is skipped. */
+ uint32_t skip_g:1;
+ /* If green color policy is skipped. */
rte_spinlock_t sl;
uint32_t ref_cnt;
/* Use count. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index cfc646c5e5..ffe97d453a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -15214,7 +15214,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
struct mlx5_priv *priv = dev->data->dev_private;
struct rte_flow_error flow_err;
const struct rte_flow_action *act;
- uint64_t action_flags = 0;
+ uint64_t action_flags;
struct mlx5_flow_handle dh;
struct mlx5_flow dev_flow;
struct mlx5_flow_dv_port_id_action_resource port_id_action;
@@ -15234,21 +15234,24 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
memset(&dh, 0, sizeof(struct mlx5_flow_handle));
memset(&dev_flow, 0, sizeof(struct mlx5_flow));
memset(&port_id_action, 0,
- sizeof(struct mlx5_flow_dv_port_id_action_resource));
+ sizeof(struct mlx5_flow_dv_port_id_action_resource));
memset(mhdr_res, 0, sizeof(*mhdr_res));
mhdr_res->ft_type = transfer ? MLX5DV_FLOW_TABLE_TYPE_FDB :
- egress ?
- MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
- MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
+ (egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
+ MLX5DV_FLOW_TABLE_TYPE_NIC_RX);
dev_flow.handle = &dh;
dev_flow.dv.port_id_action = &port_id_action;
dev_flow.external = true;
for (i = 0; i < RTE_COLORS; i++) {
if (i < MLX5_MTR_RTE_COLORS)
act_cnt = &mtr_policy->act_cnt[i];
+ /* Skip the color policy actions creation. */
+ if ((i == RTE_COLOR_YELLOW && mtr_policy->skip_y) ||
+ (i == RTE_COLOR_GREEN && mtr_policy->skip_g))
+ continue;
+ action_flags = 0;
for (act = actions[i];
- act && act->type != RTE_FLOW_ACTION_TYPE_END;
- act++) {
+ act && act->type != RTE_FLOW_ACTION_TYPE_END; act++) {
switch (act->type) {
case RTE_FLOW_ACTION_TYPE_MARK:
{
@@ -15456,7 +15459,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
(1 << MLX5_SCALE_FLOW_GROUP_BIT),
};
struct mlx5_flow_meter_sub_policy *sub_policy =
- mtr_policy->sub_policys[domain][0];
+ mtr_policy->sub_policys[domain][0];
if (i >= MLX5_MTR_RTE_COLORS)
return -rte_mtr_error_set(error,
@@ -15500,6 +15503,10 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
action_flags |= MLX5_FLOW_ACTION_JUMP;
break;
}
+ /*
+ * No need to check meter hierarchy for Y or R colors
+ * here since it is done in the validation stage.
+ */
case RTE_FLOW_ACTION_TYPE_METER:
{
const struct rte_flow_action_meter *mtr;
@@ -15615,6 +15622,7 @@ flow_dv_create_mtr_policy_acts(struct rte_eth_dev *dev,
ret = __flow_dv_create_domain_policy_acts(dev,
mtr_policy, actions,
(enum mlx5_meter_domain)i, error);
+ /* Cleaning resource is done in the caller level. */
if (ret)
return ret;
}
@@ -16156,16 +16164,15 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
for (i = 0; i < RTE_COLORS; i++) {
acts[i].actions_n = 0;
- if (i == RTE_COLOR_YELLOW)
- continue;
if (i == RTE_COLOR_RED) {
/* Only support drop on red. */
acts[i].dv_actions[0] =
- mtr_policy->dr_drop_action[domain];
+ mtr_policy->dr_drop_action[domain];
acts[i].actions_n = 1;
continue;
}
- if (mtr_policy->act_cnt[i].fate_action == MLX5_FLOW_FATE_MTR) {
+ if (i == RTE_COLOR_GREEN &&
+ mtr_policy->act_cnt[i].fate_action == MLX5_FLOW_FATE_MTR) {
struct rte_flow_attr attr = {
.transfer = transfer
};
@@ -16199,13 +16206,12 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
"mark action for policy.");
goto err_exit;
}
- acts[i].dv_actions[acts[i].actions_n] =
- tag->action;
+ acts[i].dv_actions[acts[i].actions_n] = tag->action;
acts[i].actions_n++;
}
if (mtr_policy->act_cnt[i].modify_hdr) {
acts[i].dv_actions[acts[i].actions_n] =
- mtr_policy->act_cnt[i].modify_hdr->action;
+ mtr_policy->act_cnt[i].modify_hdr->action;
acts[i].actions_n++;
}
if (mtr_policy->act_cnt[i].fate_action) {
@@ -16220,7 +16226,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
goto err_exit;
}
acts[i].dv_actions[acts[i].actions_n] =
- port_action->action;
+ port_action->action;
acts[i].actions_n++;
mtr_policy->dev = dev;
match_src_port = true;
@@ -16234,15 +16240,15 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
case MLX5_FLOW_FATE_SHARED_RSS:
case MLX5_FLOW_FATE_QUEUE:
hrxq = mlx5_ipool_get
- (priv->sh->ipool[MLX5_IPOOL_HRXQ],
- sub_policy->rix_hrxq[i]);
+ (priv->sh->ipool[MLX5_IPOOL_HRXQ],
+ sub_policy->rix_hrxq[i]);
if (!hrxq) {
DRV_LOG(ERR, "Failed to find "
"queue action for policy.");
goto err_exit;
}
acts[i].dv_actions[acts[i].actions_n] =
- hrxq->action;
+ hrxq->action;
acts[i].actions_n++;
break;
case MLX5_FLOW_FATE_MTR:
@@ -16284,7 +16290,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
if (__flow_dv_create_domain_policy_rules(dev, sub_policy,
egress, transfer, match_src_port, acts)) {
DRV_LOG(ERR,
- "Failed to create policy rules per domain.");
+ "Failed to create policy rules per domain.");
goto err_exit;
}
return 0;
@@ -16321,8 +16327,8 @@ flow_dv_create_policy_rules(struct rte_eth_dev *dev,
/* Prepare actions list and create policy rules. */
if (__flow_dv_create_policy_acts_rules(dev, mtr_policy,
mtr_policy->sub_policys[i][0], i)) {
- DRV_LOG(ERR,
- "Failed to create policy action list per domain.");
+ DRV_LOG(ERR, "Failed to create policy action "
+ "list per domain.");
return -1;
}
}
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 73eba0dabd..a6bcb8dbb5 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -686,21 +686,20 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
if (!priv->mtr_en)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
- NULL, "meter policy unsupported.");
+ NULL, "meter policy unsupported. ");
if (policy_id == MLX5_INVALID_POLICY_ID)
return -rte_mtr_error_set(error, ENOTSUP,
- RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
- "policy ID is invalid. ");
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "policy ID is invalid. ");
if (policy_id == priv->sh->mtrmng->def_policy_id)
return -rte_mtr_error_set(error, EEXIST,
- RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
- "policy ID exists. ");
- mtr_policy = mlx5_flow_meter_policy_find(dev, policy_id,
- &policy_idx);
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "default policy ID exists. ");
+ mtr_policy = mlx5_flow_meter_policy_find(dev, policy_id, &policy_idx);
if (mtr_policy)
return -rte_mtr_error_set(error, EEXIST,
- RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
- "policy ID exists. ");
+ RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+ NULL, "policy ID exists. ");
ret = mlx5_flow_validate_mtr_acts(dev, policy->actions, &attr,
&is_rss, &domain_bitmap, &is_def_policy, error);
if (ret)
@@ -730,20 +729,30 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
if (!(domain_bitmap & (1 << i)))
continue;
+ /*
+ * If RSS is found, it means that only the ingress domain can
+ * be supported. It is invalid to support RSS for one color
+ * and egress / transfer domain actions for another. Drop and
+ * jump action should have no impact.
+ */
if (is_rss) {
policy_size +=
- sizeof(struct mlx5_flow_meter_sub_policy *) *
- MLX5_MTR_RSS_MAX_SUB_POLICY;
+ sizeof(struct mlx5_flow_meter_sub_policy *) *
+ MLX5_MTR_RSS_MAX_SUB_POLICY;
break;
}
policy_size += sizeof(struct mlx5_flow_meter_sub_policy *);
}
mtr_policy = mlx5_malloc(MLX5_MEM_ZERO, policy_size,
- RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+ RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
if (!mtr_policy)
return -rte_mtr_error_set(error, ENOMEM,
RTE_MTR_ERROR_TYPE_METER_POLICY, NULL,
"Memory alloc failed for meter policy.");
+ if (policy_mode == MLX5_MTR_POLICY_MODE_OG)
+ mtr_policy->skip_y = 1;
+ if (policy_mode == MLX5_MTR_POLICY_MODE_OY)
+ mtr_policy->skip_g = 1;
policy_size = sizeof(struct mlx5_flow_meter_policy);
for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
if (!(domain_bitmap & (1 << i)))
@@ -756,10 +765,9 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
mtr_policy->transfer = 1;
sub_policy = mlx5_ipool_zmalloc
(priv->sh->ipool[MLX5_IPOOL_MTR_POLICY],
- &sub_policy_idx);
- if (!sub_policy)
- goto policy_add_err;
- if (sub_policy_idx > MLX5_MAX_SUB_POLICY_TBL_NUM)
+ &sub_policy_idx);
+ if (!sub_policy ||
+ sub_policy_idx > MLX5_MAX_SUB_POLICY_TBL_NUM)
goto policy_add_err;
sub_policy->idx = sub_policy_idx;
sub_policy->main_policy = mtr_policy;
@@ -768,7 +776,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
sub_policy->main_policy_id = 1;
}
mtr_policy->sub_policys[i] =
- (struct mlx5_flow_meter_sub_policy **)
+ (struct mlx5_flow_meter_sub_policy **)
((uint8_t *)mtr_policy + policy_size);
mtr_policy->sub_policys[i][0] = sub_policy;
sub_policy_num = (mtr_policy->sub_policy_num >>
@@ -780,11 +788,17 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
mtr_policy->sub_policy_num |=
(sub_policy_num & MLX5_MTR_SUB_POLICY_NUM_MASK) <<
(MLX5_MTR_SUB_POLICY_NUM_SHIFT * i);
+ /*
+ * If RSS is found, it means that only the ingress domain can
+ * be supported. It is invalid to support RSS for one color
+ * and egress / transfer domain actions for another. Drop and
+ * jump action should have no impact.
+ */
if (is_rss) {
mtr_policy->is_rss = 1;
break;
}
- policy_size += sizeof(struct mlx5_flow_meter_sub_policy *);
+ policy_size += sizeof(struct mlx5_flow_meter_sub_policy *);
}
rte_spinlock_init(&mtr_policy->sl);
ret = mlx5_flow_create_mtr_acts(dev, mtr_policy,
@@ -800,6 +814,10 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
goto policy_add_err;
skip_rule = (final_policy->is_rss || final_policy->is_queue);
}
+ /*
+ * If either Green or Yellow has queue / RSS action, all the policy
+ * rules will be created later in the flow splitting stage.
+ */
if (!is_rss && !mtr_policy->is_queue && !skip_rule) {
/* Create policy rules in HW. */
ret = mlx5_flow_create_policy_rules(dev, mtr_policy);
--
2.27.0
next prev parent reply other threads:[~2021-07-18 17:19 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-05 15:57 [dpdk-dev] [PATCH 0/6] support yellow color policy in mlx5 Bing Zhao
2021-07-05 15:57 ` [dpdk-dev] [PATCH 1/6] net/mlx5: add yellow color default policy Bing Zhao
2021-07-05 15:57 ` [dpdk-dev] [PATCH 2/6] net/mlx5: support yellow in meter policy validation Bing Zhao
2021-07-05 15:57 ` [dpdk-dev] [PATCH 3/6] net/mlx5: enable meter bucket overflow for yellow color Bing Zhao
2021-07-05 15:57 ` [dpdk-dev] [PATCH 4/6] net/mlx5: added support for yellow policy rules Bing Zhao
2021-07-05 15:57 ` [dpdk-dev] [PATCH 5/6] net/mlx5: split policies handling of colors Bing Zhao
2021-07-05 15:57 ` [dpdk-dev] [PATCH 6/6] doc: update mlx5 metering policy part Bing Zhao
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 0/7] support yellow color policy in mlx5 Bing Zhao
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 1/7] net/mlx5: handle yellow case in default meter policy Bing Zhao
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 2/7] net/mlx5: enable meter bucket overflow for yellow color Bing Zhao
2021-07-18 17:18 ` Bing Zhao [this message]
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 4/7] net/mlx5: split policies handling of colors Bing Zhao
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 5/7] net/mlx5: support yellow in meter policy validation Bing Zhao
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 6/7] net/mlx5: check consistency of meter policy and profile Bing Zhao
2021-07-18 17:18 ` [dpdk-dev] [PATCH v2 7/7] net/mlx5: add meter support for trTCM profiles Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 0/7] support yellow color policy in mlx5 Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 1/7] net/mlx5: handle yellow case in default meter policy Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 2/7] net/mlx5: enable meter bucket overflow for yellow color Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 3/7] net/mlx5: added support for yellow policy rules Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 4/7] net/mlx5: split policies handling of colors Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 5/7] net/mlx5: support yellow in meter policy validation Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 6/7] net/mlx5: check consistency of meter policy and profile Bing Zhao
2021-07-21 8:54 ` [dpdk-dev] [PATCH v3 7/7] net/mlx5: add meter support for trTCM profiles Bing Zhao
2021-07-22 11:28 ` [dpdk-dev] [PATCH v3 0/7] support yellow color policy in mlx5 Thomas Monjalon
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=20210718171817.23822-4-bingz@nvidia.com \
--to=bingz@nvidia.com \
--cc=dev@dpdk.org \
--cc=lizh@nvidia.com \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=rasland@nvidia.com \
--cc=shunh@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).