From patchwork Fri Apr 20 12:23:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xueming Li X-Patchwork-Id: 38627 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 1E7B3AAE8; Fri, 20 Apr 2018 14:27:11 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id C3E3CC1EE for ; Fri, 20 Apr 2018 14:27:05 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from xuemingl@mellanox.com) with ESMTPS (AES256-SHA encrypted); 20 Apr 2018 15:25:15 +0300 Received: from dev-r630-06.mtbc.labs.mlnx (dev-r630-06.mtbc.labs.mlnx [10.12.205.180]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w3KCNrlh021525; Fri, 20 Apr 2018 15:23:53 +0300 Received: from dev-r630-06.mtbc.labs.mlnx (localhost [127.0.0.1]) by dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7) with ESMTP id w3KCNrHa113406; Fri, 20 Apr 2018 20:23:53 +0800 Received: (from xuemingl@localhost) by dev-r630-06.mtbc.labs.mlnx (8.14.7/8.14.7/Submit) id w3KCNr7v113405; Fri, 20 Apr 2018 20:23:53 +0800 From: Xueming Li To: Iremonger Bernard , Nelio Laranjeiro , Shahaf Shuler Cc: Xueming Li , dev@dpdk.org Date: Fri, 20 Apr 2018 20:23:30 +0800 Message-Id: <20180420122340.113348-2-xuemingl@mellanox.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20180420122340.113348-1-xuemingl@mellanox.com> References: <20180420122340.113348-1-xuemingl@mellanox.com> In-Reply-To: <20180417151436.161374-1-xuemingl@mellanox.com> References: <20180417151436.161374-1-xuemingl@mellanox.com> Subject: [dpdk-dev] [PATCH v5 01/11] net/mlx5: support 16 hardware priorities 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" This patch supports new 16 Verbs flow priorities by trying to create a simple flow of priority 15. If 16 priorities not available, fallback to traditional 8 priorities. Verb priority mapping: 8 priorities >=16 priorities Control flow: 4-7 8-15 User normal flow: 1-3 4-7 User tunnel flow: 0-2 0-3 Signed-off-by: Xueming Li --- drivers/net/mlx5/mlx5.c | 18 +++++++ drivers/net/mlx5/mlx5.h | 5 ++ drivers/net/mlx5/mlx5_flow.c | 113 +++++++++++++++++++++++++++++++++------- drivers/net/mlx5/mlx5_trigger.c | 8 --- 4 files changed, 116 insertions(+), 28 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 68783c3ac..5a0b8de85 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -197,6 +197,7 @@ mlx5_dev_close(struct rte_eth_dev *dev) priv->txqs_n = 0; priv->txqs = NULL; } + mlx5_flow_delete_drop_queue(dev); if (priv->pd != NULL) { assert(priv->ctx != NULL); claim_zero(mlx5_glue->dealloc_pd(priv->pd)); @@ -619,6 +620,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, unsigned int mps; unsigned int cqe_comp; unsigned int tunnel_en = 0; + unsigned int verb_priorities = 0; int idx; int i; struct mlx5dv_context attrs_out = {0}; @@ -1006,6 +1008,22 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, mlx5_link_update(eth_dev, 0); /* Store device configuration on private structure. */ priv->config = config; + /* Create drop queue. */ + err = mlx5_flow_create_drop_queue(eth_dev); + if (err) { + DRV_LOG(ERR, "port %u drop queue allocation failed: %s", + eth_dev->data->port_id, strerror(rte_errno)); + goto port_error; + } + /* Supported Verbs flow priority number detection. */ + if (verb_priorities == 0) + verb_priorities = mlx5_get_max_verbs_prio(eth_dev); + if (verb_priorities < MLX5_VERBS_FLOW_PRIO_8) { + DRV_LOG(ERR, "port %u wrong Verbs flow priorities: %u", + eth_dev->data->port_id, verb_priorities); + goto port_error; + } + priv->config.max_verbs_prio = verb_priorities; continue; port_error: if (priv) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 6ad41390a..670f6860f 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -89,6 +89,7 @@ struct mlx5_dev_config { unsigned int rx_vec_en:1; /* Rx vector is enabled. */ unsigned int mpw_hdr_dseg:1; /* Enable DSEGs in the title WQEBB. */ unsigned int vf_nl_en:1; /* Enable Netlink requests in VF mode. */ + unsigned int max_verbs_prio; /* Number of Verb flow priorities. */ unsigned int tso_max_payload_sz; /* Maximum TCP payload for TSO. */ unsigned int ind_table_max_size; /* Maximum indirection table size. */ int txq_inline; /* Maximum packet size for inlining. */ @@ -105,6 +106,9 @@ enum mlx5_verbs_alloc_type { MLX5_VERBS_ALLOC_TYPE_RX_QUEUE, }; +/* 8 Verbs priorities. */ +#define MLX5_VERBS_FLOW_PRIO_8 8 + /** * Verbs allocator needs a context to know in the callback which kind of * resources it is allocating. @@ -253,6 +257,7 @@ int mlx5_traffic_restart(struct rte_eth_dev *dev); /* mlx5_flow.c */ +unsigned int mlx5_get_max_verbs_prio(struct rte_eth_dev *dev); int mlx5_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item items[], diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index e6c8b3df8..5402cb148 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -31,8 +31,8 @@ #include "mlx5_prm.h" #include "mlx5_glue.h" -/* Define minimal priority for control plane flows. */ -#define MLX5_CTRL_FLOW_PRIORITY 4 +/* Flow priority for control plane flows. */ +#define MLX5_CTRL_FLOW_PRIORITY 1 /* Internet Protocol versions. */ #define MLX5_IPV4 4 @@ -128,7 +128,7 @@ const struct hash_rxq_init hash_rxq_init[] = { IBV_RX_HASH_SRC_PORT_TCP | IBV_RX_HASH_DST_PORT_TCP), .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_TCP, - .flow_priority = 1, + .flow_priority = 0, .ip_version = MLX5_IPV4, }, [HASH_RXQ_UDPV4] = { @@ -137,7 +137,7 @@ const struct hash_rxq_init hash_rxq_init[] = { IBV_RX_HASH_SRC_PORT_UDP | IBV_RX_HASH_DST_PORT_UDP), .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_UDP, - .flow_priority = 1, + .flow_priority = 0, .ip_version = MLX5_IPV4, }, [HASH_RXQ_IPV4] = { @@ -145,7 +145,7 @@ const struct hash_rxq_init hash_rxq_init[] = { IBV_RX_HASH_DST_IPV4), .dpdk_rss_hf = (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4), - .flow_priority = 2, + .flow_priority = 1, .ip_version = MLX5_IPV4, }, [HASH_RXQ_TCPV6] = { @@ -154,7 +154,7 @@ const struct hash_rxq_init hash_rxq_init[] = { IBV_RX_HASH_SRC_PORT_TCP | IBV_RX_HASH_DST_PORT_TCP), .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_TCP, - .flow_priority = 1, + .flow_priority = 0, .ip_version = MLX5_IPV6, }, [HASH_RXQ_UDPV6] = { @@ -163,7 +163,7 @@ const struct hash_rxq_init hash_rxq_init[] = { IBV_RX_HASH_SRC_PORT_UDP | IBV_RX_HASH_DST_PORT_UDP), .dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_UDP, - .flow_priority = 1, + .flow_priority = 0, .ip_version = MLX5_IPV6, }, [HASH_RXQ_IPV6] = { @@ -171,13 +171,13 @@ const struct hash_rxq_init hash_rxq_init[] = { IBV_RX_HASH_DST_IPV6), .dpdk_rss_hf = (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6), - .flow_priority = 2, + .flow_priority = 1, .ip_version = MLX5_IPV6, }, [HASH_RXQ_ETH] = { .hash_fields = 0, .dpdk_rss_hf = 0, - .flow_priority = 3, + .flow_priority = 2, }, }; @@ -899,30 +899,50 @@ mlx5_flow_convert_allocate(unsigned int size, struct rte_flow_error *error) * Make inner packet matching with an higher priority from the non Inner * matching. * + * @param dev + * Pointer to Ethernet device. * @param[in, out] parser * Internal parser structure. * @param attr * User flow attribute. */ static void -mlx5_flow_update_priority(struct mlx5_flow_parse *parser, +mlx5_flow_update_priority(struct rte_eth_dev *dev, + struct mlx5_flow_parse *parser, const struct rte_flow_attr *attr) { + struct priv *priv = dev->data->dev_private; unsigned int i; + uint16_t priority; + /* 8 priorities >= 16 priorities + * Control flow: 4-7 8-15 + * User normal flow: 1-3 4-7 + * User tunnel flow: 0-2 0-3 + */ + priority = attr->priority * MLX5_VERBS_FLOW_PRIO_8; + if (priv->config.max_verbs_prio == MLX5_VERBS_FLOW_PRIO_8) + priority /= 2; + /* + * Lower non-tunnel flow Verbs priority 1 if only support 8 Verbs + * priorities, lower 4 otherwise. + */ + if (!parser->inner) { + if (priv->config.max_verbs_prio == MLX5_VERBS_FLOW_PRIO_8) + priority += 1; + else + priority += MLX5_VERBS_FLOW_PRIO_8 / 2; + } if (parser->drop) { - parser->queue[HASH_RXQ_ETH].ibv_attr->priority = - attr->priority + - hash_rxq_init[HASH_RXQ_ETH].flow_priority; + parser->queue[HASH_RXQ_ETH].ibv_attr->priority = priority + + hash_rxq_init[HASH_RXQ_ETH].flow_priority; return; } for (i = 0; i != hash_rxq_init_n; ++i) { - if (parser->queue[i].ibv_attr) { - parser->queue[i].ibv_attr->priority = - attr->priority + - hash_rxq_init[i].flow_priority - - (parser->inner ? 1 : 0); - } + if (!parser->queue[i].ibv_attr) + continue; + parser->queue[i].ibv_attr->priority = priority + + hash_rxq_init[i].flow_priority; } } @@ -1157,7 +1177,7 @@ mlx5_flow_convert(struct rte_eth_dev *dev, */ if (!parser->drop) mlx5_flow_convert_finalise(parser); - mlx5_flow_update_priority(parser, attr); + mlx5_flow_update_priority(dev, parser, attr); exit_free: /* Only verification is expected, all resources should be released. */ if (!parser->create) { @@ -3158,3 +3178,56 @@ mlx5_dev_filter_ctrl(struct rte_eth_dev *dev, } return 0; } + +/** + * Detect number of Verbs flow priorities supported. + * + * @param dev + * Pointer to Ethernet device. + * + * @return + * number of supported Verbs flow priority. + */ +unsigned int +mlx5_get_max_verbs_prio(struct rte_eth_dev *dev) +{ + struct priv *priv = dev->data->dev_private; + unsigned int verb_priorities = MLX5_VERBS_FLOW_PRIO_8; + struct { + struct ibv_flow_attr attr; + struct ibv_flow_spec_eth eth; + struct ibv_flow_spec_action_drop drop; + } flow_attr = { + .attr = { + .num_of_specs = 2, + }, + .eth = { + .type = IBV_FLOW_SPEC_ETH, + .size = sizeof(struct ibv_flow_spec_eth), + }, + .drop = { + .size = sizeof(struct ibv_flow_spec_action_drop), + .type = IBV_FLOW_SPEC_ACTION_DROP, + }, + }; + struct ibv_flow *flow; + + do { + flow_attr.attr.priority = verb_priorities - 1; + flow = mlx5_glue->create_flow(priv->flow_drop_queue->qp, + &flow_attr.attr); + if (flow) { + claim_zero(mlx5_glue->destroy_flow(flow)); + /* Try more priorities. */ + verb_priorities *= 2; + } else { + /* Failed, restore last right number. */ + verb_priorities /= 2; + break; + } + } while (1); + DRV_LOG(DEBUG, "port %u Verbs flow priorities: %d," + " user flow priorities: %d", + dev->data->port_id, verb_priorities, MLX5_CTRL_FLOW_PRIORITY); + return verb_priorities; +} diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index ee08c5677..fc56d1ee8 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -148,12 +148,6 @@ mlx5_dev_start(struct rte_eth_dev *dev) int ret; dev->data->dev_started = 1; - ret = mlx5_flow_create_drop_queue(dev); - if (ret) { - DRV_LOG(ERR, "port %u drop queue allocation failed: %s", - dev->data->port_id, strerror(rte_errno)); - goto error; - } DRV_LOG(DEBUG, "port %u allocating and configuring hash Rx queues", dev->data->port_id); rte_mempool_walk(mlx5_mp2mr_iter, priv); @@ -202,7 +196,6 @@ mlx5_dev_start(struct rte_eth_dev *dev) mlx5_traffic_disable(dev); mlx5_txq_stop(dev); mlx5_rxq_stop(dev); - mlx5_flow_delete_drop_queue(dev); rte_errno = ret; /* Restore rte_errno. */ return -rte_errno; } @@ -237,7 +230,6 @@ mlx5_dev_stop(struct rte_eth_dev *dev) mlx5_rxq_stop(dev); for (mr = LIST_FIRST(&priv->mr); mr; mr = LIST_FIRST(&priv->mr)) mlx5_mr_release(mr); - mlx5_flow_delete_drop_queue(dev); } /**