@@ -473,6 +473,7 @@ Limitations
- meter profile packet mode is supported.
- meter profiles of RFC2697, RFC2698 and RFC4115 are supported.
- RFC4115 implementation is following MEF, meaning yellow traffic may reclaim unused green bandwidth when green token bucket is full.
+ - When using DV flow engine (``dv_flow_en`` = 1), if meter has drop count or meter hierarchy contains any meter that uses drop count, it cannot be used by flow matching all ports.
- Integrity:
@@ -775,6 +775,8 @@ struct mlx5_flow_meter_policy {
/* Is queue action in policy table. */
uint32_t is_hierarchy:1;
/* Is meter action in policy table. */
+ uint32_t hierarchy_drop_cnt:1;
+ /* Is any meter in hierarchy contains drop_cnt. */
uint32_t skip_y:1;
/* If yellow color policy is skipped. */
uint32_t skip_g:1;
@@ -5338,6 +5338,7 @@ flow_meter_split_prep(struct rte_eth_dev *dev,
switch (item_type) {
case RTE_FLOW_ITEM_TYPE_PORT_ID:
case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
+ if (mlx5_flow_get_item_vport_id(dev, items, &flow_src_port, NULL, error))
return -rte_errno;
if (!fm->def_policy && wks->policy->is_hierarchy &&
flow_src_port != priv->representor_id) {
@@ -11012,6 +11013,8 @@ int16_t mlx5_flow_get_esw_manager_vport_id(struct rte_eth_dev *dev)
* The src port id match item.
* @param[out] vport_id
* Pointer to put the vport id.
+ * @param[out] all_ports
+ * Indicate if the item matches all ports.
* @param[out] error
* Pointer to error structure.
*
@@ -11021,6 +11024,7 @@ int16_t mlx5_flow_get_esw_manager_vport_id(struct rte_eth_dev *dev)
int mlx5_flow_get_item_vport_id(struct rte_eth_dev *dev,
const struct rte_flow_item *item,
uint16_t *vport_id,
+ bool *all_ports,
struct rte_flow_error *error)
{
struct mlx5_priv *port_priv;
@@ -11032,8 +11036,13 @@ int mlx5_flow_get_item_vport_id(struct rte_eth_dev *dev,
return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
NULL, "Incorrect item type.");
pid_v = item->spec;
- if (!pid_v)
+ if (!pid_v) {
+ if (all_ports)
+ *all_ports = (item->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT);
return 0;
+ }
+ if (all_ports)
+ *all_ports = false;
esw_mgr_port = (item->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT) ?
MLX5_REPRESENTED_PORT_ESW_MGR : MLX5_PORT_ESW_MGR;
if (pid_v->id == esw_mgr_port) {
@@ -2087,6 +2087,7 @@ int16_t mlx5_flow_get_esw_manager_vport_id(struct rte_eth_dev *dev);
int mlx5_flow_get_item_vport_id(struct rte_eth_dev *dev,
const struct rte_flow_item *item,
uint16_t *vport_id,
+ bool *all_ports,
struct rte_flow_error *error);
#endif /* RTE_PMD_MLX5_FLOW_H_ */
@@ -5245,6 +5245,8 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,
struct mlx5_flow_meter_info *fm;
struct mlx5_flow_meter_policy *mtr_policy;
struct mlx5_flow_mtr_mng *mtrmng = priv->sh->mtrmng;
+ uint16_t flow_src_port = priv->representor_id;
+ bool all_ports = false;
if (!am)
return rte_flow_error_set(error, EINVAL,
@@ -5307,27 +5309,34 @@ mlx5_flow_validate_action_meter(struct rte_eth_dev *dev,
"Flow attributes domain "
"have a conflict with current "
"meter domain attributes");
- if (attr->transfer && mtr_policy->dev) {
- /**
- * When policy has fate action of port_id,
- * the flow should have the same src port as policy.
- */
- struct mlx5_priv *policy_port_priv =
- mtr_policy->dev->data->dev_private;
- uint16_t flow_src_port = priv->representor_id;
-
- if (port_id_item) {
- if (mlx5_flow_get_item_vport_id(dev, port_id_item,
- &flow_src_port, error))
- return -rte_errno;
+ if (port_id_item) {
+ if (mlx5_flow_get_item_vport_id(dev, port_id_item, &flow_src_port,
+ &all_ports, error))
+ return -rte_errno;
+ }
+ if (attr->transfer) {
+ if (mtr_policy->dev) {
+ /**
+ * When policy has fate action of port_id,
+ * the flow should have the same src port as policy.
+ */
+ struct mlx5_priv *policy_port_priv =
+ mtr_policy->dev->data->dev_private;
+
+ if (all_ports || flow_src_port != policy_port_priv->representor_id)
+ return rte_flow_error_set(error,
+ rte_errno,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ NULL,
+ "Flow and meter policy "
+ "have different src port.");
}
- if (flow_src_port != policy_port_priv->representor_id)
- return rte_flow_error_set(error,
- rte_errno,
- RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
- NULL,
- "Flow and meter policy "
- "have different src port.");
+ /* When flow matching all src ports, meter should not have drop count. */
+ if (all_ports && (fm->drop_cnt || mtr_policy->hierarchy_drop_cnt))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC, NULL,
+ "Meter drop count not supported "
+ "when matching all ports.");
} else if (mtr_policy->is_rss) {
struct mlx5_flow_meter_policy *fp;
struct mlx5_meter_policy_action_container *acg;
@@ -16251,6 +16260,8 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
mtr_policy->dev = next_policy->dev;
if (next_policy->mark)
mtr_policy->mark = 1;
+ if (next_fm->drop_cnt || next_policy->hierarchy_drop_cnt)
+ mtr_policy->hierarchy_drop_cnt = 1;
action_flags |=
MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY;
break;