@@ -14702,22 +14702,34 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
sizeof(struct mlx5_modification_cmd) *
(MLX5_MAX_MODIFY_NUM + 1)];
} mhdr_dummy;
+ struct mlx5_flow_mtr_mng *mtrmng = priv->sh->mtrmng;
egress = (domain == MLX5_MTR_DOMAIN_EGRESS) ? 1 : 0;
transfer = (domain == MLX5_MTR_DOMAIN_TRANSFER) ? 1 : 0;
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));
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];
- for (act = actions[i];
- act && act->type != RTE_FLOW_ACTION_TYPE_END;
- act++) {
+ act = actions[i];
+ /* No policy action, use default. */
+ if (!act || act->type == RTE_FLOW_ACTION_TYPE_END) {
+ if (!mtrmng->def_policy[domain])
+ return -rte_mtr_error_set(error,
+ ENOTSUP,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL,
+ "Default policy not created.");
+ act_cnt->dr_jump_action[domain] =
+ mtrmng->def_policy[domain]->dr_jump_action[i];
+ continue;
+ }
+ for (; act->type != RTE_FLOW_ACTION_TYPE_END; act++) {
switch (act->type) {
case RTE_FLOW_ACTION_TYPE_MARK:
{
@@ -14933,6 +14945,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
action_flags |= MLX5_FLOW_ACTION_PORT_ID;
break;
}
+ /* G & Y can use the same table by default. */
case RTE_FLOW_ACTION_TYPE_JUMP:
{
uint32_t jump_group = 0;
@@ -14947,7 +14960,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,
@@ -15036,6 +15049,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);
+ /* Rollback is done in mlx5 layer. */
if (ret)
return ret;
}
@@ -15538,12 +15552,10 @@ __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;
}
@@ -15555,13 +15567,12 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
"mark action for policy.");
return -1;
}
- 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) {
@@ -15576,7 +15587,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
return -1;
}
acts[i].dv_actions[acts[i].actions_n] =
- port_action->action;
+ port_action->action;
acts[i].actions_n++;
break;
case MLX5_FLOW_FATE_DROP:
@@ -15588,15 +15599,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.");
return -1;
}
acts[i].dv_actions[acts[i].actions_n] =
- hrxq->action;
+ hrxq->action;
acts[i].actions_n++;
break;
default:
@@ -15610,7 +15621,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
if (__flow_dv_create_domain_policy_rules(dev, sub_policy,
egress, transfer, false, acts)) {
DRV_LOG(ERR,
- "Failed to create policy rules per domain.");
+ "Failed to create policy rules per domain.");
return -1;
}
return 0;
@@ -644,21 +644,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);
@@ -666,8 +665,8 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
return ret;
if (!domain_bitmap)
return -rte_mtr_error_set(error, ENOTSUP,
- RTE_MTR_ERROR_TYPE_METER_POLICY,
- NULL, "fail to find policy domain.");
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "fail to find policy domain.");
if (is_def_policy) {
if (priv->sh->mtrmng->def_policy_id != MLX5_INVALID_POLICY_ID)
return -rte_mtr_error_set(error, EEXIST,
@@ -689,16 +688,22 @@ 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,
@@ -715,7 +720,7 @@ 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);
+ &sub_policy_idx);
if (!sub_policy)
goto policy_add_err;
if (sub_policy_idx > MLX5_MAX_SUB_POLICY_TBL_NUM)
@@ -727,7 +732,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 >>
@@ -743,13 +748,17 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
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,
policy->actions, error);
if (ret)
goto policy_add_err;
+ /*
+ * 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) {
/* Create policy rules in HW. */
ret = mlx5_flow_create_policy_rules(dev, mtr_policy);