}
static int
-mlx5_flow_item_field_width(enum rte_flow_field_id field)
+mlx5_flow_item_field_width(struct mlx5_dev_config *config,
+ enum rte_flow_field_id field)
{
switch (field) {
case RTE_FLOW_FIELD_START:
case RTE_FLOW_FIELD_MARK:
return 24;
case RTE_FLOW_FIELD_META:
- return 32;
+ if (config->dv_xmeta_en == MLX5_XMETA_MODE_META16)
+ return 16;
+ else if (config->dv_xmeta_en == MLX5_XMETA_MODE_META32)
+ return 32;
+ else
+ return 0;
case RTE_FLOW_FIELD_POINTER:
case RTE_FLOW_FIELD_VALUE:
return 64;
const struct rte_flow_attr *attr,
struct rte_flow_error *error)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_dev_config *config = &priv->config;
uint32_t idx = 0;
uint64_t val = 0;
switch (data->field) {
break;
case RTE_FLOW_FIELD_META:
{
+ unsigned int xmeta = config->dv_xmeta_en;
int reg = flow_dv_get_metadata_reg(dev, attr, error);
if (reg < 0)
return;
MLX5_ASSERT(reg != REG_NON);
MLX5_ASSERT((unsigned int)reg < RTE_DIM(reg_to_field));
- info[idx] = (struct field_modify_info){4, 0,
- reg_to_field[reg]};
- if (mask)
- mask[idx] =
- rte_cpu_to_be_32(0xffffffff >>
- (32 - width));
+ if (xmeta == MLX5_XMETA_MODE_META16) {
+ info[idx] = (struct field_modify_info){2, 0,
+ reg_to_field[reg]};
+ if (mask)
+ mask[idx] = rte_cpu_to_be_16(0xffff >>
+ (16 - width));
+ } else if (xmeta == MLX5_XMETA_MODE_META32) {
+ info[idx] = (struct field_modify_info){4, 0,
+ reg_to_field[reg]};
+ if (mask)
+ mask[idx] =
+ rte_cpu_to_be_32(0xffffffff >>
+ (32 - width));
+ } else {
+ MLX5_ASSERT(false);
+ }
}
break;
case RTE_FLOW_FIELD_POINTER:
const struct rte_flow_attr *attr,
struct rte_flow_error *error)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_dev_config *config = &priv->config;
const struct rte_flow_action_modify_field *conf =
(const struct rte_flow_action_modify_field *)(action->conf);
struct rte_flow_item item;
uint32_t mask[MLX5_ACT_MAX_MOD_FIELDS] = {0, 0, 0, 0, 0};
uint32_t value[MLX5_ACT_MAX_MOD_FIELDS] = {0, 0, 0, 0, 0};
uint32_t type;
- uint32_t dst_width = mlx5_flow_item_field_width(conf->dst.field);
+ uint32_t dst_width = mlx5_flow_item_field_width(config,
+ conf->dst.field);
if (conf->src.field == RTE_FLOW_FIELD_POINTER ||
conf->src.field == RTE_FLOW_FIELD_VALUE) {
struct mlx5_dev_config *config = &priv->config;
const struct rte_flow_action_modify_field *action_modify_field =
action->conf;
- uint32_t dst_width =
- mlx5_flow_item_field_width(action_modify_field->dst.field);
- uint32_t src_width =
- mlx5_flow_item_field_width(action_modify_field->src.field);
+ uint32_t dst_width = mlx5_flow_item_field_width(config,
+ action_modify_field->dst.field);
+ uint32_t src_width = mlx5_flow_item_field_width(config,
+ action_modify_field->src.field);
ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
if (ret)
MLX5_ASSERT(dev_flow.dv.tag_resource);
act_cnt->rix_mark =
dev_flow.handle->dvh.rix_tag;
- if (action_flags & MLX5_FLOW_ACTION_QUEUE) {
- dev_flow.handle->rix_hrxq =
- mtr_policy->sub_policys[domain][0]->rix_hrxq[i];
- flow_drv_rxq_flags_set(dev,
- dev_flow.handle);
- }
action_flags |= MLX5_FLOW_ACTION_MARK;
break;
}
"set tag action");
act_cnt->modify_hdr =
dev_flow.handle->dvh.modify_hdr;
- if (action_flags & MLX5_FLOW_ACTION_QUEUE) {
- dev_flow.handle->rix_hrxq =
- mtr_policy->sub_policys[domain][0]->rix_hrxq[i];
- flow_drv_rxq_flags_set(dev,
- dev_flow.handle);
- }
action_flags |= MLX5_FLOW_ACTION_SET_TAG;
break;
}
}
case RTE_FLOW_ACTION_TYPE_QUEUE:
{
- struct mlx5_hrxq *hrxq;
- uint32_t hrxq_idx;
- struct mlx5_flow_rss_desc rss_desc;
- struct mlx5_flow_meter_sub_policy *sub_policy =
- mtr_policy->sub_policys[domain][0];
-
if (i >= MLX5_MTR_RTE_COLORS)
return -rte_mtr_error_set(error,
ENOTSUP,
RTE_MTR_ERROR_TYPE_METER_POLICY,
NULL, "cannot create policy "
"fate queue for this color");
- memset(&rss_desc, 0,
- sizeof(struct mlx5_flow_rss_desc));
- rss_desc.queue_num = 1;
- rss_desc.const_q = act->conf;
- hrxq = flow_dv_hrxq_prepare(dev, &dev_flow,
- &rss_desc, &hrxq_idx);
- if (!hrxq)
- return -rte_mtr_error_set(error,
- ENOTSUP,
- RTE_MTR_ERROR_TYPE_METER_POLICY,
- NULL,
- "cannot create policy fate queue");
- sub_policy->rix_hrxq[i] = hrxq_idx;
+ act_cnt->queue =
+ ((const struct rte_flow_action_queue *)
+ (act->conf))->index;
act_cnt->fate_action =
MLX5_FLOW_FATE_QUEUE;
dev_flow.handle->fate_action =
MLX5_FLOW_FATE_QUEUE;
- if (action_flags & MLX5_FLOW_ACTION_MARK ||
- action_flags & MLX5_FLOW_ACTION_SET_TAG) {
- dev_flow.handle->rix_hrxq = hrxq_idx;
- flow_drv_rxq_flags_set(dev,
- dev_flow.handle);
- }
+ mtr_policy->is_queue = 1;
action_flags |= MLX5_FLOW_ACTION_QUEUE;
break;
}
return NULL;
}
+
+/**
+ * Destroy the sub policy table with RX queue.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[in] mtr_policy
+ * Pointer to meter policy table.
+ */
+static void
+flow_dv_destroy_sub_policy_with_rxq(struct rte_eth_dev *dev,
+ struct mlx5_flow_meter_policy *mtr_policy)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_flow_meter_sub_policy *sub_policy = NULL;
+ uint32_t domain = MLX5_MTR_DOMAIN_INGRESS;
+ uint32_t i, j;
+ uint16_t sub_policy_num, new_policy_num;
+
+ rte_spinlock_lock(&mtr_policy->sl);
+ for (i = 0; i < MLX5_MTR_RTE_COLORS; i++) {
+ switch (mtr_policy->act_cnt[i].fate_action) {
+ case MLX5_FLOW_FATE_SHARED_RSS:
+ sub_policy_num = (mtr_policy->sub_policy_num >>
+ (MLX5_MTR_SUB_POLICY_NUM_SHIFT * domain)) &
+ MLX5_MTR_SUB_POLICY_NUM_MASK;
+ new_policy_num = sub_policy_num;
+ for (j = 0; j < sub_policy_num; j++) {
+ sub_policy =
+ mtr_policy->sub_policys[domain][j];
+ if (sub_policy) {
+ __flow_dv_destroy_sub_policy_rules(dev,
+ sub_policy);
+ if (sub_policy !=
+ mtr_policy->sub_policys[domain][0]) {
+ mtr_policy->sub_policys[domain][j] =
+ NULL;
+ mlx5_ipool_free
+ (priv->sh->ipool[MLX5_IPOOL_MTR_POLICY],
+ sub_policy->idx);
+ new_policy_num--;
+ }
+ }
+ }
+ if (new_policy_num != sub_policy_num) {
+ mtr_policy->sub_policy_num &=
+ ~(MLX5_MTR_SUB_POLICY_NUM_MASK <<
+ (MLX5_MTR_SUB_POLICY_NUM_SHIFT * domain));
+ mtr_policy->sub_policy_num |=
+ (new_policy_num &
+ MLX5_MTR_SUB_POLICY_NUM_MASK) <<
+ (MLX5_MTR_SUB_POLICY_NUM_SHIFT * domain);
+ }
+ break;
+ case MLX5_FLOW_FATE_QUEUE:
+ sub_policy = mtr_policy->sub_policys[domain][0];
+ __flow_dv_destroy_sub_policy_rules(dev,
+ sub_policy);
+ break;
+ default:
+ /*Other actions without queue and do nothing*/
+ break;
+ }
+ }
+ rte_spinlock_unlock(&mtr_policy->sl);
+}
+
/**
* Validate the batch counter support in root table.
*
.size = sizeof(value.buf),
};
struct mlx5dv_flow_matcher_attr dv_attr = {
- .type = IBV_FLOW_ATTR_NORMAL,
+ .type = IBV_FLOW_ATTR_NORMAL | IBV_FLOW_ATTR_FLAGS_EGRESS,
.priority = 0,
.match_criteria_enable = 0,
.match_mask = (void *)&mask,
void *flow = NULL;
int ret = -1;
- tbl = flow_dv_tbl_resource_get(dev, 0, 0, 0, false, NULL,
+ tbl = flow_dv_tbl_resource_get(dev, 0, 1, 0, false, NULL,
0, 0, 0, NULL);
if (!tbl)
goto err;
&actions[0]);
if (ret)
goto err;
- actions[1] = sh->dr_drop_action ? sh->dr_drop_action :
- priv->drop_queue.hrxq->action;
dv_attr.match_criteria_enable = flow_dv_matcher_enable(mask.buf);
ret = mlx5_flow_os_create_flow_matcher(sh->ctx, &dv_attr, tbl->obj,
&matcher);
if (ret)
goto err;
- ret = mlx5_flow_os_create_flow(matcher, (void *)&value, 2,
+ ret = mlx5_flow_os_create_flow(matcher, (void *)&value, 1,
actions, &flow);
err:
/*
.create_def_policy = flow_dv_create_def_policy,
.destroy_def_policy = flow_dv_destroy_def_policy,
.meter_sub_policy_rss_prepare = flow_dv_meter_sub_policy_rss_prepare,
+ .destroy_sub_policy_with_rxq = flow_dv_destroy_sub_policy_with_rxq,
.counter_alloc = flow_dv_counter_allocate,
.counter_free = flow_dv_counter_free,
.counter_query = flow_dv_counter_query,