* Split action list having QUEUE/RSS for metadata register copy. * * Once Q/RSS action is detected in user's action list, the flow action * should be split in order to copy metadata registers, which will happen in * RX_CP_TBL like, * - CQE->flow_tag := reg_c[1] (MARK) * - CQE->flow_table_metadata (reg_b) := reg_c[0] (META) * The Q/RSS action will be performed on RX_ACT_TBL after passing
| 6080 | * error/rte_error are set. |
| 6081 | */ |
| 6082 | static uint32_t |
| 6083 | flow_mreg_split_qrss_prep(struct rte_eth_dev *dev, |
| 6084 | struct rte_flow_action *split_actions, |
| 6085 | const struct rte_flow_action *actions, |
| 6086 | const struct rte_flow_action *qrss, |
| 6087 | int actions_n, int mtr_sfx, |
| 6088 | struct rte_flow_error *error) |
| 6089 | { |
| 6090 | struct mlx5_priv *priv = dev->data->dev_private; |
| 6091 | struct mlx5_rte_flow_action_set_tag *set_tag; |
| 6092 | struct rte_flow_action_jump *jump; |
| 6093 | const int qrss_idx = qrss - actions; |
| 6094 | uint32_t flow_id = 0; |
| 6095 | int ret = 0; |
| 6096 | |
| 6097 | /* |
| 6098 | * Given actions will be split |
| 6099 | * - Replace QUEUE/RSS action with SET_TAG to set flow ID. |
| 6100 | * - Add jump to mreg CP_TBL. |
| 6101 | * As a result, there will be one more action. |
| 6102 | */ |
| 6103 | memcpy(split_actions, actions, sizeof(*split_actions) * actions_n); |
| 6104 | /* Count MLX5_RTE_FLOW_ACTION_TYPE_TAG. */ |
| 6105 | ++actions_n; |
| 6106 | set_tag = (void *)(split_actions + actions_n); |
| 6107 | /* |
| 6108 | * If we are not the meter suffix flow, add the tag action. |
| 6109 | * Since meter suffix flow already has the tag added. |
| 6110 | */ |
| 6111 | if (!mtr_sfx) { |
| 6112 | /* |
| 6113 | * Allocate the new subflow ID. This one is unique within |
| 6114 | * device and not shared with representors. Otherwise, |
| 6115 | * we would have to resolve multi-thread access synch |
| 6116 | * issue. Each flow on the shared device is appended |
| 6117 | * with source vport identifier, so the resulting |
| 6118 | * flows will be unique in the shared (by master and |
| 6119 | * representors) domain even if they have coinciding |
| 6120 | * IDs. |
| 6121 | */ |
| 6122 | mlx5_ipool_malloc(priv->sh->ipool |
| 6123 | [MLX5_IPOOL_RSS_EXPANTION_FLOW_ID], &flow_id); |
| 6124 | if (!flow_id) |
| 6125 | return rte_flow_error_set(error, ENOMEM, |
| 6126 | RTE_FLOW_ERROR_TYPE_ACTION, |
| 6127 | NULL, "can't allocate id " |
| 6128 | "for split Q/RSS subflow"); |
| 6129 | /* Internal SET_TAG action to set flow ID. */ |
| 6130 | *set_tag = (struct mlx5_rte_flow_action_set_tag){ |
| 6131 | .data = flow_id, |
| 6132 | }; |
| 6133 | ret = mlx5_flow_get_reg_id(dev, MLX5_COPY_MARK, 0, error); |
| 6134 | if (ret < 0) |
| 6135 | return ret; |
| 6136 | set_tag->id = ret; |
| 6137 | /* Construct new actions array. */ |
| 6138 | /* Replace QUEUE/RSS action. */ |
| 6139 | split_actions[qrss_idx] = (struct rte_flow_action){ |
no test coverage detected