From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 386A345C13; Wed, 30 Oct 2024 10:40:18 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 143CA43351; Wed, 30 Oct 2024 10:40:18 +0100 (CET) Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) by mails.dpdk.org (Postfix) with ESMTP id 5D49F43350 for ; Wed, 30 Oct 2024 10:40:16 +0100 (CET) Received: from mail.maildlp.com (unknown [172.19.88.214]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4Xdhrx3cYkz1jw75; Wed, 30 Oct 2024 17:38:41 +0800 (CST) Received: from kwepemf500004.china.huawei.com (unknown [7.202.181.242]) by mail.maildlp.com (Postfix) with ESMTPS id 5F9A71A016C; Wed, 30 Oct 2024 17:40:13 +0800 (CST) Received: from localhost.localdomain (10.28.79.22) by kwepemf500004.china.huawei.com (7.202.181.242) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 30 Oct 2024 17:40:12 +0800 From: Jie Hai To: , , CC: , , , Subject: [PATCH] net/hns3: support flow rule priority Date: Wed, 30 Oct 2024 17:29:19 +0800 Message-ID: <20241030092919.16756-1-haijie1@huawei.com> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.28.79.22] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemf500004.china.huawei.com (7.202.181.242) X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Dengdui Huang The hardware determines the priority of the flow rule based on the position of the rule in the hardware flow director table. Lower index denotes higher priority (it means when a packet matches multiple indexes, the smaller index wins). This patch implements flow priority based on this feature. To avoid affecting the current use, use runtime config 'fdir_index_config' to select flow director index strategy. The options are as follows: 1. hash: Default config, the rule priority level cannot be set. The driver generates a flow index based on the hash of the rte_flow key. 2. priority: The flow rule priority feature is supported. The driver uses the rte_flow priority field as the flow director index. Signed-off-by: Dengdui Huang Signed-off-by: Jie Hai --- doc/guides/nics/hns3.rst | 12 +++++++ drivers/net/hns3/hns3_common.c | 25 ++++++++++++++ drivers/net/hns3/hns3_common.h | 1 + drivers/net/hns3/hns3_dump.c | 2 ++ drivers/net/hns3/hns3_ethdev.c | 3 +- drivers/net/hns3/hns3_fdir.c | 62 ++++++++++++++++++++++++---------- drivers/net/hns3/hns3_fdir.h | 10 ++++++ drivers/net/hns3/hns3_flow.c | 45 +++++++++++++++++++++--- 8 files changed, 136 insertions(+), 24 deletions(-) diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst index bdc10da1c74f..b8e79c1b575d 100644 --- a/doc/guides/nics/hns3.rst +++ b/doc/guides/nics/hns3.rst @@ -193,6 +193,15 @@ Runtime Configuration ``+outvlan-sctptag``: means disable sctp tag tuple, and enable outer vlan tuple. ``+outvlan-tunvni``: means disable tunnel vni tuple, and enable outer vlan tuple. +- ``fdir_index_config`` (default ``hash``) + + Used to select flow director index strategy, the flow director index is the index + position in the hardware flow director table. Lower index denotes higher priority + (it means when a packet matches multiple indexes, the smaller index wins). + Current supported options are as follows: + ``hash``: The driver generates a flow index based on the hash of the rte_flow key. + ``priority``: the driver uses the rte_flow priority field as the flow director index. + Driver compilation and testing ------------------------------ @@ -322,6 +331,9 @@ Generic flow API configuration for hardware which will affect other rules. The rule just setting input tuple is completely independent. + In addition, if the rule priority level is set, no error is reported, + but the rule priority level does not take effect. + Run ``testpmd``: .. code-block:: console diff --git a/drivers/net/hns3/hns3_common.c b/drivers/net/hns3/hns3_common.c index 99a1d59a8a68..25a45212bed6 100644 --- a/drivers/net/hns3/hns3_common.c +++ b/drivers/net/hns3/hns3_common.c @@ -290,6 +290,27 @@ hns3_parse_fdir_tuple_config(const char *key, const char *value, void *args) return 0; } +static int +hns3_parse_fdir_index_config(const char *key, const char *value, void *args) +{ + enum hns3_fdir_index_config cfg; + + if (strcmp(value, "hash") == 0) { + cfg = HNS3_FDIR_INDEX_CONFIG_HASH; + } else if (strcmp(value, "priority") == 0) { + cfg = HNS3_FDIR_INDEX_CONFIG_PRIORITY; + } else { + PMD_INIT_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", " + "value must be 'hash' or 'priority'", + value, key); + return -1; + } + + *(enum hns3_fdir_index_config *)args = cfg; + + return 0; +} + void hns3_parse_devargs(struct rte_eth_dev *dev) { @@ -333,6 +354,10 @@ hns3_parse_devargs(struct rte_eth_dev *dev) HNS3_DEVARG_FDIR_TUPLE_CONFIG, &hns3_parse_fdir_tuple_config, &hns->pf.fdir.tuple_cfg); + (void)rte_kvargs_process(kvlist, + HNS3_DEVARG_FDIR_INDEX_CONFIG, + &hns3_parse_fdir_index_config, + &hns->pf.fdir.index_cfg); } rte_kvargs_free(kvlist); diff --git a/drivers/net/hns3/hns3_common.h b/drivers/net/hns3/hns3_common.h index ca909365e420..7b3f96b01a82 100644 --- a/drivers/net/hns3/hns3_common.h +++ b/drivers/net/hns3/hns3_common.h @@ -29,6 +29,7 @@ enum { #define HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "fdir_vlan_match_mode" #define HNS3_DEVARG_FDIR_TUPLE_CONFIG "fdir_tuple_config" +#define HNS3_DEVARG_FDIR_INDEX_CONFIG "fdir_index_config" #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L diff --git a/drivers/net/hns3/hns3_dump.c b/drivers/net/hns3/hns3_dump.c index 1a50391851b4..738dcb0c42fc 100644 --- a/drivers/net/hns3/hns3_dump.c +++ b/drivers/net/hns3/hns3_dump.c @@ -169,6 +169,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf) "\t -- mode=%u max_key_len=%u rule_num:%u cnt_num:%u\n" "\t -- key_sel=%u tuple_active=0x%x meta_data_active=0x%x\n" "\t -- ipv6_word_en: in_s=%u in_d=%u out_s=%u out_d=%u\n" + "\t -- index_cfg: %s\n" "\t -- tuple_config: %s\n" "\t -- active_tuples:\n", fdcfg->fd_mode, fdcfg->max_key_length, @@ -181,6 +182,7 @@ hns3_get_fdir_basic_info(FILE *file, struct hns3_pf *pf) fdcfg->key_cfg[HNS3_FD_STAGE_1].inner_dipv6_word_en, fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_sipv6_word_en, fdcfg->key_cfg[HNS3_FD_STAGE_1].outer_dipv6_word_en, + hns3_fdir_index_config_name(pf->fdir.index_cfg), hns3_tuple_config_name(pf->fdir.tuple_cfg)); for (i = 0; i < MAX_TUPLE; i++) { diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 365b8529698b..0b3df565feb0 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -6674,7 +6674,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_hns3, HNS3_DEVARG_FDIR_VLAN_MATCH_MODE "=strict|nostrict " HNS3_DEVARG_FDIR_TUPLE_CONFIG "=+outvlan-insmac|+outvlan-indmac|" "+outvlan-insip|+outvlan-indip" - "+outvlan-sctptag|+outvlan-tunvni "); + "+outvlan-sctptag|+outvlan-tunvni " + HNS3_DEVARG_FDIR_INDEX_CONFIG "=hash|priority "); RTE_LOG_REGISTER_SUFFIX(hns3_logtype_init, init, NOTICE); RTE_LOG_REGISTER_SUFFIX(hns3_logtype_driver, driver, NOTICE); #ifdef RTE_ETHDEV_DEBUG_RX diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c index a354d1d32f16..d18d08353565 100644 --- a/drivers/net/hns3/hns3_fdir.c +++ b/drivers/net/hns3/hns3_fdir.c @@ -981,39 +981,44 @@ static int hns3_insert_fdir_filter(struct hns3_hw *hw, { struct hns3_fdir_key_conf *key; hash_sig_t sig; - int ret; + int index; key = &fdir_filter->fdir_conf.key_conf; sig = rte_hash_crc(key, sizeof(*key), 0); - ret = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig); - if (ret < 0) { - hns3_err(hw, "Hash table full? err:%d!", ret); - return ret; + index = rte_hash_add_key_with_hash(fdir_info->hash_handle, key, sig); + if (index < 0) { + hns3_err(hw, "Hash table full? err:%d!", index); + return index; } - fdir_info->hash_map[ret] = fdir_filter; + if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY) + index = fdir_filter->fdir_conf.location; + + fdir_info->hash_map[index] = fdir_filter; TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries); - return ret; + return index; } static int hns3_remove_fdir_filter(struct hns3_hw *hw, struct hns3_fdir_info *fdir_info, - struct hns3_fdir_key_conf *key) + struct hns3_fdir_rule *rule) { struct hns3_fdir_rule_ele *fdir_filter; hash_sig_t sig; - int ret; + int index; - sig = rte_hash_crc(key, sizeof(*key), 0); - ret = rte_hash_del_key_with_hash(fdir_info->hash_handle, key, sig); - if (ret < 0) { - hns3_err(hw, "Delete hash key fail ret=%d", ret); - return ret; + sig = rte_hash_crc(&rule->key_conf, sizeof(rule->key_conf), 0); + index = rte_hash_del_key_with_hash(fdir_info->hash_handle, &rule->key_conf, sig); + if (index < 0) { + hns3_err(hw, "Delete hash key fail ret=%d", index); + return index; } - fdir_filter = fdir_info->hash_map[ret]; - fdir_info->hash_map[ret] = NULL; + if (fdir_info->index_cfg == HNS3_FDIR_INDEX_CONFIG_PRIORITY) + index = rule->location; + fdir_filter = fdir_info->hash_map[index]; + fdir_info->hash_map[index] = NULL; TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries); rte_free(fdir_filter); @@ -1042,7 +1047,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns, rule->key_conf.spec.src_port, rule->key_conf.spec.dst_port, ret); else - ret = hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf); + ret = hns3_remove_fdir_filter(hw, fdir_info, rule); return ret; } @@ -1080,7 +1085,7 @@ int hns3_fdir_filter_program(struct hns3_adapter *hns, rule->key_conf.spec.dst_ip[IP_ADDR_KEY_ID], rule->key_conf.spec.src_port, rule->key_conf.spec.dst_port, ret); - (void)hns3_remove_fdir_filter(hw, fdir_info, &rule->key_conf); + (void)hns3_remove_fdir_filter(hw, fdir_info, rule); } return ret; @@ -1231,3 +1236,24 @@ hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg) return "unknown"; } + +static struct { + enum hns3_fdir_index_config cfg; + const char *name; +} index_cfg_map[] = { + { HNS3_FDIR_INDEX_CONFIG_HASH, "hash"}, + { HNS3_FDIR_INDEX_CONFIG_PRIORITY, "priority"}, +}; + +const char * +hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg) +{ + uint32_t i; + + for (i = 0; i < RTE_DIM(index_cfg_map); i++) { + if (cfg == index_cfg_map[i].cfg) + return index_cfg_map[i].name; + } + + return "unknown"; +} diff --git a/drivers/net/hns3/hns3_fdir.h b/drivers/net/hns3/hns3_fdir.h index 2d0c9bf3c8b6..5ba7b5b60d16 100644 --- a/drivers/net/hns3/hns3_fdir.h +++ b/drivers/net/hns3/hns3_fdir.h @@ -228,6 +228,14 @@ enum hns3_fdir_tuple_config { HNS3_FDIR_TUPLE_CONFIG_BUTT }; +enum hns3_fdir_index_config { + /* Generate the hardware flow director index based on rte_hash (Default) */ + HNS3_FDIR_INDEX_CONFIG_HASH, + + /* Use the rte_flow priority field as the hardware flow director index. */ + HNS3_FDIR_INDEX_CONFIG_PRIORITY +}; + /* * A structure used to define fields of a FDIR related info. */ @@ -238,6 +246,7 @@ struct hns3_fdir_info { struct hns3_fd_cfg fd_cfg; uint8_t vlan_match_mode; enum hns3_fdir_tuple_config tuple_cfg; + enum hns3_fdir_index_config index_cfg; }; struct hns3_adapter; @@ -254,5 +263,6 @@ int hns3_restore_all_fdir_filter(struct hns3_adapter *hns); enum hns3_fdir_tuple_config hns3_parse_tuple_config(const char *name); const char *hns3_tuple_config_name(enum hns3_fdir_tuple_config tuple_cfg); +const char *hns3_fdir_index_config_name(enum hns3_fdir_index_config cfg); #endif /* HNS3_FDIR_H */ diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c index 042359c1abf1..192ffc015e14 100644 --- a/drivers/net/hns3/hns3_flow.c +++ b/drivers/net/hns3/hns3_flow.c @@ -597,10 +597,6 @@ hns3_check_attr(const struct rte_flow_attr *attr, struct rte_flow_error *error) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr, "No support for transfer"); - if (attr->priority) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, - attr, "Not support priority"); if (attr->group) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_GROUP, @@ -1441,6 +1437,40 @@ is_tunnel_packet(enum rte_flow_item_type type) return false; } +static int +hns3_handle_attributes(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + struct hns3_fdir_rule *rule, + struct rte_flow_error *error) +{ + struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct hns3_fdir_info fdir = pf->fdir; + uint32_t rule_num; + + if (fdir.index_cfg != HNS3_FDIR_INDEX_CONFIG_PRIORITY) { + if (attr->priority == 0) + return 0; + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, + attr, "Not support priority"); + } + + rule_num = fdir.fd_cfg.rule_num[HNS3_FD_STAGE_1]; + if (attr->priority >= rule_num) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, + attr, "Priority out of range"); + + if (fdir.hash_map[attr->priority] != NULL) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, + attr, "Priority already exists"); + + rule->location = attr->priority; + + return 0; +} + /* * Parse the flow director rule. * The supported PATTERN: @@ -1468,6 +1498,7 @@ is_tunnel_packet(enum rte_flow_item_type type) */ static int hns3_parse_fdir_filter(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], struct hns3_fdir_rule *rule, @@ -1484,6 +1515,10 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Fdir not supported in VF"); + ret = hns3_handle_attributes(dev, attr, rule, error); + if (ret) + return ret; + step_mngr.items = first_items; step_mngr.count = RTE_DIM(first_items); for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { @@ -2248,7 +2283,7 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return hns3_parse_rss_filter(dev, pattern, actions, &conf->rss_conf, error); - return hns3_parse_fdir_filter(dev, pattern, actions, + return hns3_parse_fdir_filter(dev, attr, pattern, actions, &conf->fdir_conf, error); } -- 2.22.0