- yellow: NULL or END.
- RED: DROP / END.
- The only supported meter policy actions:
- - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK and SET_TAG.
- - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK and SET_TAG.
+ - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK, METER and SET_TAG.
+ - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK, METER and SET_TAG.
- RED: must be DROP.
- Policy actions of RSS for green and yellow should have the same configuration except queues.
- Policy with RSS/queue action is not supported when ``dv_xmeta_en`` enabled.
+ - If green action is METER, yellow action must be the same METER action or NULL.
- 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.
- Integrity:
NULL,
"Multiple fate actions not supported.");
*hierarchy_domain = 0;
+ fm = mlx5_flow_meter_find(priv, meter_id, NULL);
while (true) {
- fm = mlx5_flow_meter_find(priv, meter_id, NULL);
if (!fm)
return -rte_mtr_error_set(error, EINVAL,
RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
return -rte_mtr_error_set(error, EINVAL,
RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
"Non termination meter not supported in hierarchy.");
+ if (!fm->shared)
+ return -rte_mtr_error_set(error, EINVAL,
+ RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
+ "Only shared meter supported in hierarchy.");
policy = mlx5_flow_meter_policy_find(dev, fm->policy_id, NULL);
MLX5_ASSERT(policy);
/**
*is_rss = policy->is_rss;
break;
}
- meter_id = policy->act_cnt[RTE_COLOR_GREEN].next_mtr_id;
+ rte_spinlock_lock(&policy->sl);
+ fm = mlx5_flow_meter_hierarchy_next_meter(priv, policy, NULL);
+ rte_spinlock_unlock(&policy->sl);
if (++cnt >= MLX5_MTR_CHAIN_MAX_NUM)
return -rte_mtr_error_set(error, EINVAL,
RTE_MTR_ERROR_TYPE_METER_POLICY, NULL,
uint8_t def_domain = MLX5_MTR_ALL_DOMAIN_BIT;
uint8_t hierarchy_domain = 0;
const struct rte_flow_action_meter *mtr;
+ const struct rte_flow_action_meter *next_mtr = NULL;
bool def_green = false;
bool def_yellow = false;
const struct rte_flow_action_rss *rss_color[RTE_COLORS] = {NULL};
++actions_n;
action_flags[i] |= MLX5_FLOW_ACTION_JUMP;
break;
- /*
- * Only the last meter in the hierarchy will support
- * the YELLOW color steering. Then in the meter policy
- * actions list, there should be no other meter inside.
- */
case RTE_FLOW_ACTION_TYPE_METER:
- if (i != RTE_COLOR_GREEN)
- return -rte_mtr_error_set(error,
- ENOTSUP,
- RTE_MTR_ERROR_TYPE_METER_POLICY,
- NULL,
- "Meter hierarchy only supports GREEN color.");
- if (*policy_mode != MLX5_MTR_POLICY_MODE_OG)
- return -rte_mtr_error_set(error,
- ENOTSUP,
- RTE_MTR_ERROR_TYPE_METER_POLICY,
- NULL,
- "No yellow policy should be provided in meter hierarchy.");
mtr = act->conf;
+ if (next_mtr && next_mtr->mtr_id != mtr->mtr_id)
+ return -rte_mtr_error_set(error, ENOTSUP,
+ RTE_MTR_ERROR_TYPE_METER_POLICY, NULL,
+ "Green and Yellow must use the same meter.");
ret = flow_dv_validate_policy_mtr_hierarchy(dev,
mtr->mtr_id,
action_flags[i],
++actions_n;
action_flags[i] |=
MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY;
+ next_mtr = mtr;
break;
default:
return -rte_mtr_error_set(error, ENOTSUP,
}
}
}
+ if (next_mtr && *policy_mode == MLX5_MTR_POLICY_MODE_ALL) {
+ if (!(action_flags[RTE_COLOR_GREEN] & action_flags[RTE_COLOR_YELLOW] &
+ MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY))
+ return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_POLICY,
+ NULL,
+ "Meter hierarchy supports meter action only.");
+ }
/* 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]))