From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E66D2A0352; Tue, 5 Nov 2019 09:04:49 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 455161BECD; Tue, 5 Nov 2019 09:02:28 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id BC1D01BE93 for ; Tue, 5 Nov 2019 09:02:13 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from viacheslavo@mellanox.com) with ESMTPS (AES256-SHA encrypted); 5 Nov 2019 10:02:09 +0200 Received: from pegasus11.mtr.labs.mlnx (pegasus11.mtr.labs.mlnx [10.210.16.104]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id xA5828Ou026488; Tue, 5 Nov 2019 10:02:08 +0200 Received: from pegasus11.mtr.labs.mlnx (localhost [127.0.0.1]) by pegasus11.mtr.labs.mlnx (8.14.7/8.14.7) with ESMTP id xA5828Ym030770; Tue, 5 Nov 2019 08:02:08 GMT Received: (from viacheslavo@localhost) by pegasus11.mtr.labs.mlnx (8.14.7/8.14.7/Submit) id xA5828Bn030769; Tue, 5 Nov 2019 08:02:08 GMT X-Authentication-Warning: pegasus11.mtr.labs.mlnx: viacheslavo set sender to viacheslavo@mellanox.com using -f From: Viacheslav Ovsiienko To: dev@dpdk.org Cc: matan@mellanox.com, rasland@mellanox.com, thomas@monjalon.net, orika@mellanox.com, Yongseok Koh Date: Tue, 5 Nov 2019 08:01:43 +0000 Message-Id: <1572940915-29416-9-git-send-email-viacheslavo@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1572940915-29416-1-git-send-email-viacheslavo@mellanox.com> References: <1572940915-29416-1-git-send-email-viacheslavo@mellanox.com> Subject: [dpdk-dev] [PATCH 08/20] net/mlx5: check metadata registers availability X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The metadata registers reg_c provide support for TAG and SET_TAG features. Although there are 8 registers are available on the current mlx5 devices, some of them can be reserved. The availability should be queried by iterative trial-and-error implemented by mlx5_flow_discover_mreg_c() routine. If reg_c is available, it can be regarded inclusively that the extensive metadata support is possible. E.g. metadata register copy action, supporting 16 modify header actions (instead of 8 by default) preserving register across different domains (FDB and NIC) and so on. Signed-off-by: Yongseok Koh Signed-off-by: Viacheslav Ovsiienko Acked-by: Matan Azrad --- drivers/net/mlx5/mlx5.c | 11 +++++ drivers/net/mlx5/mlx5.h | 11 ++++- drivers/net/mlx5/mlx5_ethdev.c | 8 +++- drivers/net/mlx5/mlx5_flow.c | 98 +++++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_flow.h | 13 ------ drivers/net/mlx5/mlx5_flow_dv.c | 9 ++-- drivers/net/mlx5/mlx5_prm.h | 18 ++++++++ 7 files changed, 148 insertions(+), 20 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 72c30bf..1b86b7b 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -2341,6 +2341,17 @@ struct mlx5_flow_id_pool * goto error; } priv->config.flow_prio = err; + /* Query availibility of metadata reg_c's. */ + err = mlx5_flow_discover_mreg_c(eth_dev); + if (err < 0) { + err = -err; + goto error; + } + if (!mlx5_flow_ext_mreg_supported(eth_dev)) { + DRV_LOG(DEBUG, + "port %u extensive metadata register is not supported", + eth_dev->data->port_id); + } return eth_dev; error: if (priv) { diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index f644998..6b82c6d 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -37,6 +37,7 @@ #include "mlx5_autoconf.h" #include "mlx5_defs.h" #include "mlx5_glue.h" +#include "mlx5_prm.h" enum { PCI_VENDOR_ID_MELLANOX = 0x15b3, @@ -252,6 +253,8 @@ struct mlx5_dev_config { } mprq; /* Configurations for Multi-Packet RQ. */ int mps; /* Multi-packet send supported mode. */ unsigned int flow_prio; /* Number of flow priorities. */ + enum modify_reg flow_mreg_c[MLX5_MREG_C_NUM]; + /* Availibility of mreg_c's. */ unsigned int tso_max_payload_sz; /* Maximum TCP payload for TSO. */ unsigned int ind_table_max_size; /* Maximum indirection table size. */ unsigned int max_dump_files_num; /* Maximum dump files per queue. */ @@ -561,6 +564,10 @@ struct mlx5_flow_tbl_resource { #define MLX5_MAX_TABLES UINT16_MAX #define MLX5_HAIRPIN_TX_TABLE (UINT16_MAX - 1) +/* Reserve the last two tables for metadata register copy. */ +#define MLX5_FLOW_MREG_ACT_TABLE_GROUP (MLX5_MAX_TABLES - 1) +#define MLX5_FLOW_MREG_CP_TABLE_GROUP \ + (MLX5_FLOW_MREG_ACT_TABLE_GROUP - 1) #define MLX5_MAX_TABLES_FDB UINT16_MAX #define MLX5_DBR_PAGE_SIZE 4096 /* Must be >= 512. */ @@ -786,7 +793,7 @@ int mlx5_dev_to_pci_addr(const char *dev_path, int mlx5_is_removed(struct rte_eth_dev *dev); eth_tx_burst_t mlx5_select_tx_function(struct rte_eth_dev *dev); eth_rx_burst_t mlx5_select_rx_function(struct rte_eth_dev *dev); -struct mlx5_priv *mlx5_port_to_eswitch_info(uint16_t port); +struct mlx5_priv *mlx5_port_to_eswitch_info(uint16_t port, bool valid); struct mlx5_priv *mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev); int mlx5_sysfs_switch_info(unsigned int ifindex, struct mlx5_switch_info *info); @@ -866,6 +873,8 @@ int mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused, /* mlx5_flow.c */ +int mlx5_flow_discover_mreg_c(struct rte_eth_dev *eth_dev); +bool mlx5_flow_ext_mreg_supported(struct rte_eth_dev *dev); int mlx5_flow_discover_priorities(struct rte_eth_dev *dev); void mlx5_flow_print(struct rte_flow *flow); int mlx5_flow_validate(struct rte_eth_dev *dev, diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index c2bed2f..2b7c867 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -1793,6 +1793,10 @@ int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) * * @param[in] port * Device port id. + * @param[in] valid + * Device port id is valid, skip check. This flag is useful + * when trials are performed from probing and device is not + * flagged as valid yet (in attaching process). * @param[out] es_domain_id * E-Switch domain id. * @param[out] es_port_id @@ -1803,7 +1807,7 @@ int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) * on success, NULL otherwise and rte_errno is set. */ struct mlx5_priv * -mlx5_port_to_eswitch_info(uint16_t port) +mlx5_port_to_eswitch_info(uint16_t port, bool valid) { struct rte_eth_dev *dev; struct mlx5_priv *priv; @@ -1812,7 +1816,7 @@ struct mlx5_priv * rte_errno = EINVAL; return NULL; } - if (!rte_eth_dev_is_valid_port(port)) { + if (!valid && !rte_eth_dev_is_valid_port(port)) { rte_errno = ENODEV; return NULL; } diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 6e6c845..f32ea8d 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -368,6 +368,33 @@ static enum modify_reg flow_get_reg_id(struct rte_eth_dev *dev, NULL, "invalid feature name"); } + +/** + * Check extensive flow metadata register support. + * + * @param dev + * Pointer to rte_eth_dev structure. + * + * @return + * True if device supports extensive flow metadata register, otherwise false. + */ +bool +mlx5_flow_ext_mreg_supported(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_config *config = &priv->config; + + /* + * Having available reg_c can be regarded inclusively as supporting + * extensive flow metadata register, which could mean, + * - metadata register copy action by modify header. + * - 16 modify header actions is supported. + * - reg_c's are preserved across different domain (FDB and NIC) on + * packet loopback by flow lookup miss. + */ + return config->flow_mreg_c[2] != REG_NONE; +} + /** * Discover the maximum number of priority available. * @@ -4033,3 +4060,74 @@ struct rte_flow * } return 0; } + +/** + * Discover availability of metadata reg_c's. + * + * Iteratively use test flows to check availability. + * + * @param[in] dev + * Pointer to the Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_config *config = &priv->config; + enum modify_reg idx; + int n = 0; + + /* reg_c[0] and reg_c[1] are reserved. */ + config->flow_mreg_c[n++] = REG_C_0; + config->flow_mreg_c[n++] = REG_C_1; + /* Discover availability of other reg_c's. */ + for (idx = REG_C_2; idx <= REG_C_7; ++idx) { + struct rte_flow_attr attr = { + .group = MLX5_FLOW_MREG_CP_TABLE_GROUP, + .priority = MLX5_FLOW_PRIO_RSVD, + .ingress = 1, + }; + struct rte_flow_item items[] = { + [0] = { + .type = RTE_FLOW_ITEM_TYPE_END, + }, + }; + struct rte_flow_action actions[] = { + [0] = { + .type = MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG, + .conf = &(struct mlx5_flow_action_copy_mreg){ + .src = REG_C_1, + .dst = idx, + }, + }, + [1] = { + .type = RTE_FLOW_ACTION_TYPE_JUMP, + .conf = &(struct rte_flow_action_jump){ + .group = MLX5_FLOW_MREG_ACT_TABLE_GROUP, + }, + }, + [2] = { + .type = RTE_FLOW_ACTION_TYPE_END, + }, + }; + struct rte_flow *flow; + struct rte_flow_error error; + + if (!config->dv_flow_en) + break; + /* Create internal flow, validation skips copy action. */ + flow = flow_list_create(dev, NULL, &attr, items, + actions, false, &error); + if (!flow) + continue; + if (dev->data->dev_started || !flow_drv_apply(dev, flow, NULL)) + config->flow_mreg_c[n++] = idx; + flow_list_destroy(dev, NULL, flow); + } + for (; n < MLX5_MREG_C_NUM; ++n) + config->flow_mreg_c[n] = REG_NONE; + return 0; +} diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index b9a9507..f2b6726 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -27,19 +27,6 @@ #include "mlx5.h" #include "mlx5_prm.h" -enum modify_reg { - REG_A, - REG_B, - REG_C_0, - REG_C_1, - REG_C_2, - REG_C_3, - REG_C_4, - REG_C_5, - REG_C_6, - REG_C_7, -}; - /* Private rte flow items. */ enum mlx5_rte_flow_item_type { MLX5_RTE_FLOW_ITEM_TYPE_END = INT_MIN, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 853e879..8b93022 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -830,6 +830,7 @@ struct field_modify_info modify_tcp[] = { } static enum mlx5_modification_field reg_to_field[] = { + [REG_NONE] = MLX5_MODI_OUT_NONE, [REG_A] = MLX5_MODI_META_DATA_REG_A, [REG_B] = MLX5_MODI_META_DATA_REG_B, [REG_C_0] = MLX5_MODI_META_REG_C_0, @@ -1038,7 +1039,7 @@ struct field_modify_info modify_tcp[] = { return ret; if (!spec) return 0; - esw_priv = mlx5_port_to_eswitch_info(spec->id); + esw_priv = mlx5_port_to_eswitch_info(spec->id, false); if (!esw_priv) return rte_flow_error_set(error, rte_errno, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, spec, @@ -2695,7 +2696,7 @@ struct field_modify_info modify_tcp[] = { "failed to obtain E-Switch info"); port_id = action->conf; port = port_id->original ? dev->data->port_id : port_id->id; - act_priv = mlx5_port_to_eswitch_info(port); + act_priv = mlx5_port_to_eswitch_info(port, false); if (!act_priv) return rte_flow_error_set (error, rte_errno, @@ -5090,7 +5091,7 @@ struct field_modify_info modify_tcp[] = { mask = pid_m ? pid_m->id : 0xffff; id = pid_v ? pid_v->id : dev->data->port_id; - priv = mlx5_port_to_eswitch_info(id); + priv = mlx5_port_to_eswitch_info(id, item == NULL); if (!priv) return -rte_errno; /* Translate to vport field or to metadata, depending on mode. */ @@ -5538,7 +5539,7 @@ struct field_modify_info modify_tcp[] = { (const struct rte_flow_action_port_id *)action->conf; port = conf->original ? dev->data->port_id : conf->id; - priv = mlx5_port_to_eswitch_info(port); + priv = mlx5_port_to_eswitch_info(port, false); if (!priv) return rte_flow_error_set(error, -rte_errno, RTE_FLOW_ERROR_TYPE_ACTION, diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h index b9e53f5..c17ba66 100644 --- a/drivers/net/mlx5/mlx5_prm.h +++ b/drivers/net/mlx5/mlx5_prm.h @@ -392,6 +392,7 @@ enum { /* The field of packet to be modified. */ enum mlx5_modification_field { + MLX5_MODI_OUT_NONE = -1, MLX5_MODI_OUT_SMAC_47_16 = 1, MLX5_MODI_OUT_SMAC_15_0, MLX5_MODI_OUT_ETHERTYPE, @@ -455,6 +456,23 @@ enum mlx5_modification_field { MLX5_MODI_IN_TCP_ACK_NUM = 0x5C, }; +/* Total number of metadata reg_c's. */ +#define MLX5_MREG_C_NUM (MLX5_MODI_META_REG_C_7 - MLX5_MODI_META_REG_C_0 + 1) + +enum modify_reg { + REG_NONE = 0, + REG_A, + REG_B, + REG_C_0, + REG_C_1, + REG_C_2, + REG_C_3, + REG_C_4, + REG_C_5, + REG_C_6, + REG_C_7, +}; + /* Modification sub command. */ struct mlx5_modification_cmd { union { -- 1.8.3.1