@@ -401,9 +401,6 @@ struct mlx5_hw_q_job {
const void *action; /* Indirect action attached to the job. */
};
void *user_data; /* Job user data. */
- uint8_t *encap_data; /* Encap data. */
- uint8_t *push_data; /* IPv6 routing push data. */
- struct mlx5_modification_cmd *mhdr_cmd;
struct rte_flow_item *items;
union {
struct {
@@ -1306,6 +1306,16 @@ typedef int
#define MLX5_MHDR_MAX_CMD ((MLX5_MAX_MODIFY_NUM) * 2 + 1)
+/** Container for flow action data constructed during flow rule creation. */
+struct mlx5_flow_hw_action_params {
+ /** Array of constructed modify header commands. */
+ struct mlx5_modification_cmd mhdr_cmd[MLX5_MHDR_MAX_CMD];
+ /** Constructed encap/decap data buffer. */
+ uint8_t encap_data[MLX5_ENCAP_MAX_LEN];
+ /** Constructed IPv6 routing data buffer. */
+ uint8_t ipv6_push_data[MLX5_PUSH_MAX_LEN];
+};
+
/* rte flow action translate to DR action struct. */
struct mlx5_action_construct_data {
LIST_ENTRY(mlx5_action_construct_data) next;
@@ -158,7 +158,7 @@ static int flow_hw_translate_group(struct rte_eth_dev *dev,
struct rte_flow_error *error);
static __rte_always_inline int
flow_hw_set_vlan_vid_construct(struct rte_eth_dev *dev,
- struct mlx5_hw_q_job *job,
+ struct mlx5_modification_cmd *mhdr_cmd,
struct mlx5_action_construct_data *act_data,
const struct mlx5_hw_actions *hw_acts,
const struct rte_flow_action *action);
@@ -2812,7 +2812,7 @@ flow_hw_mhdr_cmd_is_nop(const struct mlx5_modification_cmd *cmd)
* 0 on success, negative value otherwise and rte_errno is set.
*/
static __rte_always_inline int
-flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
+flow_hw_modify_field_construct(struct mlx5_modification_cmd *mhdr_cmd,
struct mlx5_action_construct_data *act_data,
const struct mlx5_hw_actions *hw_acts,
const struct rte_flow_action *action)
@@ -2871,7 +2871,7 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
if (i >= act_data->modify_header.mhdr_cmds_end)
return -1;
- if (flow_hw_mhdr_cmd_is_nop(&job->mhdr_cmd[i])) {
+ if (flow_hw_mhdr_cmd_is_nop(&mhdr_cmd[i])) {
++i;
continue;
}
@@ -2891,7 +2891,7 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
mhdr_action->dst.field == RTE_FLOW_FIELD_IPV6_DSCP)
data <<= MLX5_IPV6_HDR_DSCP_SHIFT;
data = (data & mask) >> off_b;
- job->mhdr_cmd[i++].data1 = rte_cpu_to_be_32(data);
+ mhdr_cmd[i++].data1 = rte_cpu_to_be_32(data);
++field;
} while (field->size);
return 0;
@@ -2905,8 +2905,10 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
*
* @param[in] dev
* Pointer to the rte_eth_dev structure.
- * @param[in] job
- * Pointer to job descriptor.
+ * @param[in] flow
+ * Pointer to flow structure.
+ * @param[in] ap
+ * Pointer to container for temporarily constructed actions' parameters.
* @param[in] hw_acts
* Pointer to translated actions from template.
* @param[in] it_idx
@@ -2923,7 +2925,8 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
*/
static __rte_always_inline int
flow_hw_actions_construct(struct rte_eth_dev *dev,
- struct mlx5_hw_q_job *job,
+ struct rte_flow_hw *flow,
+ struct mlx5_flow_hw_action_params *ap,
const struct mlx5_hw_action_template *hw_at,
const uint8_t it_idx,
const struct rte_flow_action actions[],
@@ -2933,7 +2936,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_aso_mtr_pool *pool = priv->hws_mpool;
- struct rte_flow_template_table *table = job->flow->table;
+ struct rte_flow_template_table *table = flow->table;
struct mlx5_action_construct_data *act_data;
const struct rte_flow_actions_template *at = hw_at->action_template;
const struct mlx5_hw_actions *hw_acts = &hw_at->acts;
@@ -2945,8 +2948,6 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
const struct rte_flow_action_meter *meter = NULL;
const struct rte_flow_action_age *age = NULL;
const struct rte_flow_action_nat64 *nat64_c = NULL;
- uint8_t *buf = job->encap_data;
- uint8_t *push_buf = job->push_data;
struct rte_flow_attr attr = {
.ingress = 1,
};
@@ -2971,17 +2972,17 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
if (hw_acts->mhdr && hw_acts->mhdr->mhdr_cmds_num > 0 && !hw_acts->mhdr->shared) {
uint16_t pos = hw_acts->mhdr->pos;
- mp_segment = mlx5_multi_pattern_segment_find(table, job->flow->res_idx);
+ mp_segment = mlx5_multi_pattern_segment_find(table, flow->res_idx);
if (!mp_segment || !mp_segment->mhdr_action)
return -1;
rule_acts[pos].action = mp_segment->mhdr_action;
/* offset is relative to DR action */
rule_acts[pos].modify_header.offset =
- job->flow->res_idx - mp_segment->head_index;
+ flow->res_idx - mp_segment->head_index;
rule_acts[pos].modify_header.data =
- (uint8_t *)job->mhdr_cmd;
- rte_memcpy(job->mhdr_cmd, hw_acts->mhdr->mhdr_cmds,
- sizeof(*job->mhdr_cmd) * hw_acts->mhdr->mhdr_cmds_num);
+ (uint8_t *)ap->mhdr_cmd;
+ rte_memcpy(ap->mhdr_cmd, hw_acts->mhdr->mhdr_cmds,
+ sizeof(*ap->mhdr_cmd) * hw_acts->mhdr->mhdr_cmds_num);
}
LIST_FOREACH(act_data, &hw_acts->act_list, next) {
uint32_t jump_group;
@@ -3014,7 +3015,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_INDIRECT:
if (flow_hw_shared_action_construct
(dev, queue, action, table, it_idx,
- at->action_flags, job->flow,
+ at->action_flags, flow,
&rule_acts[act_data->action_dst]))
return -1;
break;
@@ -3039,8 +3040,8 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
return -1;
rule_acts[act_data->action_dst].action =
(!!attr.group) ? jump->hws_action : jump->root_action;
- job->flow->jump = jump;
- job->flow->fate_type = MLX5_FLOW_FATE_JUMP;
+ flow->jump = jump;
+ flow->fate_type = MLX5_FLOW_FATE_JUMP;
break;
case RTE_FLOW_ACTION_TYPE_RSS:
case RTE_FLOW_ACTION_TYPE_QUEUE:
@@ -3050,8 +3051,8 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
if (!hrxq)
return -1;
rule_acts[act_data->action_dst].action = hrxq->action;
- job->flow->hrxq = hrxq;
- job->flow->fate_type = MLX5_FLOW_FATE_QUEUE;
+ flow->hrxq = hrxq;
+ flow->fate_type = MLX5_FLOW_FATE_QUEUE;
break;
case MLX5_RTE_FLOW_ACTION_TYPE_RSS:
item_flags = table->its[it_idx]->item_flags;
@@ -3063,38 +3064,37 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
enc_item = ((const struct rte_flow_action_vxlan_encap *)
action->conf)->definition;
- if (flow_dv_convert_encap_data(enc_item, buf, &encap_len, NULL))
+ if (flow_dv_convert_encap_data(enc_item, ap->encap_data, &encap_len, NULL))
return -1;
break;
case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
enc_item = ((const struct rte_flow_action_nvgre_encap *)
action->conf)->definition;
- if (flow_dv_convert_encap_data(enc_item, buf, &encap_len, NULL))
+ if (flow_dv_convert_encap_data(enc_item, ap->encap_data, &encap_len, NULL))
return -1;
break;
case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
raw_encap_data =
(const struct rte_flow_action_raw_encap *)
action->conf;
- rte_memcpy((void *)buf, raw_encap_data->data, act_data->encap.len);
- MLX5_ASSERT(raw_encap_data->size ==
- act_data->encap.len);
+ rte_memcpy(ap->encap_data, raw_encap_data->data, act_data->encap.len);
+ MLX5_ASSERT(raw_encap_data->size == act_data->encap.len);
break;
case RTE_FLOW_ACTION_TYPE_IPV6_EXT_PUSH:
ipv6_push =
(const struct rte_flow_action_ipv6_ext_push *)action->conf;
- rte_memcpy((void *)push_buf, ipv6_push->data,
+ rte_memcpy(ap->ipv6_push_data, ipv6_push->data,
act_data->ipv6_ext.len);
MLX5_ASSERT(ipv6_push->size == act_data->ipv6_ext.len);
break;
case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD:
if (action->type == RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID)
- ret = flow_hw_set_vlan_vid_construct(dev, job,
+ ret = flow_hw_set_vlan_vid_construct(dev, ap->mhdr_cmd,
act_data,
hw_acts,
action);
else
- ret = flow_hw_modify_field_construct(job,
+ ret = flow_hw_modify_field_construct(ap->mhdr_cmd,
act_data,
hw_acts,
action);
@@ -3130,8 +3130,8 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
rule_acts[act_data->action_dst + 1].action =
(!!attr.group) ? jump->hws_action :
jump->root_action;
- job->flow->jump = jump;
- job->flow->fate_type = MLX5_FLOW_FATE_JUMP;
+ flow->jump = jump;
+ flow->fate_type = MLX5_FLOW_FATE_JUMP;
if (mlx5_aso_mtr_wait(priv->sh, MLX5_HW_INV_QUEUE, aso_mtr))
return -1;
break;
@@ -3145,11 +3145,11 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
*/
age_idx = mlx5_hws_age_action_create(priv, queue, 0,
age,
- job->flow->res_idx,
+ flow->res_idx,
error);
if (age_idx == 0)
return -rte_errno;
- job->flow->age_idx = age_idx;
+ flow->age_idx = age_idx;
if (at->action_flags & MLX5_FLOW_ACTION_INDIRECT_COUNT)
/*
* When AGE uses indirect counter, no need to
@@ -3172,7 +3172,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
);
if (ret != 0)
return ret;
- job->flow->cnt_id = cnt_id;
+ flow->cnt_id = cnt_id;
break;
case MLX5_RTE_FLOW_ACTION_TYPE_COUNT:
ret = mlx5_hws_cnt_pool_get_action_offset
@@ -3183,7 +3183,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
);
if (ret != 0)
return ret;
- job->flow->cnt_id = act_data->shared_counter.id;
+ flow->cnt_id = act_data->shared_counter.id;
break;
case RTE_FLOW_ACTION_TYPE_CONNTRACK:
ct_idx = MLX5_INDIRECT_ACTION_IDX_GET(action->conf);
@@ -3210,8 +3210,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
*/
ret = flow_hw_meter_mark_compile(dev,
act_data->action_dst, action,
- rule_acts, &job->flow->mtr_id,
- MLX5_HW_INV_QUEUE, error);
+ rule_acts, &flow->mtr_id, MLX5_HW_INV_QUEUE, error);
if (ret != 0)
return ret;
break;
@@ -3226,9 +3225,9 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
}
if (at->action_flags & MLX5_FLOW_ACTION_INDIRECT_COUNT) {
if (at->action_flags & MLX5_FLOW_ACTION_INDIRECT_AGE) {
- age_idx = job->flow->age_idx & MLX5_HWS_AGE_IDX_MASK;
+ age_idx = flow->age_idx & MLX5_HWS_AGE_IDX_MASK;
if (mlx5_hws_cnt_age_get(priv->hws_cpool,
- job->flow->cnt_id) != age_idx)
+ flow->cnt_id) != age_idx)
/*
* This is first use of this indirect counter
* for this indirect AGE, need to increase the
@@ -3240,7 +3239,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
* Update this indirect counter the indirect/direct AGE in which
* using it.
*/
- mlx5_hws_cnt_age_set(priv->hws_cpool, job->flow->cnt_id,
+ mlx5_hws_cnt_age_set(priv->hws_cpool, flow->cnt_id,
age_idx);
}
if (hw_acts->encap_decap && !hw_acts->encap_decap->shared) {
@@ -3250,21 +3249,21 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
if (ix < 0)
return -1;
if (!mp_segment)
- mp_segment = mlx5_multi_pattern_segment_find(table, job->flow->res_idx);
+ mp_segment = mlx5_multi_pattern_segment_find(table, flow->res_idx);
if (!mp_segment || !mp_segment->reformat_action[ix])
return -1;
ra->action = mp_segment->reformat_action[ix];
/* reformat offset is relative to selected DR action */
- ra->reformat.offset = job->flow->res_idx - mp_segment->head_index;
- ra->reformat.data = buf;
+ ra->reformat.offset = flow->res_idx - mp_segment->head_index;
+ ra->reformat.data = ap->encap_data;
}
if (hw_acts->push_remove && !hw_acts->push_remove->shared) {
rule_acts[hw_acts->push_remove_pos].ipv6_ext.offset =
- job->flow->res_idx - 1;
- rule_acts[hw_acts->push_remove_pos].ipv6_ext.header = push_buf;
+ flow->res_idx - 1;
+ rule_acts[hw_acts->push_remove_pos].ipv6_ext.header = ap->ipv6_push_data;
}
if (mlx5_hws_cnt_id_valid(hw_acts->cnt_id))
- job->flow->cnt_id = hw_acts->cnt_id;
+ flow->cnt_id = hw_acts->cnt_id;
return 0;
}
@@ -3364,6 +3363,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
.burst = attr->postpone,
};
struct mlx5dr_rule_action *rule_acts;
+ struct mlx5_flow_hw_action_params ap;
struct rte_flow_hw *flow = NULL;
struct mlx5_hw_q_job *job = NULL;
const struct rte_flow_item *rule_items;
@@ -3420,7 +3420,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
* No need to copy and contrust a new "actions" list based on the
* user's input, in order to save the cost.
*/
- if (flow_hw_actions_construct(dev, job,
+ if (flow_hw_actions_construct(dev, flow, &ap,
&table->ats[action_template_index],
pattern_template_index, actions,
rule_acts, queue, error)) {
@@ -3512,6 +3512,7 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
.burst = attr->postpone,
};
struct mlx5dr_rule_action *rule_acts;
+ struct mlx5_flow_hw_action_params ap;
struct rte_flow_hw *flow = NULL;
struct mlx5_hw_q_job *job = NULL;
uint32_t flow_idx = 0;
@@ -3564,7 +3565,7 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
* No need to copy and contrust a new "actions" list based on the
* user's input, in order to save the cost.
*/
- if (flow_hw_actions_construct(dev, job,
+ if (flow_hw_actions_construct(dev, flow, &ap,
&table->ats[action_template_index],
0, actions, rule_acts, queue, error)) {
rte_errno = EINVAL;
@@ -3646,6 +3647,7 @@ flow_hw_async_flow_update(struct rte_eth_dev *dev,
.burst = attr->postpone,
};
struct mlx5dr_rule_action *rule_acts;
+ struct mlx5_flow_hw_action_params ap;
struct rte_flow_hw *of = (struct rte_flow_hw *)flow;
struct rte_flow_hw *nf;
struct rte_flow_template_table *table = of->table;
@@ -3698,7 +3700,7 @@ flow_hw_async_flow_update(struct rte_eth_dev *dev,
* No need to copy and contrust a new "actions" list based on the
* user's input, in order to save the cost.
*/
- if (flow_hw_actions_construct(dev, job,
+ if (flow_hw_actions_construct(dev, nf, &ap,
&table->ats[action_template_index],
nf->mt_idx, actions,
rule_acts, queue, error)) {
@@ -6682,7 +6684,7 @@ flow_hw_set_vlan_vid(struct rte_eth_dev *dev,
static __rte_always_inline int
flow_hw_set_vlan_vid_construct(struct rte_eth_dev *dev,
- struct mlx5_hw_q_job *job,
+ struct mlx5_modification_cmd *mhdr_cmd,
struct mlx5_action_construct_data *act_data,
const struct mlx5_hw_actions *hw_acts,
const struct rte_flow_action *action)
@@ -6710,8 +6712,7 @@ flow_hw_set_vlan_vid_construct(struct rte_eth_dev *dev,
.conf = &conf
};
- return flow_hw_modify_field_construct(job, act_data, hw_acts,
- &modify_action);
+ return flow_hw_modify_field_construct(mhdr_cmd, act_data, hw_acts, &modify_action);
}
static int
@@ -10121,10 +10122,6 @@ flow_hw_configure(struct rte_eth_dev *dev,
}
mem_size += (sizeof(struct mlx5_hw_q_job *) +
sizeof(struct mlx5_hw_q_job) +
- sizeof(uint8_t) * MLX5_ENCAP_MAX_LEN +
- sizeof(uint8_t) * MLX5_PUSH_MAX_LEN +
- sizeof(struct mlx5_modification_cmd) *
- MLX5_MHDR_MAX_CMD +
sizeof(struct rte_flow_item) *
MLX5_HW_MAX_ITEMS +
sizeof(struct rte_flow_hw)) *
@@ -10137,8 +10134,6 @@ flow_hw_configure(struct rte_eth_dev *dev,
goto err;
}
for (i = 0; i < nb_q_updated; i++) {
- uint8_t *encap = NULL, *push = NULL;
- struct mlx5_modification_cmd *mhdr_cmd = NULL;
struct rte_flow_item *items = NULL;
struct rte_flow_hw *upd_flow = NULL;
@@ -10152,20 +10147,11 @@ flow_hw_configure(struct rte_eth_dev *dev,
&job[_queue_attr[i - 1]->size - 1].upd_flow[1];
job = (struct mlx5_hw_q_job *)
&priv->hw_q[i].job[_queue_attr[i]->size];
- mhdr_cmd = (struct mlx5_modification_cmd *)
- &job[_queue_attr[i]->size];
- encap = (uint8_t *)
- &mhdr_cmd[_queue_attr[i]->size * MLX5_MHDR_MAX_CMD];
- push = (uint8_t *)
- &encap[_queue_attr[i]->size * MLX5_ENCAP_MAX_LEN];
items = (struct rte_flow_item *)
- &push[_queue_attr[i]->size * MLX5_PUSH_MAX_LEN];
+ &job[_queue_attr[i]->size];
upd_flow = (struct rte_flow_hw *)
&items[_queue_attr[i]->size * MLX5_HW_MAX_ITEMS];
for (j = 0; j < _queue_attr[i]->size; j++) {
- job[j].mhdr_cmd = &mhdr_cmd[j * MLX5_MHDR_MAX_CMD];
- job[j].encap_data = &encap[j * MLX5_ENCAP_MAX_LEN];
- job[j].push_data = &push[j * MLX5_PUSH_MAX_LEN];
job[j].items = &items[j * MLX5_HW_MAX_ITEMS];
job[j].upd_flow = &upd_flow[j];
priv->hw_q[i].job[j] = &job[j];