From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D45DCA0564 for ; Fri, 28 Feb 2020 04:34:12 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AAE6C1BFE3; Fri, 28 Feb 2020 04:34:12 +0100 (CET) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id B865D1BFCD for ; Fri, 28 Feb 2020 04:34:11 +0100 (CET) From: Suanming Mou To: luca.boccassi@gmail.com Cc: stable@dpdk.org, Matan Azrad Date: Fri, 28 Feb 2020 11:33:55 +0800 Message-Id: <1582860835-282594-12-git-send-email-suanmingm@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1582860835-282594-1-git-send-email-suanmingm@mellanox.com> References: <1582860835-282594-1-git-send-email-suanmingm@mellanox.com> Subject: [dpdk-stable] [PATCH 19.11 11/11] net/mlx5: fix metadata split with encap action X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" From: Matan Azrad [ upstream commit 35594a9b6f96ac6e45bbb851d9180c841c35cfff ] In order to move the mbuf metadata from the WQE to the FDB steering domain, the PMD add for each NIC TX flow a new action to copy the metadata register REG_A to REG_C_0. This copy action is considered as modify header action from HW perspective. The HW doesn't support to do modify header action after ant encapsulation action. The split metadata function wrongly added the copy action in the end of the original actions list, hence, NIC egress flow with encapsulation action failed when the PMD worked with dv_xmeta_en mode. Move the copy action to be before and back to back with the encapsulation action for the aforementioned case. Fixes: 71e254bc0294 ("net/mlx5: split Rx flows to provide metadata copy") Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow.c | 66 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 17ce2e3..1070b87 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2725,7 +2725,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, } /** - * Get QUEUE/RSS action from the action list. + * Get metadata split action information. * * @param[in] actions * Pointer to the list of actions. @@ -2734,18 +2734,38 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, * @param[out] qrss_type * Pointer to the action type to return. RTE_FLOW_ACTION_TYPE_END is returned * if no QUEUE/RSS is found. + * @param[out] encap_idx + * Pointer to the index of the encap action if exists, otherwise the last + * action index. * * @return * Total number of actions. */ static int -flow_parse_qrss_action(const struct rte_flow_action actions[], - const struct rte_flow_action **qrss) +flow_parse_metadata_split_actions_info(const struct rte_flow_action actions[], + const struct rte_flow_action **qrss, + int *encap_idx) { + const struct rte_flow_action_raw_encap *raw_encap; int actions_n = 0; + int raw_decap_idx = -1; + *encap_idx = -1; for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: + *encap_idx = actions_n; + break; + case RTE_FLOW_ACTION_TYPE_RAW_DECAP: + raw_decap_idx = actions_n; + break; + case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: + raw_encap = actions->conf; + if (raw_encap->size > MLX5_ENCAPSULATION_DECISION_SIZE) + *encap_idx = raw_decap_idx != -1 ? + raw_decap_idx : actions_n; + break; case RTE_FLOW_ACTION_TYPE_QUEUE: case RTE_FLOW_ACTION_TYPE_RSS: *qrss = actions; @@ -2755,6 +2775,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, } actions_n++; } + if (*encap_idx == -1) + *encap_idx = actions_n; /* Count RTE_FLOW_ACTION_TYPE_END. */ return actions_n + 1; } @@ -3719,6 +3741,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, * Number of actions in the list. * @param[out] error * Perform verbose error reporting if not NULL. + * @param[in] encap_idx + * The encap action inndex. * * @return * 0 on success, negative value otherwise @@ -3727,7 +3751,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, flow_mreg_tx_copy_prep(struct rte_eth_dev *dev, struct rte_flow_action *ext_actions, const struct rte_flow_action *actions, - int actions_n, struct rte_flow_error *error) + int actions_n, struct rte_flow_error *error, + int encap_idx) { struct mlx5_flow_action_copy_mreg *cp_mreg = (struct mlx5_flow_action_copy_mreg *) @@ -3742,15 +3767,24 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, if (ret < 0) return ret; cp_mreg->src = ret; - memcpy(ext_actions, actions, - sizeof(*ext_actions) * actions_n); - ext_actions[actions_n - 1] = (struct rte_flow_action){ - .type = MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG, - .conf = cp_mreg, - }; - ext_actions[actions_n] = (struct rte_flow_action){ - .type = RTE_FLOW_ACTION_TYPE_END, - }; + if (encap_idx != 0) + memcpy(ext_actions, actions, sizeof(*ext_actions) * encap_idx); + if (encap_idx == actions_n - 1) { + ext_actions[actions_n - 1] = (struct rte_flow_action){ + .type = MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG, + .conf = cp_mreg, + }; + ext_actions[actions_n] = (struct rte_flow_action){ + .type = RTE_FLOW_ACTION_TYPE_END, + }; + } else { + ext_actions[encap_idx] = (struct rte_flow_action){ + .type = MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG, + .conf = cp_mreg, + }; + memcpy(ext_actions + encap_idx + 1, actions + encap_idx, + sizeof(*ext_actions) * (actions_n - encap_idx)); + } return 0; } @@ -3801,6 +3835,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, int mtr_sfx = 0; size_t act_size; int actions_n; + int encap_idx; int ret; /* Check whether extensive metadata feature is engaged. */ @@ -3810,7 +3845,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, return flow_create_split_inner(dev, flow, NULL, prefix_layers, attr, items, actions, external, error); - actions_n = flow_parse_qrss_action(actions, &qrss); + actions_n = flow_parse_metadata_split_actions_info(actions, &qrss, + &encap_idx); if (qrss) { /* Exclude hairpin flows from splitting. */ if (qrss->type == RTE_FLOW_ACTION_TYPE_QUEUE) { @@ -3885,7 +3921,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, "metadata flow"); /* Create the action list appended with copy register. */ ret = flow_mreg_tx_copy_prep(dev, ext_actions, actions, - actions_n, error); + actions_n, error, encap_idx); if (ret < 0) goto exit; } -- 1.8.3.1