From patchwork Mon Nov 5 07:20:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yongseok Koh X-Patchwork-Id: 47803 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 04E0E4F9C; Mon, 5 Nov 2018 08:20:48 +0100 (CET) Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00044.outbound.protection.outlook.com [40.107.0.44]) by dpdk.org (Postfix) with ESMTP id ED4F14F98 for ; Mon, 5 Nov 2018 08:20:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ee33pfwJp5VIPEwagP++rWbenOUk7K9wNBeQVLOBtl8=; b=S5y+aLJVfRrrmLpWPRAHcY8fodf2temhs3cKDgEtHwLKcTZ63nHO1iTqYaQ799Af6B0Nbq6izgRMby8bDbk9s5ekx0NBH4KzURW3NlMdS7i3HMgozevabHm5q+YoCacNQ4u23EjkGkCqr2KdvaAkbYo5OFhDQ1d1zKaE2RKVlao= Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by DB3PR0502MB4076.eurprd05.prod.outlook.com (52.134.66.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.30; Mon, 5 Nov 2018 07:20:44 +0000 Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323]) by DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323%3]) with mapi id 15.20.1294.028; Mon, 5 Nov 2018 07:20:44 +0000 From: Yongseok Koh To: Shahaf Shuler CC: "dev@dpdk.org" , Ori Kam , Yongseok Koh Thread-Topic: [PATCH v2 1/3] net/mlx5: fix Verbs flow tunnel Thread-Index: AQHUdNgQsUtxjTMsqU6WigTcJP4Q5w== Date: Mon, 5 Nov 2018 07:20:44 +0000 Message-ID: <20181105072032.42374-2-yskoh@mellanox.com> References: <20181102210801.28370-1-yskoh@mellanox.com> <20181105072032.42374-1-yskoh@mellanox.com> In-Reply-To: <20181105072032.42374-1-yskoh@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR07CA0030.namprd07.prod.outlook.com (2603:10b6:a02:bc::43) To DB3PR0502MB3980.eurprd05.prod.outlook.com (2603:10a6:8:10::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [209.116.155.178] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR0502MB4076; 6:I0JKB7LSWcMJNLCb6HJJ6hQp1+HW3HLxj6+eIc6QfmD+mKVbOagE0zT4433yv5dTKdOP7RTKI5kmwL17ISkteR7koIom/2F9TIeCAM58vLyqKReKy9/GsyinScB8Wc5QFQb/0H0j+HfSuMzzrZD2IOdiQm5hMFb6wgqX/MBX5PA7d0DcQv3624GRR/H6Ux8ubf3Ry2LYHFBNe6KMmB+t1agKCt/9HFAxXTGnnKFMlHgBp8wNpjdhV1vAuxEUcATiXCkkVhqv5F0xR46TT8mWQmMqNTRgZ24LYG+bTpv3Fx4peSwAmTvmidChPxiIt7OV5BPwPPQRIOxfkghIKFp4C4XzH3/wcnRjs0/YjfOV4gUZ2kDxMM2cMNPOS7DSG760H9hknf5qafxHfTWpVB9Nsel0dStLFwggNM3XKgg+ZzkdHLiklKBNYnMTTmOL0Sn9i1QQQ26px8Ud8lx3uqMY7Q==; 5:aVhMF7jlc4GuwCqvayA1XOaQ9FX1OLUaTupGgj40vDjitGEqRMf3sjN2PlFRIQIF1fey5pmQHa7dto7oJc0tF56MmyWTRcwLV3Dgfjy2U1jHsWPUfWqT1U+dfmsAoWMGr81grsSwCITIOrVLik6q+aTTe95/0+wxLdgsGg7GZ2c=; 7:8jd+46hvIlHuo8gT0OvMfoZr4SO3L3a7yWpIjKHLom2H+8WuJhhkSbZpFYGPiORyF79oagypqegyLAKsN6l9dBofRCi8DMhpVctr8+4i4L2IHlHtUZTBym8XIQECHs45nnxwuDVXpM3BOBOhG9Yy9g== x-ms-office365-filtering-correlation-id: 4ef168a4-a0c4-4441-ef74-08d642ef32e7 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB3PR0502MB4076; x-ms-traffictypediagnostic: DB3PR0502MB4076: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(788757137089); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(3002001)(93006095)(93001095)(3231382)(944501410)(52105095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:DB3PR0502MB4076; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB4076; x-forefront-prvs: 08476BC6EF x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(376002)(366004)(396003)(136003)(39860400002)(51234002)(189003)(199004)(66066001)(106356001)(25786009)(446003)(11346002)(97736004)(256004)(14454004)(105586002)(14444005)(68736007)(6512007)(53946003)(2900100001)(2906002)(53936002)(3846002)(6116002)(1076002)(37006003)(6506007)(386003)(52116002)(99286004)(36756003)(4744004)(7736002)(305945005)(6486002)(316002)(6436002)(54906003)(186003)(4326008)(102836004)(86362001)(71190400001)(71200400001)(81166006)(81156014)(486006)(8676002)(6862004)(6636002)(5660300001)(478600001)(107886003)(575784001)(476003)(2616005)(8936002)(76176011)(26005)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB4076; H:DB3PR0502MB3980.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: wd9aPATq3ExKb5x8FLn5pIxzFyRVrId+SW8AdtEAp+G19PUq86zD3/2twPw7I46V9RW0yjpQwWPVJFgxojIQHjxC0o06WG/3hACIGHyKzOThZJSlLvmNlXMUq9Zv5tIy7Q6wujO6HS17j5lzEiKmFyjrXAbZ9IrITjR3GInk59SXbxVh+XfZiEJmcvbB9GmVQs62gzbovJypS0N0ecKy2jF397U7ENfjcDRIUg+X8u9kcnh70EleJpBnx0QI7k9g/BFsABATNV3/eOyzfLZF8R0HTuuTPqKjJNspLvwD+wCTlCo+BIzztLUhTYPq8f3Zn6IS9EyLbUWIsgd0xA5NkMnYh4Vg7/pwhpm4d2PAV68= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4ef168a4-a0c4-4441-ef74-08d642ef32e7 X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Nov 2018 07:20:44.2556 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR0502MB4076 Subject: [dpdk-dev] [PATCH v2 1/3] net/mlx5: fix Verbs flow tunnel 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" 1) Fix layer parsing In translation of tunneled flows, dev_flow->layers must not be used to check tunneled layer as it contains all the layers parsed from flow_drv_prepare(). Checking tunneled layer is needed to set IBV_FLOW_SPEC_INNER and it should be based on dynamic parsing. With dev_flow->layers on a tunneled flow, items will always be interpreted as inner as dev_flow->layer already has all the items. 2) Refactoring code It is partly because flow_verbs_translate_item_*() sets layer flag. Same code is repeating in multiple locations and that could be error-prone. - Introduce VERBS_SPEC_INNER() to unify setting IBV_FLOW_SPEC_INNER. - flow_verbs_translate_item_*() doesn't set parsing result - MLX5_FLOW_LAYER_*. - flow_verbs_translate_item_*() doesn't set priority or adjust hashfields but does only item translation. Both have to be done outside. - Make more consistent between Verbs and DV. 3) Remove flow_verbs_mark_update() This code can never be reached as validation prohibits specifying mark and flag actions together. No need to convert flag to mark. Fixes: 84c406e74524 ("net/mlx5: add flow translate function") Cc: orika@mellanox.com Signed-off-by: Yongseok Koh Acked-by: Ori Kam --- drivers/net/mlx5/mlx5_flow_verbs.c | 568 +++++++++++++++++-------------------- 1 file changed, 258 insertions(+), 310 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index 54ac620c72..43fcd0d29e 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -33,6 +33,9 @@ #include "mlx5_glue.h" #include "mlx5_flow.h" +#define VERBS_SPEC_INNER(item_flags) \ + (!!((item_flags) & MLX5_FLOW_LAYER_TUNNEL) ? IBV_FLOW_SPEC_INNER : 0) + /** * Create Verbs flow counter with Verbs library. * @@ -231,27 +234,26 @@ flow_verbs_counter_query(struct rte_eth_dev *dev __rte_unused, } /** - * Add a verbs item specification into @p flow. + * Add a verbs item specification into @p verbs. * - * @param[in, out] flow - * Pointer to flow structure. + * @param[out] verbs + * Pointer to verbs structure. * @param[in] src * Create specification. * @param[in] size * Size in bytes of the specification to copy. */ static void -flow_verbs_spec_add(struct mlx5_flow *flow, void *src, unsigned int size) +flow_verbs_spec_add(struct mlx5_flow_verbs *verbs, void *src, unsigned int size) { - struct mlx5_flow_verbs *verbs = &flow->verbs; + void *dst; - if (verbs->specs) { - void *dst; - - dst = (void *)(verbs->specs + verbs->size); - memcpy(dst, src, size); - ++verbs->attr->num_of_specs; - } + if (!verbs) + return; + assert(verbs->specs); + dst = (void *)(verbs->specs + verbs->size); + memcpy(dst, src, size); + ++verbs->attr->num_of_specs; verbs->size += size; } @@ -260,24 +262,23 @@ flow_verbs_spec_add(struct mlx5_flow *flow, void *src, unsigned int size) * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. * @param[in] item_flags - * Bit field with all detected items. - * @param[in, out] dev_flow - * Pointer to dev_flow structure. + * Parsed item flags. */ static void -flow_verbs_translate_item_eth(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_eth(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags) { const struct rte_flow_item_eth *spec = item->spec; const struct rte_flow_item_eth *mask = item->mask; - const int tunnel = !!(*item_flags & MLX5_FLOW_LAYER_TUNNEL); const unsigned int size = sizeof(struct ibv_flow_spec_eth); struct ibv_flow_spec_eth eth = { - .type = IBV_FLOW_SPEC_ETH | (tunnel ? IBV_FLOW_SPEC_INNER : 0), + .type = IBV_FLOW_SPEC_ETH | VERBS_SPEC_INNER(item_flags), .size = size, }; @@ -298,11 +299,8 @@ flow_verbs_translate_item_eth(const struct rte_flow_item *item, eth.val.src_mac[i] &= eth.mask.src_mac[i]; } eth.val.ether_type &= eth.mask.ether_type; - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L2; } - flow_verbs_spec_add(dev_flow, ð, size); - *item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 : - MLX5_FLOW_LAYER_OUTER_L2; + flow_verbs_spec_add(&dev_flow->verbs, ð, size); } /** @@ -344,24 +342,24 @@ flow_verbs_item_vlan_update(struct ibv_flow_attr *attr, * the input is valid and that there is space to insert the requested item * into the flow. * - * @param[in] item - * Item specification. - * @param[in, out] item_flags - * Bit mask that holds all detected items. * @param[in, out] dev_flow * Pointer to dev_flow structure. + * @param[in] item + * Item specification. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_vlan(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_vlan(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags) { const struct rte_flow_item_vlan *spec = item->spec; const struct rte_flow_item_vlan *mask = item->mask; unsigned int size = sizeof(struct ibv_flow_spec_eth); - const int tunnel = !!(*item_flags & MLX5_FLOW_LAYER_TUNNEL); + const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); struct ibv_flow_spec_eth eth = { - .type = IBV_FLOW_SPEC_ETH | (tunnel ? IBV_FLOW_SPEC_INNER : 0), + .type = IBV_FLOW_SPEC_ETH | VERBS_SPEC_INNER(item_flags), .size = size, }; const uint32_t l2m = tunnel ? MLX5_FLOW_LAYER_INNER_L2 : @@ -377,16 +375,10 @@ flow_verbs_translate_item_vlan(const struct rte_flow_item *item, eth.mask.ether_type = mask->inner_type; eth.val.ether_type &= eth.mask.ether_type; } - if (!(*item_flags & l2m)) { - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L2; - flow_verbs_spec_add(dev_flow, ð, size); - } else { + if (!(item_flags & l2m)) + flow_verbs_spec_add(&dev_flow->verbs, ð, size); + else flow_verbs_item_vlan_update(dev_flow->verbs.attr, ð); - size = 0; /* Only an update is done in eth specification. */ - } - *item_flags |= tunnel ? - (MLX5_FLOW_LAYER_INNER_L2 | MLX5_FLOW_LAYER_INNER_VLAN) : - (MLX5_FLOW_LAYER_OUTER_L2 | MLX5_FLOW_LAYER_OUTER_VLAN); } /** @@ -394,32 +386,28 @@ flow_verbs_translate_item_vlan(const struct rte_flow_item *item, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_ipv4(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_ipv4(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags) { const struct rte_flow_item_ipv4 *spec = item->spec; const struct rte_flow_item_ipv4 *mask = item->mask; - const int tunnel = !!(*item_flags & MLX5_FLOW_LAYER_TUNNEL); unsigned int size = sizeof(struct ibv_flow_spec_ipv4_ext); struct ibv_flow_spec_ipv4_ext ipv4 = { - .type = IBV_FLOW_SPEC_IPV4_EXT | - (tunnel ? IBV_FLOW_SPEC_INNER : 0), + .type = IBV_FLOW_SPEC_IPV4_EXT | VERBS_SPEC_INNER(item_flags), .size = size, }; if (!mask) mask = &rte_flow_item_ipv4_mask; - *item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : - MLX5_FLOW_LAYER_OUTER_L3_IPV4; if (spec) { ipv4.val = (struct ibv_flow_ipv4_ext_filter){ .src_ip = spec->hdr.src_addr, @@ -439,12 +427,7 @@ flow_verbs_translate_item_ipv4(const struct rte_flow_item *item, ipv4.val.proto &= ipv4.mask.proto; ipv4.val.tos &= ipv4.mask.tos; } - dev_flow->verbs.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, tunnel, - MLX5_IPV4_LAYER_TYPES, - MLX5_IPV4_IBV_RX_HASH); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L3; - flow_verbs_spec_add(dev_flow, &ipv4, size); + flow_verbs_spec_add(&dev_flow->verbs, &ipv4, size); } /** @@ -452,31 +435,28 @@ flow_verbs_translate_item_ipv4(const struct rte_flow_item *item, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_ipv6(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_ipv6(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags) { const struct rte_flow_item_ipv6 *spec = item->spec; const struct rte_flow_item_ipv6 *mask = item->mask; - const int tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); unsigned int size = sizeof(struct ibv_flow_spec_ipv6); struct ibv_flow_spec_ipv6 ipv6 = { - .type = IBV_FLOW_SPEC_IPV6 | (tunnel ? IBV_FLOW_SPEC_INNER : 0), + .type = IBV_FLOW_SPEC_IPV6 | VERBS_SPEC_INNER(item_flags), .size = size, }; if (!mask) mask = &rte_flow_item_ipv6_mask; - *item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : - MLX5_FLOW_LAYER_OUTER_L3_IPV6; if (spec) { unsigned int i; uint32_t vtc_flow_val; @@ -516,12 +496,7 @@ flow_verbs_translate_item_ipv6(const struct rte_flow_item *item, ipv6.val.next_hdr &= ipv6.mask.next_hdr; ipv6.val.hop_limit &= ipv6.mask.hop_limit; } - dev_flow->verbs.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, tunnel, - MLX5_IPV6_LAYER_TYPES, - MLX5_IPV6_IBV_RX_HASH); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L3; - flow_verbs_spec_add(dev_flow, &ipv6, size); + flow_verbs_spec_add(&dev_flow->verbs, &ipv6, size); } /** @@ -529,46 +504,38 @@ flow_verbs_translate_item_ipv6(const struct rte_flow_item *item, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_udp(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_tcp(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags __rte_unused) { - const struct rte_flow_item_udp *spec = item->spec; - const struct rte_flow_item_udp *mask = item->mask; - const int tunnel = !!(*item_flags & MLX5_FLOW_LAYER_TUNNEL); + const struct rte_flow_item_tcp *spec = item->spec; + const struct rte_flow_item_tcp *mask = item->mask; unsigned int size = sizeof(struct ibv_flow_spec_tcp_udp); - struct ibv_flow_spec_tcp_udp udp = { - .type = IBV_FLOW_SPEC_UDP | (tunnel ? IBV_FLOW_SPEC_INNER : 0), + struct ibv_flow_spec_tcp_udp tcp = { + .type = IBV_FLOW_SPEC_TCP | VERBS_SPEC_INNER(item_flags), .size = size, }; if (!mask) - mask = &rte_flow_item_udp_mask; - *item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP : - MLX5_FLOW_LAYER_OUTER_L4_UDP; + mask = &rte_flow_item_tcp_mask; if (spec) { - udp.val.dst_port = spec->hdr.dst_port; - udp.val.src_port = spec->hdr.src_port; - udp.mask.dst_port = mask->hdr.dst_port; - udp.mask.src_port = mask->hdr.src_port; + tcp.val.dst_port = spec->hdr.dst_port; + tcp.val.src_port = spec->hdr.src_port; + tcp.mask.dst_port = mask->hdr.dst_port; + tcp.mask.src_port = mask->hdr.src_port; /* Remove unwanted bits from values. */ - udp.val.src_port &= udp.mask.src_port; - udp.val.dst_port &= udp.mask.dst_port; + tcp.val.src_port &= tcp.mask.src_port; + tcp.val.dst_port &= tcp.mask.dst_port; } - dev_flow->verbs.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, tunnel, ETH_RSS_UDP, - (IBV_RX_HASH_SRC_PORT_UDP | - IBV_RX_HASH_DST_PORT_UDP)); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L4; - flow_verbs_spec_add(dev_flow, &udp, size); + flow_verbs_spec_add(&dev_flow->verbs, &tcp, size); } /** @@ -576,46 +543,38 @@ flow_verbs_translate_item_udp(const struct rte_flow_item *item, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_tcp(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_udp(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags __rte_unused) { - const struct rte_flow_item_tcp *spec = item->spec; - const struct rte_flow_item_tcp *mask = item->mask; - const int tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); + const struct rte_flow_item_udp *spec = item->spec; + const struct rte_flow_item_udp *mask = item->mask; unsigned int size = sizeof(struct ibv_flow_spec_tcp_udp); - struct ibv_flow_spec_tcp_udp tcp = { - .type = IBV_FLOW_SPEC_TCP | (tunnel ? IBV_FLOW_SPEC_INNER : 0), + struct ibv_flow_spec_tcp_udp udp = { + .type = IBV_FLOW_SPEC_UDP | VERBS_SPEC_INNER(item_flags), .size = size, }; if (!mask) - mask = &rte_flow_item_tcp_mask; - *item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP : - MLX5_FLOW_LAYER_OUTER_L4_TCP; + mask = &rte_flow_item_udp_mask; if (spec) { - tcp.val.dst_port = spec->hdr.dst_port; - tcp.val.src_port = spec->hdr.src_port; - tcp.mask.dst_port = mask->hdr.dst_port; - tcp.mask.src_port = mask->hdr.src_port; + udp.val.dst_port = spec->hdr.dst_port; + udp.val.src_port = spec->hdr.src_port; + udp.mask.dst_port = mask->hdr.dst_port; + udp.mask.src_port = mask->hdr.src_port; /* Remove unwanted bits from values. */ - tcp.val.src_port &= tcp.mask.src_port; - tcp.val.dst_port &= tcp.mask.dst_port; + udp.val.src_port &= udp.mask.src_port; + udp.val.dst_port &= udp.mask.dst_port; } - dev_flow->verbs.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, tunnel, ETH_RSS_TCP, - (IBV_RX_HASH_SRC_PORT_TCP | - IBV_RX_HASH_DST_PORT_TCP)); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L4; - flow_verbs_spec_add(dev_flow, &tcp, size); + flow_verbs_spec_add(&dev_flow->verbs, &udp, size); } /** @@ -623,17 +582,17 @@ flow_verbs_translate_item_tcp(const struct rte_flow_item *item, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_vxlan(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_vxlan(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags __rte_unused) { const struct rte_flow_item_vxlan *spec = item->spec; const struct rte_flow_item_vxlan *mask = item->mask; @@ -657,9 +616,7 @@ flow_verbs_translate_item_vxlan(const struct rte_flow_item *item, /* Remove unwanted bits from values. */ vxlan.val.tunnel_id &= vxlan.mask.tunnel_id; } - flow_verbs_spec_add(dev_flow, &vxlan, size); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L2; - *item_flags |= MLX5_FLOW_LAYER_VXLAN; + flow_verbs_spec_add(&dev_flow->verbs, &vxlan, size); } /** @@ -667,17 +624,17 @@ flow_verbs_translate_item_vxlan(const struct rte_flow_item *item, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_vxlan_gpe(const struct rte_flow_item *item, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_vxlan_gpe(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item, + uint64_t item_flags __rte_unused) { const struct rte_flow_item_vxlan_gpe *spec = item->spec; const struct rte_flow_item_vxlan_gpe *mask = item->mask; @@ -701,9 +658,7 @@ flow_verbs_translate_item_vxlan_gpe(const struct rte_flow_item *item, /* Remove unwanted bits from values. */ vxlan_gpe.val.tunnel_id &= vxlan_gpe.mask.tunnel_id; } - flow_verbs_spec_add(dev_flow, &vxlan_gpe, size); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L2; - *item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; + flow_verbs_spec_add(&dev_flow->verbs, &vxlan_gpe, size); } /** @@ -763,17 +718,17 @@ flow_verbs_item_gre_ip_protocol_update(struct ibv_flow_attr *attr, * the input is valid and that there is space to insert the requested item * into the flow. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_gre(const struct rte_flow_item *item __rte_unused, - uint64_t *item_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_item_gre(struct mlx5_flow *dev_flow, + const struct rte_flow_item *item __rte_unused, + uint64_t item_flags) { struct mlx5_flow_verbs *verbs = &dev_flow->verbs; #ifndef HAVE_IBV_DEVICE_MPLS_SUPPORT @@ -804,7 +759,7 @@ flow_verbs_translate_item_gre(const struct rte_flow_item *item __rte_unused, tunnel.val.key &= tunnel.mask.key; } #endif - if (*item_flags & MLX5_FLOW_LAYER_OUTER_L3_IPV4) + if (item_flags & MLX5_FLOW_LAYER_OUTER_L3_IPV4) flow_verbs_item_gre_ip_protocol_update(verbs->attr, IBV_FLOW_SPEC_IPV4_EXT, IPPROTO_GRE); @@ -812,9 +767,7 @@ flow_verbs_translate_item_gre(const struct rte_flow_item *item __rte_unused, flow_verbs_item_gre_ip_protocol_update(verbs->attr, IBV_FLOW_SPEC_IPV6, IPPROTO_GRE); - flow_verbs_spec_add(dev_flow, &tunnel, size); - verbs->attr->priority = MLX5_PRIORITY_MAP_L2; - *item_flags |= MLX5_FLOW_LAYER_GRE; + flow_verbs_spec_add(verbs, &tunnel, size); } /** @@ -822,17 +775,17 @@ flow_verbs_translate_item_gre(const struct rte_flow_item *item __rte_unused, * the input is valid and that there is space to insert the requested action * into the flow. This function also return the action that was added. * + * @param[in, out] dev_flow + * Pointer to dev_flow structure. * @param[in] item * Item specification. - * @param[in, out] item_flags - * Bit mask that marks all detected items. - * @param[in, out] dev_flow - * Pointer to sepacific flow structure. + * @param[in] item_flags + * Parsed item flags. */ static void -flow_verbs_translate_item_mpls(const struct rte_flow_item *item __rte_unused, - uint64_t *action_flags __rte_unused, - struct mlx5_flow *dev_flow __rte_unused) +flow_verbs_translate_item_mpls(struct mlx5_flow *dev_flow __rte_unused, + const struct rte_flow_item *item __rte_unused, + uint64_t item_flags __rte_unused) { #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT const struct rte_flow_item_mpls *spec = item->spec; @@ -851,25 +804,24 @@ flow_verbs_translate_item_mpls(const struct rte_flow_item *item __rte_unused, /* Remove unwanted bits from values. */ mpls.val.label &= mpls.mask.label; } - flow_verbs_spec_add(dev_flow, &mpls, size); - dev_flow->verbs.attr->priority = MLX5_PRIORITY_MAP_L2; - *action_flags |= MLX5_FLOW_LAYER_MPLS; + flow_verbs_spec_add(&dev_flow->verbs, &mpls, size); #endif } /** * Convert the @p action into a Verbs specification. This function assumes that * the input is valid and that there is space to insert the requested action - * into the flow. This function also return the action that was added. + * into the flow. * - * @param[in, out] action_flags - * Pointer to the detected actions. * @param[in] dev_flow * Pointer to mlx5_flow. + * @param[in] action + * Action configuration. */ static void -flow_verbs_translate_action_drop(uint64_t *action_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_action_drop + (struct mlx5_flow *dev_flow, + const struct rte_flow_action *action __rte_unused) { unsigned int size = sizeof(struct ibv_flow_spec_action_drop); struct ibv_flow_spec_action_drop drop = { @@ -877,26 +829,22 @@ flow_verbs_translate_action_drop(uint64_t *action_flags, .size = size, }; - flow_verbs_spec_add(dev_flow, &drop, size); - *action_flags |= MLX5_FLOW_ACTION_DROP; + flow_verbs_spec_add(&dev_flow->verbs, &drop, size); } /** * Convert the @p action into a Verbs specification. This function assumes that * the input is valid and that there is space to insert the requested action - * into the flow. This function also return the action that was added. + * into the flow. * - * @param[in] action - * Action configuration. - * @param[in, out] action_flags - * Pointer to the detected actions. * @param[in] dev_flow * Pointer to mlx5_flow. + * @param[in] action + * Action configuration. */ static void -flow_verbs_translate_action_queue(const struct rte_flow_action *action, - uint64_t *action_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_action_queue(struct mlx5_flow *dev_flow, + const struct rte_flow_action *action) { const struct rte_flow_action_queue *queue = action->conf; struct rte_flow *flow = dev_flow->flow; @@ -904,13 +852,12 @@ flow_verbs_translate_action_queue(const struct rte_flow_action *action, if (flow->queue) (*flow->queue)[0] = queue->index; flow->rss.queue_num = 1; - *action_flags |= MLX5_FLOW_ACTION_QUEUE; } /** * Convert the @p action into a Verbs specification. This function assumes that * the input is valid and that there is space to insert the requested action - * into the flow. This function also return the action that was added. + * into the flow. * * @param[in] action * Action configuration. @@ -920,9 +867,8 @@ flow_verbs_translate_action_queue(const struct rte_flow_action *action, * Pointer to mlx5_flow. */ static void -flow_verbs_translate_action_rss(const struct rte_flow_action *action, - uint64_t *action_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_action_rss(struct mlx5_flow *dev_flow, + const struct rte_flow_action *action) { const struct rte_flow_action_rss *rss = action->conf; const uint8_t *rss_key; @@ -938,26 +884,22 @@ flow_verbs_translate_action_rss(const struct rte_flow_action *action, /* RSS type 0 indicates default RSS type (ETH_RSS_IP). */ flow->rss.types = !rss->types ? ETH_RSS_IP : rss->types; flow->rss.level = rss->level; - *action_flags |= MLX5_FLOW_ACTION_RSS; } /** * Convert the @p action into a Verbs specification. This function assumes that * the input is valid and that there is space to insert the requested action - * into the flow. This function also return the action that was added. + * into the flow. * - * @param[in] action - * Action configuration. - * @param[in, out] action_flags - * Pointer to the detected actions. * @param[in] dev_flow * Pointer to mlx5_flow. + * @param[in] action + * Action configuration. */ static void flow_verbs_translate_action_flag - (const struct rte_flow_action *action __rte_unused, - uint64_t *action_flags, - struct mlx5_flow *dev_flow) + (struct mlx5_flow *dev_flow, + const struct rte_flow_action *action __rte_unused) { unsigned int size = sizeof(struct ibv_flow_spec_action_tag); struct ibv_flow_spec_action_tag tag = { @@ -965,87 +907,44 @@ flow_verbs_translate_action_flag .size = size, .tag_id = mlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT), }; - *action_flags |= MLX5_FLOW_ACTION_MARK; - flow_verbs_spec_add(dev_flow, &tag, size); -} -/** - * Update verbs specification to modify the flag to mark. - * - * @param[in, out] verbs - * Pointer to the mlx5_flow_verbs structure. - * @param[in] mark_id - * Mark identifier to replace the flag. - */ -static void -flow_verbs_mark_update(struct mlx5_flow_verbs *verbs, uint32_t mark_id) -{ - struct ibv_spec_header *hdr; - int i; - - if (!verbs) - return; - /* Update Verbs specification. */ - hdr = (struct ibv_spec_header *)verbs->specs; - if (!hdr) - return; - for (i = 0; i != verbs->attr->num_of_specs; ++i) { - if (hdr->type == IBV_FLOW_SPEC_ACTION_TAG) { - struct ibv_flow_spec_action_tag *t = - (struct ibv_flow_spec_action_tag *)hdr; - - t->tag_id = mlx5_flow_mark_set(mark_id); - } - hdr = (struct ibv_spec_header *)((uintptr_t)hdr + hdr->size); - } + flow_verbs_spec_add(&dev_flow->verbs, &tag, size); } /** * Convert the @p action into a Verbs specification. This function assumes that * the input is valid and that there is space to insert the requested action - * into the flow. This function also return the action that was added. + * into the flow. * - * @param[in] action - * Action configuration. - * @param[in, out] action_flags - * Pointer to the detected actions. * @param[in] dev_flow * Pointer to mlx5_flow. + * @param[in] action + * Action configuration. */ static void -flow_verbs_translate_action_mark(const struct rte_flow_action *action, - uint64_t *action_flags, - struct mlx5_flow *dev_flow) +flow_verbs_translate_action_mark(struct mlx5_flow *dev_flow, + const struct rte_flow_action *action) { const struct rte_flow_action_mark *mark = action->conf; unsigned int size = sizeof(struct ibv_flow_spec_action_tag); struct ibv_flow_spec_action_tag tag = { .type = IBV_FLOW_SPEC_ACTION_TAG, .size = size, + .tag_id = mlx5_flow_mark_set(mark->id), }; - struct mlx5_flow_verbs *verbs = &dev_flow->verbs; - if (*action_flags & MLX5_FLOW_ACTION_FLAG) { - flow_verbs_mark_update(verbs, mark->id); - size = 0; - } else { - tag.tag_id = mlx5_flow_mark_set(mark->id); - flow_verbs_spec_add(dev_flow, &tag, size); - } - *action_flags |= MLX5_FLOW_ACTION_MARK; + flow_verbs_spec_add(&dev_flow->verbs, &tag, size); } /** * Convert the @p action into a Verbs specification. This function assumes that * the input is valid and that there is space to insert the requested action - * into the flow. This function also return the action that was added. + * into the flow. * * @param[in] dev * Pointer to the Ethernet device structure. * @param[in] action * Action configuration. - * @param[in, out] action_flags - * Pointer to the detected actions. * @param[in] dev_flow * Pointer to mlx5_flow. * @param[out] error @@ -1055,10 +954,9 @@ flow_verbs_translate_action_mark(const struct rte_flow_action *action, * 0 On success else a negative errno value is returned and rte_errno is set. */ static int -flow_verbs_translate_action_count(struct rte_eth_dev *dev, +flow_verbs_translate_action_count(struct mlx5_flow *dev_flow, const struct rte_flow_action *action, - uint64_t *action_flags, - struct mlx5_flow *dev_flow, + struct rte_eth_dev *dev, struct rte_flow_error *error) { const struct rte_flow_action_count *count = action->conf; @@ -1082,13 +980,12 @@ flow_verbs_translate_action_count(struct rte_eth_dev *dev, "cannot get counter" " context."); } - *action_flags |= MLX5_FLOW_ACTION_COUNT; #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) counter.counter_set_handle = flow->counter->cs->handle; - flow_verbs_spec_add(dev_flow, &counter, size); + flow_verbs_spec_add(&dev_flow->verbs, &counter, size); #elif defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) counter.counters = flow->counter->cs; - flow_verbs_spec_add(dev_flow, &counter, size); + flow_verbs_spec_add(&dev_flow->verbs, &counter, size); #endif return 0; } @@ -1120,7 +1017,6 @@ flow_verbs_validate(struct rte_eth_dev *dev, int ret; uint64_t action_flags = 0; uint64_t item_flags = 0; - int tunnel = 0; uint8_t next_protocol = 0xff; if (items == NULL) @@ -1129,9 +1025,9 @@ flow_verbs_validate(struct rte_eth_dev *dev, if (ret < 0) return ret; for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { + int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); int ret = 0; - tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); switch (items->type) { case RTE_FLOW_ITEM_TYPE_VOID: break; @@ -1148,8 +1044,10 @@ flow_verbs_validate(struct rte_eth_dev *dev, error); if (ret < 0) return ret; - item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_VLAN : - MLX5_FLOW_LAYER_OUTER_VLAN; + item_flags |= tunnel ? (MLX5_FLOW_LAYER_INNER_L2 | + MLX5_FLOW_LAYER_INNER_VLAN) : + (MLX5_FLOW_LAYER_OUTER_L2 | + MLX5_FLOW_LAYER_OUTER_VLAN); break; case RTE_FLOW_ITEM_TYPE_IPV4: ret = mlx5_flow_validate_item_ipv4(items, item_flags, @@ -1399,8 +1297,11 @@ flow_verbs_get_items_and_size(const struct rte_flow_item items[], break; case RTE_FLOW_ITEM_TYPE_VLAN: size += sizeof(struct ibv_flow_spec_eth); - detected_items |= tunnel ? MLX5_FLOW_LAYER_INNER_VLAN : - MLX5_FLOW_LAYER_OUTER_VLAN; + detected_items |= + tunnel ? (MLX5_FLOW_LAYER_INNER_L2 | + MLX5_FLOW_LAYER_INNER_VLAN) : + (MLX5_FLOW_LAYER_OUTER_L2 | + MLX5_FLOW_LAYER_OUTER_VLAN); break; case RTE_FLOW_ITEM_TYPE_IPV4: size += sizeof(struct ibv_flow_spec_ipv4_ext); @@ -1532,50 +1433,48 @@ flow_verbs_translate(struct rte_eth_dev *dev, const struct rte_flow_action actions[], struct rte_flow_error *error) { - uint64_t action_flags = 0; + struct rte_flow *flow = dev_flow->flow; uint64_t item_flags = 0; + uint64_t action_flags = 0; uint64_t priority = attr->priority; + uint32_t subpriority = 0; struct priv *priv = dev->data->dev_private; if (priority == MLX5_FLOW_PRIO_RSVD) priority = priv->config.flow_prio - 1; for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { int ret; + switch (actions->type) { case RTE_FLOW_ACTION_TYPE_VOID: break; case RTE_FLOW_ACTION_TYPE_FLAG: - flow_verbs_translate_action_flag(actions, - &action_flags, - dev_flow); + flow_verbs_translate_action_flag(dev_flow, actions); + action_flags |= MLX5_FLOW_ACTION_FLAG; break; case RTE_FLOW_ACTION_TYPE_MARK: - flow_verbs_translate_action_mark(actions, - &action_flags, - dev_flow); + flow_verbs_translate_action_mark(dev_flow, actions); + action_flags |= MLX5_FLOW_ACTION_MARK; break; case RTE_FLOW_ACTION_TYPE_DROP: - flow_verbs_translate_action_drop(&action_flags, - dev_flow); + flow_verbs_translate_action_drop(dev_flow, actions); + action_flags |= MLX5_FLOW_ACTION_DROP; break; case RTE_FLOW_ACTION_TYPE_QUEUE: - flow_verbs_translate_action_queue(actions, - &action_flags, - dev_flow); + flow_verbs_translate_action_queue(dev_flow, actions); + action_flags |= MLX5_FLOW_ACTION_QUEUE; break; case RTE_FLOW_ACTION_TYPE_RSS: - flow_verbs_translate_action_rss(actions, - &action_flags, - dev_flow); + flow_verbs_translate_action_rss(dev_flow, actions); + action_flags |= MLX5_FLOW_ACTION_RSS; break; case RTE_FLOW_ACTION_TYPE_COUNT: - ret = flow_verbs_translate_action_count(dev, + ret = flow_verbs_translate_action_count(dev_flow, actions, - &action_flags, - dev_flow, - error); + dev, error); if (ret < 0) return ret; + action_flags |= MLX5_FLOW_ACTION_COUNT; break; default: return rte_flow_error_set(error, ENOTSUP, @@ -1584,51 +1483,100 @@ flow_verbs_translate(struct rte_eth_dev *dev, "action not supported"); } } - /* Device flow should have action flags by flow_drv_prepare(). */ - assert(dev_flow->flow->actions == action_flags); + flow->actions = action_flags; for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { + int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + switch (items->type) { case RTE_FLOW_ITEM_TYPE_VOID: break; case RTE_FLOW_ITEM_TYPE_ETH: - flow_verbs_translate_item_eth(items, &item_flags, - dev_flow); + flow_verbs_translate_item_eth(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L2; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 : + MLX5_FLOW_LAYER_OUTER_L2; break; case RTE_FLOW_ITEM_TYPE_VLAN: - flow_verbs_translate_item_vlan(items, &item_flags, - dev_flow); + flow_verbs_translate_item_vlan(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L2; + item_flags |= tunnel ? (MLX5_FLOW_LAYER_INNER_L2 | + MLX5_FLOW_LAYER_INNER_VLAN) : + (MLX5_FLOW_LAYER_OUTER_L2 | + MLX5_FLOW_LAYER_OUTER_VLAN); break; case RTE_FLOW_ITEM_TYPE_IPV4: - flow_verbs_translate_item_ipv4(items, &item_flags, - dev_flow); + flow_verbs_translate_item_ipv4(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L3; + dev_flow->verbs.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, + MLX5_IPV4_LAYER_TYPES, + MLX5_IPV4_IBV_RX_HASH); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : + MLX5_FLOW_LAYER_OUTER_L3_IPV4; break; case RTE_FLOW_ITEM_TYPE_IPV6: - flow_verbs_translate_item_ipv6(items, &item_flags, - dev_flow); - break; - case RTE_FLOW_ITEM_TYPE_UDP: - flow_verbs_translate_item_udp(items, &item_flags, - dev_flow); + flow_verbs_translate_item_ipv6(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L3; + dev_flow->verbs.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, + MLX5_IPV6_LAYER_TYPES, + MLX5_IPV6_IBV_RX_HASH); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; break; case RTE_FLOW_ITEM_TYPE_TCP: - flow_verbs_translate_item_tcp(items, &item_flags, - dev_flow); + flow_verbs_translate_item_tcp(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L4; + dev_flow->verbs.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, ETH_RSS_TCP, + (IBV_RX_HASH_SRC_PORT_TCP | + IBV_RX_HASH_DST_PORT_TCP)); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP : + MLX5_FLOW_LAYER_OUTER_L4_TCP; + break; + case RTE_FLOW_ITEM_TYPE_UDP: + flow_verbs_translate_item_udp(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L4; + dev_flow->verbs.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, ETH_RSS_UDP, + (IBV_RX_HASH_SRC_PORT_UDP | + IBV_RX_HASH_DST_PORT_UDP)); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP : + MLX5_FLOW_LAYER_OUTER_L4_UDP; break; case RTE_FLOW_ITEM_TYPE_VXLAN: - flow_verbs_translate_item_vxlan(items, &item_flags, - dev_flow); + flow_verbs_translate_item_vxlan(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L2; + item_flags |= MLX5_FLOW_LAYER_VXLAN; break; case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - flow_verbs_translate_item_vxlan_gpe(items, &item_flags, - dev_flow); + flow_verbs_translate_item_vxlan_gpe(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L2; + item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; case RTE_FLOW_ITEM_TYPE_GRE: - flow_verbs_translate_item_gre(items, &item_flags, - dev_flow); + flow_verbs_translate_item_gre(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L2; + item_flags |= MLX5_FLOW_LAYER_GRE; break; case RTE_FLOW_ITEM_TYPE_MPLS: - flow_verbs_translate_item_mpls(items, &item_flags, - dev_flow); + flow_verbs_translate_item_mpls(dev_flow, items, + item_flags); + subpriority = MLX5_PRIORITY_MAP_L2; + item_flags |= MLX5_FLOW_LAYER_MPLS; break; default: return rte_flow_error_set(error, ENOTSUP, @@ -1637,9 +1585,9 @@ flow_verbs_translate(struct rte_eth_dev *dev, "item not supported"); } } + dev_flow->layers = item_flags; dev_flow->verbs.attr->priority = - mlx5_flow_adjust_priority(dev, priority, - dev_flow->verbs.attr->priority); + mlx5_flow_adjust_priority(dev, priority, subpriority); return 0; } From patchwork Mon Nov 5 07:20:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yongseok Koh X-Patchwork-Id: 47804 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2B4915689; Mon, 5 Nov 2018 08:20:50 +0100 (CET) Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00064.outbound.protection.outlook.com [40.107.0.64]) by dpdk.org (Postfix) with ESMTP id 0335A4F9B for ; Mon, 5 Nov 2018 08:20:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7lowDM5CaRDMMHrU/ONzELJK/PVlD3Lg5Zk7sB8YhUc=; b=L94ayeUAp0ba7AzCuzdi1rEoUniwWhp/NxL9P9cAtmzv5eN10d7RFwogO9+JoGhrxzAcgAl4YL30oWQEoGtvrmWmHu68BwKAQji2e4UkLnbvGRRoMB1uNiIw1+6d6eOf025qvn1fpEIsVHn7gIiYOxyqBILENiZnMOOWXSJrTj0= Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by DB3PR0502MB4076.eurprd05.prod.outlook.com (52.134.66.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.30; Mon, 5 Nov 2018 07:20:45 +0000 Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323]) by DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323%3]) with mapi id 15.20.1294.028; Mon, 5 Nov 2018 07:20:45 +0000 From: Yongseok Koh To: Shahaf Shuler CC: "dev@dpdk.org" , Ori Kam , Yongseok Koh Thread-Topic: [PATCH v2 2/3] net/mlx5: fix Direct Verbs flow tunnel Thread-Index: AQHUdNgRO6HStSTstEiBskO3OlOxZQ== Date: Mon, 5 Nov 2018 07:20:45 +0000 Message-ID: <20181105072032.42374-3-yskoh@mellanox.com> References: <20181102210801.28370-1-yskoh@mellanox.com> <20181105072032.42374-1-yskoh@mellanox.com> In-Reply-To: <20181105072032.42374-1-yskoh@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR07CA0030.namprd07.prod.outlook.com (2603:10b6:a02:bc::43) To DB3PR0502MB3980.eurprd05.prod.outlook.com (2603:10a6:8:10::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [209.116.155.178] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR0502MB4076; 6:Q8nWe3ihAZyS46CKVCVxnm4S4ykkBO4IOmiPSJl0sWE6OHs24Ox8/hhOZB8QGWpwDhAjO/ZFooxZlF2gBrxM72bRhT858vdjNCsApuCl4kP/NHXI+sqK3jWkN4i/UZaAC6WfTECG1SHntAMl1qeN+f85ryaoM3MXdbFi1xWPrz6yFeV04JgG2hHRvbIc8GqKkwoRfeVAwJ8wqmwVeWIcnxt65vYCRWaA4f9lewI6Z8cjBS9AqF5PPKLMUsfcI2FX7fKk2vXl91DXR4A/0oTOews7xDAt5UEV7OiFik49gjqcnhX/Ua/OZOkU6hAm5VwViHIgpux6Wd3gtuaHWlTE+ScrXvkNX5twlpefjAl1DmgIi6yWODdhCIucyvQ9sYYdXH1jXI5D8c8OYV2ry8sjxETew85H5cYaObNXK5RR6KQWznk9Zd0TVd2UzOUmZQ8/VAQkvLmZGP4dpl2Cek5Cfw==; 5:mKXKlQSgQYyhEXsWvdHMEh6gsMRT4ORxhFDApJrf0lGoAszNxtcHBB26A9Iz7NdPpj/CJUlyJ+Mj4f6ujDt5pWZCIVSIPURxkWZwgXyrUkdgRitmLfhc9ymG3zde2UB7ZKBPfuW1nPFGah7SNcmFNIjdr6Tgf+Eh4gAY30cD7LM=; 7:GiUqf8APODY5JzgoiyC2i3JFk7EmS4J77Ur1w3qCj9uWZMJt5q7gqPOoWCRsRa7bV6F1qBIzVnbi1516WjRyb+VcCpxy3/vvIT50HS6fSO2QCz8MMP0UwAolRm1bQoHLDbYH77XXRNlVMqiJ5lgmYg== x-ms-office365-filtering-correlation-id: b840c058-d074-4267-6e9d-08d642ef33ca x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB3PR0502MB4076; x-ms-traffictypediagnostic: DB3PR0502MB4076: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(3002001)(93006095)(93001095)(3231382)(944501410)(52105095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:DB3PR0502MB4076; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB4076; x-forefront-prvs: 08476BC6EF x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(376002)(366004)(396003)(136003)(39860400002)(51234002)(189003)(199004)(66066001)(106356001)(25786009)(446003)(11346002)(97736004)(256004)(14454004)(105586002)(14444005)(68736007)(6512007)(53946003)(2900100001)(2906002)(53936002)(3846002)(6116002)(1076002)(37006003)(6506007)(386003)(52116002)(99286004)(36756003)(4744004)(7736002)(305945005)(6486002)(316002)(6436002)(54906003)(186003)(4326008)(102836004)(86362001)(71190400001)(71200400001)(81166006)(81156014)(486006)(8676002)(6862004)(6636002)(5660300001)(478600001)(107886003)(476003)(2616005)(8936002)(76176011)(26005); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB4076; H:DB3PR0502MB3980.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: FcdE986TdCyTkz3dcQE/0dooLBYBp9GS93U6XyW3g3LJWVCbXlRLX7rBU8VV4CL4d17Jrq0fD5y6ih5Tb1fePHoWWAB26ujcYc58fN82VAvCziNBNoXNpTOc4n7XB5j7lAhaTfAvWqFEg/CuIjtMVlVDRq1kzyzufdLHSnMUaNld6rxUEdawQEy5gQRA5dcbN8s+0b3KB2XFvbiWSiGmQo/HI/bVHHW9LWrnDJibDtBbnYzG25qlvjJwu7dn0A/WmO6+cRgZNDYyBOztMOefX5AkFDdV/9HCDKuxhgal/GbiMkch5j57QWCfJTiJIn8YGEzEhNkHsqt7wxskZbR4EkIGEN5IKzQ02yuUnR4jdCY= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: b840c058-d074-4267-6e9d-08d642ef33ca X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Nov 2018 07:20:45.6931 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR0502MB4076 Subject: [dpdk-dev] [PATCH v2 2/3] net/mlx5: fix Direct Verbs flow tunnel 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" 1) Fix layer parsing In translation of tunneled flows, dev_flow->layers must not be used to check tunneled layer as it contains all the layers parsed from flow_drv_prepare(). Checking tunneled layer is needed to distinguish between outer and inner item. This should be based on dynamic parsing. With dev_flow->layers on a tunneled flow, items will always be interpreted as inner as dev_flow->layer already has all the items. Dynamic parsing (item_flags) is added as there's no such code. 2) Refactoring code - flow_dv_create_item() and flow_dv_create_action() are merged into flow_dv_translate() for consistency with Verbs and *_validate(). Fixes: 246636411536 ("net/mlx5: fix flow tunnel handling") Fixes: d02cb0691299 ("net/mlx5: add Direct Verbs translate actions") Fixes: fc2c498ccb94 ("net/mlx5: add Direct Verbs translate items") Cc: orika@mellanox.com Signed-off-by: Yongseok Koh Acked-by: Ori Kam --- drivers/net/mlx5/mlx5_flow_dv.c | 494 +++++++++++++++++++--------------------- 1 file changed, 237 insertions(+), 257 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 1d5b6bf60a..8b4d5956ba 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -1602,252 +1602,6 @@ flow_dv_translate_item_meta(void *matcher, void *key, } } -/** - * Update the matcher and the value based the selected item. - * - * @param[in, out] matcher - * Flow matcher. - * @param[in, out] key - * Flow matcher value. - * @param[in] item - * Flow pattern to translate. - * @param[in, out] dev_flow - * Pointer to the mlx5_flow. - * @param[in] inner - * Item is inner pattern. - */ -static void -flow_dv_create_item(void *matcher, void *key, - const struct rte_flow_item *item, - struct mlx5_flow *dev_flow, - int inner) -{ - struct mlx5_flow_dv_matcher *tmatcher = matcher; - - switch (item->type) { - case RTE_FLOW_ITEM_TYPE_ETH: - flow_dv_translate_item_eth(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority = MLX5_PRIORITY_MAP_L2; - break; - case RTE_FLOW_ITEM_TYPE_VLAN: - flow_dv_translate_item_vlan(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_IPV4: - flow_dv_translate_item_ipv4(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority = MLX5_PRIORITY_MAP_L3; - dev_flow->dv.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, inner, - MLX5_IPV4_LAYER_TYPES, - MLX5_IPV4_IBV_RX_HASH); - break; - case RTE_FLOW_ITEM_TYPE_IPV6: - flow_dv_translate_item_ipv6(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority = MLX5_PRIORITY_MAP_L3; - dev_flow->dv.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, inner, - MLX5_IPV6_LAYER_TYPES, - MLX5_IPV6_IBV_RX_HASH); - break; - case RTE_FLOW_ITEM_TYPE_TCP: - flow_dv_translate_item_tcp(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority = MLX5_PRIORITY_MAP_L4; - dev_flow->dv.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, inner, - ETH_RSS_TCP, - (IBV_RX_HASH_SRC_PORT_TCP | - IBV_RX_HASH_DST_PORT_TCP)); - break; - case RTE_FLOW_ITEM_TYPE_UDP: - flow_dv_translate_item_udp(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority = MLX5_PRIORITY_MAP_L4; - dev_flow->verbs.hash_fields |= - mlx5_flow_hashfields_adjust(dev_flow, inner, - ETH_RSS_UDP, - (IBV_RX_HASH_SRC_PORT_UDP | - IBV_RX_HASH_DST_PORT_UDP)); - break; - case RTE_FLOW_ITEM_TYPE_GRE: - flow_dv_translate_item_gre(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_NVGRE: - flow_dv_translate_item_nvgre(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_VXLAN: - case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - flow_dv_translate_item_vxlan(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_META: - flow_dv_translate_item_meta(tmatcher->mask.buf, key, item); - break; - default: - break; - } -} - -/** - * Store the requested actions in an array. - * - * @param[in] dev - * Pointer to rte_eth_dev structure. - * @param[in] action - * Flow action to translate. - * @param[in, out] dev_flow - * Pointer to the mlx5_flow. - * @param[in] attr - * Pointer to the flow attributes. - * @param[out] error - * Pointer to the error structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -flow_dv_create_action(struct rte_eth_dev *dev, - const struct rte_flow_action *action, - struct mlx5_flow *dev_flow, - const struct rte_flow_attr *attr, - struct rte_flow_error *error) -{ - const struct rte_flow_action_queue *queue; - const struct rte_flow_action_rss *rss; - int actions_n = dev_flow->dv.actions_n; - struct rte_flow *flow = dev_flow->flow; - const struct rte_flow_action *action_ptr = action; - const uint8_t *rss_key; - - switch (action->type) { - case RTE_FLOW_ACTION_TYPE_VOID: - break; - case RTE_FLOW_ACTION_TYPE_FLAG: - dev_flow->dv.actions[actions_n].type = MLX5DV_FLOW_ACTION_TAG; - dev_flow->dv.actions[actions_n].tag_value = - mlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT); - actions_n++; - flow->actions |= MLX5_FLOW_ACTION_FLAG; - break; - case RTE_FLOW_ACTION_TYPE_MARK: - dev_flow->dv.actions[actions_n].type = MLX5DV_FLOW_ACTION_TAG; - dev_flow->dv.actions[actions_n].tag_value = - mlx5_flow_mark_set - (((const struct rte_flow_action_mark *) - (action->conf))->id); - flow->actions |= MLX5_FLOW_ACTION_MARK; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_DROP: - dev_flow->dv.actions[actions_n].type = MLX5DV_FLOW_ACTION_DROP; - flow->actions |= MLX5_FLOW_ACTION_DROP; - break; - case RTE_FLOW_ACTION_TYPE_QUEUE: - queue = action->conf; - flow->rss.queue_num = 1; - (*flow->queue)[0] = queue->index; - flow->actions |= MLX5_FLOW_ACTION_QUEUE; - break; - case RTE_FLOW_ACTION_TYPE_RSS: - rss = action->conf; - if (flow->queue) - memcpy((*flow->queue), rss->queue, - rss->queue_num * sizeof(uint16_t)); - flow->rss.queue_num = rss->queue_num; - /* NULL RSS key indicates default RSS key. */ - rss_key = !rss->key ? rss_hash_default_key : rss->key; - memcpy(flow->key, rss_key, MLX5_RSS_HASH_KEY_LEN); - /* RSS type 0 indicates default RSS type ETH_RSS_IP. */ - flow->rss.types = !rss->types ? ETH_RSS_IP : rss->types; - flow->rss.level = rss->level; - /* Added to array only in apply since we need the QP */ - flow->actions |= MLX5_FLOW_ACTION_RSS; - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: - case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: - if (flow_dv_create_action_l2_encap(dev, action, - dev_flow, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type = - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action = - dev_flow->dv.encap_decap->verbs_action; - flow->actions |= action->type == - RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP ? - MLX5_FLOW_ACTION_VXLAN_ENCAP : - MLX5_FLOW_ACTION_NVGRE_ENCAP; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: - case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: - if (flow_dv_create_action_l2_decap(dev, dev_flow, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type = - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action = - dev_flow->dv.encap_decap->verbs_action; - flow->actions |= action->type == - RTE_FLOW_ACTION_TYPE_VXLAN_DECAP ? - MLX5_FLOW_ACTION_VXLAN_DECAP : - MLX5_FLOW_ACTION_NVGRE_DECAP; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: - /* Handle encap action with preceding decap */ - if (flow->actions & MLX5_FLOW_ACTION_RAW_DECAP) { - if (flow_dv_create_action_raw_encap(dev, action, - dev_flow, - attr, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type = - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action = - dev_flow->dv.encap_decap->verbs_action; - } else { - /* Handle encap action without preceding decap */ - if (flow_dv_create_action_l2_encap(dev, action, - dev_flow, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type = - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action = - dev_flow->dv.encap_decap->verbs_action; - } - flow->actions |= MLX5_FLOW_ACTION_RAW_ENCAP; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_RAW_DECAP: - /* Check if this decap action is followed by encap. */ - for (; action_ptr->type != RTE_FLOW_ACTION_TYPE_END && - action_ptr->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP; - action_ptr++) { - } - /* Handle decap action only if it isn't followed by encap */ - if (action_ptr->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { - if (flow_dv_create_action_l2_decap(dev, dev_flow, - error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type = - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action = - dev_flow->dv.encap_decap->verbs_action; - actions_n++; - } - /* If decap is followed by encap, handle it at encap case. */ - flow->actions |= MLX5_FLOW_ACTION_RAW_DECAP; - break; - default: - break; - } - dev_flow->dv.actions_n = actions_n; - return 0; -} - static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 }; #define HEADER_IS_ZERO(match_criteria, headers) \ @@ -1989,34 +1743,260 @@ flow_dv_translate(struct rte_eth_dev *dev, struct rte_flow_error *error) { struct priv *priv = dev->data->dev_private; + struct rte_flow *flow = dev_flow->flow; + uint64_t item_flags = 0; + uint64_t action_flags = 0; uint64_t priority = attr->priority; struct mlx5_flow_dv_matcher matcher = { .mask = { .size = sizeof(matcher.mask.buf), }, }; - void *match_value = dev_flow->dv.value.buf; - int tunnel = 0; + int actions_n = 0; if (priority == MLX5_FLOW_PRIO_RSVD) priority = priv->config.flow_prio - 1; for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { - tunnel = !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); - flow_dv_create_item(&matcher, match_value, items, dev_flow, - tunnel); + int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + void *match_mask = matcher.mask.buf; + void *match_value = dev_flow->dv.value.buf; + + switch (items->type) { + case RTE_FLOW_ITEM_TYPE_ETH: + flow_dv_translate_item_eth(match_mask, match_value, + items, tunnel); + matcher.priority = MLX5_PRIORITY_MAP_L2; + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 : + MLX5_FLOW_LAYER_OUTER_L2; + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + flow_dv_translate_item_vlan(match_mask, match_value, + items, tunnel); + matcher.priority = MLX5_PRIORITY_MAP_L2; + item_flags |= tunnel ? (MLX5_FLOW_LAYER_INNER_L2 | + MLX5_FLOW_LAYER_INNER_VLAN) : + (MLX5_FLOW_LAYER_OUTER_L2 | + MLX5_FLOW_LAYER_OUTER_VLAN); + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + flow_dv_translate_item_ipv4(match_mask, match_value, + items, tunnel); + matcher.priority = MLX5_PRIORITY_MAP_L3; + dev_flow->dv.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, + MLX5_IPV4_LAYER_TYPES, + MLX5_IPV4_IBV_RX_HASH); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : + MLX5_FLOW_LAYER_OUTER_L3_IPV4; + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + flow_dv_translate_item_ipv6(match_mask, match_value, + items, tunnel); + matcher.priority = MLX5_PRIORITY_MAP_L3; + dev_flow->dv.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, + MLX5_IPV6_LAYER_TYPES, + MLX5_IPV6_IBV_RX_HASH); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; + break; + case RTE_FLOW_ITEM_TYPE_TCP: + flow_dv_translate_item_tcp(match_mask, match_value, + items, tunnel); + matcher.priority = MLX5_PRIORITY_MAP_L4; + dev_flow->dv.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, ETH_RSS_TCP, + IBV_RX_HASH_SRC_PORT_TCP | + IBV_RX_HASH_DST_PORT_TCP); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP : + MLX5_FLOW_LAYER_OUTER_L4_TCP; + break; + case RTE_FLOW_ITEM_TYPE_UDP: + flow_dv_translate_item_udp(match_mask, match_value, + items, tunnel); + matcher.priority = MLX5_PRIORITY_MAP_L4; + dev_flow->verbs.hash_fields |= + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, ETH_RSS_UDP, + IBV_RX_HASH_SRC_PORT_UDP | + IBV_RX_HASH_DST_PORT_UDP); + item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP : + MLX5_FLOW_LAYER_OUTER_L4_UDP; + break; + case RTE_FLOW_ITEM_TYPE_GRE: + flow_dv_translate_item_gre(match_mask, match_value, + items, tunnel); + item_flags |= MLX5_FLOW_LAYER_GRE; + break; + case RTE_FLOW_ITEM_TYPE_NVGRE: + flow_dv_translate_item_nvgre(match_mask, match_value, + items, tunnel); + item_flags |= MLX5_FLOW_LAYER_GRE; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + flow_dv_translate_item_vxlan(match_mask, match_value, + items, tunnel); + item_flags |= MLX5_FLOW_LAYER_VXLAN; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + flow_dv_translate_item_vxlan(match_mask, match_value, + items, tunnel); + item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; + break; + case RTE_FLOW_ITEM_TYPE_META: + flow_dv_translate_item_meta(match_mask, match_value, + items); + item_flags |= MLX5_FLOW_ITEM_METADATA; + break; + default: + break; + } } + dev_flow->layers = item_flags; + /* Register matcher. */ matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf, - matcher.mask.size); - if (priority == MLX5_FLOW_PRIO_RSVD) - priority = priv->config.flow_prio - 1; + matcher.mask.size); matcher.priority = mlx5_flow_adjust_priority(dev, priority, matcher.priority); matcher.egress = attr->egress; if (flow_dv_matcher_register(dev, &matcher, dev_flow, error)) return -rte_errno; - for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) - if (flow_dv_create_action(dev, actions, dev_flow, attr, error)) - return -rte_errno; + for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { + const struct rte_flow_action_queue *queue; + const struct rte_flow_action_rss *rss; + const struct rte_flow_action *action = actions; + const uint8_t *rss_key; + + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_VOID: + break; + case RTE_FLOW_ACTION_TYPE_FLAG: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_TAG; + dev_flow->dv.actions[actions_n].tag_value = + mlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT); + actions_n++; + action_flags |= MLX5_FLOW_ACTION_FLAG; + break; + case RTE_FLOW_ACTION_TYPE_MARK: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_TAG; + dev_flow->dv.actions[actions_n].tag_value = + mlx5_flow_mark_set + (((const struct rte_flow_action_mark *) + (actions->conf))->id); + actions_n++; + action_flags |= MLX5_FLOW_ACTION_MARK; + break; + case RTE_FLOW_ACTION_TYPE_DROP: + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_DROP; + action_flags |= MLX5_FLOW_ACTION_DROP; + break; + case RTE_FLOW_ACTION_TYPE_QUEUE: + queue = actions->conf; + flow->rss.queue_num = 1; + (*flow->queue)[0] = queue->index; + action_flags |= MLX5_FLOW_ACTION_QUEUE; + break; + case RTE_FLOW_ACTION_TYPE_RSS: + rss = actions->conf; + if (flow->queue) + memcpy((*flow->queue), rss->queue, + rss->queue_num * sizeof(uint16_t)); + flow->rss.queue_num = rss->queue_num; + /* NULL RSS key indicates default RSS key. */ + rss_key = !rss->key ? rss_hash_default_key : rss->key; + memcpy(flow->key, rss_key, MLX5_RSS_HASH_KEY_LEN); + /* RSS type 0 indicates default RSS type ETH_RSS_IP. */ + flow->rss.types = !rss->types ? ETH_RSS_IP : rss->types; + flow->rss.level = rss->level; + action_flags |= MLX5_FLOW_ACTION_RSS; + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: + if (flow_dv_create_action_l2_encap(dev, actions, + dev_flow, error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + dev_flow->dv.encap_decap->verbs_action; + actions_n++; + action_flags |= actions->type == + RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP ? + MLX5_FLOW_ACTION_VXLAN_ENCAP : + MLX5_FLOW_ACTION_NVGRE_ENCAP; + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: + if (flow_dv_create_action_l2_decap(dev, dev_flow, + error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + dev_flow->dv.encap_decap->verbs_action; + actions_n++; + action_flags |= actions->type == + RTE_FLOW_ACTION_TYPE_VXLAN_DECAP ? + MLX5_FLOW_ACTION_VXLAN_DECAP : + MLX5_FLOW_ACTION_NVGRE_DECAP; + break; + case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: + /* Handle encap with preceding decap. */ + if (action_flags & MLX5_FLOW_ACTION_RAW_DECAP) { + if (flow_dv_create_action_raw_encap + (dev, actions, dev_flow, attr, error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + dev_flow->dv.encap_decap->verbs_action; + } else { + /* Handle encap without preceding decap. */ + if (flow_dv_create_action_l2_encap(dev, actions, + dev_flow, + error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + dev_flow->dv.encap_decap->verbs_action; + } + actions_n++; + action_flags |= MLX5_FLOW_ACTION_RAW_ENCAP; + break; + case RTE_FLOW_ACTION_TYPE_RAW_DECAP: + /* Check if this decap is followed by encap. */ + for (; action->type != RTE_FLOW_ACTION_TYPE_END && + action->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP; + action++) { + } + /* Handle decap only if it isn't followed by encap. */ + if (action->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { + if (flow_dv_create_action_l2_decap(dev, + dev_flow, + error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type = + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action = + dev_flow->dv.encap_decap->verbs_action; + actions_n++; + } + /* If decap is followed by encap, handle it at encap. */ + action_flags |= MLX5_FLOW_ACTION_RAW_DECAP; + break; + default: + break; + } + } + dev_flow->dv.actions_n = actions_n; + flow->actions = action_flags; return 0; } From patchwork Mon Nov 5 07:20:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yongseok Koh X-Patchwork-Id: 47805 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 88C5158CB; Mon, 5 Nov 2018 08:20:51 +0100 (CET) Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on0083.outbound.protection.outlook.com [104.47.1.83]) by dpdk.org (Postfix) with ESMTP id B30D05424 for ; Mon, 5 Nov 2018 08:20:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=O3bt4pGO/GhBJPcuRZfhShFIdVsiem0v7RLiW/qTmFw=; b=PBhQfb5z2Rg2C7D1LqXuvO7MkyFB4RZY8UsKTz9o9+c0J6Pj3n3mcNk4WaDqs0jLzWrxg8kvPDLbK/unoBP92eltpPH6m6G9mL3Id+sfBiGeGR/wLqe2XqrNFCD9a+Ine76QcK6mOcNu5vL/Fl+ildBChNrf3rwVZV4qFi15Pao= Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by DB3PR0502MB4076.eurprd05.prod.outlook.com (52.134.66.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.30; Mon, 5 Nov 2018 07:20:47 +0000 Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323]) by DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323%3]) with mapi id 15.20.1294.028; Mon, 5 Nov 2018 07:20:47 +0000 From: Yongseok Koh To: Shahaf Shuler CC: "dev@dpdk.org" , Ori Kam , Yongseok Koh Thread-Topic: [PATCH v2 3/3] net/mlx5: remove flags setting from flow preparation Thread-Index: AQHUdNgSSYth6STsQ06BUuIakiejTA== Date: Mon, 5 Nov 2018 07:20:47 +0000 Message-ID: <20181105072032.42374-4-yskoh@mellanox.com> References: <20181102210801.28370-1-yskoh@mellanox.com> <20181105072032.42374-1-yskoh@mellanox.com> In-Reply-To: <20181105072032.42374-1-yskoh@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR07CA0030.namprd07.prod.outlook.com (2603:10b6:a02:bc::43) To DB3PR0502MB3980.eurprd05.prod.outlook.com (2603:10a6:8:10::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [209.116.155.178] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR0502MB4076; 6:FGUSvpRDtnccGD/kzNMumQOpypsRrQ2pvBjZb2ewmaxW0bHMISqwqQ4IO7Vc68j4jLURLsDJQCKgddcd/yNLqnAAffLoI+5SOmn2xJ9WdjrkOVegWV9f6UpAxmsxfwCtbd9PyIkQiTgmZfnijBTlZvMfACSsl6n1eTJ9H/t/Ms6ocaaNVVvHp4lh8tvP02PUJE+OR1mLhY/gtEjXlvFp86rjcozA7XeYM+W9CfKCvpLYPSR2wbXo5l5umkoTVG4RqJXBZ4rIY8WMVYeIww0ytAZoi4LbbLrpIejZamWnM/bbC5WcqECUg7UF3/iT6D096oYJAkpmyz6Nx4YchA7fMwMvfHl/6KDInIDq3nkFcJKxom5IcUOKPYaa1dMOcngB/qoQBeNE1kYWxmIrarzKP6nd/ExkeOTarvGl+2i0rHzDft+VNXl6S/VhOO7ZRqsnyup8RheYqdCSnLJPCq87Qw==; 5:oOUrJIgbqzfzKt4bwcbXJiZATpOcKm5VIE3dof2ZupmTEclOcrcN5y9ep83xM2jqTyDmGdgWzQ1IIqve352nSNBX9ij4nAxU0+N9Pmy8T0RefJIc7r+sGPX63e8ce1HXKwI4c3uA5TWPHKy8OTRjeXpoD5WpDdSEcM54G+yESJQ=; 7:Q5Flzis1xbwvdYFP7QlcSTHITVlKiJCQz4PAP5vhTuDghNVQuW6JH6j6CGqhopTSaehBtb1c6NMlJ/YpJig6K+wyzmy9CLJAblTt8+bC0mIy5ObdQeB0l7uOyBl29Y95Vd5zqM7J75hbCxZDfMYBig== x-ms-office365-filtering-correlation-id: b580b2c5-7908-4d75-c6a8-08d642ef34a5 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB3PR0502MB4076; x-ms-traffictypediagnostic: DB3PR0502MB4076: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(3002001)(93006095)(93001095)(3231382)(944501410)(52105095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:DB3PR0502MB4076; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB4076; x-forefront-prvs: 08476BC6EF x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(376002)(366004)(396003)(136003)(39860400002)(51234002)(189003)(199004)(66066001)(106356001)(25786009)(446003)(11346002)(97736004)(256004)(14454004)(105586002)(14444005)(68736007)(6512007)(53946003)(2900100001)(2906002)(53936002)(3846002)(6116002)(1076002)(37006003)(6506007)(386003)(52116002)(99286004)(36756003)(4744004)(7736002)(305945005)(6486002)(316002)(6436002)(54906003)(186003)(4326008)(102836004)(86362001)(71190400001)(71200400001)(81166006)(81156014)(486006)(8676002)(6862004)(6636002)(5660300001)(478600001)(107886003)(575784001)(476003)(2616005)(8936002)(76176011)(26005); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB4076; H:DB3PR0502MB3980.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: MmjePiicq3+dV4k6HYkVQCtk9QEU/Pu1PnNj17q325Fc2EzyvwJY3F6Z6hpcgGv5LTFCzGyvBYcvxKsyXzr/kaakwmz06N2mQrTJIUfOJS5QqpK2998bs1cYE9Po3MHY5b28XQsRJSOjoyGbFBT7apBfZAOn6Q+6JXwAokHK6efEE4EXT/avtXhkzwX1RQIbiu6fKnou/j2WqRuIsM77tikDcp2hGc9AaGB4YuvRgkqapPEY7e+xaAyHpGMSH75BdTOv7+rG8/jcmZpxFCxmQqUj/Y3zJMgxs1h7gEC1xXAJAmma1eSa9tWqSIBeWOf5StCgHfovHpVcMLrDzqJ7wi/EigLFOZDBDjcMJWs7Kjk= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: b580b2c5-7908-4d75-c6a8-08d642ef34a5 X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Nov 2018 07:20:47.1462 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR0502MB4076 Subject: [dpdk-dev] [PATCH v2 3/3] net/mlx5: remove flags setting from flow preparation 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" Even though flow_drv_prepare() takes item_flags and action_flags to be filled in, those are not used and will be overwritten by parsing of flow_drv_translate(). There's no reason to keep the flags and fill it. Appropriate notes are added to the documentation of flow_drv_prepare() and flow_drv_translate(). Signed-off-by: Yongseok Koh Acked-by: Ori Kam --- drivers/net/mlx5/mlx5_flow.c | 38 ++++++++++------------ drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 6 ---- drivers/net/mlx5/mlx5_flow_tcf.c | 39 +++++++---------------- drivers/net/mlx5/mlx5_flow_verbs.c | 64 +++++--------------------------------- 5 files changed, 37 insertions(+), 113 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index be2cc6b93f..3c2ac4b377 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -1663,8 +1663,6 @@ static struct mlx5_flow * flow_null_prepare(const struct rte_flow_attr *attr __rte_unused, const struct rte_flow_item items[] __rte_unused, const struct rte_flow_action actions[] __rte_unused, - uint64_t *item_flags __rte_unused, - uint64_t *action_flags __rte_unused, struct rte_flow_error *error __rte_unused) { rte_errno = ENOTSUP; @@ -1792,16 +1790,19 @@ flow_drv_validate(struct rte_eth_dev *dev, * calculates the size of memory required for device flow, allocates the memory, * initializes the device flow and returns the pointer. * + * @note + * This function initializes device flow structure such as dv, tcf or verbs in + * struct mlx5_flow. However, it is caller's responsibility to initialize the + * rest. For example, adding returning device flow to flow->dev_flow list and + * setting backward reference to the flow should be done out of this function. + * layers field is not filled either. + * * @param[in] attr * Pointer to the flow attributes. * @param[in] items * Pointer to the list of items. * @param[in] actions * Pointer to the list of actions. - * @param[out] item_flags - * Pointer to bit mask of all items detected. - * @param[out] action_flags - * Pointer to bit mask of all actions detected. * @param[out] error * Pointer to the error structure. * @@ -1809,12 +1810,10 @@ flow_drv_validate(struct rte_eth_dev *dev, * Pointer to device flow on success, otherwise NULL and rte_ernno is set. */ static inline struct mlx5_flow * -flow_drv_prepare(struct rte_flow *flow, +flow_drv_prepare(const struct rte_flow *flow, const struct rte_flow_attr *attr, const struct rte_flow_item items[], const struct rte_flow_action actions[], - uint64_t *item_flags, - uint64_t *action_flags, struct rte_flow_error *error) { const struct mlx5_flow_driver_ops *fops; @@ -1822,8 +1821,7 @@ flow_drv_prepare(struct rte_flow *flow, assert(type > MLX5_FLOW_TYPE_MIN && type < MLX5_FLOW_TYPE_MAX); fops = flow_get_drv_ops(type); - return fops->prepare(attr, items, actions, item_flags, action_flags, - error); + return fops->prepare(attr, items, actions, error); } /** @@ -1832,6 +1830,12 @@ flow_drv_prepare(struct rte_flow *flow, * translates a generic flow into a driver flow. flow_drv_prepare() must * precede. * + * @note + * dev_flow->layers could be filled as a result of parsing during translation + * if needed by flow_drv_apply(). dev_flow->flow->actions can also be filled + * if necessary. As a flow can have multiple dev_flows by RSS flow expansion, + * flow->actions could be overwritten even though all the expanded dev_flows + * have the same actions. * * @param[in] dev * Pointer to the rte dev structure. @@ -1895,7 +1899,7 @@ flow_drv_apply(struct rte_eth_dev *dev, struct rte_flow *flow, * Flow driver remove API. This abstracts calling driver specific functions. * Parent flow (rte_flow) should have driver type (drv_type). It removes a flow * on device. All the resources of the flow should be freed by calling - * flow_dv_destroy(). + * flow_drv_destroy(). * * @param[in] dev * Pointer to Ethernet device. @@ -2026,8 +2030,6 @@ flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, { struct rte_flow *flow = NULL; struct mlx5_flow *dev_flow; - uint64_t action_flags = 0; - uint64_t item_flags = 0; const struct rte_flow_action_rss *rss; union { struct rte_flow_expand_rss buf; @@ -2070,16 +2072,10 @@ flow_list_create(struct rte_eth_dev *dev, struct mlx5_flows *list, } for (i = 0; i < buf->entries; ++i) { dev_flow = flow_drv_prepare(flow, attr, buf->entry[i].pattern, - actions, &item_flags, &action_flags, - error); + actions, error); if (!dev_flow) goto error; dev_flow->flow = flow; - dev_flow->layers = item_flags; - /* Store actions once as expanded flows have same actions. */ - if (i == 0) - flow->actions = action_flags; - assert(flow->actions == action_flags); LIST_INSERT_HEAD(&flow->dev_flows, dev_flow, next); ret = flow_drv_translate(dev, dev_flow, attr, buf->entry[i].pattern, diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 2a3ce44b0b..51ab47fe44 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -302,8 +302,7 @@ typedef int (*mlx5_flow_validate_t)(struct rte_eth_dev *dev, struct rte_flow_error *error); typedef struct mlx5_flow *(*mlx5_flow_prepare_t) (const struct rte_flow_attr *attr, const struct rte_flow_item items[], - const struct rte_flow_action actions[], uint64_t *item_flags, - uint64_t *action_flags, struct rte_flow_error *error); + const struct rte_flow_action actions[], struct rte_flow_error *error); typedef int (*mlx5_flow_translate_t)(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow, const struct rte_flow_attr *attr, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 8b4d5956ba..7909615360 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -1014,10 +1014,6 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, * Pointer to the list of items. * @param[in] actions * Pointer to the list of actions. - * @param[out] item_flags - * Pointer to bit mask of all items detected. - * @param[out] action_flags - * Pointer to bit mask of all actions detected. * @param[out] error * Pointer to the error structure. * @@ -1029,8 +1025,6 @@ static struct mlx5_flow * flow_dv_prepare(const struct rte_flow_attr *attr __rte_unused, const struct rte_flow_item items[] __rte_unused, const struct rte_flow_action actions[] __rte_unused, - uint64_t *item_flags __rte_unused, - uint64_t *action_flags __rte_unused, struct rte_flow_error *error) { uint32_t size = sizeof(struct mlx5_flow); diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index ee614b3f1d..fb817b2311 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -2370,24 +2370,21 @@ flow_tcf_validate(struct rte_eth_dev *dev, } /** - * Calculate maximum size of memory for flow items of Linux TC flower and - * extract specified items. + * Calculate maximum size of memory for flow items of Linux TC flower. * + * @param[in] attr + * Pointer to the flow attributes. * @param[in] items * Pointer to the list of items. - * @param[out] item_flags - * Pointer to the detected items. * * @return * Maximum size of memory for items. */ static int -flow_tcf_get_items_and_size(const struct rte_flow_attr *attr, - const struct rte_flow_item items[], - uint64_t *item_flags) +flow_tcf_get_items_size(const struct rte_flow_attr *attr, + const struct rte_flow_item items[]) { int size = 0; - uint64_t flags = 0; size += SZ_NLATTR_STRZ_OF("flower") + SZ_NLATTR_NEST + /* TCA_OPTIONS. */ @@ -2404,7 +2401,6 @@ flow_tcf_get_items_and_size(const struct rte_flow_attr *attr, size += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */ SZ_NLATTR_DATA_OF(ETHER_ADDR_LEN) * 4; /* dst/src MAC addr and mask. */ - flags |= MLX5_FLOW_LAYER_OUTER_L2; break; case RTE_FLOW_ITEM_TYPE_VLAN: size += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */ @@ -2412,37 +2408,31 @@ flow_tcf_get_items_and_size(const struct rte_flow_attr *attr, /* VLAN Ether type. */ SZ_NLATTR_TYPE_OF(uint8_t) + /* VLAN prio. */ SZ_NLATTR_TYPE_OF(uint16_t); /* VLAN ID. */ - flags |= MLX5_FLOW_LAYER_OUTER_VLAN; break; case RTE_FLOW_ITEM_TYPE_IPV4: size += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */ SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_TYPE_OF(uint32_t) * 4; /* dst/src IP addr and mask. */ - flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV4; break; case RTE_FLOW_ITEM_TYPE_IPV6: size += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */ SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_DATA_OF(IPV6_ADDR_LEN) * 4; /* dst/src IP addr and mask. */ - flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV6; break; case RTE_FLOW_ITEM_TYPE_UDP: size += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_TYPE_OF(uint16_t) * 4; /* dst/src port and mask. */ - flags |= MLX5_FLOW_LAYER_OUTER_L4_UDP; break; case RTE_FLOW_ITEM_TYPE_TCP: size += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */ SZ_NLATTR_TYPE_OF(uint16_t) * 4; /* dst/src port and mask. */ - flags |= MLX5_FLOW_LAYER_OUTER_L4_TCP; break; case RTE_FLOW_ITEM_TYPE_VXLAN: size += SZ_NLATTR_TYPE_OF(uint32_t); - flags |= MLX5_FLOW_LAYER_VXLAN; break; default: DRV_LOG(WARNING, @@ -2452,7 +2442,6 @@ flow_tcf_get_items_and_size(const struct rte_flow_attr *attr, break; } } - *item_flags = flags; return size; } @@ -2668,10 +2657,6 @@ flow_tcf_nl_brand(struct nlmsghdr *nlh, uint32_t handle) * Pointer to the list of items. * @param[in] actions * Pointer to the list of actions. - * @param[out] item_flags - * Pointer to bit mask of all items detected. - * @param[out] action_flags - * Pointer to bit mask of all actions detected. * @param[out] error * Pointer to the error structure. * @@ -2683,7 +2668,6 @@ static struct mlx5_flow * flow_tcf_prepare(const struct rte_flow_attr *attr, const struct rte_flow_item items[], const struct rte_flow_action actions[], - uint64_t *item_flags, uint64_t *action_flags, struct rte_flow_error *error) { size_t size = RTE_ALIGN_CEIL @@ -2692,12 +2676,13 @@ flow_tcf_prepare(const struct rte_flow_attr *attr, MNL_ALIGN(sizeof(struct nlmsghdr)) + MNL_ALIGN(sizeof(struct tcmsg)); struct mlx5_flow *dev_flow; + uint64_t action_flags = 0; struct nlmsghdr *nlh; struct tcmsg *tcm; uint8_t *sp, *tun = NULL; - size += flow_tcf_get_items_and_size(attr, items, item_flags); - size += flow_tcf_get_actions_and_size(actions, action_flags); + size += flow_tcf_get_items_size(attr, items); + size += flow_tcf_get_actions_and_size(actions, &action_flags); dev_flow = rte_zmalloc(__func__, size, MNL_ALIGNTO); if (!dev_flow) { rte_flow_error_set(error, ENOMEM, @@ -2706,7 +2691,7 @@ flow_tcf_prepare(const struct rte_flow_attr *attr, return NULL; } sp = (uint8_t *)(dev_flow + 1); - if (*action_flags & MLX5_FLOW_ACTION_VXLAN_ENCAP) { + if (action_flags & MLX5_FLOW_ACTION_VXLAN_ENCAP) { sp = RTE_PTR_ALIGN (sp, alignof(struct flow_tcf_tunnel_hdr)); tun = sp; @@ -2718,7 +2703,7 @@ flow_tcf_prepare(const struct rte_flow_attr *attr, (sizeof(struct flow_tcf_vxlan_encap), MNL_ALIGNTO); #endif - } else if (*action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) { + } else if (action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) { sp = RTE_PTR_ALIGN (sp, alignof(struct flow_tcf_tunnel_hdr)); tun = sp; @@ -2747,9 +2732,9 @@ flow_tcf_prepare(const struct rte_flow_attr *attr, .tcm = tcm, }, }; - if (*action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) + if (action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) dev_flow->tcf.tunnel->type = FLOW_TCF_TUNACT_VXLAN_DECAP; - else if (*action_flags & MLX5_FLOW_ACTION_VXLAN_ENCAP) + else if (action_flags & MLX5_FLOW_ACTION_VXLAN_ENCAP) dev_flow->tcf.tunnel->type = FLOW_TCF_TUNACT_VXLAN_ENCAP; /* * Generate a reasonably unique handle based on the address of the diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index 43fcd0d29e..699cc88c8c 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -1209,23 +1209,18 @@ flow_verbs_validate(struct rte_eth_dev *dev, /** * Calculate the required bytes that are needed for the action part of the verbs - * flow, in addtion returns bit-fields with all the detected action, in order to - * avoid another interation over the actions. + * flow. * * @param[in] actions * Pointer to the list of actions. - * @param[out] action_flags - * Pointer to the detected actions. * * @return * The size of the memory needed for all actions. */ static int -flow_verbs_get_actions_and_size(const struct rte_flow_action actions[], - uint64_t *action_flags) +flow_verbs_get_actions_size(const struct rte_flow_action actions[]) { int size = 0; - uint64_t detected_actions = 0; for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { switch (actions->type) { @@ -1233,128 +1228,89 @@ flow_verbs_get_actions_and_size(const struct rte_flow_action actions[], break; case RTE_FLOW_ACTION_TYPE_FLAG: size += sizeof(struct ibv_flow_spec_action_tag); - detected_actions |= MLX5_FLOW_ACTION_FLAG; break; case RTE_FLOW_ACTION_TYPE_MARK: size += sizeof(struct ibv_flow_spec_action_tag); - detected_actions |= MLX5_FLOW_ACTION_MARK; break; case RTE_FLOW_ACTION_TYPE_DROP: size += sizeof(struct ibv_flow_spec_action_drop); - detected_actions |= MLX5_FLOW_ACTION_DROP; break; case RTE_FLOW_ACTION_TYPE_QUEUE: - detected_actions |= MLX5_FLOW_ACTION_QUEUE; break; case RTE_FLOW_ACTION_TYPE_RSS: - detected_actions |= MLX5_FLOW_ACTION_RSS; break; case RTE_FLOW_ACTION_TYPE_COUNT: #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) || \ defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) size += sizeof(struct ibv_flow_spec_counter_action); #endif - detected_actions |= MLX5_FLOW_ACTION_COUNT; break; default: break; } } - *action_flags = detected_actions; return size; } /** * Calculate the required bytes that are needed for the item part of the verbs - * flow, in addtion returns bit-fields with all the detected action, in order to - * avoid another interation over the actions. + * flow. * - * @param[in] actions + * @param[in] items * Pointer to the list of items. - * @param[in, out] item_flags - * Pointer to the detected items. * * @return * The size of the memory needed for all items. */ static int -flow_verbs_get_items_and_size(const struct rte_flow_item items[], - uint64_t *item_flags) +flow_verbs_get_items_size(const struct rte_flow_item items[]) { int size = 0; - uint64_t detected_items = 0; for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) { - int tunnel = !!(detected_items & MLX5_FLOW_LAYER_TUNNEL); - switch (items->type) { case RTE_FLOW_ITEM_TYPE_VOID: break; case RTE_FLOW_ITEM_TYPE_ETH: size += sizeof(struct ibv_flow_spec_eth); - detected_items |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 : - MLX5_FLOW_LAYER_OUTER_L2; break; case RTE_FLOW_ITEM_TYPE_VLAN: size += sizeof(struct ibv_flow_spec_eth); - detected_items |= - tunnel ? (MLX5_FLOW_LAYER_INNER_L2 | - MLX5_FLOW_LAYER_INNER_VLAN) : - (MLX5_FLOW_LAYER_OUTER_L2 | - MLX5_FLOW_LAYER_OUTER_VLAN); break; case RTE_FLOW_ITEM_TYPE_IPV4: size += sizeof(struct ibv_flow_spec_ipv4_ext); - detected_items |= tunnel ? - MLX5_FLOW_LAYER_INNER_L3_IPV4 : - MLX5_FLOW_LAYER_OUTER_L3_IPV4; break; case RTE_FLOW_ITEM_TYPE_IPV6: size += sizeof(struct ibv_flow_spec_ipv6); - detected_items |= tunnel ? - MLX5_FLOW_LAYER_INNER_L3_IPV6 : - MLX5_FLOW_LAYER_OUTER_L3_IPV6; break; case RTE_FLOW_ITEM_TYPE_UDP: size += sizeof(struct ibv_flow_spec_tcp_udp); - detected_items |= tunnel ? - MLX5_FLOW_LAYER_INNER_L4_UDP : - MLX5_FLOW_LAYER_OUTER_L4_UDP; break; case RTE_FLOW_ITEM_TYPE_TCP: size += sizeof(struct ibv_flow_spec_tcp_udp); - detected_items |= tunnel ? - MLX5_FLOW_LAYER_INNER_L4_TCP : - MLX5_FLOW_LAYER_OUTER_L4_TCP; break; case RTE_FLOW_ITEM_TYPE_VXLAN: size += sizeof(struct ibv_flow_spec_tunnel); - detected_items |= MLX5_FLOW_LAYER_VXLAN; break; case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: size += sizeof(struct ibv_flow_spec_tunnel); - detected_items |= MLX5_FLOW_LAYER_VXLAN_GPE; break; #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT case RTE_FLOW_ITEM_TYPE_GRE: size += sizeof(struct ibv_flow_spec_gre); - detected_items |= MLX5_FLOW_LAYER_GRE; break; case RTE_FLOW_ITEM_TYPE_MPLS: size += sizeof(struct ibv_flow_spec_mpls); - detected_items |= MLX5_FLOW_LAYER_MPLS; break; #else case RTE_FLOW_ITEM_TYPE_GRE: size += sizeof(struct ibv_flow_spec_tunnel); - detected_items |= MLX5_FLOW_LAYER_TUNNEL; break; #endif default: break; } } - *item_flags = detected_items; return size; } @@ -1369,10 +1325,6 @@ flow_verbs_get_items_and_size(const struct rte_flow_item items[], * Pointer to the list of items. * @param[in] actions * Pointer to the list of actions. - * @param[out] item_flags - * Pointer to bit mask of all items detected. - * @param[out] action_flags - * Pointer to bit mask of all actions detected. * @param[out] error * Pointer to the error structure. * @@ -1384,15 +1336,13 @@ static struct mlx5_flow * flow_verbs_prepare(const struct rte_flow_attr *attr __rte_unused, const struct rte_flow_item items[], const struct rte_flow_action actions[], - uint64_t *item_flags, - uint64_t *action_flags, struct rte_flow_error *error) { uint32_t size = sizeof(struct mlx5_flow) + sizeof(struct ibv_flow_attr); struct mlx5_flow *flow; - size += flow_verbs_get_actions_and_size(actions, action_flags); - size += flow_verbs_get_items_and_size(items, item_flags); + size += flow_verbs_get_actions_size(actions); + size += flow_verbs_get_items_size(items); flow = rte_calloc(__func__, 1, size, 0); if (!flow) { rte_flow_error_set(error, ENOMEM,