@@ -608,8 +608,8 @@ struct mlx5_dev_shared_port {
/*ASO flow meter structures*/
/* Modify this value if enum rte_mtr_color changes. */
#define RTE_MTR_DROPPED RTE_COLORS
-/* Yellow is not supported. */
-#define MLX5_MTR_RTE_COLORS (RTE_COLOR_GREEN + 1)
+/* Yellow is now supported. */
+#define MLX5_MTR_RTE_COLORS (RTE_COLOR_YELLOW + 1)
/* table_id 22 bits in mlx5_flow_tbl_key so limit policy number. */
#define MLX5_MAX_SUB_POLICY_TBL_NUM 0x3FFFFF
#define MLX5_INVALID_POLICY_ID UINT32_MAX
@@ -7093,8 +7093,8 @@ mlx5_flow_validate_mtr_acts(struct rte_eth_dev *dev,
const struct mlx5_flow_driver_ops *fops;
fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV);
- return fops->validate_mtr_acts(dev, actions, attr,
- is_rss, domain_bitmap, is_def_policy, error);
+ return fops->validate_mtr_acts(dev, actions, attr, is_rss,
+ domain_bitmap, is_def_policy, error);
}
/**
@@ -16430,6 +16430,19 @@ flow_dv_action_validate(struct rte_eth_dev *dev,
}
}
+static inline int
+flow_dv_mtr_policy_rss_compare(const struct rte_flow_action_rss *r1,
+ const struct rte_flow_action_rss *r2)
+{
+ if (!r1 || !r2)
+ return 0;
+ if (r1->func != r2->func || r1->level != r2->level ||
+ r1->types != r2->types || r1->key_len != r2->key_len ||
+ memcmp(r1->key, r2->key, r1->key_len))
+ return 1;
+ return 0;
+}
+
/**
* Validate meter policy actions.
* Dispatcher for action type specific validation.
@@ -16459,42 +16472,46 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_dev_config *dev_conf = &priv->config;
const struct rte_flow_action *act;
- uint64_t action_flags = 0;
+ uint64_t action_flags[RTE_COLORS] = {0};
int actions_n;
int i, ret;
struct rte_flow_error flow_err;
uint8_t domain_color[RTE_COLORS] = {0};
uint8_t def_domain = MLX5_MTR_ALL_DOMAIN_BIT;
+ bool def_green = false;
+ bool def_yellow = false;
+ const struct rte_flow_action_rss *rss_color[RTE_COLORS] = {NULL};
if (!priv->config.dv_esw_en)
def_domain &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT;
*domain_bitmap = def_domain;
- if (actions[RTE_COLOR_YELLOW] &&
- actions[RTE_COLOR_YELLOW]->type != RTE_FLOW_ACTION_TYPE_END)
- return -rte_mtr_error_set(error, ENOTSUP,
- RTE_MTR_ERROR_TYPE_METER_POLICY,
- NULL,
- "Yellow color does not support any action.");
- if (actions[RTE_COLOR_YELLOW] &&
- actions[RTE_COLOR_YELLOW]->type != RTE_FLOW_ACTION_TYPE_DROP)
+ if (actions[RTE_COLOR_RED] &&
+ actions[RTE_COLOR_RED]->type != RTE_FLOW_ACTION_TYPE_DROP)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "Red color only supports drop action.");
/*
* Check default policy actions:
- * Green/Yellow: no action, Red: drop action
+ * Green / Yellow: no action, Red: drop action
+ * Either G or Y will trigger default policy actions to be created.
*/
- if ((!actions[RTE_COLOR_GREEN] ||
- actions[RTE_COLOR_GREEN]->type == RTE_FLOW_ACTION_TYPE_END)) {
+ if (!actions[RTE_COLOR_GREEN] ||
+ actions[RTE_COLOR_GREEN]->type == RTE_FLOW_ACTION_TYPE_END)
+ def_green = true;
+ if (!actions[RTE_COLOR_YELLOW] ||
+ actions[RTE_COLOR_YELLOW]->type == RTE_FLOW_ACTION_TYPE_END)
+ def_yellow = true;
+ if (def_green && def_yellow) {
*is_def_policy = true;
return 0;
}
- flow_err.message = NULL;
+ /* Set to empty string in case of NULL pointer access by user. */
+ flow_err.message = "";
for (i = 0; i < RTE_COLORS; i++) {
act = actions[i];
- for (action_flags = 0, actions_n = 0;
- act && act->type != RTE_FLOW_ACTION_TYPE_END;
- act++) {
+ for (action_flags[i] = 0, actions_n = 0;
+ act && act->type != RTE_FLOW_ACTION_TYPE_END;
+ act++) {
if (actions_n == MLX5_DV_MAX_NUMBER_OF_ACTIONS)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
@@ -16508,7 +16525,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
NULL, "PORT action validate check"
" fail for ESW disable");
ret = flow_dv_validate_action_port_id(dev,
- action_flags,
+ action_flags[i],
act, attr, &flow_err);
if (ret)
return -rte_mtr_error_set(error,
@@ -16518,11 +16535,11 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
flow_err.message :
"PORT action validate check fail");
++actions_n;
- action_flags |= MLX5_FLOW_ACTION_PORT_ID;
+ action_flags[i] |= MLX5_FLOW_ACTION_PORT_ID;
break;
case RTE_FLOW_ACTION_TYPE_MARK:
ret = flow_dv_validate_action_mark(dev, act,
- action_flags,
+ action_flags[i],
attr, &flow_err);
if (ret < 0)
return -rte_mtr_error_set(error,
@@ -16539,12 +16556,12 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
NULL, "Extend MARK action is "
"not supported. Please try use "
"default policy for meter.");
- action_flags |= MLX5_FLOW_ACTION_MARK;
+ action_flags[i] |= MLX5_FLOW_ACTION_MARK;
++actions_n;
break;
case RTE_FLOW_ACTION_TYPE_SET_TAG:
ret = flow_dv_validate_action_set_tag(dev,
- act, action_flags,
+ act, action_flags[i],
attr, &flow_err);
if (ret)
return -rte_mtr_error_set(error,
@@ -16557,15 +16574,14 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
* Count all modify-header actions
* as one action.
*/
- if (!(action_flags &
- MLX5_FLOW_MODIFY_HDR_ACTIONS))
+ if (!(action_flags[i] &
+ MLX5_FLOW_MODIFY_HDR_ACTIONS))
++actions_n;
- action_flags |= MLX5_FLOW_ACTION_SET_TAG;
+ action_flags[i] |= MLX5_FLOW_ACTION_SET_TAG;
break;
case RTE_FLOW_ACTION_TYPE_DROP:
ret = mlx5_flow_validate_action_drop
- (action_flags,
- attr, &flow_err);
+ (action_flags[i], attr, &flow_err);
if (ret < 0)
return -rte_mtr_error_set(error,
ENOTSUP,
@@ -16573,7 +16589,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
NULL, flow_err.message ?
flow_err.message :
"Drop action validate check fail");
- action_flags |= MLX5_FLOW_ACTION_DROP;
+ action_flags[i] |= MLX5_FLOW_ACTION_DROP;
++actions_n;
break;
case RTE_FLOW_ACTION_TYPE_QUEUE:
@@ -16582,9 +16598,9 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
* metadata feature is engaged.
*/
if (dev_conf->dv_flow_en &&
- (dev_conf->dv_xmeta_en !=
- MLX5_XMETA_MODE_LEGACY) &&
- mlx5_flow_ext_mreg_supported(dev))
+ (dev_conf->dv_xmeta_en !=
+ MLX5_XMETA_MODE_LEGACY) &&
+ mlx5_flow_ext_mreg_supported(dev))
return -rte_mtr_error_set(error,
ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
@@ -16592,7 +16608,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
"is not supported. Please try use "
"default policy for meter.");
ret = mlx5_flow_validate_action_queue(act,
- action_flags, dev,
+ action_flags[i], dev,
attr, &flow_err);
if (ret < 0)
return -rte_mtr_error_set(error,
@@ -16601,14 +16617,14 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
NULL, flow_err.message ?
flow_err.message :
"Queue action validate check fail");
- action_flags |= MLX5_FLOW_ACTION_QUEUE;
+ action_flags[i] |= MLX5_FLOW_ACTION_QUEUE;
++actions_n;
break;
case RTE_FLOW_ACTION_TYPE_RSS:
if (dev_conf->dv_flow_en &&
- (dev_conf->dv_xmeta_en !=
- MLX5_XMETA_MODE_LEGACY) &&
- mlx5_flow_ext_mreg_supported(dev))
+ (dev_conf->dv_xmeta_en !=
+ MLX5_XMETA_MODE_LEGACY) &&
+ mlx5_flow_ext_mreg_supported(dev))
return -rte_mtr_error_set(error,
ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
@@ -16624,13 +16640,14 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
NULL, flow_err.message ?
flow_err.message :
"RSS action validate check fail");
- action_flags |= MLX5_FLOW_ACTION_RSS;
+ action_flags[i] |= MLX5_FLOW_ACTION_RSS;
++actions_n;
- *is_rss = true;
+ /* Either G or Y will set the RSS. */
+ rss_color[i] = act->conf;
break;
case RTE_FLOW_ACTION_TYPE_JUMP:
ret = flow_dv_validate_action_jump(dev,
- NULL, act, action_flags,
+ NULL, act, action_flags[i],
attr, true, &flow_err);
if (ret)
return -rte_mtr_error_set(error,
@@ -16640,7 +16657,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
flow_err.message :
"Jump action validate check fail");
++actions_n;
- action_flags |= MLX5_FLOW_ACTION_JUMP;
+ action_flags[i] |= MLX5_FLOW_ACTION_JUMP;
break;
default:
return -rte_mtr_error_set(error, ENOTSUP,
@@ -16649,17 +16666,14 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
"Doesn't support optional action");
}
}
- /* Yellow is not supported, just skip. */
- if (i == RTE_COLOR_YELLOW)
- continue;
- if (action_flags & MLX5_FLOW_ACTION_PORT_ID)
+ if (action_flags[i] & MLX5_FLOW_ACTION_PORT_ID)
domain_color[i] = MLX5_MTR_DOMAIN_TRANSFER_BIT;
- else if ((action_flags &
- (MLX5_FLOW_ACTION_RSS | MLX5_FLOW_ACTION_QUEUE)) ||
- (action_flags & MLX5_FLOW_ACTION_MARK))
+ else if ((action_flags[i] &
+ (MLX5_FLOW_ACTION_RSS | MLX5_FLOW_ACTION_QUEUE)) ||
+ (action_flags[i] & MLX5_FLOW_ACTION_MARK))
/*
* Only support MLX5_XMETA_MODE_LEGACY
- * so MARK action only in ingress domain.
+ * so MARK action is only in ingress domain.
*/
domain_color[i] = MLX5_MTR_DOMAIN_INGRESS_BIT;
else
@@ -16669,8 +16683,8 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
* with other actions. Drop action is mutually-exclusive
* with any other action, except for Count action.
*/
- if ((action_flags & MLX5_FLOW_ACTION_DROP) &&
- (action_flags & ~MLX5_FLOW_ACTION_DROP)) {
+ if ((action_flags[i] & MLX5_FLOW_ACTION_DROP) &&
+ (action_flags[i] & ~MLX5_FLOW_ACTION_DROP)) {
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "Drop action is mutually-exclusive "
@@ -16679,30 +16693,29 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
/* Eswitch has few restrictions on using items and actions */
if (domain_color[i] & MLX5_MTR_DOMAIN_TRANSFER_BIT) {
if (!mlx5_flow_ext_mreg_supported(dev) &&
- action_flags & MLX5_FLOW_ACTION_MARK)
+ action_flags[i] & MLX5_FLOW_ACTION_MARK)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "unsupported action MARK");
- if (action_flags & MLX5_FLOW_ACTION_QUEUE)
+ if (action_flags[i] & MLX5_FLOW_ACTION_QUEUE)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "unsupported action QUEUE");
- if (action_flags & MLX5_FLOW_ACTION_RSS)
+ if (action_flags[i] & MLX5_FLOW_ACTION_RSS)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "unsupported action RSS");
- if (!(action_flags & MLX5_FLOW_FATE_ESWITCH_ACTIONS))
+ if (!(action_flags[i] & MLX5_FLOW_FATE_ESWITCH_ACTIONS))
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "no fate action is found");
} else {
- if (!(action_flags & MLX5_FLOW_FATE_ACTIONS) &&
- (domain_color[i] &
- MLX5_MTR_DOMAIN_INGRESS_BIT)) {
+ if (!(action_flags[i] & MLX5_FLOW_FATE_ACTIONS) &&
+ (domain_color[i] & MLX5_MTR_DOMAIN_INGRESS_BIT)) {
if ((domain_color[i] &
- MLX5_MTR_DOMAIN_EGRESS_BIT))
+ MLX5_MTR_DOMAIN_EGRESS_BIT))
domain_color[i] =
- MLX5_MTR_DOMAIN_EGRESS_BIT;
+ MLX5_MTR_DOMAIN_EGRESS_BIT;
else
return -rte_mtr_error_set(error,
ENOTSUP,
@@ -16710,9 +16723,27 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
NULL, "no fate action is found");
}
}
- if (domain_color[i] != def_domain)
- *domain_bitmap = domain_color[i];
}
+ /* If both colors have RSS, the attributes should be the same. */
+ if (flow_dv_mtr_policy_rss_compare(rss_color[RTE_COLOR_GREEN],
+ rss_color[RTE_COLOR_YELLOW]))
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "policy RSS attr conflict");
+ if (rss_color[RTE_COLOR_GREEN] || rss_color[RTE_COLOR_YELLOW])
+ *is_rss = true;
+ /* "domain_color[C]" is non-zero for each color, default is ALL. */
+ if (!def_green && !def_yellow &&
+ domain_color[RTE_COLOR_GREEN] != domain_color[RTE_COLOR_YELLOW])
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL, "policy domains conflict");
+ /*
+ * At least one color policy is listed in the actions, the domains
+ * to be supported should be the intersection.
+ */
+ *domain_bitmap = domain_color[RTE_COLOR_GREEN] &
+ domain_color[RTE_COLOR_YELLOW];
return 0;
}
@@ -660,7 +660,8 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
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);
+ &is_rss, &domain_bitmap,
+ &is_def_policy, error);
if (ret)
return ret;
if (!domain_bitmap)