From patchwork Tue Dec 15 07:49:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawei Wang X-Patchwork-Id: 85195 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1DA55A09E9; Tue, 15 Dec 2020 08:49:57 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 606D9C9BA; Tue, 15 Dec 2020 08:49:55 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id EE11DC9B8 for ; Tue, 15 Dec 2020 08:49:53 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jiaweiw@nvidia.com) with SMTP; 15 Dec 2020 09:49:52 +0200 Received: from nvidia.com (gen-l-vrt-281.mtl.labs.mlnx [10.237.44.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BF7nqhO023341; Tue, 15 Dec 2020 09:49:52 +0200 From: Jiawei Wang To: viacheslavo@nvidia.com, matan@nvidia.com, orika@nvidia.com Cc: dev@dpdk.org, rasland@nvidia.com Date: Tue, 15 Dec 2020 09:49:48 +0200 Message-Id: <1608018591-97942-2-git-send-email-jiaweiw@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> References: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> Subject: [dpdk-dev] [RFC 1/4] common/mlx5: query register c preserve capability via DevX X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Update function mlx5_devx_cmd_query_hca_attr() to add the reg_c_preserve bit query. The stored metadata in register C may be lost in NIC Tx and FDB egress while doing one one of the following operations: - packet encapsulation. - packet mirroring (multiple processing paths). - packet sampling (using Flow Sampler). If the reg_c_preserve bit is set to 1, then the above limitation is obsolete, the all metadata registers Cx preserve their values even through the operations mentioned above. Signed-off-by: Jiawei Wang --- drivers/common/mlx5/mlx5_devx_cmds.c | 2 ++ drivers/common/mlx5/mlx5_devx_cmds.h | 1 + drivers/common/mlx5/mlx5_prm.h | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 9c1d188..084368a 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -720,6 +720,8 @@ struct mlx5_devx_obj * attr->flow_hit_aso = !!(MLX5_GET64(cmd_hca_cap, hcattr, general_obj_types) & MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO); + attr->reg_c_preserve = + MLX5_GET(cmd_hca_cap, hcattr, reg_c_preserve); if (attr->qos.sup) { MLX5_SET(query_hca_cap_in, in, op_mod, MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 726e9f5..177320e 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -113,6 +113,7 @@ struct mlx5_hca_attr { uint32_t scatter_fcs_w_decap_disable:1; uint32_t flow_hit_aso:1; /* General obj type FLOW_HIT_ASO supported. */ uint32_t regex:1; + uint32_t reg_c_preserve:1; uint32_t regexp_num_of_engines; uint32_t log_max_ft_sampler_num:8; struct mlx5_hca_qos_attr qos; diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 58d1804..c62c3a6 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -1113,7 +1113,9 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 regexp[0x1]; u8 reserved_at_a1[0x3]; u8 regexp_num_of_engines[0x4]; - u8 reserved_at_a8[0x3]; + u8 reserved_at_a8[0x1]; + u8 reg_c_preserve[0x1]; + u8 reserved_at_aa[0x1]; u8 log_max_srq[0x5]; u8 reserved_at_b0[0x3]; u8 regexp_log_crspace_size[0x5]; From patchwork Tue Dec 15 07:49:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawei Wang X-Patchwork-Id: 85196 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id EC032A09E9; Tue, 15 Dec 2020 08:50:12 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 52A62C9CA; Tue, 15 Dec 2020 08:49:57 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id F1EFCC9BA for ; Tue, 15 Dec 2020 08:49:53 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jiaweiw@nvidia.com) with SMTP; 15 Dec 2020 09:49:52 +0200 Received: from nvidia.com (gen-l-vrt-281.mtl.labs.mlnx [10.237.44.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BF7nqhP023341; Tue, 15 Dec 2020 09:49:52 +0200 From: Jiawei Wang To: viacheslavo@nvidia.com, matan@nvidia.com, orika@nvidia.com Cc: dev@dpdk.org, rasland@nvidia.com Date: Tue, 15 Dec 2020 09:49:49 +0200 Message-Id: <1608018591-97942-3-git-send-email-jiaweiw@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> References: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> Subject: [dpdk-dev] [RFC 2/4] net/mlx5: support E-Switch mirroring and jump in one flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" mlx5 E-Switch mirroring is implemented as multiple destination array in one steering table. The array currently supports only port ID as destination actions. This patch adds the jump action support to the array as one of destination. The packets can be mirrored to the port and jump to next table in the same destination array allowing to continue handling in the new table. For example: set sample_actions 0 port_id id 1 / end flow create 0 ingress transfer pattern eth / end actions sample ratio 1 index 0 / jump group 1 / end flow create 1 ingress transfer group 1 pattern eth / end actions set_mac_dst mac_addr 00:aa:bb:cc:dd:ee / port_id id 2 / end The flow results all the matched ingress packets are mirrored to port id 1 and go to group 1. In the group 1, packets are modified with the destination mac and sent to port id 2. Signed-off-by: Jiawei Wang --- drivers/net/mlx5/mlx5_flow.c | 36 ++++++++++-------- drivers/net/mlx5/mlx5_flow.h | 2 + drivers/net/mlx5/mlx5_flow_dv.c | 81 +++++++++++++++++++++++++++++------------ 3 files changed, 80 insertions(+), 39 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 82e24d7..3bf4484 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -4478,7 +4478,6 @@ struct mlx5_hlist_entry * { const struct rte_flow_action_sample *sample; int actions_n = 0; - int jump_flag = 0; uint32_t ratio = 0; int sub_type = 0; int flag = 0; @@ -4493,8 +4492,6 @@ struct mlx5_hlist_entry * if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE || actions->type == RTE_FLOW_ACTION_TYPE_RSS) *qrss_action_pos = actions_n; - if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP) - jump_flag = 1; if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) { sample = actions->conf; ratio = sample->ratio; @@ -4505,10 +4502,10 @@ struct mlx5_hlist_entry * } if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) { if (ratio == 1) { - /* JUMP Action not support for Mirroring; - * Mirroring support multi-destination; + /* FDB mirroring uses the destination array to implement + * instead of FLOW_SAMPLER object. */ - if (!jump_flag && sub_type != RTE_FLOW_ACTION_TYPE_END) + if (sub_type != RTE_FLOW_ACTION_TYPE_END) flag = 0; } } @@ -4529,8 +4526,8 @@ struct mlx5_hlist_entry * * * @param dev * Pointer to Ethernet device. - * @param[in] fdb_tx - * FDB egress flow flag. + * @param[in] add_tag + * Add extra tag action flag. * @param[out] sfx_items * Suffix flow match items (list terminated by the END pattern item). * @param[in] actions @@ -4554,7 +4551,7 @@ struct mlx5_hlist_entry * */ static int flow_sample_split_prep(struct rte_eth_dev *dev, - uint32_t fdb_tx, + int add_tag, struct rte_flow_item sfx_items[], const struct rte_flow_action actions[], struct rte_flow_action actions_sfx[], @@ -4577,7 +4574,11 @@ struct mlx5_hlist_entry * RTE_FLOW_ERROR_TYPE_ACTION, NULL, "invalid position of sample " "action in list"); - if (!fdb_tx) { + /* For CX5, add an extra tag action for NIC-RX and E-Switch ingress. + * For CX6DX and above, metadata registers Cx preserve their value, + * add an extra tag action for NIC-RX and E-Switch ingress and egress. + */ + if (add_tag) { /* Prepare the prefix tag action. */ set_tag = (void *)(actions_pre + actions_n + 1); ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error); @@ -4628,8 +4629,7 @@ struct mlx5_hlist_entry * memcpy(actions_pre, actions, sizeof(struct rte_flow_action) * index); } - /* Add the extra tag action for NIC-RX and E-Switch ingress. */ - if (!fdb_tx) { + if (add_tag) { actions_pre[index++] = (struct rte_flow_action){ .type = (enum rte_flow_action_type) @@ -5042,6 +5042,7 @@ struct mlx5_hlist_entry * int actions_n = 0; int sample_action_pos; int qrss_action_pos; + int add_tag = 0; int ret = 0; if (priv->sampler_en) @@ -5063,16 +5064,21 @@ struct mlx5_hlist_entry * "sample flow"); /* The representor_id is -1 for uplink. */ fdb_tx = (attr->transfer && priv->representor_id != -1); - if (!fdb_tx) + /* + * When reg_c_preserve is set, metadata registers Cx preserve + * their value even through packet duplication. + */ + add_tag = (!fdb_tx || priv->config.hca_attr.reg_c_preserve); + if (add_tag) sfx_items = (struct rte_flow_item *)((char *)sfx_actions + act_size); pre_actions = sfx_actions + actions_n; - tag_id = flow_sample_split_prep(dev, fdb_tx, sfx_items, + tag_id = flow_sample_split_prep(dev, add_tag, sfx_items, actions, sfx_actions, pre_actions, actions_n, sample_action_pos, qrss_action_pos, error); - if (tag_id < 0 || (!fdb_tx && !tag_id)) { + if (tag_id < 0 || (add_tag && !tag_id)) { ret = -rte_errno; goto exit; } diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index d85dd19..0172ee5 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -552,6 +552,7 @@ struct mlx5_flow_sub_actions_list { void *dr_cnt_action; void *dr_port_id_action; void *dr_encap_action; + void *dr_jump_action; }; /* Sample sub-actions resource list. */ @@ -561,6 +562,7 @@ struct mlx5_flow_sub_actions_idx { uint32_t cnt; uint32_t rix_port_id_action; /**< Index to port ID action resource. */ uint32_t rix_encap_decap; /**< Index to encap/decap resource. */ + uint32_t rix_jump; /**< Index to the jump action resource. */ }; /* Sample action resource structure. */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index c317376..4a8154f 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -76,7 +76,7 @@ static int flow_dv_encap_decap_resource_release(struct rte_eth_dev *dev, - uint32_t encap_decap_idx); + uint32_t encap_decap_idx); static int flow_dv_port_id_action_resource_release(struct rte_eth_dev *dev, @@ -84,6 +84,10 @@ static void flow_dv_shared_rss_action_release(struct rte_eth_dev *dev, uint32_t srss); +static int +flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev, + uint32_t rix_jump); + /** * Initialize flow attributes structure according to flow items' types. * @@ -3580,7 +3584,7 @@ struct mlx5_cache_entry * (dev, &res, dev_flow, error); } -static int fdb_mirror; +static int fdb_mirror_limit; /** * Validate the modify-header actions. @@ -3609,7 +3613,7 @@ struct mlx5_cache_entry * RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have encap action before" " modify action"); - if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror) + if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror_limit) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't support sample action before" @@ -3945,12 +3949,6 @@ struct mlx5_cache_entry * return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "jump with meter not support"); - if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "E-Switch mirroring can't support" - " Sample action and jump action in" - " same flow now"); if (!action->conf) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_CONF, @@ -4347,8 +4345,8 @@ struct mlx5_hlist_entry * uint16_t queue_index = 0xFFFF; int actions_n = 0; int ret; - fdb_mirror = 0; + fdb_mirror_limit = 0; if (!sample) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, @@ -4465,7 +4463,7 @@ struct mlx5_hlist_entry * "E-Switch doesn't support " "any optional action " "for sampling"); - fdb_mirror = 1; + fdb_mirror_limit = 1; if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -8685,6 +8683,10 @@ struct mlx5_hlist_entry * flow_dv_counter_free(dev, act_res->cnt); act_res->cnt = 0; } + if (act_res->rix_jump) { + flow_dv_jump_tbl_resource_release(dev, act_res->rix_jump); + act_res->rix_jump = 0; + } } int @@ -8896,6 +8898,7 @@ struct mlx5_cache_entry * struct mlx5dv_dr_domain *domain; uint32_t idx = 0, res_idx = 0; struct rte_flow_error *error = ctx->error; + uint64_t action_flags; /* Register new destination array resource. */ cache_resource = mlx5_ipool_zmalloc(sh->ipool[MLX5_IPOOL_DEST_ARRAY], @@ -8928,19 +8931,31 @@ struct mlx5_cache_entry * } dest_attr[idx]->type = MLX5DV_DR_ACTION_DEST; sample_act = &resource->sample_act[idx]; - if (sample_act->action_flags == MLX5_FLOW_ACTION_QUEUE) { + action_flags = sample_act->action_flags; + switch (action_flags) { + case MLX5_FLOW_ACTION_QUEUE: dest_attr[idx]->dest = sample_act->dr_queue_action; - } else if (sample_act->action_flags == - (MLX5_FLOW_ACTION_PORT_ID | MLX5_FLOW_ACTION_ENCAP)) { + break; + case (MLX5_FLOW_ACTION_PORT_ID | MLX5_FLOW_ACTION_ENCAP): dest_attr[idx]->type = MLX5DV_DR_ACTION_DEST_REFORMAT; dest_attr[idx]->dest_reformat = &dest_reformat[idx]; dest_attr[idx]->dest_reformat->reformat = sample_act->dr_encap_action; dest_attr[idx]->dest_reformat->dest = sample_act->dr_port_id_action; - } else if (sample_act->action_flags == - MLX5_FLOW_ACTION_PORT_ID) { + break; + case MLX5_FLOW_ACTION_PORT_ID: dest_attr[idx]->dest = sample_act->dr_port_id_action; + break; + case MLX5_FLOW_ACTION_JUMP: + dest_attr[idx]->dest = sample_act->dr_jump_action; + break; + default: + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "unsupported actions type"); + goto error; } } /* create a dest array actioin */ @@ -8976,6 +8991,10 @@ struct mlx5_cache_entry * !flow_dv_port_id_action_resource_release(dev, act_res->rix_port_id_action)) act_res->rix_port_id_action = 0; + if (act_res->rix_jump && + !flow_dv_jump_tbl_resource_release(dev, + act_res->rix_jump)) + act_res->rix_jump = 0; if (dest_attr[idx]) mlx5_free(dest_attr[idx]); } @@ -9312,6 +9331,14 @@ struct mlx5_cache_entry * sample_act->dr_port_id_action = dev_flow->dv.port_id_action->action; } + if (sample_act->action_flags & MLX5_FLOW_ACTION_JUMP) { + normal_idx++; + mdest_res->sample_idx[dest_index].rix_jump = + dev_flow->handle->rix_jump; + sample_act->dr_jump_action = + dev_flow->dv.jump->action; + dev_flow->handle->rix_jump = 0; + } sample_act->actions_num = normal_idx; /* update sample action resource into first index of array */ mdest_res->ft_type = res->ft_type; @@ -10070,6 +10097,8 @@ struct mlx5_cache_entry * dev_flow->dv.jump->action; action_flags |= MLX5_FLOW_ACTION_JUMP; dev_flow->handle->fate_action = MLX5_FLOW_FATE_JUMP; + sample_act->action_flags |= MLX5_FLOW_ACTION_JUMP; + num_of_dest++; break; case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: @@ -10292,7 +10321,8 @@ struct mlx5_cache_entry * * So need remove the original these actions in the flow and only * use the sample action instead of. */ - if (num_of_dest > 1 && sample_act->dr_port_id_action) { + if (num_of_dest > 1 && + (sample_act->dr_port_id_action || sample_act->dr_jump_action)) { int i; void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0}; @@ -10302,6 +10332,9 @@ struct mlx5_cache_entry * dev_flow->dv.actions[i]) || (sample_act->dr_port_id_action && sample_act->dr_port_id_action == + dev_flow->dv.actions[i]) || + (sample_act->dr_jump_action && + sample_act->dr_jump_action == dev_flow->dv.actions[i])) continue; temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i]; @@ -10923,21 +10956,21 @@ struct mlx5_cache_entry * * * @param dev * Pointer to Ethernet device. - * @param handle - * Pointer to mlx5_flow_handle. + * @param rix_jump + * Index to the jump action resource. * * @return * 1 while a reference on it exists, 0 when freed. */ static int flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev, - struct mlx5_flow_handle *handle) + uint32_t rix_jump) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_tbl_data_entry *tbl_data; tbl_data = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_JUMP], - handle->rix_jump); + rix_jump); if (!tbl_data) return 0; return flow_dv_tbl_resource_release(MLX5_SH(dev), &tbl_data->tbl); @@ -11091,7 +11124,7 @@ struct mlx5_cache_entry * mlx5_hrxq_release(dev, handle->rix_hrxq); break; case MLX5_FLOW_FATE_JUMP: - flow_dv_jump_tbl_resource_release(dev, handle); + flow_dv_jump_tbl_resource_release(dev, handle->rix_jump); break; case MLX5_FLOW_FATE_PORT_ID: flow_dv_port_id_action_resource_release(dev, @@ -11190,8 +11223,8 @@ struct mlx5_cache_entry * * * @param dev * Pointer to Ethernet device. - * @param handle - * Pointer to mlx5_flow_handle. + * @param port_id + * Index to port ID action resource. * * @return * 1 while a reference on it exists, 0 when freed. From patchwork Tue Dec 15 07:49:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawei Wang X-Patchwork-Id: 85198 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D2903A09E9; Tue, 15 Dec 2020 08:50:46 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4815AC9F6; Tue, 15 Dec 2020 08:50:00 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 0A5DBC9F0 for ; Tue, 15 Dec 2020 08:49:58 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jiaweiw@nvidia.com) with SMTP; 15 Dec 2020 09:49:52 +0200 Received: from nvidia.com (gen-l-vrt-281.mtl.labs.mlnx [10.237.44.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BF7nqhQ023341; Tue, 15 Dec 2020 09:49:52 +0200 From: Jiawei Wang To: viacheslavo@nvidia.com, matan@nvidia.com, orika@nvidia.com Cc: dev@dpdk.org, rasland@nvidia.com Date: Tue, 15 Dec 2020 09:49:50 +0200 Message-Id: <1608018591-97942-4-git-send-email-jiaweiw@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> References: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> Subject: [dpdk-dev] [RFC 3/4] net/mlx5: extend the skip scale flag X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The sampling feature introduces the scale flow group with factor, then the scaled table value can be used for the normal path table due to this table be created implicitly. But if the input group value already be scaled, for example the group value of sampling suffix flow, then use 'skip_scale" flag to skip the scale twice in the translation action. Consider the flow with jump action and this jump action could be created implicitly, PMD may only scale the original flow group value or scale the jump group value or both, so extend the 'skip_scale' flag to two bits: If bit0 of 'skip_scale' flag is set to 1, then skip the scale the original flow group; If bit1 of 'skip_scale' flag is set to 1, then skip the scale the jump flow group. Signed-off-by: Jiawei Wang --- drivers/net/mlx5/mlx5_flow.c | 2 +- drivers/net/mlx5/mlx5_flow.h | 21 ++++++++++++++++++--- drivers/net/mlx5/mlx5_flow_dv.c | 9 +++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 3bf4484..6095e03 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -5108,7 +5108,7 @@ struct mlx5_hlist_entry * /* Suffix group level already be scaled with factor, set * skip_scale to 1 to avoid scale again in translation. */ - flow_split_info->skip_scale = 1; + flow_split_info->skip_scale = 1 << MLX5_SCALE_FLOW_GROUP_BIT; #endif } /* Add the suffix subflow. */ diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 0172ee5..96becd7 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -759,6 +759,9 @@ struct mlx5_flow_verbs_workspace { /**< Specifications & actions buffer of verbs flow. */ }; +#define MLX5_SCALE_FLOW_GROUP_BIT 0 +#define MLX5_SCALE_JUMP_FLOW_GROUP_BIT 1 + /** Maximal number of device sub-flows supported. */ #define MLX5_NUM_MAX_DEV_FLOWS 32 @@ -772,8 +775,20 @@ struct mlx5_flow { /**< Bit-fields of detected actions, see MLX5_FLOW_ACTION_*. */ bool external; /**< true if the flow is created external to PMD. */ uint8_t ingress:1; /**< 1 if the flow is ingress. */ - uint8_t skip_scale:1; - /**< 1 if skip the scale the table with factor. */ + uint8_t skip_scale:2; + /** + * Each Bit be set to 1 if Skip the scale the flow group with factor. + * If bit0 be set to 1, then skip the scale the original flow group; + * If bit1 be set to 1, then skip the scale the jump flow group if + * having jump action. + * 00: Enable scale in a flow, default value. + * 01: Skip scale the flow group with factor, enable scale the group + * of jump action. + * 10: Enable scale the group with factor, skip scale the group of + * jump action. + * 11: Skip scale the table with factor both for flow group and jump + * group. + */ union { #ifdef HAVE_IBV_FLOW_DV_SUPPORT struct mlx5_flow_dv_workspace dv; @@ -1240,7 +1255,7 @@ struct flow_grp_info { uint64_t fdb_def_rule:1; /* force standard group translation */ uint64_t std_tbl_fix:1; - uint64_t skip_scale:1; + uint64_t skip_scale:2; }; static inline bool diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 4a8154f..109369e 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -9708,7 +9708,8 @@ struct mlx5_cache_entry * .external = !!dev_flow->external, .transfer = !!attr->transfer, .fdb_def_rule = !!priv->fdb_def_rule, - .skip_scale = !!dev_flow->skip_scale, + .skip_scale = dev_flow->skip_scale & + (1 << MLX5_SCALE_FLOW_GROUP_BIT), }; if (!wks) @@ -10066,7 +10067,11 @@ struct mlx5_cache_entry * jump_group = ((const struct rte_flow_action_jump *) action->conf)->group; grp_info.std_tbl_fix = 0; - grp_info.skip_scale = 0; + if (dev_flow->skip_scale & + (1 << MLX5_SCALE_JUMP_FLOW_GROUP_BIT)) + grp_info.skip_scale = 1; + else + grp_info.skip_scale = 0; ret = mlx5_flow_group_to_table(dev, tunnel, jump_group, &table, From patchwork Tue Dec 15 07:49:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawei Wang X-Patchwork-Id: 85199 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D45ACA09E9; Tue, 15 Dec 2020 08:51:02 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 04D95CA04; Tue, 15 Dec 2020 08:50:02 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 0333CC9EE for ; Tue, 15 Dec 2020 08:49:58 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jiaweiw@nvidia.com) with SMTP; 15 Dec 2020 09:49:52 +0200 Received: from nvidia.com (gen-l-vrt-281.mtl.labs.mlnx [10.237.44.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BF7nqhR023341; Tue, 15 Dec 2020 09:49:52 +0200 From: Jiawei Wang To: viacheslavo@nvidia.com, matan@nvidia.com, orika@nvidia.com Cc: dev@dpdk.org, rasland@nvidia.com Date: Tue, 15 Dec 2020 09:49:51 +0200 Message-Id: <1608018591-97942-5-git-send-email-jiaweiw@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> References: <1608018591-97942-1-git-send-email-jiaweiw@nvidia.com> Subject: [dpdk-dev] [RFC 4/4] net/mlx5: supports modify one port in E-Switch mirroring X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" While there's the modify action and sample action with ratio=1 in the E-Switch flow, and modify action is after the sample action, means that the modify should only impact on after sample. MLX5 PMD will monitor the above case and split the E-Switch flow into two sub flows, smiliar as sample flow did before: - the prefix sub flow with all actions preceding the sample and the sample action itself, also append the new jump action after sample in the prefix sub flow; - the suffix sub flow with the modify action and other actions following the sample action. The flow split as below: Original flow: items / actions pre / sample / modify / actions sfx prefix sub flow - items / actions pre / set_tag action / sample / jump suffix sub flow - tag_item / modify / actions sfx Signed-off-by: Jiawei Wang --- drivers/net/mlx5/mlx5_flow.c | 175 ++++++++++++++++++++++++++++------------ drivers/net/mlx5/mlx5_flow_dv.c | 10 --- 2 files changed, 123 insertions(+), 62 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 6095e03..aca3436 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -4465,6 +4465,8 @@ struct mlx5_hlist_entry * * Pointer to the position of the matched action if exists, otherwise is -1. * @param[out] qrss_action_pos * Pointer to the position of the Queue/RSS action if exists, otherwise is -1. + * @param[out] modify_after_mirror + * Pointer to the flag of modify action after FDB mirroring. * * @return * > 0 the total number of actions. @@ -4474,13 +4476,15 @@ struct mlx5_hlist_entry * flow_check_match_action(const struct rte_flow_action actions[], const struct rte_flow_attr *attr, enum rte_flow_action_type action, - int *match_action_pos, int *qrss_action_pos) + int *match_action_pos, int *qrss_action_pos, + int *modify_after_mirror) { const struct rte_flow_action_sample *sample; int actions_n = 0; uint32_t ratio = 0; int sub_type = 0; int flag = 0; + int fdb_mirror = 0; *match_action_pos = -1; *qrss_action_pos = -1; @@ -4489,25 +4493,53 @@ struct mlx5_hlist_entry * flag = 1; *match_action_pos = actions_n; } - if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE || - actions->type == RTE_FLOW_ACTION_TYPE_RSS) + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_QUEUE: + case RTE_FLOW_ACTION_TYPE_RSS: *qrss_action_pos = actions_n; - if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) { + break; + case RTE_FLOW_ACTION_TYPE_SAMPLE: sample = actions->conf; ratio = sample->ratio; sub_type = ((const struct rte_flow_action *) (sample->actions))->type; + if (ratio == 1 && attr->transfer) + fdb_mirror = 1; + break; + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + case RTE_FLOW_ACTION_TYPE_DEC_TTL: + case RTE_FLOW_ACTION_TYPE_SET_TTL: + case RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ: + case RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ: + case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK: + case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK: + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP: + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP: + case RTE_FLOW_ACTION_TYPE_FLAG: + case RTE_FLOW_ACTION_TYPE_MARK: + case RTE_FLOW_ACTION_TYPE_SET_META: + case RTE_FLOW_ACTION_TYPE_SET_TAG: + if (fdb_mirror) + *modify_after_mirror = 1; + break; + default: + break; } actions_n++; } - if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) { - if (ratio == 1) { - /* FDB mirroring uses the destination array to implement - * instead of FLOW_SAMPLER object. - */ - if (sub_type != RTE_FLOW_ACTION_TYPE_END) - flag = 0; - } + if (flag && fdb_mirror && !*modify_after_mirror) { + /* FDB mirroring uses the destination array to implement + * instead of FLOW_SAMPLER object. + */ + if (sub_type != RTE_FLOW_ACTION_TYPE_END) + flag = 0; } /* Count RTE_FLOW_ACTION_TYPE_END. */ return flag ? actions_n + 1 : 0; @@ -4542,6 +4574,8 @@ struct mlx5_hlist_entry * * The sample action position. * @param[in] qrss_action_pos * The Queue/RSS action position. + * @param[in] jump_table + * Add extra jump action flag. * @param[out] error * Perform verbose error reporting if not NULL. * @@ -4559,14 +4593,17 @@ struct mlx5_hlist_entry * int actions_n, int sample_action_pos, int qrss_action_pos, + int jump_table, struct rte_flow_error *error) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_rte_flow_action_set_tag *set_tag; struct mlx5_rte_flow_item_tag *tag_spec; struct mlx5_rte_flow_item_tag *tag_mask; + struct rte_flow_action_jump *jump_action; uint32_t tag_id = 0; int index; + int append_index = 0; int ret; if (sample_action_pos < 0) @@ -4574,13 +4611,37 @@ struct mlx5_hlist_entry * RTE_FLOW_ERROR_TYPE_ACTION, NULL, "invalid position of sample " "action in list"); + /* Prepare the actions for prefix and suffix flow. */ + if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) { + index = qrss_action_pos; + /* Put the preceding the Queue/RSS action into prefix flow. */ + if (index != 0) + memcpy(actions_pre, actions, + sizeof(struct rte_flow_action) * index); + /* Put others preceding the sample action into prefix flow. */ + if (sample_action_pos > index + 1) + memcpy(actions_pre + index, actions + index + 1, + sizeof(struct rte_flow_action) * + (sample_action_pos - index - 1)); + index = sample_action_pos - 1; + /* Put Queue/RSS action into Suffix flow. */ + memcpy(actions_sfx, actions + qrss_action_pos, + sizeof(struct rte_flow_action)); + actions_sfx++; + } else { + index = sample_action_pos; + if (index != 0) + memcpy(actions_pre, actions, + sizeof(struct rte_flow_action) * index); + } /* For CX5, add an extra tag action for NIC-RX and E-Switch ingress. * For CX6DX and above, metadata registers Cx preserve their value, - * add an extra tag action for NIC-RX and E-Switch ingress and egress. + * add an extra tag action for NIC-RX and E-Switch Domain. */ if (add_tag) { /* Prepare the prefix tag action. */ - set_tag = (void *)(actions_pre + actions_n + 1); + append_index++; + set_tag = (void *)(actions_pre + actions_n + append_index); ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error); if (ret < 0) return ret; @@ -4605,31 +4666,7 @@ struct mlx5_hlist_entry * .type = (enum rte_flow_item_type) RTE_FLOW_ITEM_TYPE_END, }; - } - /* Prepare the actions for prefix and suffix flow. */ - if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) { - index = qrss_action_pos; - /* Put the preceding the Queue/RSS action into prefix flow. */ - if (index != 0) - memcpy(actions_pre, actions, - sizeof(struct rte_flow_action) * index); - /* Put others preceding the sample action into prefix flow. */ - if (sample_action_pos > index + 1) - memcpy(actions_pre + index, actions + index + 1, - sizeof(struct rte_flow_action) * - (sample_action_pos - index - 1)); - index = sample_action_pos - 1; - /* Put Queue/RSS action into Suffix flow. */ - memcpy(actions_sfx, actions + qrss_action_pos, - sizeof(struct rte_flow_action)); - actions_sfx++; - } else { - index = sample_action_pos; - if (index != 0) - memcpy(actions_pre, actions, - sizeof(struct rte_flow_action) * index); - } - if (add_tag) { + /* Prepare the tag action in prefix subflow. */ actions_pre[index++] = (struct rte_flow_action){ .type = (enum rte_flow_action_type) @@ -4640,6 +4677,22 @@ struct mlx5_hlist_entry * memcpy(actions_pre + index, actions + sample_action_pos, sizeof(struct rte_flow_action)); index += 1; + /* For the modify action after the sample action in E-Switch mirroring, + * Add the extra jump action in prefix subflow and jump into the next + * table, then do the modify action in the new table. + */ + if (jump_table) { + /* Prepare the prefix jump action. */ + append_index++; + jump_action = (void *)(actions_pre + actions_n + append_index); + jump_action->group = jump_table; + actions_pre[index++] = + (struct rte_flow_action){ + .type = (enum rte_flow_action_type) + RTE_FLOW_ACTION_TYPE_JUMP, + .conf = jump_action, + }; + } actions_pre[index] = (struct rte_flow_action){ .type = (enum rte_flow_action_type) RTE_FLOW_ACTION_TYPE_END, @@ -5043,12 +5096,16 @@ struct mlx5_hlist_entry * int sample_action_pos; int qrss_action_pos; int add_tag = 0; + int modify_after_mirror = 0; + uint16_t jump_table = 0; + const uint32_t next_ft_step = 1; int ret = 0; if (priv->sampler_en) actions_n = flow_check_match_action(actions, attr, RTE_FLOW_ACTION_TYPE_SAMPLE, - &sample_action_pos, &qrss_action_pos); + &sample_action_pos, &qrss_action_pos, + &modify_after_mirror); if (actions_n) { /* The prefix actions must includes sample, tag, end. */ act_size = sizeof(struct rte_flow_action) * (actions_n * 2 + 1) @@ -5072,16 +5129,23 @@ struct mlx5_hlist_entry * if (add_tag) sfx_items = (struct rte_flow_item *)((char *)sfx_actions + act_size); + if (modify_after_mirror) + jump_table = attr->group * MLX5_FLOW_TABLE_FACTOR + + next_ft_step; pre_actions = sfx_actions + actions_n; tag_id = flow_sample_split_prep(dev, add_tag, sfx_items, actions, sfx_actions, pre_actions, actions_n, sample_action_pos, - qrss_action_pos, error); + qrss_action_pos, jump_table, + error); if (tag_id < 0 || (add_tag && !tag_id)) { ret = -rte_errno; goto exit; } + if (modify_after_mirror) + flow_split_info->skip_scale = + 1 << MLX5_SCALE_JUMP_FLOW_GROUP_BIT; /* Add the prefix subflow. */ ret = flow_create_split_inner(dev, flow, &dev_flow, attr, items, pre_actions, @@ -5092,21 +5156,28 @@ struct mlx5_hlist_entry * } dev_flow->handle->split_flow_id = tag_id; #ifdef HAVE_IBV_FLOW_DV_SUPPORT - /* Set the sfx group attr. */ - sample_res = (struct mlx5_flow_dv_sample_resource *) - dev_flow->dv.sample_res; - sfx_tbl = (struct mlx5_flow_tbl_resource *) - sample_res->normal_path_tbl; - sfx_tbl_data = container_of(sfx_tbl, - struct mlx5_flow_tbl_data_entry, tbl); - sfx_attr.group = sfx_attr.transfer ? - (sfx_tbl_data->table_id - 1) : - sfx_tbl_data->table_id; + if (!modify_after_mirror) { + /* Set the sfx group attr. */ + sample_res = (struct mlx5_flow_dv_sample_resource *) + dev_flow->dv.sample_res; + sfx_tbl = (struct mlx5_flow_tbl_resource *) + sample_res->normal_path_tbl; + sfx_tbl_data = container_of(sfx_tbl, + struct mlx5_flow_tbl_data_entry, + tbl); + sfx_attr.group = sfx_attr.transfer ? + (sfx_tbl_data->table_id - 1) : + sfx_tbl_data->table_id; + } else { + MLX5_ASSERT(attr->transfer); + sfx_attr.group = jump_table; + } flow_split_info->prefix_layers = flow_get_prefix_layer_flags(dev_flow); flow_split_info->prefix_mark = dev_flow->handle->mark; /* Suffix group level already be scaled with factor, set - * skip_scale to 1 to avoid scale again in translation. + * MLX5_SCALE_FLOW_GROUP_BIT of skip_scale to 1 to avoid scale + * again in translation. */ flow_split_info->skip_scale = 1 << MLX5_SCALE_FLOW_GROUP_BIT; #endif diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 109369e..f930eaa 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3584,8 +3584,6 @@ struct mlx5_cache_entry * (dev, &res, dev_flow, error); } -static int fdb_mirror_limit; - /** * Validate the modify-header actions. * @@ -3613,12 +3611,6 @@ struct mlx5_cache_entry * RTE_FLOW_ERROR_TYPE_ACTION, NULL, "can't have encap action before" " modify action"); - if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror_limit) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "can't support sample action before" - " modify action for E-Switch" - " mirroring"); return 0; } @@ -4346,7 +4338,6 @@ struct mlx5_hlist_entry * int actions_n = 0; int ret; - fdb_mirror_limit = 0; if (!sample) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, action, @@ -4463,7 +4454,6 @@ struct mlx5_hlist_entry * "E-Switch doesn't support " "any optional action " "for sampling"); - fdb_mirror_limit = 1; if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,